关于gurobi中约束没有布尔值的解决办法

在使用gurobi求解器时,有时会出现“Constraint has no bool value (are you trying "lb <= expr <= ub"?)”的报错信息,错误原因主要包括以下三点1
1.尝试添加双侧约束
2.在约束的左侧使用 NumPy 标量
3.在 if 子句中使用变量或表达式

尝试添加双侧约束

从 Gurobi 优化器 9.0.0 开始,尝试通过 Python API 添加双边约束(如 1 <= x <= 2)时,您可能会看到此错误。在 Gurobi 9.0 及更高版本中不支持添加双侧约束。尽管相同的语法在 Gurobi 8.1.1 及更早版本中不会导致错误,但不支持添加双边约束,并且行为与预期不符。

“请注意,双重不等式约束,如 1 <= x + y <= 2 或 1 <= x[i] + y[i] <= 2 for i in range(3),在此 API 中不受支持,并且将导致其中一个不等式被默默忽略,这将导致意外行为。
例如,请考虑以下代码:

m = Model()x = m.addVar(name="x")m.addConstr(1 <= x <= 2, name="twosided")

在 Gurobi 8.1.1 中,这将生成以下模型(LP 格式):

MinimizeSubject To  twosided: x <= 2BoundsEnd

请注意,缺少约束 1 <= x。在 v9.0.0 及更高版本中,Gurobi 通过抛出错误来主动禁止此语法,从而防止此类意外行为。相反,可以将这两个约束中的每一个分别添加到模型中:

m.addConstr(1 <= x, name="lefthandside")m.addConstr(x <= 2, name="righthandside")

在约束的左侧使用 NumPy 标量

在约束的左侧使用 NumPy 标量(如 numpy.int32、numpy.int64、numpy.float32 或 numpy.float64)时,也会发生此错误。例如,以下代码会导致“约束没有布尔值”错误:

import numpy as npimport gurobipy as gpmodel = gp.Model()x = model.addVar()a = np.float64(5)model.addConstr(a >= x) # error!

该错误是 Python 使用相应 NumPy 数据类中的__ge__ 或者__le__ 方法的结果,该方法不适用于构造 Gurobi 约束表达式。
两种可能的解决方法是:

  • 将 NumPy 数据结构重新转换为标准的 Python 数字类型,如 int 或 float。在这种情况下,最后一行变为 model.addConstr(int(a) >= x)。
  • 重写约束,使左侧表达式以 Var 或 LinExpr 对象开头。使用此解决方法,最后一行将变为 model.addConstr(x <= a)。
    约束没有布尔值

在 if 子句中使用变量或表达式

在 if 子句中使用变量对象或表达式对象(如 LinExpr 或 QuadExpr)时,也会发生此错误。例如,以下代码会导致名义错误:

import gurobipy as gpm = gp.Model()x = m.addVars(3)y = m.addVars(2)if (gp.quicksum(x) >= 1):  # error!    m.addConstr(gp.quicksum(y) == 0)·

发生此错误的原因是,由 gp.quicksum(x) 调用创建的表达式对象没有任何可用于计算 if 条件的值。在数学编程中,必须通过附加约束和二进制变量对此类条件语句进行建模。
如何在 Gurobi 中对条件语句建模?解释了如何对上述 if 条件进行建模。

参考文献:

[1] https://support.gurobi.com/hc/en-us/articles/360039628832-Constraint-has-no-bool-value-are-you-trying-lb-expr-ub-#h_01GFRWBTABJC8CNFDR92Z5SVQ8
最后修改:2023 年 03 月 08 日
如果觉得我的文章对你有用,请随意赞赏