在 Pyomo 中复制模型克隆之间的后缀信息的有效方法
Effective way to copy Suffix information between model clones in Pyomo
假设我有一个使用 m2 = m.clone()
构建的 ConcreteModel
m2
。如果 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
可能很昂贵。这是推荐的方法,还是有更好的方法?
我通常做的是在每个模型上创建从 ComponentUID 字符串到模型组件的前向和后向映射。为 Pyomo 对象创建映射是棘手的,通常不能使用标准 dict
来完成,因为像 Var 这样的东西是不可哈希的。有一个名为 ComponentMap
的 class,您可以使用它代替字典。还有一个名为 generate_cuid_names
的辅助函数,它可以高效地为模型批量生成所有 CUID 字符串,并且 returns 和 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 中的文档字符串。
假设我有一个使用 m2 = m.clone()
构建的 ConcreteModel
m2
。如果 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
可能很昂贵。这是推荐的方法,还是有更好的方法?
我通常做的是在每个模型上创建从 ComponentUID 字符串到模型组件的前向和后向映射。为 Pyomo 对象创建映射是棘手的,通常不能使用标准 dict
来完成,因为像 Var 这样的东西是不可哈希的。有一个名为 ComponentMap
的 class,您可以使用它代替字典。还有一个名为 generate_cuid_names
的辅助函数,它可以高效地为模型批量生成所有 CUID 字符串,并且 returns 和 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 中的文档字符串。