我正在试图优化一个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)时,就会出现错误。如果我错了,请纠正我。
我有Python2.7.12,Pyomo-5.3 (Linux上的CPython-2.7.12)。当我安装它时,我将不得不向某人询问安装方法,所以可能需要时间。我会更新安装方法,一旦我问谁安装它。
谢谢。
发布于 2018-02-21 17:58:56
这里有两件事:
问题的根源在于,您将抽象模型视为一个具体的模型。对于抽象模型,当您声明m.a时,您只声明参数a的存在。然后Python继续解析和执行模型的其余部分。当它命中c = m.a*(m.a-1)/2时,Python会生成一个Pyomo表达式树,表示右侧.最后,当它到达m.var = Var(range(1,c), within=Binary)时,Python首先在调用Var()构造函数之前执行Var()。range (一个Python函数)在生成范围列表之前将其参数转换为int。这个转换就是产生错误的原因。
您可以通过使用(Pyomo) 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)https://stackoverflow.com/questions/48860735
复制相似问题