提问者:小点点

如何在Pyomo中对变量设置简单的双域约束?


我正在使用Pyomo解决一个供应链优化问题,我需要在模型中设置特定变量的约束。约束条件是变量应在集合(0,1)或(200,无穷大)内。但是,当我尝试设置该约束时,我得到一个TypeError,下面是我的代码:

def rail_rule(model):
        for route in routes:
            if "rail" in route[0].lower():
                dest = route[0]
                dg = route[1]
                sg = route[2]
                site = route[3]
                return model.x[dest, dg, sg, site]>=200 or model.x[dest, dg, sg, site]<=1

model.railconst = Constraint(rule = rail_rule)

我在运行时遇到此错误:

TypeError: Relational expression used in an unexpected Boolean context.

        The inequality expression:
            200.0  <=  x[RAIL - KENSINGTON,8,8,BROCKLESBY]
        contains non-constant terms (variables) that were evaluated in an
        unexpected Boolean context at
          File '<ipython-input-168-901363ebc86f>', line 8:
    return model.x[dest, dg, sg, site]>=200 or model.x[dest, dg, sg, site]<=1

        Evaluating Pyomo variables in a Boolean context, e.g.
            if expression <= 5:
        is generally invalid.  If you want to obtain the Boolean value of the
        expression based on the current variable values, explicitly evaluate the
        expression using the value() function:
            if value(expression) <= 5:
        or
            if value(expression <= 5):

所以我的理解是,我不能给Pyomo一个布尔表达式作为约束,但是我对Pyomo很陌生,不太确定这是我的问题还是我做得正确。

这个约束也可以作为边界在变量初始化中实现,但是我找不到在Pyomo中为单个变量设置两个边界的方法。

谢谢


共1个答案

匿名用户

有不同的方法来处理这个问题:

(1) 使用二进制变量。假设你在x上有一个很好的上界,即x∈ [0,U]。然后制定约束条件

  x ≤ 1 + (U-1) δ
  x ≥ 200 δ
  δ ∈ {0,1}  (binary variable)

这是最简单的方法。

(2) 如果x上没有好的上界,可以使用SOS1集。(SOS1表示类型1的特殊有序集)。假设x,s1,s2≥ 0

  x ≤ 1 + s1
  x ≥ 200 - s2
  s1,s2 ∈ SOS1   (s1,s2 form a SOS1 set)

(3) 使用析取编程。