PYOMO带索引变量约束设置:逐点1对1约束定义报错如何解决
Pyomo逐点约束错误修正方案
报错原因
你代码中((Gen[i] - PPA)/M for i in m.IDX)是Python生成器对象,不属于Pyomo可识别的数学表达式类型,同时单个Constraint对象仅支持传入单个约束表达式,无法直接承载全索引点的约束集合。
正确写法
Pyomo中要实现逐点索引约束,需要给Constraint传入对应的索引集合,再通过规则函数为每个索引返回对应约束表达式,示例如下:
- 先修正你代码中存在的变量名不一致问题:
# 修正前你代码存在变量名混用、大小写不统一问题,调整后参考: January = Data['Full_Data'][(Data['Full_Data']['Month'] == 1) & (Data['Full_Data']['Year'] == 2011)] Gen = January['Producible (MWh)'] time = len(Gen) # 原代码中Time、Generacion等变量名不一致,统一修正 M = 100 # 模型变量定义: m = ConcreteModel() m.IDX = range(time) m.PPA = Var(initialize = 2.0, bounds =(1,7)) m.compra = Var(m.IDX, bounds = (0, None)) m.venta = Var(m.IDX, bounds = (0, None)) m.b1 = Var(m.IDX, within = Binary) m.b2 = Var(m.IDX, within = Binary)
- 添加逐点约束:
写法1:使用自定义规则函数
def b1_constraint_rule(m, i): # 每个索引i对应返回一条独立约束 return (Gen[i] - m.PPA) / M <= m.b1[i] # 传入索引集合m.IDX,Pyomo自动为每个索引生成对应约束 m.b1_constraint = Constraint(m.IDX, rule=b1_constraint_rule)
写法2:使用lambda简化写法
m.b1_constraint = Constraint(m.IDX, rule=lambda m, i: (Gen[i] - m.PPA)/M <= m.b1[i])
额外注意事项
- 模型属性引用要完整:你定义的
PPA是模型m的属性,不能直接写PPA,必须写m.PPA - 变量名需保持一致:原代码中出现的
Generacion、大小写不统一的Time/time都会触发额外报错
内容的提问来源于stack exchange,提问作者lucassculp
相关产品推荐
相关产品推荐

