在Pyomo中模拟克隆之间复制后缀信息的有效方法

时间:2017-06-23 17:12:03

标签: mathematical-optimization pyomo

想象一下,我使用ConcreteModel构建了m2 m2 = m.clone()。如果m2有关于Suffix的信息,例如m2.ipopt_zL_out,我想将其复制回m,那么最有效的方式是什么?

我可以做m.ipopt_zL_out[m.var] = m2.ipopt_zL_out[ComponentUID(m.var).find_component_on(m2)]之类的事情,但我被告知ComponentUID可能很贵。这是推荐的方法,还是有更好的方法呢?

1 个答案:

答案 0 :(得分:1)

我通常做的是创建从ComponentUID字符串到每个模型上的模型组件的前向和后向映射。为Pyomo对象创建映射很棘手,通常无法使用标准dict来完成,因为像Var这样的东西是不可清除的。有一个名为ComponentMap的类,您可以使用它来代替字典。还有一个名为generate_cuid_names的辅助函数,它可以有效地为模型生成所有CUID字符串,并返回ComponentMap

以下是一些示例代码:

# m1 and m2 are ConcreteModels

from pyomo.core.base.block import generate_cuid_names

# generate forward and reverse mappings for model 1
m1.obj_to_cuid = generate_cuid_names(m1)
m1.cuid_to_obj = dict((cuid, obj) for obj, cuid in m1.obj_to_cuid.items())

# generate forward and reverse mappings for model 2
m2.obj_to_cuid = generate_cuid_names(m2)
m2.cuid_to_obj = dict((cuid, obj) for obj, cuid in m2.obj_to_cuid.items())

# load model 2 suffix solution into model 1
m1.s.update((m1.cuid_to_obj[m2.obj_to_cuid[obj]], val)
            for obj, val in m2.s.items())

除了在这里和那里进行额外的字典查找(在Python中相对较快)之外,唯一缓慢的部分应该是ComponentUID字符串的初始生成,但它只是前期成本。

我也使用这种方法长期存储其他解决方案信息,或者通过网络将解决方案信息传输到相关模型。

请记住,generate_cuid_names函数默认情况下会在块本地上下文中生成CUID字符串。这意味着如果在模型的子块上调用它,则父块标识符将不会出现在字符串中。这在某些情况下很有用,但是该函数还有一个关键字,允许您更新现有的ComponentMap(假设包含父块标识符)。在这种情况下,将生成完全限定的CUID字符串。有关详细信息,请参阅pyomo / core / base / block.py中的doc字符串。