Transshipment problem

Widgetco manufactures widgets at two factories, one in Memphis and one in Denver. The Memphis factory can produce as many as 150 widgets per day, and the Denver factory can produce as many as 200 widgets per day. Widgets are shipped by air to customers in Los Angeles and Boston. The customers in each city require 130 widgets per day. Because of the deregulation of airfares, Widgetco believes that it may be cheaper to first fly some widgets to New York or Chicago and then fly them to their final destinations. The costs of flying a widget are shown in Table 58. Widgetco wants to minimize the total cost of shipping the required widgets to its customers.


In [5]:
from gurobipy import *

m = Model("Transshipment Prolem")

NUMBER_OF_SOURCES =  4
NUMBER_OF_TARGETS = 5

cost_matrix = [[8, 13, 25, 28, 0], [15,12,26,25, 0], [0, 6, 16, 17, 0], [6, 0 ,14, 16, 0]]

supply = [150,200, 350,350]
demand = [350,350,130,130,90]

variables = [ 
    [m.addVar(vtype=GRB.CONTINUOUS, 
              obj = cost_matrix[source][target], 
              name="(node-%d%d)" % (target+1, source+1))
     for target in range(NUMBER_OF_TARGETS) ] 
        for source in range(NUMBER_OF_SOURCES)
    ]
            

m.modelSense = GRB.MINIMIZE
m.update()

In [7]:
for source in range(NUMBER_OF_SOURCES):
    m.addConstr(
        quicksum(variables[source][target] for target in range(NUMBER_OF_TARGETS)) == supply[source], 
        "supply requirment for source - %d" % (source + 1))

for target in range(NUMBER_OF_TARGETS):
    m.addConstr(
        quicksum(variables[source][target] for source in range(NUMBER_OF_SOURCES)) == demand[target], 
        "demand requirment for target - %d" % (target + 1))

m.optimize()

for v in m.getVars():
    print (v.varName, v.x)
    

print (m.getObjective().getValue())


Optimize a model with 9 rows, 20 columns and 40 nonzeros
Coefficient statistics:
  Matrix range     [1e+00, 1e+00]
  Objective range  [6e+00, 3e+01]
  Bounds range     [0e+00, 0e+00]
  RHS range        [9e+01, 4e+02]
Presolve time: 0.02s
Presolved: 9 rows, 20 columns, 40 nonzeros

Iteration    Objective       Primal Inf.    Dual Inf.      Time
       0    3.9000000e+03   6.300000e+02   0.000000e+00      0s
       3    6.3700000e+03   0.000000e+00   0.000000e+00      2s

Solved in 3 iterations and 1.53 seconds
Optimal objective  6.370000000e+03
(node-11) 130.0
(node-21) 0.0
(node-31) 0.0
(node-41) 0.0
(node-51) 20.0
(node-12) 0.0
(node-22) 0.0
(node-32) 0.0
(node-42) 130.0
(node-52) 70.0
(node-13) 220.0
(node-23) 0.0
(node-33) 130.0
(node-43) 0.0
(node-53) 0.0
(node-14) 0.0
(node-24) 350.0
(node-34) 0.0
(node-44) 0.0
(node-54) 0.0
6370.0