Food Manufacture 2 (mpex02)
/***************************************************************/
/* */
/* S A S S A M P L E L I B R A R Y */
/* */
/* NAME: mpex02 */
/* TITLE: Food Manufacture 2 (mpex02) */
/* PRODUCT: OR */
/* SYSTEM: ALL */
/* KEYS: OR */
/* PROCS: OPTMODEL */
/* DATA: */
/* */
/* SUPPORT: UPDATE: */
/* REF: */
/* MISC: Example 02 from the Mathematical Programming */
/* Examples book. */
/* */
/***************************************************************/
data cost_data;
input veg1-veg2 oil1-oil3;
datalines;
110 120 130 110 115
130 130 110 90 115
110 140 130 100 95
120 110 120 120 125
100 120 150 110 105
90 100 140 80 135
;
data hardness_data;
input oil $ hardness;
datalines;
veg1 8.8
veg2 6.1
oil1 2.0
oil2 4.2
oil3 5.0
;
%let revenue_per_ton = 150;
%let veg_ub = 200;
%let nonveg_ub = 250;
%let store_ub = 1000;
%let storage_cost_per_ton = 5;
%let hardness_lb = 3;
%let hardness_ub = 6;
%let init_storage = 500;
%let max_num_oils_used = 3;
%let min_oil_used_threshold = 20;
proc optmodel;
set <str> OILS;
num hardness {OILS};
read data hardness_data into OILS=[oil] hardness;
set PERIODS;
num cost {OILS, PERIODS};
read data cost_data into PERIODS=[_N_] {oil in OILS}
<cost[oil,_N_]=col(oil)>;
var Buy {OILS, PERIODS} >= 0;
var Use {OILS, PERIODS} >= 0;
impvar Manufacture {period in PERIODS} = sum {oil in OILS} Use[oil,period];
num last_period = max {period in PERIODS} period;
var Store {OILS, PERIODS union {0}} >= 0 <= &store_ub;
for {oil in OILS} do;
fix Store[oil,0] = &init_storage;
fix Store[oil,last_period] = &init_storage;
end;
set VEG = {oil in OILS: substr(oil,1,3) = 'veg'};
set NONVEG = OILS diff VEG;
impvar Revenue =
sum {period in PERIODS} &revenue_per_ton * Manufacture[period];
impvar RawCost =
sum {oil in OILS, period in PERIODS} cost[oil,period] * Buy[oil,period];
impvar StorageCost =
sum {oil in OILS, period in PERIODS}
&storage_cost_per_ton * Store[oil,period];
max Profit = Revenue - RawCost - StorageCost;
con Veg_ub_con {period in PERIODS}:
sum {oil in VEG} Use[oil,period] <= &veg_ub;
con Nonveg_ub_con {period in PERIODS}:
sum {oil in NONVEG} Use[oil,period] <= &nonveg_ub;
con Flow_balance_con {oil in OILS, period in PERIODS}:
Store[oil,period-1] + Buy[oil,period]
= Use[oil,period] + Store[oil,period];
con Hardness_ub_con {period in PERIODS}:
sum {oil in OILS} hardness[oil] * Use[oil,period]
>= &hardness_lb * Manufacture[period];
con Hardness_lb_con {period in PERIODS}:
sum {oil in OILS} hardness[oil] * Use[oil,period]
<= &hardness_ub * Manufacture[period];
var IsUsed {OILS, PERIODS} binary;
for {period in PERIODS} do;
for {oil in VEG} Use[oil,period].ub = &veg_ub;
for {oil in NONVEG} Use[oil,period].ub = &nonveg_ub;
end;
con Link {oil in OILS, period in PERIODS}:
Use[oil,period] <= Use[oil,period].ub * IsUsed[oil,period];
con Logical1 {period in PERIODS}:
sum {oil in OILS} IsUsed[oil,period] <= &max_num_oils_used;
con Logical2 {oil in OILS, period in PERIODS}:
Use[oil,period] >= &min_oil_used_threshold * IsUsed[oil,period];
con Logical3 {oil in {'veg1','veg2'}, period in PERIODS}:
IsUsed[oil,period] <= IsUsed['oil3',period];
num hardness_sol {period in PERIODS} =
(sum {oil in OILS} hardness[oil] * Use[oil,period].sol)
/ Manufacture[period].sol;
solve;
print Buy Use Store IsUsed Manufacture hardness_sol Logical1.body;
create data sol_data1 from [oil period] Buy Use Store IsUsed;
create data sol_data2 from [period] Manufacture;
quit;