"""
## GAMSSOURCE: https://www.gams.com/latest/gamslib_ml/libhtml/gamslib_trnsport.html
## LICENSETYPE: Demo
## MODELTYPE: LP
## KEYWORDS: linear programming, transportation problem, scheduling
A Transportation Problem (TRNSPORT)
This problem finds a least cost shipping schedule that meets
requirements at markets and supplies at factories.
Dantzig, G B, Chapter 3.3. In Linear Programming and Extensions.
Princeton University Press, Princeton, New Jersey, 1963.
This formulation is described in detail in:
Rosenthal, R E, Chapter 2: A GAMS Tutorial. In GAMS: A User's Guide.
The Scientific Press, Redwood City, California, 1988.
The line numbers will not match those in the book because of these
comments.
"""
from __future__ import annotations
import os
import sys
from gamspy import (
Container,
Equation,
Model,
Parameter,
Sense,
Set,
Sum,
Variable,
)
def main():
m = Container(
system_directory=os.getenv("SYSTEM_DIRECTORY", None),
)
# Prepare data
distances = [
["seattle", "new-york", 2.5],
["seattle", "chicago", 1.7],
["seattle", "topeka", 1.8],
["san-diego", "new-york", 2.5],
["san-diego", "chicago", 1.8],
["san-diego", "topeka", 1.4],
]
capacities = [["seattle", 350], ["san-diego", 600]]
demands = [["new-york", 325], ["chicago", 300], ["topeka", 275]]
# Set
i = Set(
m,
name="i",
records=["seattle", "san-diego"],
description="canning plants",
)
j = Set(
m,
name="j",
records=["new-york", "chicago", "topeka"],
description="markets",
)
# Data
a = Parameter(
m,
name="a",
domain=i,
records=capacities,
description="capacity of plant i in cases",
)
b = Parameter(
m,
name="b",
domain=j,
records=demands,
description="demand at market j in cases",
)
d = Parameter(
m,
name="d",
domain=[i, j],
records=distances,
description="distance in thousands of miles",
)
c = Parameter(
m,
name="c",
domain=[i, j],
description="transport cost in thousands of dollars per case",
)
c[i, j] = 90 * d[i, j] / 1000
# Variable
x = Variable(
m,
name="x",
domain=[i, j],
type="Positive",
description="shipment quantities in cases",
)
# Equation
supply = Equation(
m,
name="supply",
domain=i,
description="observe supply limit at plant i",
)
demand = Equation(
m, name="demand", domain=j, description="satisfy demand at market j"
)
supply[i] = Sum(j, x[i, j]) <= a[i]
demand[j] = Sum(i, x[i, j]) >= b[j]
transport = Model(
m,
name="transport",
equations=m.getEquations(),
problem="LP",
sense=Sense.MIN,
objective=Sum((i, j), c[i, j] * x[i, j]),
)
transport.solve(output=sys.stdout)
import math
assert math.isclose(transport.objective_value, 153.675000, rel_tol=0.001)
print(x.records)
print(transport.objective_value)
print(transport.status)
if __name__ == "__main__":
main()