酸洗 Pyomo 表达式时如何修复 'recursion error'
How to fix 'recursion error' when pickling Pyomo Expressions
我之前在 pickle Pyomo 模型时没有遇到过问题,但现在在尝试 pickle 表达式时出现递归错误。
有趣的是,在下面的示例中可以通过几种方式避免错误:
- 通过从参数中删除 "mutable" 标志
- 通过将集合的大小减小到非常小的值,例如范围 (0, 10)
...但我不知道为什么这些会修复错误,它们也不是我尝试 pickle 的实际优化模型的可行解决方案。
以下示例 仅从单个表达式的酸洗中生成错误。
(我使用的是 pyomo=5.6.2、cloudpickle=0.6.1 和 python=3.7.4)
import cloudpickle
import pyomo.environ as pyo
test_model = pyo.ConcreteModel()
# A set is added.
set_elements = list(range(0, 500))
test_model.my_set = pyo.Set(initialize=set_elements)
# A parameter is added.
param_values = dict()
for e in set_elements:
param_values[e] = 1
test_model.my_param = pyo.Param(test_model.my_set, initialize=param_values, mutable=True)
# An expression is added.
def calculation_rule(mdl):
return sum(mdl.my_param[e] for e in mdl.my_set)
test_model.calculation_expr = pyo.Expression(rule=calculation_rule)
# We attempt to pickle the expression.
pickle_str = cloudpickle.dumps(test_model.calculation_expr)
上述代码的最后一行引发了以下异常:
PicklingError: Could not pickle object as excessively deep recursion required.
问题:我是否需要修改表达式的编写方式才能 pickle 模型,或者我应该使用 Cloudpickle 以外的其他东西保存模型?
在此先感谢您的帮助!
一个解决方法是使用 Pyomo 的 quicksum
而不是 Python 的 sum
。它导致更紧凑的表达式树并且似乎解决了您看到的递归问题:
# An expression is added.
def calculation_rule(mdl):
return pyo.quicksum(mdl.my_param[e] for e in mdl.my_set)
test_model.calculation_expr = pyo.Expression(rule=calculation_rule)
文档 here.
我之前在 pickle Pyomo 模型时没有遇到过问题,但现在在尝试 pickle 表达式时出现递归错误。
有趣的是,在下面的示例中可以通过几种方式避免错误:
- 通过从参数中删除 "mutable" 标志
- 通过将集合的大小减小到非常小的值,例如范围 (0, 10)
...但我不知道为什么这些会修复错误,它们也不是我尝试 pickle 的实际优化模型的可行解决方案。
以下示例 仅从单个表达式的酸洗中生成错误。 (我使用的是 pyomo=5.6.2、cloudpickle=0.6.1 和 python=3.7.4)
import cloudpickle
import pyomo.environ as pyo
test_model = pyo.ConcreteModel()
# A set is added.
set_elements = list(range(0, 500))
test_model.my_set = pyo.Set(initialize=set_elements)
# A parameter is added.
param_values = dict()
for e in set_elements:
param_values[e] = 1
test_model.my_param = pyo.Param(test_model.my_set, initialize=param_values, mutable=True)
# An expression is added.
def calculation_rule(mdl):
return sum(mdl.my_param[e] for e in mdl.my_set)
test_model.calculation_expr = pyo.Expression(rule=calculation_rule)
# We attempt to pickle the expression.
pickle_str = cloudpickle.dumps(test_model.calculation_expr)
上述代码的最后一行引发了以下异常:
PicklingError: Could not pickle object as excessively deep recursion required.
问题:我是否需要修改表达式的编写方式才能 pickle 模型,或者我应该使用 Cloudpickle 以外的其他东西保存模型?
在此先感谢您的帮助!
一个解决方法是使用 Pyomo 的 quicksum
而不是 Python 的 sum
。它导致更紧凑的表达式树并且似乎解决了您看到的递归问题:
# An expression is added.
def calculation_rule(mdl):
return pyo.quicksum(mdl.my_param[e] for e in mdl.my_set)
test_model.calculation_expr = pyo.Expression(rule=calculation_rule)
文档 here.