Depot Location (Distribution 2): Where Should New Depots Be Built


PROC OPTMODEL Statements and Output

The first several PROC OPTMODEL statements declare index sets and parameters and then read the input data:

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;

The following statements are the same as in Chapter 19:

   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];

The following statements declare the additional variables and constraints:

   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];

The following statements fix the IsOpen variable to 1 for depots that are not eligible to be closed (indicated by a missing value for close_savings in the input data):

   for {i in DEPOTS: close_savings[i] = .} do;
      close_savings[i] = 0;
      fix IsOpen[i] = 1;
   end;

The following statements declare FixedCost and VariableCost as implicit variables and TotalCost as the objective:

   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;

The following statements call the mixed integer linear programming solver and then print the various parts of the objective, the positive variables in the resulting optimal solution, and the additional decision variables:

   solve;
   print FixedCost VariableCost TotalCost;
   print {<i,j> in ARCS: Flow[i,j].sol > 0} Flow;
   print IsOpen Expand;
quit;

Figure 20.1 shows the output from the mixed integer linear programming solver.

Figure 20.1: Output from Mixed Integer Linear Programming Solver

The OPTMODEL Procedure

Problem Summary
Objective Sense Minimization
Objective Function TotalCost
Objective Type Linear
   
Number of Variables 49
Bounded Above 0
Bounded Below 42
Bounded Below and Above 5
Free 0
Fixed 2
Binary 7
Integer 0
   
Number of Constraints 22
Linear LE (<=) 22
Linear EQ (=) 0
Linear GE (>=) 0
Linear Range 0
   
Constraint Coefficients 125

Performance Information
Execution Mode Single-Machine
Number of Threads 4

Solution Summary
Solver MILP
Algorithm Branch and Cut
Objective Function TotalCost
Solution Status Optimal
Objective Value 174000
   
Relative Gap 0
Absolute Gap 0
Primal Infeasibility 0
Bound Infeasibility 0
Integer Infeasibility 0
   
Best Bound 174000
Nodes 1
Iterations 24
Presolve Time 0.00
Solution Time 0.01

FixedCost VariableCost TotalCost
-3000 177000 174000

[1] [2] Flow
Birmingham C2 10000
Birmingham C4 10000
Birmingham C5 50000
Brighton Birmingham 70000
Brighton London 10000
Brighton Northampton 25000
Exeter C3 40000
Liverpool C1 50000
Liverpool C6 20000
Liverpool Exeter 40000
London C5 10000
Northampton C4 25000

[1] IsOpen Expand
Birmingham 1 1
Bristol 0  
Exeter 1  
London 1  
Newcastle 0  
Northampton 1