我正在尝试优化pyomo抽象模型(m)。该模型有一个名为a
的(整数)参数。我想在构建模型时计算另一个整数值。让其他变量为c = a*(a-1)/2
。我想要一个大小为c
的二进制变量数组
为此,我写了以下几行 -
#File - test.py#
from pyomo.environ import *
m = AbstractModel()
m.a = Param()
c = m.a*(m.a-1)/2
m.var = Var(range(1,c), within=Binary)
m.obj = Objective(expr = 0)
#File - data.dat#
param a := 5 ;
为了解决这个问题,我跑了 - pyomo solve test.py data.dat --solver=glpk
运行此操作后,我收到以下错误:
Implicit conversion of Pyomo NumericValue type `<class
'pyomo.core.kernel.expr_coopr3._ProductExpression'>' to an integer
is disabled. This error is often the result of using Pyomo components as
arguments to one of the Python built-in math
module functions when defining expressions. Avoid this error by using Pyomo-
provided math functions.
我认为当我尝试range(1,c)
时会出现错误。如果我错了,请纠正我。
我有Python 2.7.12,Pyomo-5.3(Linux上的CPython-2.7.12)。当我安装它时,我将不得不向某人询问安装方法,因此可能需要一些时间。一旦我问安装人员,我会更新安装方法。
感谢。
答案 0 :(得分:1)
这里有两件事:
问题的根源在于您将抽象模型视为具体模型。对于抽象模型,当您声明m.a
时,您只声明参数a
的存在。 Python然后继续解析并执行模型的其余部分。当它命中c = m.a*(m.a-1)/2
时,Python会生成一个表示右侧的Pyomo表达式树。最后,当它到达m.var = Var(range(1,c), within=Binary)
时,Python首先在调用range(1,c)
构造函数之前执行Var()
。 range
(Python函数)在生成范围列表之前将其参数强制转换为int
。该演员阵容是产生错误的原因。
c
函数显式评估表达式(value(c)
)的值, 可以绕过该错误。但是,这会产生一个不同的(可能更具信息性)错误,您在构建Param a
之前会对其进行评估。这是因为此时模型仍然是抽象的,并且甚至没有读取为a
提供值的数据文件。
解决方案是制作一个显式的 Pyomo Set
,它将作为表达式的占位符,并且在构建模型的其余部分之前不会被构造(即,表达式c
的评估将推迟到a
的值可用)。例如:
from pyomo.environ import *
m = AbstractModel()
m.a = Param()
c = m.a*(m.a-1)/2
# Note that RangeSet includes the upper bound, whereas range stops one short
m.IDX = RangeSet(1,c-1)
m.var = Var(m.IDX, within=Binary)
m.obj = Objective(expr = 0)