基于CPLEX与Pyomo的库存优化建模索引错误排查求助
基于CPLEX的库存优化数学建模

我尝试用Pyomo结合CPLEX求解该模型,但运行代码时出现错误:Index '0' is not valid for indexed component 'inv',代码如下:
import pyomo.environ as pyo from pyomo.environ import * from pyomo.opt import SolverFactory import numpy as np model=pyo.ConcreteModel() T=10 cap=1000 inflow=500 outflow=250 demand=300 cost=25 model.inv=pyo.Var(range(1,T+1),within=Integers, bounds=(0,np.inf)) inv=model.inv model.c0=pyo.Constraint(expr=inv[0]==300) model.c1=pyo.ConstraintList() for t in range(0,(T)): model.c1.add(expr=inv[t]<=cap) model.c2=pyo.ConstraintList() for t in range(0,(T)): model.c2.add(expr=inv[t]+inflow-outflow<=inv[t+1]) model.c3=pyo.ConstraintList() for t in range(0,(T)): model.c3.add(inv[t]>=demand) model.obj=pyo.Objective(expr=sum(inv[t]*cost for t in range(1,(T+1))),sense=minimize) opt=SolverFactory('cplex') opt.solve(model) model.pprint() for t in range(1,T+1): print(pyo.value(inv[t])) print(pyo.value(model.obj))
问题原因
代码中model.inv的索引范围是1到T,但约束c0、c1、c2、c3中都使用了inv[0],而0不在变量的索引范围内,导致索引无效错误。
修正方案
将model.inv的索引范围扩展为0到T,包含初始库存的索引,同时调整相关约束和目标函数的索引逻辑:
import pyomo.environ as pyo from pyomo.environ import * from pyomo.opt import SolverFactory import numpy as np model = pyo.ConcreteModel() T = 10 cap = 1000 inflow = 500 outflow = 250 demand = 300 cost = 25 # 调整变量索引为0到T,包含初始库存点 model.inv = pyo.Var(range(0, T+1), within=Integers, bounds=(0, np.inf)) inv = model.inv # 初始库存约束 model.c0 = pyo.Constraint(expr=inv[0] == 300) # 库存容量约束:覆盖t=0到t=T model.c1 = pyo.ConstraintList() for t in range(0, T+1): model.c1.add(expr=inv[t] <= cap) # 库存递推约束:t从0到T-1,关联inv[t]和inv[t+1] model.c2 = pyo.ConstraintList() for t in range(0, T): model.c2.add(expr=inv[t] + inflow - outflow <= inv[t+1]) # 满足需求约束:覆盖t=0到t=T model.c3 = pyo.ConstraintList() for t in range(0, T+1): model.c3.add(expr=inv[t] >= demand) # 目标函数:计算t=1到T的库存持有成本 model.obj = pyo.Objective(expr=sum(inv[t] * cost for t in range(1, T+1)), sense=minimize) opt = SolverFactory('cplex') result = opt.solve(model) # 输出结果 model.pprint() print("各期库存值:") for t in range(0, T+1): print(f"t={t}: {pyo.value(inv[t])}") print(f"最小持有总成本:{pyo.value(model.obj)}")
说明
- 扩展变量索引后,
inv[0]作为初始库存变量,符合模型的递推逻辑 - 修正了
c1和c3的循环范围,确保所有时间点的库存都满足容量和需求约束 - 目标函数保持计算t=1到T的持有成本,与原模型一致
内容的提问来源于stack exchange,提问作者Salman M Sulphi
相关产品推荐
相关产品推荐

