You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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)

额外需要修正的问题

  1. 约束定义语法错误:原代码中rule=sum(...)==0的写法不符合Pyomo约束定义规范,应改用expr参数直接传入表达式。
  2. 绝对值表达式问题: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 18:35:15