关于Pyomo运输/航运问题的问题



我正在学习pyomo并练习关于运输问题的练习,条件如下:

  1. 货物可以直接从货源城市发往目的地,也可以通过仓库(货源城市->得宝→目的地)
  2. 运输方式将根据最低成本消耗来选择
  3. 每个车厂都有自己的容量限制

我试着用pyomo来解决这个问题,但是,没有办法解决。请给我一些建议和方向,为什么代码不工作。谢谢你!

import pyomo.environ as pyomo
import numpy as np
supply = dict({'Liverpool': 150000,
'Brighton': 200000})
through = dict({'Newcastle': 70000,
'Birmingham': 50000,
'London': 100000,
'Exeter': 40000,
'Liverpool': 150000,
'Brighton': 200000
})
demand = dict({'C1': 50000,
'C2': 10000,
'C3': 40000,
'C4': 35000,
'C5': 60000,
'C6': 20000})
cost = dict({
('Liverpool', 'Newcastle'): 0.5,
('Liverpool', 'Birmingham'): 0.5,
('Liverpool', 'London'): 1.0,
('Liverpool', 'Exeter'): 0.2,
('Liverpool', 'C1'): 1.0,
('Liverpool', 'C3'): 1.5,
('Liverpool', 'C4'): 2.0,
('Liverpool', 'C6'): 1.0,
('Brighton', 'Birmingham'): 0.3,
('Brighton', 'London'): 0.5,
('Brighton', 'Exeter'): 0.2,
('Brighton', 'C1'): 2.0,
('Newcastle', 'C2'): 1.5,
('Newcastle', 'C3'): 0.5,
('Newcastle', 'C5'): 1.5,
('Newcastle', 'C6'): 1.0,
('Birmingham', 'C1'): 1.0,
('Birmingham', 'C2'): 0.5,
('Birmingham', 'C3'): 0.5,
('Birmingham', 'C4'): 1.0,
('Birmingham', 'C5'): 0.5,
('London', 'C2'): 1.5,
('London', 'C3'): 2.0,
('London', 'C5'): 0.5,
('London', 'C6'): 1.5,
('Exeter', 'C3'): 0.2,
('Exeter', 'C4'): 1.5,
('Exeter', 'C5'): 0.5,
('Exeter', 'C6'): 1.5
})
cost_total = {}
for city_from in supply.keys():
for city_through in through.keys():
for city_to in demand.keys():
if city_from == city_through:
cost_total[(city_from , city_through , city_to)] = 0 + cost.get((city_through , city_to) , 9999)
else:
cost_total[(city_from , city_through , city_to)] = cost.get((city_from , city_through) , 9999) + cost.get((city_through , city_to) , 9999)
supplier = supply.keys()
througher  = through.keys()
demander = demand.keys()
model = pyomo.ConcreteModel()
model.i = pyomo.Set(initialize = supplier , doc = 'City From')
model.j = pyomo.Set(initialize = througher , doc = 'City Through')
model.k = pyomo.Set(initialize = demander , doc = 'City To')
model.s = pyomo.Param(model.i , initialize=supply, doc='Supply by City')
model.t = pyomo.Param(model.j , initialize = through , doc = 'through / warehouse')
model.d = pyomo.Param(model.k , initialize=demand , doc='Demand by City')
model.cost = pyomo.Param(model.i , model.j , model.k , initialize=cost_total , doc = 'total cost')
model.x = pyomo.Var(model.i , model.j , model.k , bounds = (0 , None))
def supply_rule(model, i):
return sum(model.x[i,j,k] for j in model.j for k in model.k) <= model.s[i]
model.supply = pyomo.Constraint(model.i, rule=supply_rule, doc='Observe supply limit at plant i')
def demand_rule(model, k):
return sum(model.x[i,j,k] for i in model.i for j in model.j) == model.d[k]  
model.demand = pyomo.Constraint(model.k, rule=demand_rule, doc='Satisfy demand at market j')
def depot_cont(model , j):
return sum(model.x[i , j , k] for i in model.i for k in model.k) <= model.t[j]
model.through_cont2 = pyomo.Constraint(model.j , rule = depot_cont)
def objective_rule(model):
return sum(model.cost[i,j,k]*model.x[i,j,k] for i in model.i for j in model.j for k in model.k)
model.objective = pyomo.Objective(rule=objective_rule, sense=pyomo.minimize, doc='Define objective function')

您的代码(未修改)似乎为我工作。

意识到有几种方法可以设置这个,这是一个更大的讨论…在你的例子中,你列举了所有可能的路线,并在直接路线中加入了零成本选项,而在不可行的路线上增加了高成本,这很好。在更大的问题或更复杂的网络中,解决这个问题的标准方法是将其作为所有节点(城市)具有流量平衡约束的网络流问题。

不管怎样,你的问题不太清楚什么"不起作用"。我将此添加到代码末尾:

solver = pyomo.SolverFactory('glpk')
result = solver.solve(model)
print(result)
for ijk in model.x.index_set():
if model.x[ijk]:
print(f'ship : {ijk} qty: {model.x[ijk].value}')

,它产生了这个结果,它通过了第一级的完整性检查,但我没有太仔细地看它…

Problem: 
- Name: unknown
Lower bound: 198500.0
Upper bound: 198500.0
Number of objectives: 1
Number of constraints: 15
Number of variables: 73
Number of nonzeros: 217
Sense: minimize
Solver: 
- Status: ok
Termination condition: optimal
Statistics: 
Branch and bound: 
Number of bounded subproblems: 0
Number of created subproblems: 0
Error rc: 0
Time: 0.007380008697509766
Solution: 
- number of solutions: 0
number of solutions displayed: 0
ship : ('Liverpool', 'Liverpool', 'C1') qty: 50000.0
ship : ('Liverpool', 'Liverpool', 'C6') qty: 20000.0
ship : ('Brighton', 'Birmingham', 'C2') qty: 10000.0
ship : ('Brighton', 'Birmingham', 'C4') qty: 35000.0
ship : ('Brighton', 'Birmingham', 'C5') qty: 5000.0
ship : ('Brighton', 'London', 'C5') qty: 55000.0
ship : ('Brighton', 'Exeter', 'C3') qty: 40000.0
[Finished in 579ms]

最新更新