Reputation: 1159
I'm trying to solve the classical 'Transportation theory' to optimize the production and transportation of goods from 3 factories to 5 distribution centers.
There are:
I'm able to solve it with Pyomo:
from pyomo.environ import *
import pyomo.environ as pyo
model = ConcreteModel()
model.i = Set(initialize=['Factory A','Factory B', 'Factory C'])
model.j = Set(initialize=['DC 1', 'DC 2', 'DC 3', 'DC 4', 'DC 5'])
model.a = Param(model.i, initialize={'Factory A':1000,'Factory B':4000, 'Factory C':2000}) #Weekly_capacities
model.b = Param(model.j, initialize={'DC 1':500,'DC 2':900,'DC 3':1800, 'DC 4':200, 'DC 5':700 }) #Weekly_demands
# Transportation costs
costs = {('Factory A', 'DC 1'): 2,('Factory A', 'DC 2'): 4, ('Factory A', 'DC 3'): 5, ('Factory A', 'DC 4'): 2, ('Factory A', 'DC 5'): 1, \
('Factory B', 'DC 1'): 3, ('Factory B', 'DC 2'): 1, ('Factory B', 'DC 3'): 3, ('Factory B', 'DC 4'): 2, ('Factory B', 'DC 5'): 3, \
('Factory C', 'DC 1'): 1, ('Factory C', 'DC 2'): 3, ('Factory C', 'DC 3'): 3, ('Factory C', 'DC 4'): 1, ('Factory C', 'DC 5'): 5}
model.d = Param(model.i, model.j, initialize=costs)
def f_costs(model, i, j):
return model.d[i,j]
model.c = Param(model.i, model.j, initialize=f_costs)
model.x = Var(model.i, model.j, bounds=(0.0,None)) #Production
def f_supply(model, i):
return sum(model.x[i,j] for j in model.j) <= model.a[i]
model.supply = Constraint(model.i, rule=f_supply)
def f_demand(model, j):
return sum(model.x[i,j] for i in model.i) >= model.b[j]
model.demand = Constraint(model.j, rule=f_demand)
def f_objetive(model):
return sum(model.c[i,j]*model.x[i,j] for i in model.i for j in model.j)
model.objetive = Objective(rule=f_objetive, sense=minimize)
def pyomo_postprocess(options=None, instance=None, results=None):
model.x.display()
opt = SolverFactory("glpk")
results = opt.solve(model)
pyomo_postprocess(None, None, results)
Solution:
x : Size=15, Index=x_index
Key : Lower : Value : Upper : Fixed : Stale : Domain
('Factory A', 'DC 1') : 0.0 : 0.0 : None : False : False : Reals
('Factory A', 'DC 2') : 0.0 : 0.0 : None : False : False : Reals
('Factory A', 'DC 3') : 0.0 : 0.0 : None : False : False : Reals
('Factory A', 'DC 4') : 0.0 : 0.0 : None : False : False : Reals
('Factory A', 'DC 5') : 0.0 : 700.0 : None : False : False : Reals
('Factory B', 'DC 1') : 0.0 : 0.0 : None : False : False : Reals
('Factory B', 'DC 2') : 0.0 : 900.0 : None : False : False : Reals
('Factory B', 'DC 3') : 0.0 : 500.0 : None : False : False : Reals
('Factory B', 'DC 4') : 0.0 : 0.0 : None : False : False : Reals
('Factory B', 'DC 5') : 0.0 : 0.0 : None : False : False : Reals
('Factory C', 'DC 1') : 0.0 : 500.0 : None : False : False : Reals
('Factory C', 'DC 2') : 0.0 : 0.0 : None : False : False : Reals
('Factory C', 'DC 3') : 0.0 : 1300.0 : None : False : False : Reals
('Factory C', 'DC 4') : 0.0 : 200.0 : None : False : False : Reals
('Factory C', 'DC 5') : 0.0 : 0.0 : None : False : False : Reals
However, due to my business and my logistics, I need that the supply of each one of the Distribution Centers comes exclusively from just one factory (and not from two or three). For instance, 'DC 3' is receiving the goods from 'Factory B' and 'Factory C' and I would like to force it to just 'Factory B' or just 'Factory C'.
Is there any way to include a Pyomo constraint to limit the number of sources for the Distribution Costs?
Upvotes: 0
Views: 112
Reputation: 16772
You need binary variables for this. I'll use math notation below as this is much less unwieldy than Pyomo code. The standard transportation model looks like:
min sum((i,j), c[i,j]*x[i,j])
sum(j, x[i,j]) <= a[i] ∀i
sum(i, x[i,j]) >= b[j] ∀j
x[i,j] >= 0
Now add binary variables y[i,j]
and use:
min sum((i,j), c[i,j]*x[i,j])
sum(j, x[i,j]) <= a[i] ∀i
sum(i, x[i,j]) >= b[j] ∀j
x[i,j] <= M[i,j]*y[i,j] ∀i,j
sum(i,y[i,j]) = 1 ∀j
x[i,j] >= 0
y[i,j] ∈ {0,1}
here M[i,j]
is an upper bound on x[i,j]
. E.g.
M[i,j] = min(a[i],b[j])
Upvotes: 1