Pyomo:如何更新现有模型实例的约束定义?
Pyomo: How to update constraint definition for existing model instance?
我被困在一个问题上,我确信有一个答案(可能是一行代码)。
我有以下最小模型(这在数学上是荒谬的,但它描述了我的问题):
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 "re-read the model file and re-assess all if-clauses, based on the new values of the mutableParameters"?
我有一个虚拟的方法:使用新参数编写一个新的 .dat 文件,并通过另一个 create_instance() 调用创建一个全新的实例。但这需要我为任何可变参数的每次更改编写一个新的 .dat 文件。我相信有更聪明的方法可以做到这一点。
如有任何提示,我将不胜感激。谢谢!
我已经弄明白了,感谢 Qi Chen 为我指明了正确的道路。
需要做的是在再次评估模型之前重建约束,而不是整个模型。
之前,我正在尝试
instance.reconstruct()
再次调用 opt.solve() 之前。那没有用。实际需要做的是通过
重建约束本身
instance.changingConstraint.reconstruct()
然后 re-evaluates 约束中的 if-clause,基于可变参数的新值。
我被困在一个问题上,我确信有一个答案(可能是一行代码)。
我有以下最小模型(这在数学上是荒谬的,但它描述了我的问题):
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 "re-read the model file and re-assess all if-clauses, based on the new values of the mutableParameters"?
我有一个虚拟的方法:使用新参数编写一个新的 .dat 文件,并通过另一个 create_instance() 调用创建一个全新的实例。但这需要我为任何可变参数的每次更改编写一个新的 .dat 文件。我相信有更聪明的方法可以做到这一点。
如有任何提示,我将不胜感激。谢谢!
我已经弄明白了,感谢 Qi Chen 为我指明了正确的道路。
需要做的是在再次评估模型之前重建约束,而不是整个模型。
之前,我正在尝试
instance.reconstruct()
再次调用 opt.solve() 之前。那没有用。实际需要做的是通过
重建约束本身instance.changingConstraint.reconstruct()
然后 re-evaluates 约束中的 if-clause,基于可变参数的新值。