## Multicommodity Transshipment w/Fixed Charges (misole02)

```/*******************************************************************/
/*                                                                 */
/*          S A S   S A M P L E   L I B R A R Y                    */
/*                                                                 */
/*    NAME: misole02                                               */
/*   TITLE: Multicommodity Transshipment w/Fixed Charges (misole02)*/
/* PRODUCT: OR                                                     */
/*  SYSTEM: ALL                                                    */
/*    KEYS: OR                                                     */
/*   PROCS: OPTMODEL                                               */
/*    DATA:                                                        */
/*                                                                 */
/* SUPPORT:                             UPDATE:                    */
/*     REF:                                                        */
/*    MISC: Example 2 from the Mixed Integer Linear Programming    */
/*          Solver chapter of Mathematical Programming.            */
/*                                                                 */
/*******************************************************************/

title 'Multicommodity Transshipment Problem with Fixed Charges';

data commodity_data;
do c = 1 to 4;
output;
end;
run;

data arc_data;
input from \$ to \$ c1 c2 c3 c4 fx;
datalines;
farm-a  Chicago 20 15 17 22 100
farm-b  Chicago 15 15 15 30  75
farm-c  Chicago 30 30 10 10 100
farm-a  StLouis 30 25 27 22 150
farm-c  StLouis 10 9 11 10   75
Chicago NY      75 75 75 75 200
StLouis NY      80 80 80 80 200
;
run;

data supply_data;
input node \$ sd1 sd2 sd3 sd4;
datalines;
farm-a  100  100  40   .
farm-b  100  200  50  50
farm-c   40  100  75 100
NY     -150 -200 -50 -75
;
run;

proc optmodel;
set COMMODITIES;

set <str,str> ARCS;
num unit_cost {ARCS, COMMODITIES};
num fixed_charge {ARCS};
read data arc_data into ARCS=[from to] {c in COMMODITIES}
<unit_cost[from,to,c]=col('c'||c)> fixed_charge=fx;
print unit_cost fixed_charge;

set <str> NODES = union {<i,j> in ARCS} {i,j};
num supply {NODES, COMMODITIES} init 0;
read data supply_data nomiss into [node] {c in COMMODITIES}
<supply[node,c]=col('sd'||c)>;
print supply;

var AmountShipped {ARCS, c in COMMODITIES} >= 0 <= sum {i in NODES}
max(supply[i,c],0);

/* UseArc[i,j] = 1 if arc (i,j) is used, 0 otherwise */
var UseArc {ARCS} binary;

/* TotalCost = variable costs + fixed charges */
min TotalCost = sum {<i,j> in ARCS, c in COMMODITIES}
unit_cost[i,j,c] * AmountShipped[i,j,c]
+ sum {<i,j> in ARCS} fixed_charge[i,j] * UseArc[i,j];

con flow_balance {i in NODES, c in COMMODITIES}:
sum {<(i),j> in ARCS} AmountShipped[i,j,c] -
sum {<j,(i)> in ARCS} AmountShipped[j,i,c] <= supply[i,c];

/* if AmountShipped[i,j,c] > 0 then UseArc[i,j] = 1 */
con fixed_charge_def {<i,j> in ARCS, c in COMMODITIES}:
AmountShipped[i,j,c] <= AmountShipped[i,j,c].ub * UseArc[i,j];

solve;

print AmountShipped;

create data solution from [from to commodity]={<i,j> in ARCS,
c in COMMODITIES: AmountShipped[i,j,c].sol ne 0} amount=AmountShipped;
quit;

/* print the solution */
proc print data=solution;
run;

```