在Pyomo中创建固定常量列表:用Set/Param/Var?报错求解
问题分析与解决
核心错误原因
Pyomo的RangeSet默认从1开始生成索引集合,你用model.N = pyo.RangeSet(model.nVars)创建的是{1,2,3,4},但初始化model.oldweights时用列表[0,0,0,0],Pyomo会尝试将列表索引0对应到模型索引0,而索引0不在model.N中,因此触发KeyError。
解决方案
方案1:用字典初始化Param(推荐,索引对应更清晰)
将model.oldweights的初始化改为字典,明确绑定每个索引值:
model.oldweights = pyo.Param(model.N, initialize={1:0, 2:0, 3:0, 4:0})
方案2:修改RangeSet从0开始
如果习惯用0起始的索引,调整model.N的定义:
model.N = pyo.RangeSet(0, model.nVars-1)
额外需要修正的问题
- 约束定义语法错误:原代码中
rule=sum(...)==0的写法不符合Pyomo约束定义规范,应改用expr参数直接传入表达式。 - 绝对值表达式问题:Python内置
abs()无法被Pyomo解析为优化模型的表达式,需替换为Pyomo提供的pyo.Abs()。
完整修正代码
import pyomo.environ as pyo from pyomo.core.expr.numeric_expr import LinearExpression model = pyo.ConcreteModel() model.nVars = pyo.Param(initialize=4) model.N = pyo.RangeSet(model.nVars) # 索引1-4 model.x = pyo.Var(model.N, within=pyo.Reals) model.er = [1, 1, 3, 1] # 用字典初始化Param,对应索引1-4 model.oldweights = pyo.Param(model.N, initialize={1:0, 2:0, 3:0, 4:0}) model.linexp = LinearExpression(constant=0, linear_coefs=model.er, linear_vars=[model.x[i] for i in model.N]) # 修正约束定义语法,替换abs为pyo.Abs() model.c1 = pyo.Constraint(expr=sum(model.x[i] for i in model.N) == 0) model.c2 = pyo.Constraint(expr=sum(pyo.Abs(model.x[i]) for i in model.N) == 2) model.c3 = pyo.Constraint(expr=sum(pyo.Abs(model.x[i] - model.oldweights[i]) for i in model.N) <= 0.03) model.obj = pyo.Objective(expr=model.linexp, sense=pyo.maximize) # 求解模型 results = pyo.SolverFactory('ipopt', executable='/content/ipopt').solve(model) results.write()
内容的提问来源于stack exchange,提问作者lara_toff
相关产品推荐
相关产品推荐

