Pyomo - 将pyomo数值隐式转换为整数

时间:2018-02-19 06:38:27

标签: optimization pyomo

我正在尝试优化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)。当我安装它时,我将不得不向某人询问安装方法,因此可能需要一些时间。一旦我问安装人员,我会更新安装方法。

感谢。

1 个答案:

答案 0 :(得分:1)

这里有两件事:

  1. 您在定义之前正在评估Param。
  2. 您隐式将Pyomo表达式转换为整数。
  3. 问题的根源在于您将抽象模型视为具体模型。对于抽象模型,当您声明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。该演员阵容是产生错误的原因。

    通过使用(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)