Introduction to Optimization examples (intmplp0)
/***************************************************************/
/* */
/* S A S S A M P L E L I B R A R Y */
/* */
/* NAME: intmplp0 */
/* TITLE: Introduction to Optimization examples (intmplp0) */
/* PRODUCT: OR, GRAPH */
/* SYSTEM: ALL */
/* KEYS: OR */
/* PROCS: LP, NETFLOW, GCHART */
/* DATA: */
/* */
/* SUPPORT: UPDATE: */
/* REF: */
/* MISC: Examples from the Introduction to Optimization */
/* chapter of Mathematical Programming Legacy */
/* Procedures. */
/* */
/***************************************************************/
data factory;
input _id_ $ CHOCO TOFFEE _type_ $ _rhs_;
datalines;
object 0.25 0.75 MAX .
process1 15.00 40.00 LE 27000
process2 0.00 56.25 LE 27000
process3 18.75 0.00 LE 27000
process4 12.00 50.00 LE 27000
;
proc lp data=factory;
run;
/***************************************************************
Model Building: PROC LP
***************************************************************/
data sp_factory;
format _type_ $8. _row_ $10. _col_ $10.;
input _type_ $_row_ $ _col_ $ _coef_;
datalines;
max object . .
. object chocolate .25
. object toffee .75
le process1 . .
. process1 chocolate 15
. process1 toffee 40
. process1 _RHS_ 27000
le process2 . .
. process2 toffee 56.25
. process2 _RHS_ 27000
le process3 . .
. process3 chocolate 18.75
. process3 _RHS_ 27000
le process4 . .
. process4 chocolate 12
. process4 toffee 50
. process4 _RHS_ 27000
;
proc lp data=sp_factory sparsedata;
run;
data manfg;
format product $12.;
input product $ object process1 - process4 ;
datalines;
chocolate .25 15 0.00 18.75 12
toffee .75 40 56.25 0.00 50
licorice 1.00 29 30.00 20.00 20
jelly_beans .85 10 0.00 30.00 10
_RHS_ . 27000 27000 27000 27000
;
data model;
array process {5} object process1-process4;
format _type_ $8. _row_ $12. _col_ $12. ;
keep _type_ _row_ _col_ _coef_;
set manfg; /* read the manufacturing data */
/* build the object function */
if _n_=1 then do;
_type_='max'; _row_='object'; _col_=' '; _coef_=.;
output;
end;
/* build the constraints */
do i=1 to 5;
if i>1 then do;
_type_='le'; _row_='process'||put(_i_-1,1.);
end;
else _row_='object';
_col_=product; _coef_=process[i];
output;
end;
run;
proc print data=model;
run;
/***************************************************************
Model Building: PROC NETFLOW
***************************************************************/
data nodes;
format node $10. ;
input node $ supdem;
datalines;
customer_1 -100
customer_2 -200
customer_3 -50
factory_1 500
factory_2 500
;
data network;
format from $12. to $12.;
input from $ to $ cost ;
datalines;
factory_1 warehouse_1 10
factory_2 warehouse_1 5
factory_1 warehouse_2 7
factory_2 warehouse_2 9
warehouse_1 customer_1 3
warehouse_1 customer_2 4
warehouse_1 customer_3 4
warehouse_2 customer_1 5
warehouse_2 customer_2 5
warehouse_2 customer_3 6
;
proc netflow arcout=arc_sav
arcdata=network nodedata=nodes;
node node; /* node data set information */
supdem supdem;
tail from; /* arc data set information */
head to;
cost cost;
run;
proc print;
var from to cost _capac_ _lo_ _supply_ _demand_
_flow_ _fcost_ _rcost_;
sum _fcost_;
run;
/***************************************************************
Matrix Generation
***************************************************************/
data material;
format descpt $20.;
input descpt $ cost supply;
datalines;
silk_material .21 25.8
polyester_material .6 22.0
cotton_material .9 13.6
;
data tie;
format descpt $20.;
input descpt $ price contract demand;
datalines;
all_silk 6.70 6.0 7.00
all_polyester 3.55 10.0 14.00
poly_cotton_blend 4.31 13.0 16.00
cotton_poly_blend 4.81 6.0 8.50
;
data manfg;
format descpt $20.;
input descpt $ silk poly cotton;
datalines;
all_silk 100 0 0
all_polyester 0 100 0
poly_cotton_blend 0 50 50
cotton_poly_blend 0 30 70
;
data model;
array raw_mat {3} $ 20 ;
array raw_comp {3} silk poly cotton;
length _type_ $ 8 _col_ $ 20 _row_ $ 20 _coef_ 8 ;
keep _type_ _col_ _row_ _coef_ ;
/* define the objective, lower, and upper bound rows */
_row_='profit'; _type_='max'; output;
_row_='lower'; _type_='lowerbd'; output;
_row_='upper'; _type_='upperbd'; output;
_type_=' ';
/* the object and upper rows for the raw materials */
do i=1 to 3;
set material;
raw_mat[i]=descpt; _col_=descpt;
_row_='profit'; _coef_=-cost; output;
_row_='upper'; _coef_=supply; output;
end;
/* the object, upper, and lower rows for the products */
do i=1 to 4;
set tie;
_col_=descpt;
_row_='profit'; _coef_=price; output;
_row_='lower'; _coef_=contract; output;
_row_='upper'; _coef_=demand; output;
end;
/* the coefficient matrix for manufacturing */
_type_='eq';
do i=1 to 4; /* loop for each raw material */
set manfg;
do j=1 to 3; /* loop for each product */
_col_=descpt; /* % of material in product */
_row_ = raw_mat[j];
_coef_ = raw_comp[j]/100;
output;
_col_ = raw_mat[j]; _coef_ = -1;
output;
/* the right-hand side */
if i=1 then do;
_col_='_RHS_';
_coef_=0;
output;
end;
end;
_type_=' ';
end;
stop;
run;
proc lp sparsedata primalout=solution;
proc print;
id _var_;
var _lbound_--_r_cost_;
run;
/***************************************************************
Exploiting Model Structure
***************************************************************/
data network;
format from $12. to $12.;
input from $ to $ cost ;
datalines;
factory_1 warehouse_1 10
factory_2 warehouse_1 5
factory_1 warehouse_2 7
factory_2 warehouse_2 9
warehouse_1 customer_1 3
warehouse_1 customer_2 4
warehouse_1 customer_3 4
warehouse_2 customer_1 5
warehouse_2 customer_2 5
warehouse_2 customer_3 6
;
data nodes;
format node $12. ;
input node $ supdem;
datalines;
customer_1 -100
customer_2 -200
customer_3 -50
factory_1 500
factory_2 500
;
data side_con;
format _type_ $8. _row_ $8. _col_ $21. ;
input _type_ _row_ _col_ _coef_ ;
datalines;
eq balance . .
. balance factory_1_warehouse_1 1
. balance factory_1_warehouse_2 1
. balance factory_2_warehouse_1 -1
. balance factory_2_warehouse_2 -1
. balance diff -1
lo lowerbd diff -100
up upperbd diff 100
;
proc netflow
conout=con_sav
arcdata=network nodedata=nodes condata=side_con
sparsecondata ;
node node;
supdem supdem;
tail from;
head to;
cost cost;
run;
proc print;
var from to _name_ cost _capac_ _lo_ _supply_ _demand_
_flow_ _fcost_ _rcost_;
sum _fcost_;
run;
/***************************************************************
Report Writing: The DATA Step
***************************************************************/
data product(keep= _var_ _value_ _price_ revenue)
material(keep=_var_ _value_ _price_ cost);
set solution;
if _price_>0 then do;
revenue=_price_*_value_; output product;
end;
else if _price_<0 then do;
_price_=-_price_;
cost = _price_*_value_; output material;
end;
run;
/* display the product report */
proc print data=product;
id _var_;
var _value_ _price_ revenue ;
sum revenue;
title 'Revenue Generated from Tie Sales';
run;
/* display the materials report */
proc print data=material;
id _var_;
var _value_ _price_ cost;
sum cost;
title 'Cost of Raw Materials';
run;
/***************************************************************
Report Writing: Other Reporting Procedures
***************************************************************/
title;
proc gchart data=con_sav;
hbar from / sumvar=_flow_;
run;
proc gchart data=product;
pie _var_ / sumvar=revenue;
title h=2.5 'Projected Tie Sales Revenue';
run;