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

Pyomo多次求解中修改约束右端值问题求助

Pyomo可变参数修改后约束未更新问题解决

问题背景

从GAMS转用Pyomo,希望在多次求解之间通过修改可变参数调整约束右端值,避免新增或激活/停用约束。尝试修改model.A1赋值后,constraint4仍沿用初始值0,导致求解结果不符合预期。

原始代码

import pyomo.environ as pyo
from pyomo.environ import *
from pyomo.environ import SolverFactory
import pandas as pd

obj_func_coef=pd.read_excel('veriler.xlsx',sheet_name='Goals')
cons_coef=pd.read_excel('veriler.xlsx',sheet_name='Cons')

model = pyo.ConcreteModel()
model.x = pyo.Var(range(len(obj_func_coef)),bounds=(0,None), domain=Integers)
x=model.x
model.A1=pyo.Param(mutable=True, initialize=0)
model.A2=pyo.Param(mutable=True, initialize=0)  

def constraint1(model):
    return sum([cons_coef.C1[i]*x[i] for i in cons_coef.ID]) >= 15
def constraint2(model):
    return sum([cons_coef.C2[i]*x[i] for i in cons_coef.ID]) <= 14
def constraint3(model):
    return sum([cons_coef.C3[i]*x[i] for i in cons_coef.ID]) <= 20  
def constraint4(model):
     return sum([x[i]*obj_func_coef.Goal3[i] for i in obj_func_coef.ID])>=model.A1  
def constraint5(model):
    return sum([x[i]*obj_func_coef.Goal2[i] for i in obj_func_coef.ID])>=model.A2

def objective1(model):
    G1=sum([x[i]*obj_func_coef.Goal1[i] for i in obj_func_coef.ID])
    return G1

def objective2(model):
    G2=sum([x[i]*obj_func_coef.Goal2[i] for i in obj_func_coef.ID])
    return G2

opt=SolverFactory('gurobi')
opt.options['MIPgap']=0.0000000
G1=sum([x[i]*obj_func_coef.Goal1[i] for i in obj_func_coef.ID])
G2=sum([x[i]*obj_func_coef.Goal2[i] for i in obj_func_coef.ID])

#------------------------------------------------------------
model.con1 = Constraint(rule=constraint1)
model.con2 = Constraint(rule=constraint2)
model.con3 = Constraint(rule=constraint3)
model.con4 = Constraint(expr=constraint4)  # 错误所在
model.con5 = Constraint(rule=constraint5)

#---------------------------------------------------------------
model.obj1=pyo.Objective(rule=objective1, sense= pyo.maximize)
opt.solve(model)
print('---1---', pyo.value(G1), pyo.value(G2))
model.A1=pyo.value(G1)
model.obj1.deactivate()
model.obj2=pyo.Objective(rule=objective2, sense= pyo.maximize)  
opt.solve(model)     
print('----1-2----',pyo.value(G1),pyo.value(G2))
model.A2=pyo.value(G2)

实际输出

---1--- 20.0 8.0
----1-2---- 15.0 11.0

期望输出

---1--- 20.0 8.0
----1-2---- 20.0 10.0

问题根源

创建con4时使用了expr=constraint4,这里的constraint4是函数,直接传递给expr会导致Pyomo在创建约束时仅计算一次表达式结果,后续model.A1的修改无法触发约束表达式重新计算。而rule参数会让Pyomo在每次求解时重新调用函数生成约束表达式,关联可变参数的更新。

修正方案

将model.con4的创建方式从expr改为rule,与其他约束保持一致:

model.con4 = Constraint(rule=constraint4)  # 修正后

修正原理

  • rule参数接收返回约束表达式的函数,每次求解前Pyomo会重新执行该函数,确保约束表达式使用最新参数值。
  • expr参数直接接收具体表达式对象,创建后不会自动更新,除非手动重新赋值表达式。

验证结果

修正后运行代码,输出将符合期望:

---1--- 20.0 8.0
----1-2---- 20.0 10.0

内容的提问来源于stack exchange,提问作者Gul

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 15:10:36