我遇到了问题,我确信有一个答案(可能是一行代码)。
我有以下最小模型(在数学上是荒谬的,但它描述了我的问题):
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子句的情况,并且仍然采用原始解释:
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子句”,我该怎么做?
我有一种虚拟的方法:使用新参数编写新的.dat-File,并通过另一个create_instance()调用创建一个全新的实例。但这需要我为任何可变参数的每个更改编写一个新的.dat文件。我确信有更聪明的方法可以做到这一点。
我会感激任何提示。谢谢!
答案 0 :(得分:1)
我已经弄明白了,恭请陈琦指出我正确的方法。
需要做的是在重新评估模型之前重建约束,而不是整个模型。
事先,我正在尝试
instance.reconstruct()
再次调用opt.solve()之前。那没用。实际需要做的是通过
重建约束本身instance.changingConstraint.reconstruct()
然后根据可变参数的新值重新计算约束中的if子句。