Depot Location (Distribution 2) (mpex20)
/***************************************************************/
/* */
/* S A S S A M P L E L I B R A R Y */
/* */
/* NAME: mpex20 */
/* TITLE: Depot Location (Distribution 2) (mpex20) */
/* PRODUCT: OR */
/* SYSTEM: ALL */
/* PROCS: OPTMODEL */
/* DATA: */
/* */
/* SUPPORT: UPDATE: */
/* REF: */
/* MISC: Example 20 from the Mathematical Programming */
/* Examples book. */
/* */
/***************************************************************/
data arc_data;
input j $12. i $12. cost;
datalines;
Newcastle Liverpool 0.5
Birmingham Liverpool 0.5
Birmingham Brighton 0.3
London Liverpool 1.0
London Brighton 0.5
Exeter Liverpool 0.2
Exeter Brighton 0.2
C1 Liverpool 1.0
C1 Brighton 2.0
C1 Birmingham 1.0
C2 Newcastle 1.5
C2 Birmingham 0.5
C2 London 1.5
C3 Liverpool 1.5
C3 Newcastle 0.5
C3 Birmingham 0.5
C3 London 2.0
C3 Exeter 0.2
C4 Liverpool 2.0
C4 Newcastle 1.5
C4 Birmingham 1.0
C4 Exeter 1.5
C5 Birmingham 0.5
C5 London 0.5
C5 Exeter 0.5
C6 Liverpool 1.0
C6 Newcastle 1.0
C6 London 1.5
C6 Exeter 1.5
Bristol Liverpool 0.6
Bristol Brighton 0.4
Northampton Liverpool 0.4
Northampton Brighton 0.3
C1 Bristol 1.2
C2 Bristol 0.6
C2 Northampton 0.4
C3 Bristol 0.5
C4 Northampton 0.5
C5 Bristol 0.3
C5 Northampton 0.6
C6 Bristol 0.8
C6 Northampton 0.9
;
data customer_data;
input customer $ demand;
datalines;
C1 50000
C2 10000
C3 40000
C4 35000
C5 60000
C6 20000
;
data factory_data;
input factory $10. capacity;
datalines;
Liverpool 150000
Brighton 200000
;
data depot_data;
input depot $12. throughput cost savings;
datalines;
Newcastle 70000 0 10000
Birmingham 50000 0 .
London 100000 0 .
Exeter 40000 0 5000
Bristol 30000 12000 0
Northampton 25000 4000 0
;
data expand_depot_data;
input depot $12. throughput cost;
datalines;
Birmingham 20000 3000
;
%let max_num_depots = 4;
proc optmodel;
set <str,str> ARCS;
num cost {ARCS};
read data arc_data into ARCS=[i j] cost;
set <str> FACTORIES;
num capacity {FACTORIES};
read data factory_data into FACTORIES=[factory] capacity;
set <str> DEPOTS;
num throughput {DEPOTS};
num open_cost {DEPOTS};
num close_savings {DEPOTS};
read data depot_data into DEPOTS=[depot]
throughput open_cost=cost close_savings=savings;
set <str> EXPAND_DEPOTS;
num expand_throughput {EXPAND_DEPOTS};
num expand_cost {EXPAND_DEPOTS};
read data expand_depot_data into EXPAND_DEPOTS=[depot]
expand_throughput=throughput expand_cost=cost;
set <str> CUSTOMERS;
num demand {CUSTOMERS};
read data customer_data into CUSTOMERS=[customer] demand;
set NODES = FACTORIES union DEPOTS union CUSTOMERS;
num supply {NODES} init 0;
for {i in FACTORIES} supply[i] = capacity[i];
for {i in CUSTOMERS} supply[i] = -demand[i];
var Flow {ARCS} >= 0;
con Flow_balance_con {i in NODES}:
sum {<(i),j> in ARCS} Flow[i,j] - sum {<j,(i)> in ARCS} Flow[j,i]
<= supply[i];
var IsOpen {DEPOTS} binary;
var Expand {EXPAND_DEPOTS} binary;
con Max_num_depots_con:
sum {i in DEPOTS} IsOpen[i] <= &max_num_depots;
con Depot_con {i in DEPOTS}:
sum {<(i),j> in ARCS} Flow[i,j]
<= throughput[i] * IsOpen[i]
+ (if i in EXPAND_DEPOTS then expand_throughput[i] * Expand[i]);
con Expand_con {i in EXPAND_DEPOTS}:
Expand[i] <= IsOpen[i];
for {i in DEPOTS: close_savings[i] = .} do;
close_savings[i] = 0;
fix IsOpen[i] = 1;
end;
impvar FixedCost =
sum {depot in DEPOTS}
(open_cost[depot] * IsOpen[depot] -
close_savings[depot] * (1 - IsOpen[depot]))
+ sum {depot in EXPAND_DEPOTS} expand_cost[depot] * Expand[depot];
impvar VariableCost = sum {<i,j> in ARCS} cost[i,j] * Flow[i,j];
min TotalCost = FixedCost + VariableCost;
solve;
print FixedCost VariableCost TotalCost;
print {<i,j> in ARCS: Flow[i,j].sol > 0} Flow;
print IsOpen Expand;
quit;