更改索引参数值的最佳方法

Posted

技术标签:

【中文标题】更改索引参数值的最佳方法【英文标题】:Best way to change the value of an indexed parameter 【发布时间】:2020-03-24 15:23:27 【问题描述】:

我是 Pyomo 的新手,我想知道如何更改具有一个或多个索引的现有模型参数的值。

我见过一些标量参数的例子,即没有索引。例如:

model5 = ConcreteModel()
model5.data2 = Param(initialize=10.0, mutable=True)
print("print data2 before")
model5.data2.pprint()
model5.data2 = 999
print("print data2 after")
model5.data2.pprint()

这会产生输出:

print data2 before
data2 : Size=1, Index=None, Domain=Any, Default=None, Mutable=True
    Key  : Value
    None :  10.0
print data2 after
data2 : Size=1, Index=None, Domain=Any, Default=None, Mutable=True
    Key  : Value
    None :   999

但是,如果我尝试使用具有索引的参数来执行此操作,则会出现错误。以下代码失败,但可能并不奇怪,因为我试图将 Python 对象分配给 Pyomo 对象。使用索引(或多个索引)更新参数的正确方法是什么?

model5 = ConcreteModel()
# Make a small set
myList = ['i1', 'i2', 'i3', 'i4']
model5.i = Set(dimen=1, initialize=myList)
# Make a dict for each element in the set and give it the value 10
dataDict = 
for  element in myList:
  dataDict[element] = 10
print("print dataDict")
print(dataDict)
# Make the data into a model Param
model5.data = Param(model5.i, initialize=dataDict, mutable=True)
print("print data parameter")
model5.data.pprint()
# Change a values for each element to 999
for  element in myList:
  dataDict[element] = 999
# Try and update the Param
model5.data = dataDict # THIS FAILS <-- how do I do this?

【问题讨论】:

【参考方案1】:

tl,dr:使用您要更新的(可变!)参数的reconstruct 方法。

首先,我的建议是将初始化你的模型的过程放到一个函数中,这样你就可以从不同的地方调用它并重用它。

from pyomo import environ as pe

def create_model(d: dict) -> pe.ConcreteModel:
    """Create Pyomo Concrete Model.

    Parameters
    ----------
    d : Dictionary with keys corresponding to components names.
    """
    model = pe.ConcreteModel()
    model.I = pe.Set(initialize=d['I'])
    model.data = pe.Param(model.I, mutable=True, initialize=d['data'])
    return model

然后你可以用你想要的任何数据初始化模型:

d = 
d['I'] = ['i1', 'i2', 'i3', 'i4']
d['data'] = i : 10 for i in d['I']

model = create_model(d)
​
model.data.pprint()

data : Size=4, Index=I, Domain=Any, Default=None, Mutable=True
    Key : Value
     i1 :    10
     i2 :    10
     i3 :    10
     i4 :    10

现在使用 reconstruct 更新值:

new_values = i: 5 for i in d['I'] # 5 here is arbitrary, you
model.data.reconstruct(new_values) 
​
model.data.pprint()
data : Size=4, Index=I, Domain=Any, Default=None, Mutable=True
    Key : Value
     i1 :     5
     i2 :     5
     i3 :     5
     i4 :     5

附带说明,data 是一个非常令人困惑的参数名称,您应该找到更具体的名称。

【讨论】:

谢谢,完美运行。我教我 Pyomo 的那本书根本没有提到 .reconstruct() 方法! 是的,Pyomo 有很多“隐藏”的功能。我的印象是,它已经存在这么久了,它有一个巨大的 API,并不是所有的都被开发者/维护者“推荐”。

以上是关于更改索引参数值的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章

通过某些(索引)参数将值插入熊猫数据框中“适当”位置的最佳方法是啥?

从函数返回多个值的最佳方法是啥?

从函数返回多个值的最佳方法是啥?

设置应该是 Python 列表的参数的默认值的最佳实践?

在 REST 调用中使用 URI 作为参数值的最佳实践

在 Java 中更改 XML 文件中的一个值的最佳方法是啥?