我遇到了一个问题,我确信有一个答案(可能是一行代码) .
我有以下最小模型(数学上是荒谬的,但它描述了我的问题):
from pyomo.environ import *
model=AbstractModel()
m=model
m.name="Example model"
#Sets
m.mySet=Set(doc="my set")
m.myVar = Var(m.mySet, name="my variable", initialize=0, within=NonNegativeReals)
m.mutableParameter = Param(m.mySet, name="some mutable parameter", default=0, mutable=True)
m.someDefaultValue = 10
m.someOtherValue = 20
def changingConstraint_rule(m, n):
if m.mutableParameter[n] == 0:
return m.myVar[n] == m.someDefaultValue
else:
return m.myVar[n] == m.someOtherValue/m.mutableParameter[n]
m.changingConstraint = Constraint(m.mySet, rule=changingConstraint_rule)
#Objective function
def myObj(m):
return sum([m.myVar[n] for n in m.mySet])
m.myObjective = Objective(rule=myObj, sense=minimize)
如您所见,changingConstraint的行为取决于mutableParameter所具有的值 .
现在,当我使用m.create_instance('mydata.dat')创建此模型的实例时,Pyomo会根据mutableParameter创建实例时的值自动决定使用if子句的哪个部分 .
但是当我现在更新我的mutableParameter(到一个非零值)并再次运行模型时,Pyomo不更新它在约束中if-clause的用法,并且仍然使用原始解释:
from pyomo import *
from pyomo.environ import *
from minimalModel import m
instance = m.create_instance('datafile.dat')
# Run model once with standard values
solver = 'ipopt'
opt = SolverFactory(solver)
results = opt.solve(instance)
# Change the mutableParameter and run the model again
for t in instance.mySet:
instance.mutableParameter[t] = 99
# --> This is where I seem to be missing some call to update the instance. I've tried instance.preprocess(), that didn't work <--
results = opt.solve(instance)
我该怎么做才能告诉Pyomo“重新读取模型文件并根据mutableParameters的新值重新评估所有if-clauses”?
我有一个虚拟的方法:使用新参数编写一个新的.dat-File,并通过另一个create_instance()调用创建一个全新的实例 . 但这需要我为任何可变参数的每个更改编写一个新的.dat文件 . 我确信有一种更聪明的方法可以做到这一点 .
我会感激任何提示 . 谢谢!
1 回答
我已经弄明白了,恭请陈琦指出我正确的方法 .
需要做的是在重新评估模型之前重建约束,而不是整个模型 .
事先,我正在努力
在再次调用opt.solve()之前 . 那没用 . 实际需要做的是通过重建约束本身
然后根据可变参数的新值重新计算约束中的if子句 .