Model Construction (omod3)
/***************************************************************/
/* */
/* S A S S A M P L E L I B R A R Y */
/* */
/* NAME: omod3 */
/* TITLE: Model Construction (omod3) */
/* PRODUCT: OR */
/* SYSTEM: ALL */
/* KEYS: OR */
/* PROCS: OPTMODEL, TABULATE */
/* DATA: */
/* */
/* SUPPORT: UPDATE: */
/* REF: */
/* MISC: Example 3 from the OPTMODEL chapter of */
/* Mathematical Programming. */
/* */
/***************************************************************/
title 'An Assignment Problem';
data grade(drop=i);
do i = 1 to 6;
grade = 'grade'||put(i,1.);
output;
end;
run;
data object;
input machine customer
grade1 grade2 grade3 grade4 grade5 grade6;
datalines;
1 1 102 140 105 105 125 148
1 2 115 133 118 118 143 166
1 3 70 108 83 83 88 86
1 4 79 117 87 87 107 105
1 5 77 115 90 90 105 148
2 1 123 150 125 124 154 .
2 2 130 157 132 131 166 .
2 3 103 130 115 114 129 .
2 4 101 128 108 107 137 .
2 5 118 145 130 129 154 .
3 1 83 . . 97 122 147
3 2 119 . . 133 163 180
3 3 67 . . 91 101 101
3 4 85 . . 104 129 129
3 5 90 . . 114 134 179
4 1 108 121 79 . 112 132
4 2 121 132 92 . 130 150
4 3 78 91 59 . 77 72
4 4 100 113 76 . 109 104
4 5 96 109 77 . 105 145
;
data demand;
input customer
grade1 grade2 grade3 grade4 grade5 grade6;
datalines;
1 100 100 150 150 175 250
2 300 125 300 275 310 325
3 400 0 400 500 340 0
4 250 0 750 750 0 0
5 0 600 300 0 210 360
;
data resource;
input machine
grade1 grade2 grade3 grade4 grade5 grade6 avail;
datalines;
1 .250 .275 .300 .350 .310 .295 744
2 .300 .300 .305 .315 .320 . 244
3 .350 . . .320 .315 .300 790
4 .280 .275 .260 . .250 .295 672
;
proc optmodel;
/* declare index sets */
set CUSTOMERS;
set <str> GRADES;
set MACHINES;
/* declare parameters */
num return {CUSTOMERS, GRADES, MACHINES} init 0;
num demand {CUSTOMERS, GRADES};
num cost {GRADES, MACHINES} init 0;
num avail {MACHINES};
/* read the set of grades */
read data grade into GRADES=[grade];
/* read the set of customers and their demands */
read data demand
into CUSTOMERS=[customer]
{j in GRADES} <demand[customer,j]=col(j)>;
/* read the set of machines, costs, and availability */
read data resource nomiss
into MACHINES=[machine]
{j in GRADES} <cost[j,machine]=col(j)>
avail;
/* read objective data */
read data object nomiss
into [machine customer]
{j in GRADES} <return[customer,j,machine]=col(j)>;
/* declare the model */
var AmountProduced {CUSTOMERS, GRADES, MACHINES} >= 0;
max TotalReturn = sum {i in CUSTOMERS, j in GRADES, k in MACHINES}
return[i,j,k] * AmountProduced[i,j,k];
con req_demand {i in CUSTOMERS, j in GRADES}:
sum {k in MACHINES} AmountProduced[i,j,k] = demand[i,j];
con req_avail {k in MACHINES}:
sum {i in CUSTOMERS, j in GRADES}
cost[j,k] * AmountProduced[i,j,k] <= avail[k];
/* call the solver and save the results */
solve;
create data solution
from [customer grade machine] = {i in CUSTOMERS, j in GRADES,
k in MACHINES: AmountProduced[i,j,k].sol ne 0}
amount=AmountProduced;
/* print optimal solution */
print AmountProduced;
quit;
proc tabulate data=solution;
class customer grade machine;
var amount;
table (machine*customer), (grade*amount=''*sum='');
run;