Lumber Transportation Problem#
Reeb and S. Leavengood
Millco has three wood mills and is planning three new logging sites. Each mill has a maximum capacity and each logging site can harvest a certain number of truckloads of lumber per day. The cost of a haul is $2/mile of distance. If distances from logging sites to mills are given below, how should the hauls be routed to minimize hauling costs while meeting all demands?
Logging Site |
Mill A |
Mill B |
Mill C |
Max loads per day |
---|---|---|---|---|
1 |
8 |
15 |
50 |
20 |
2 |
10 |
17 |
20 |
30 |
3 |
30 |
26 |
15 |
45 |
Mill demand |
30 |
35 |
30 |
[1]:
from gamspy import Container, Set, Alias, Parameter, Variable, Equation, Model, Sum, Sense
import numpy as np
[2]:
m = Container()
# Model sets and parameters
sites = Set(container=m, name="sites", records=["1", "2", "3"])
mills = Set(container=m, name="mills", records=["Mill A", "Mill B", "Mill C"])
dist = Parameter(
container=m,
name="dist",
domain=[sites, mills],
records=np.array([[8, 15, 50], [10, 17, 20], [30, 26, 15]]),
)
supply = Parameter(
container=m, name="supply", domain=sites, records=np.array([20, 30, 45])
)
demand = Parameter(
container=m, name="demand", domain=mills, records=np.array([30, 35, 30])
)
cost_per_haul = 4
# Model variables
ship = Variable(container=m, name="ship", type="positive", domain=[sites, mills])
defcost = cost_per_haul * Sum([sites, mills], ship[sites, mills] * dist[sites, mills])
defsupply = Equation(container=m, name="defsupply", domain=sites)
defsupply[sites] = Sum(mills, ship[sites, mills]) == supply[sites]
defdemand = Equation(container=m, name="defdemand", domain=mills)
defdemand[mills] = Sum(sites, ship[sites, mills]) == demand[mills]
millco = Model(
container=m,
name="millco",
equations=m.getEquations(),
problem="LP",
sense=Sense.MIN,
objective=defcost,
)
[3]:
millco.solve()
[3]:
Solver Status | Model Status | Objective | Num of Equations | Num of Variables | Model Type | Solver | Solver Time | |
---|---|---|---|---|---|---|---|---|
0 | Normal | OptimalGlobal | 5760 | 7 | 10 | LP | CPLEX | 0 |
[4]:
ship.records.pivot(index='sites', columns='mills', values='level')
[4]:
mills | Mill A | Mill B | Mill C |
---|---|---|---|
sites | |||
1 | 0.0 | 20.0 | 0.0 |
2 | 30.0 | 0.0 | 0.0 |
3 | 0.0 | 15.0 | 30.0 |
[5]:
print(f'Total cost will be {millco.objective_value}')
Total cost will be 5760.0
[6]:
m = Container()
# Generic Model sets and parameters
i = Set(
container=m,
name="i",
records=["i" + str(i) for i in range(6)],
description="equation index",
)
j = Set(
container=m,
name="j",
records=["j" + str(j) for j in range(9)],
description="variable index",
)
A = Parameter(
container=m,
name="A",
domain=[i, j],
records=np.array(
[
[1, 1, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 1, 1],
[1, 0, 0, 1, 0, 0, 1, 0, 0],
[0, 1, 0, 0, 1, 0, 0, 1, 0],
[0, 0, 1, 0, 0, 1, 0, 0, 1],
]
),
)
b = Parameter(
container=m, name="b", domain=i, records=np.array([20, 30, 45, 30, 35, 30])
)
c = Parameter(
container=m,
name="c",
domain=j,
records=np.array([8, 15, 50, 10, 17, 20, 30, 26, 15]),
)
x = Variable(container=m, name="x", type="positive", domain=j)
obj = 4 * Sum(j, c[j] * x[j])
e = Equation(container=m, name="e", domain=i)
e[i] = Sum(j, A[i, j] * x[j]) == b[i]
generic_model = Model(
container=m,
name="generic_model",
equations=m.getEquations(),
problem="LP",
sense=Sense.MIN,
objective=obj,
)
[7]:
generic_model.solve()
[7]:
Solver Status | Model Status | Objective | Num of Equations | Num of Variables | Model Type | Solver | Solver Time | |
---|---|---|---|---|---|---|---|---|
0 | Normal | OptimalGlobal | 5760 | 7 | 10 | LP | CPLEX | 0 |
[8]:
x.records
[8]:
j | level | marginal | lower | upper | scale | |
---|---|---|---|---|---|---|
0 | j0 | 0.0 | -0.0 | 0.0 | inf | 1.0 |
1 | j1 | 20.0 | 0.0 | 0.0 | inf | 1.0 |
2 | j2 | 0.0 | 184.0 | 0.0 | inf | 1.0 |
3 | j3 | 30.0 | 0.0 | 0.0 | inf | 1.0 |
4 | j4 | 0.0 | 0.0 | 0.0 | inf | 1.0 |
5 | j5 | 0.0 | 56.0 | 0.0 | inf | 1.0 |
6 | j6 | 0.0 | 44.0 | 0.0 | inf | 1.0 |
7 | j7 | 15.0 | 0.0 | 0.0 | inf | 1.0 |
8 | j8 | 30.0 | 0.0 | 0.0 | inf | 1.0 |
[9]:
print(f'Total cost will be {generic_model.objective_value}')
Total cost will be 5760.0