Distribution 1: Which Factories and Depots to Supply Which Customers

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};
   read data depot_data into DEPOTS=[depot] throughput;

   set <str> CUSTOMERS;
   num demand {CUSTOMERS};
   read data customer_data into CUSTOMERS=[customer] demand;

The following statements use the UNION set operator to declare the NODES index set, declare the supply parameter with an initial value of 0, and populate supply for both factories and customers:

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

The following statements declare the variables, constraints, and TotalCost objective:

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

   con Depot_con {i in DEPOTS}:
      sum {<(i),j> in ARCS} Flow[i,j] <= throughput[i];

   min TotalCost = sum {<i,j> in ARCS} cost[i,j] * Flow[i,j];

The following statements call the default linear programming algorithm (which is the dual simplex algorithm), print the positive variables in the resulting optimal solution, and print the left-hand side (.body), right-hand side (.ub), and dual value (.dual) of each constraint:

   put 'Minimizing TotalCost...';
   solve;
   print {<i,j> in ARCS: Flow[i,j].sol > 0} Flow;
   print Flow_balance_con.body Flow_balance_con.ub Flow_balance_con.dual;
   print Depot_con.body Depot_con.ub Depot_con.dual;

Figure 19.2 shows the output when you use the (default) dual simplex algorithm.

Figure 19.2: Output from Dual Simplex Algorithm, Minimizing TotalCost

The OPTMODEL Procedure

Problem Summary
Objective SenseMinimization
Objective FunctionTotalCost
Objective TypeLinear
  
Number of Variables29
Bounded Above0
Bounded Below29
Bounded Below and Above0
Free0
Fixed0
  
Number of Constraints16
Linear LE (<=)16
Linear EQ (=)0
Linear GE (>=)0
Linear Range0
  
Constraint Coefficients75

Solution Summary
SolverLP
AlgorithmDual Simplex
Objective FunctionTotalCost
Solution StatusOptimal
Objective Value198500
  
Primal Infeasibility0
Dual Infeasibility5.551115E-17
Bound Infeasibility0
  
Iterations14
Presolve Time0.00
Solution Time0.01

[1][2]Flow
BirminghamC210000
BirminghamC435000
BirminghamC55000
BrightonBirmingham50000
BrightonLondon55000
ExeterC340000
LiverpoolC150000
LiverpoolC620000
LiverpoolExeter40000
LondonC555000

[1]Flow_balance_con.BODYFlow_balance_con.UBFlow_balance_con.DUAL
Birmingham00-0.3
Brighton1050002000000.0
C1-50000-50000-1.0
C2-10000-10000-1.0
C3-40000-40000-1.0
C4-35000-35000-1.5
C5-60000-60000-1.0
C6-20000-20000-1.0
Exeter00-0.2
Liverpool1100001500000.0
London00-0.5
Newcastle00-0.5

[1]Depot_con.BODYDepot_con.UBDepot_con.DUAL
Birmingham5000050000-0.2
Exeter4000040000-0.6
London550001000000.0
Newcastle0700000.0


The following statements call the network simplex linear programming algorithm and print the same solution information as before:

   put 'Minimizing TotalCost by using network simplex...';
   solve with LP / algorithm=ns;
   print {<i,j> in ARCS: Flow[i,j].sol > 0} Flow;
   print Flow_balance_con.body Flow_balance_con.ub Flow_balance_con.dual;
   print Depot_con.body Depot_con.ub Depot_con.dual;

Figure 19.3 shows the output when you use the ALGORITHM=NS option to invoke the network simplex algorithm.

Figure 19.3: Output from Network Simplex Algorithm, Minimizing TotalCost

Problem Summary
Objective SenseMinimization
Objective FunctionTotalCost
Objective TypeLinear
  
Number of Variables29
Bounded Above0
Bounded Below29
Bounded Below and Above0
Free0
Fixed0
  
Number of Constraints16
Linear LE (<=)16
Linear EQ (=)0
Linear GE (>=)0
Linear Range0
  
Constraint Coefficients75

Solution Summary
SolverLP
AlgorithmNetwork Simplex
Objective FunctionTotalCost
Solution StatusOptimal
Objective Value198500
  
Primal Infeasibility0
Dual Infeasibility5.551115E-17
Bound Infeasibility0
  
Iterations15
Iterations25
Presolve Time0.00
Solution Time0.01

[1][2]Flow
BirminghamC210000
BirminghamC435000
BirminghamC55000
BrightonBirmingham50000
BrightonLondon55000
ExeterC340000
LiverpoolC150000
LiverpoolC620000
LiverpoolExeter40000
LondonC555000

[1]Flow_balance_con.BODYFlow_balance_con.UBFlow_balance_con.DUAL
Birmingham00-0.3
Brighton1050002000000.0
C1-50000-50000-1.0
C2-10000-10000-1.0
C3-40000-40000-1.0
C4-35000-35000-1.5
C5-60000-60000-1.0
C6-20000-20000-1.0
Exeter00-0.2
Liverpool1100001500000.0
London00-0.5
Newcastle00-0.5

