Multicommodity Transshipment w/ Fixed Charges (milpsl2)
/*******************************************************************/
/* */
/* S A S S A M P L E L I B R A R Y */
/* */
/* NAME: milpsl2 */
/* TITLE: Multicommodity Transshipment w/ Fixed Charges (milpsl2)*/
/* 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;
read data commodity_data into COMMODITIES=[c];
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;