# Lumber Transportation Problem#

1. 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

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