Constraint has no bool value (are you trying "lb <= expr <= ub"?)
OngoingI get the following error for a constraint. Note this was working in Gurobi 8 but not in Gurobi 9.
m.addConstrs(0 <= f1[i,j,h] <= 200*z[i,j] for i,j in arcs for h in area)
The full error is as follows:
GurobiError Traceback (most recent call last) <ipythoninput11a72e0ea229a7> in <module>()
> 5 m.addConstrs(0*z[i,j] <= f1[i,j,h] <= 200*z[i,j] for i,j in arcs for h in area) #(4g)
model.pxi in gurobipy.Model.addConstrs()
tempconstr.pxi in gurobipy.TempConstr.__bool__() GurobiError: Constraint has no bool value (are you trying "lb <= expr <= ub"?)
I will be very grateful if someone can help me with this error!
Sagnik

I had to break the constraint into two parts and it worked
m.addConstrs(0 <= f1[i,j,h] for i,j in arcs for h in area) #(4g)
m.addConstrs(f1[i,j,h] <= 200*z[i,j] for i,j in arcs for h in area) #(4g)I am wondering why this change was made!
0 
Hi Sagnik,
Adding twosided constraints was never supported in Gurobi 8.1.1. This is noted in the Gurobi 8.1.1 documentation here:
"Note that double inequality constraints, like 1 <= x + y <= 2 or 1 <= x[i] + y[i] <= 2 for i in range(3) are NOT supported in this API, and will result in one of the inequalities to be silently disregarded, which will result in unexpected behavior."
For example, consider the following code:
m = Model()
x = m.addVar(name="x")
m.addConstr(1 <= x <= 2, name="twosided")In Gurobi 8.1.1, this results in the following model (in LP format):
Minimize
Subject To
twosided: x <= 2
Bounds
EndNote the missing constraint. This change of behavior in Gurobi 9.0 simply disallows this syntax, preventing unexpected behavior like this.
In your example, is f1 is a variable? If so, it is nonnegative by default (unless you explicitly set its lower bound), so you may not even need the nonnegativity constraint.
I hope this helps. Thanks!
Eli
0 
thank you so much!
0 
Hello, I am having a similar problem, I know that if we want to write a constraint like this \(LB \leq v \leq UB\) I have to do it separately so, I wrote them like this:
rxn = ['a','b','c','d','e']
LB = [1000,0,1000,0,1000]
UB = [1000,1000,1000,1000,1000]
reactions = [i for i in range(len(rxn))]
m = gp.Model()
vo = m.addVars(range(len(rxn),name='v')
m.addConstrs((LB[j] <= vo[j] for j in reactions), name='LB')
m.addConstrs((vo[j] <= UB[j] for j in reactions), name='UB)And I get the same error:
> 16 f.addConstrs((LB[j] <= v[j] for j in reactions), name='LB') 17 18 f.addConstrs((v[j] <= UB[j] for j in reactions), name='UB') src\gurobipy\tempconstr.pxi in gurobipy.gurobipy.TempConstr.__bool__() GurobiError: Constraint has no bool value (are you trying "lb <= expr <= ub"?)
Ultimately I want to have a set of constraints like this:
\[LB*y_j \leq v_j \leq UB*y_j\] for j in a knockout set and:
\[LB \leq v_j \leq UB\] if j not in the knockout set, the easiest way I could think of is:
for j in reactions:
if j in knockout:
m.addConstr((LB[j] * yo[j] <= vo[j]), name='LBy')
m.addConstr((vo[j] <= yo[j] * UB[j]), name='UBy')
else:
m.addConstr((LB[j] <= vo[j]), name='LB')
m.addConstr((vo[j] <= UB[j]), name='UB')It is worth to mention that \(v_o\) is a continuous variable and \(y_o\) is binary, I would appreciate some help with this.
Thanks in advance
0 
Which version of Gurobi are you using? The first code snippet is missing a parenthesis in the call to Model.addVars() and an apostrophe in the last line. Otherwise, the code should work as intended. I.e., the snippet
import gurobipy as gp
rxn = ['a', 'b', 'c', 'd', 'e']
LB = [1000, 0, 1000, 0, 1000]
UB = [1000, 1000, 1000, 1000, 1000]
reactions = [i for i in range(len(rxn))]
m = gp.Model()
vo = m.addVars(range(len(rxn)), name='v')
m.addConstrs((LB[j] <= vo[j] for j in reactions), name='LB')
m.addConstrs((vo[j] <= UB[j] for j in reactions), name='UB')adds the following constraints to the model:
LB[0]: v[0] >= 1000
LB[1]: v[1] >= 0
LB[2]: v[2] >= 1000
LB[3]: v[3] >= 0
LB[4]: v[4] >= 1000
UB[0]: v[0] <= 1000
UB[1]: v[1] <= 1000
UB[2]: v[2] <= 1000
UB[3]: v[3] <= 1000
UB[4]: v[4] <= 10000 
Hello Eli,
Thanks for your answer,
I am using 9.1.0 and python 3.7.6
0 
Can you please try running the code snippet I posted, and also post the output of \( \texttt{gp.gurobi.version()} \)? The error message you posted does not match the code you posted (the error message references a model named \( \texttt{f} \) instead of \( \texttt{m} \)).
Note that since \( \texttt{LB} \) and \( \texttt{UB} \) are bounds on the \( \texttt{vo} \) variables, you could just assign these bounds in the call to Model.addVars():
vo = m.addVars(range(len(rxn)), lb=LB, ub=UB, name='v')
Of course, this approach won't work for constraints of the form \( \ell y_j \leq v_j \leq u y_j \), which you're working towards.
0 
Hello Eli,
I ran the code snippet you posted and it gives me the same constraints as you wrote
These are the actual constraints I have written in my model:
f = gp.Model()
reactions = [i for i in range(len(rxn))]
metabolites = [i for i in range(len(met))]
v = f.addVars(range(len(rxn)),obj=c, name='v')
f.modelSense = GRB.MAXIMIZE
f.addConstrs((gp.quicksum(S[i,j] * v[j] for j in reactions) == b[i] for i in metabolites), name='FBA')
f.addConstrs((LB[j] <= v[j] for j in reactions), name='LB')
f.addConstrs((v[j] <= UB[j] for j in reactions), name='UB')
f.optimize()Note that: reactions, c, LB and UB are arrays of the same length, and S has a length of (metabolitesXreactions) b and metabolites have the same length
Other than the name I see no difference, I will try to run again my code, I tried with the bounds being declared in m.AddVars but as you point out is not what I am working towards, if I relaxed the model that way it works without any problem
0 
Hello,
I tried by allowing the lb and ub in f.addVars to be from  infinity to infinity and declaring them as continuos, but I still get the same error, I thought maybe it had to do with the values the variables were taking given the default values in the bounds
0 
Can you please post a complete, selfcontained code example that reproduces the issue? I don't see anything wrong with the snippet you posted, but it is missing some definitions. Based on the error message, I would guess that \( \texttt{LB} \) was at some point overwritten to include a TempConstr object.
0 
Hello Eli,
This is just a brief example, but the error doesn't show, I will go carefully on my model to figure what's causing it
met = ['A','B','C','D','E']
metabolites = [ i for i in range(len(met))]
reac = ['v1','v2','v3','v4','v5','v6','v7']
reactions = [i for i in range(len(reac))]
LB =[0,10,0,0,10,10,10]
UB =[10,10,10,10,10,10,10]
SM = {(0,0):1,(0,1):0,(0,2):1,(0,3):0,(0,4):0,(0,5):0,(0,6):0,
(1,0):1,(1,1):1,(1,2):0,(1,3):1,(1,4):0,(1,5):0,(1,6):0,
(2,0):0,(2,1):1,(2,2):0,(2,3):0,(2,4):1,(2,5):0,(2,6):0,
(3,0):1,(3,1):0,(3,2):0,(3,3):0,(3,4):0,(3,5):1,(3,6):0,
(4,0):1,(4,1):0,(4,2):0,(4,3):0,(4,4):0,(4,5):0,(4,6):1}
ob = [0,0,0,1,0,0,0]
m = gp.Model()
v = m.AddVars(range(len(reac)), vtype=GRB.CONTINUOUS, obj=ob, name='v')
m.addConstrs((gp.quicksum(SM[i,j]*v[j] for j in reactions) == 0 for ir in metabolites), name='FBA')
m.addConstrs((LB[j] <= v[j] for j in reactions), name='LB')
m.addConstrs((v[j] <= UB[j] for j in reactions), name='UB)m.optimize()
if m.status == GRB.OPTIMAL:
obj = m.getObjective()
print('Max v4 Flux','>',obj.getValue())
var = m.getAttr('X',m.getVars())
print('>')
for i in range(len(reac)):
print('flux:',reac[i],'>',var[i])which produces :
Gurobi Optimizer version 9.1.0 build v9.1.0rc0 (win64) Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 19 rows, 7 columns and 25 nonzeros
Model fingerprint: 0x4d86fd76
Coefficient statistics:
Matrix range [1e+00, 1e+00] Objective range [1e+00, 1e+00] Bounds range [0e+00, 0e+00] RHS range [1e+01, 1e+01]
Presolve removed 19 rows and 7 columns
Presolve time: 0.01s
Presolve: All rows and columns removed
Iteration Objective Primal Inf. Dual Inf. Time 0 0.0000000e+00 0.000000e+00 0.000000e+00 0s Solved in 0 iterations and 0.01 seconds Optimal objective 0.000000000e+00
Max v4 Flux > 0.0 >
flux: v1 > 0.0
flux: v2 > 0.0
flux: v3 > 0.0
flux: v4 > 0.0
flux: v5 > 0.0
flux: v6 > 0.0
flux: v7 > 0.0However, when I declare the bounds and delete the corresponding constraints
m.AddVars(range(len(reac)),lb=UB,ub=UB, vtype=GRB.CONTINUOUS, obj=ob, name='v')
The result is different (and the correct answer)
Gurobi Optimizer version 9.1.0 build v9.1.0rc0 (win64)
Thread count: 4 physical cores, 8 logical processors, using up to 8 threads
Optimize a model with 19 rows, 7 columns and 25 nonzeros
Model fingerprint: 0xbc50aaa9
Coefficient statistics: Matrix range [1e+00, 1e+00] Objective range [1e+00, 1e+00] Bounds range [1e+01, 1e+01] RHS range [1e+01, 1e+01]
Presolve removed 19 rows and 7 columns Presolve time: 0.02s Presolve: All rows and columns removed
Iteration Objective Primal Inf. Dual Inf. Time 0 1.0000000e+01 0.000000e+00 0.000000e+00 0s Solved in 0 iterations and 0.02 seconds Optimal objective 1.000000000e+01
Max v4 Flux > 10.0 >
flux: v1 > 0.0
flux: v2 > 10.0
flux: v3 > 0.0
flux: v4 > 10.0
flux: v5 > 10.0
flux: v6 > 0.0
flux: v7 > 0.0Upon further analysis, I realized the difference is that if I declare lb=GRB.INFINITY, ub=GRB.INFINITY in the first model, the result is the same, so I am assuming it has to do with how 'open' the variable is. Still quite confused to be honest but, I appreciate the time you've taken to answer me back.
0 
By default, the lower bound on variables added with Model.addVar()/Model.addVars() is 0. Since your variables can be negative, you either need to pass \( \texttt{LB} \) as the \( \texttt{lb} \) keyword argument of Model.addVars(), or explicitly set a lower bound of \( \texttt{GRB.CONTINUOUS} \) and add lowerbound constraints later.
0 
Hello Eli,
Kindly let me know why the following code sets the indicator variable z to zero.
My work is such that if the variable resource_allocation_variables[j,p,r] is one, then the constraint cap_2[1] <= quicksum(DR_dicts_using_user_BS_BBU_pair_key[(j,p,r)]*resource_allocation_variables[j,p,r] for r in MBS_BBU_list) <= capacity_vector[1] should be satisfied, for a given user p attached to node j.
So I created indicator variable z for this conditional statement. Now I am wondering why no user p is allocated any resource r on the node j, yet the resources are available.
z = f.addVars(DR_dicts_using_user_BS_pair_key.keys(), vtype=GRB.BINARY, name="z")
f.addConstrs(((z[j,p]==1)>>(cap_2[1] <= quicksum(DR_dicts_using_user_BS_BBU_pair_key[(j,p,r)]*resource_allocation_variables[j,p,r] for r in MBS_BBU_list)) for j in MBS_list for p in list_R_users), name='MBS_uRLLC_QoS_1')
f.addConstrs(((z[j,p]==1)>>(quicksum(DR_dicts_using_user_BS_BBU_pair_key[(j,p,r)]*resource_allocation_variables[j,p,r] for r in MBS_BBU_list) <= capacity_vector[1]) for j in MBS_list for p in list_R_users), name='MBS_uRLLC_QoS_1')
f.addConstrs(((z[j,p]==0) >> (quicksum(resource_allocation_variables[j,p,r] for r in MBS_BBU_list) <=0) for j in MBS_list for p in list_R_users), name='MBS_uRLLC_QoS_2')
f.addConstrs(((z[j+Num_BS,p]==1)>>(cap_2[1] <= quicksum(DR_dicts_using_user_BS_BBU_pair_key[(j+Num_BS,p,r)]*resource_allocation_variables[j+Num_BS,p,r] for r in UAV_BBU_list)) for j in UAV_list for p in list_R_users), name='UAV_uRLLC_QoS_1')
f.addConstrs(((z[j+Num_BS,p]==1)>>(quicksum(DR_dicts_using_user_BS_BBU_pair_key[(j+Num_BS,p,r)]*resource_allocation_variables[j+Num_BS,p,r] for r in UAV_BBU_list) <= capacity_vector[1]) for j in UAV_list for p in list_R_users), name='UAV_uRLLC_QoS_1')
f.addConstrs(((z[j+Num_BS,p]==0) >> (quicksum(resource_allocation_variables[j+Num_BS,p,r] for r in UAV_BBU_list) <=0) for j in UAV_list for p in list_R_users), name='UAV_uRLLC_QoS_2')
f.addConstrs(((z[j+Num_BS+Num_UAVS,p]==1)>>(cap_2[1] <= quicksum(DR_dicts_using_user_BS_BBU_pair_key[(j+Num_BS+Num_UAVS,p,r)]*resource_allocation_variables[j+Num_BS+Num_UAVS,p,r] for r in HAP_BBU_list)) for j in HAP_list for p in list_R_users), name='HAP_uRLLC_QoS_1')
f.addConstrs(((z[j+Num_BS+Num_UAVS,p]==1)>>(quicksum(DR_dicts_using_user_BS_BBU_pair_key[(j+Num_BS+Num_UAVS,p,r)]*resource_allocation_variables[j+Num_BS+Num_UAVS,p,r] for r in HAP_BBU_list) <= capacity_vector[1]) for j in HAP_list for p in list_R_users), name='HAP_uRLLC_QoS_1')
f.addConstrs(((z[j+Num_BS+Num_UAVS,p]==0) >> (quicksum(resource_allocation_variables[j+Num_BS+Num_UAVS,p,r] for r in HAP_BBU_list) <=0) for j in HAP_list for p in list_R_users), name='HAP_uRLLC_QoS_2')0 
if the variable resource_allocation_variables[j,p,r] is one, then the constraint [...] should be satisfied, for a given user p attached to node j
Do you mean the constraint should be satisfied if the variable \( \texttt{z[j, p]} \) equals \( 1 \)? This is what your code currently models.
It's hard to say exactly what's wrong, because the code you provided does not run on its own. Due to your third constraint family, it is expected that if \( \texttt{z[j, p]} \) equals \( 0 \), then all of the corresponding resource allocation variables also equal \( 0 \).
Below are a few ideas that may help:
 You can use Model.write() to write out an LP model file, then visually inspect the constraints for correctness. Before you do this, I recommend changing your constraint names to be unique. Your first two constraint families both use the name \( \texttt{MBS_uRLLC_QoS_1} \). This will result in (e.g.) two constraints named \( \texttt{MBS_uRLLC_QoS_1[0,0]} \), two constraints named \( \texttt{MBS_uRLLC_QoS_1[0,1]} \), etc.
 If there is a specific \( \texttt{z[j, p]} \) variable you think should equal \( 1 \) in the optimal solution, you could try fixing that variable to \( 1 \) and solving the model again. The resulting model should either (i) be infeasible, or (ii) admit an optimal objective value that is no less than (for a minimization problem) the optimal objective value obtained by leaving that \( \texttt{z[j, p]} \) variable unfixed.
 Semicontinuous variables are variables that must assume a value of \( 0 \), or a value between the specified lower and upper bounds. You could remove the binary indicator variables \( \texttt{z} \) and instead introduce semicontinuous variables equal to the weighted resource allocation for each user and node. The code to do so would look something like this:
y = f.addVars(
DR_dicts_using_user_BS_pair_key.keys(),
lb=cap_2[1],
ub=capacity_vector[1],
vtype=GRB.SEMICONT,
name="y"
)
m.addConstrs(
(
y[j, p]
== quicksum(
DR_dicts_using_user_BS_BBU_pair_key[(j, p, r)]
* resource_allocation_variables[j, p, r]
for r in MBS_BBU_list
)
for j in MBS_list
for p in list_R_users
),
name="MBS_uRLLC_QoS"
)If these ideas do not help, please post a minimal, selfcontained code example that reproduces the behavior you describe.
0 
Hello Eli,
I've same problem with error "Constraint has no bool value (are you trying "lb <= expr <= ub"?)". I worked in Gurobi 10.0.3 and python 3.11.4
This is my main code:
import pandas as pd
import gurobipy as gp
import timeit
import numpy as np
df = pd.read_excel('3D_data_IJRT.xlsx')
J = [int(value) for value in df['J'].unique().tolist()]
T = [int(value) for value in df['P'].unique().tolist()]
max_T = max(T)
I = [int(value) for value in df.columns[2:].tolist()] # Assuming C0, C1, C3, C4 are the column headers
R = []
# Define the rank_value function
def rank_value(value):
if value <= 8:
return 1
elif value <= 15:
return 2
else:
return 3
for j in J:
for t in T:
filtered_data = df[(df['J'] == j) & (df['P'] == t)][I].values.flatten() # Get values as a flattened NumPy array
ranked_data = [rank_value(value) for value in filtered_data] # Apply rank_value to each element
R.extend(ranked_data)D = {}
for i in I:
D[i] = {}
for t in T:
D[i][t] = df[df['P'] == t][i].count()
alpha = {}
for i in I:
alpha[i] = {}
for t in T:
alpha[i][t] = D[i][t] * 1/3
S = {}
for i in I:
S[i] = {}
for j in J:
S[i][j] = {}
for t in T:
S[i][j][t] = (df[(df['J'] == j) & (df['P'] == t)][i].values) + 2 + 10 + 5This is my Decision Variable code:
def decisionVariables(M, gp, I, J, T, R, x, y, d, delta, theta, ar):
for j in J:
for t in T:
y[j, t] = M.addVar(vtype=gp.GRB.INTEGER, name=f"y_{j}_{t}")
M.update()
for i in I:
for j in J:
for r in R:
for t in T:
d[i, j, r, t] = M.addVar(vtype=gp.GRB.CONTINUOUS, name=f"d_{i}_{j}_{r}_{t}")
And this is my constraint code:for j in (J):
for t in (T):
result = gp.quicksum(alpha[i][t] * S[i][j][t] * d[i, j, r, t] for i in (I) for r in (R))
M.addConstr(result <= (150 * y[j, t]))
The Error:constraints.constraints(M, gp, x, y, I, J, T, R, Zmax, Atotal, Amax, delta, d, theta, alpha, ar, max_T, S, L)
File D:\Laela Widiyaningsih\py\constraints.py:67 in constraints
M.addConstr(result <= (150 * y[j, t]))
File src\gurobipy\tempconstr.pxi:57 in gurobipy.TempConstr.__bool__
GurobiError: Constraint has no bool value (are you trying "lb <= expr <= ub"?)0 
Unfortunately, I can't say for certain what's causing the issue, because the code is not selfcontained. Can you please (i) post a link to the \(\texttt{3D_data_IJRT.xlsx}\) workbook, and (ii) modify the code so it will run without any modifications?
0
Please sign in to leave a comment.
Comments
16 comments