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
相关产品推荐
相关产品推荐

