## 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 */
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;
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;

```