Skip to main content

gurobipy.GurobiError: Constraint has no bool value (are you trying "lb <= expr <= ub"?)

Answered

Comments

3 comments

  • Maliheh Aramon
    Gurobi Staff Gurobi Staff

    Hi Qiuyan, 

    It is not possible to use Gurobi variable objects in if-clauses because there is no value associated with them to be used in comparison. The reason for the error you see is well-explained in the article Constraint has no bool value (are you trying "lb <= expr <= ub"?). Please check the cause number 3). 

    I assume you would like to model the following constraint:

    \[\mbox{if}~~ TS_i \leq p  ~\mbox{and}~ TE_i \geq p \rightarrow \lambda_{ip} (TE_i - TS_i + 1) = D_i \]

    To implement the above constraint, you need to use three binary auxiliary variables to model the relationships below:

    • \(\mbox{if}~~ TS_i \leq p  \rightarrow  x_i = 1 \)
    • \(\mbox{if}~~ TE_i \geq p  \rightarrow  y_i = 1 \)
    • \(\mbox{if}~~ x_i = 1 ~\mbox{and}~ y_i= 1 \rightarrow  z_i = 1 \)
    • \(\mbox{if}~~ z_i = 1 \rightarrow \lambda_{ip} (TE_i - TS_i + 1) = D_i \)

    You can use Gurobi Python APIs for the Indicator constraint to implement the above relationships. 

    Best regards,

    Maliheh

    1
  • johann hong
    First Comment
    First Question

    Hello,Maliheh,Thanks for your advice,it's helpful.I tried to modeling the constraint using the method above.However, the value of  variable: lambda_i_p[i, p] all become 0.And I check the code,I think the problem  may still lie in this section of the code.Which part do you think the problem occurred?

    # Define the lambda_i_p derived variables
    lambda_i_p = {}
    for i in V:
    for p in P:
    lambda_i_p[i, p] = model.addVar(vtype=GRB.CONTINUOUS, name=f"lambda_i_p_{i}_{p}")
    # Add auxiliary variables x, y, and z
    x = {}
    y = {}
    z = {}
    for i in V:
    for p in P:
    x[i, p] = model.addVar(vtype=GRB.BINARY, name=f"x_{i}{p}")
    y[i, p] = model.addVar(vtype=GRB.BINARY, name=f"y_{i}{p}")
    z[i, p] = model.addVar(vtype=GRB.BINARY, name=f"z_{i}{p}")

    # Add constraints: x[i]=1 if and only if TS_i[i] <= p
    # Add constraints: y[i]=1 if and only if TE_i[i] >= p
    # Add constraints: z[i]=1 if and only if x[i]=1 and y[i]=1

    # Add constraint: lambda_i_p[i, p] * (TE_i[i] - TS_i[i] + 1) == D_i[i] when z[i]=1 holds
    for i in V:
    for p in P:
    model.addConstr((x[i, p] == 1) >> (TS_i[i] <= p), name=f"constraint_x_{i}_{p}")
    model.addConstr((y[i, p] == 1) >> (p <= TE_i[i]), name=f"constraint_y_{i}_{p}")
    model.addConstr(z[i, p] == x[i, p] * y[i, p], name=f"constraint_z_{i}{p}")
    model.addConstr(lambda_i_p[i, p] * (TE_i[i] - TS_i[i] + 1) == D_i[i] * z[i, p], name=f"constraint_lambda_ip_{i}_{p}")
    0
  • Maliheh Aramon
    Gurobi Staff Gurobi Staff

    Do you get an error? Or do you mean that having all \(\lambda_{ip}\) assigned to 0 is not what you expect to see in the optimal solution? 

    Please note that you have modelled different relationships. In your implementation version below, if \(z_i = 0\), the expression \(\lambda_{ip}(TE_i - TS_i +1)\) must be 0 then. However, in the constraint \(\mbox{if}~ z_i = 1 ~ \rightarrow ~ \lambda_{ip} (TE_i - TS_i +1) = D_i\), we do not impose any constraint on the value of \(\lambda_{ip} (TE_i - TS_i +1)\) if \(z_i = 0\).

    model.addConstr(lambda_i_p[i, p] * (TE_i[i] - TS_i[i] + 1) == D_i[i] * z[i, p], name=f"constraint_lambda_ip_{i}_{p}")

    The same is true for all the other constraints you have implemented.

    • The constraint \(\mbox{if}~~ TS_i \leq p  \rightarrow  x_i = 1 \) is different from the constraint \(\mbox{if}~~   x_i = 1 \rightarrow  TS_i \leq p \). To model the former relationship using Gurobi Python API for indicator constraints, you can implement its equivalent logical contrapositive in the form \(\mbox{if}~~   x_i \neq 1 \rightarrow  TS_i \nleq p \) which is \(\mbox{if}~~   x_i = 0 \rightarrow  TS_i \geq p + \epsilon \).
    • The constraint \(\mbox{if}~~ TE_i \geq p  \rightarrow  y_i = 1 \) is different from the constraint \(\mbox{if}~~ y _i = 1 \rightarrow TE_i \geq p\) (see above).
    • The constraint \(\mbox{if}~~ x_i = 1 ~\mbox{and}~ y_i= 1 \rightarrow  z_i = 1 \) is different from \(z_i = x_i y_i\). In the former version, we are not imposing any constraint on the value of \(z_i\) if, for example, \(x_i = 0\) and \(y_i = 1\). 

    Best regards,

    Maliheh

    0

Please sign in to leave a comment.