[1]Depot_con.BODYDepot_con.UBDepot_con.DUAL
Birmingham5000050000-0.2
Exeter4000040000-0.6
London550001000000.0
Newcastle0700000.0


The following statements call the linear programming solver to minimize NonpreferredFlow and print both objectives, the positive variables in the resulting optimal solution, and the flow along nonpreferred arcs:

   set <str,str> PREFERRED_ARCS;
   read data preferred_arc_data into PREFERRED_ARCS=[i j];
   set CUSTOMERS_WITH_PREFERENCES = setof {<i,j> in PREFERRED_ARCS} j;
   min NonpreferredFlow =
      sum {<i,j> in ARCS diff PREFERRED_ARCS: j in CUSTOMERS_WITH_PREFERENCES}
         Flow[i,j];

   put 'Minimizing NonpreferredFlow...';
   solve;
   print TotalCost NonpreferredFlow;
   print {<i,j> in ARCS: Flow[i,j].sol > 0} Flow;
   print
      {<i,j> in ARCS diff PREFERRED_ARCS: j in CUSTOMERS_WITH_PREFERENCES}
         Flow;

Figure 19.4 shows the output from the linear programming solver.

Figure 19.4: Output from Linear Programming Solver, Minimizing NonpreferredFlow

Problem Summary
Objective SenseMinimization
Objective FunctionNonpreferredFlow
Objective TypeLinear
  
Number of Variables29
Bounded Above0
Bounded Below29
Bounded Below and Above0
Free0
Fixed0
  
Number of Constraints16
Linear LE (<=)16
Linear EQ (=)0
Linear GE (>=)0
Linear Range0
  
Constraint Coefficients75

Solution Summary
SolverLP
AlgorithmDual Simplex
Objective FunctionNonpreferredFlow
Solution StatusOptimal
Objective Value10000
  
Primal Infeasibility0
Dual Infeasibility0
Bound Infeasibility0
  
Iterations15
Presolve Time0.00
Solution Time0.00

TotalCostNonpreferredFlow
27900010000

[1][2]Flow
BirminghamC550000
BrightonBirmingham50000
BrightonExeter20000
BrightonLondon10000
ExeterC620000
LiverpoolC150000
LiverpoolC435000
LiverpoolNewcastle65000
LondonC510000
NewcastleC210000
NewcastleC355000

[1][2]Flow
BirminghamC10
BirminghamC20
BrightonC10
ExeterC50
LiverpoolC60
LondonC20
LondonC510000
NewcastleC60


The following CON statement declares a constraint that limits NonpreferredFlow to the minimum value found in the previous solve:

   con Objective_cut:
      NonpreferredFlow <= NonpreferredFlow.sol;

The following statements call the linear programming solver to minimize TotalCost with a constrained NonpreferredFlow and print the same solution information as before:

   put 'Minimizing TotalCost with constrained NonpreferredFlow...';
   solve obj TotalCost;
   print TotalCost NonpreferredFlow;
   print {<i,j> in ARCS: Flow[i,j].sol > 0} Flow;
   print
      {<i,j> in ARCS diff PREFERRED_ARCS: j in CUSTOMERS_WITH_PREFERENCES}
         Flow;
quit;

Figure 19.5 shows the output from the linear programming solver. As expected, NonpreferredFlow remains at its minimum value and TotalCost is less than its value from Figure 19.4.

Figure 19.5: Output from Linear Programming Solver, Minimizing TotalCost with Constrained NonpreferredFlow

Problem Summary
Objective SenseMinimization
Objective FunctionTotalCost
Objective TypeLinear
  
Number of Variables29
Bounded Above0
Bounded Below29
Bounded Below and Above0
Free0
Fixed0
  
Number of Constraints17
Linear LE (<=)17
Linear EQ (=)0
Linear GE (>=)0
Linear Range0
  
Constraint Coefficients83

Solution Summary
SolverLP
AlgorithmDual Simplex
Objective FunctionTotalCost
Solution StatusOptimal
Objective Value246000
  
Primal Infeasibility0
Dual Infeasibility1.665335E-16
Bound Infeasibility0
  
Iterations15
Presolve Time0.00
Solution Time0.00

TotalCostNonpreferredFlow
24600010000

[1][2]Flow
BirminghamC550000
BrightonBirmingham50000
BrightonLondon30000
ExeterC340000
LiverpoolC150000
LiverpoolC435000
LiverpoolExeter40000
LiverpoolNewcastle10000
LondonC510000
LondonC620000
NewcastleC210000

[1][2]Flow
BirminghamC10
BirminghamC20
BrightonC10
ExeterC50
LiverpoolC60
LondonC20
LondonC510000
NewcastleC60


Last updated: October 22, 2018