TypeError: '<' not supported between instances of 'Var' and 'Var'
AnsweredI am trying to write a constraint for: E_im<= min {xi,...,xim}
for example: E_12 <= min(x["1"], x["2"]) where x is a binary variables and E is a 2d binary variable. The values come from a matrix I = ["1", "5", "2"]. I tried using:
for i in I:
for ii in I:
if i != ii:
model.addConstr(E[i,ii] <= min((x[i]),(x[ii])))
but it is giving me the error TypeError: '<' not supported between instances of 'Var' and 'Var' and I not sure why since x should be giving values of 0 and 1.
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
Hi Sab,
You can use the min_() general constraint helper function to model minimums. But in your case, it seems much better to just break each of these constraints into two separate constraints. For example:
$$\begin{align*} E_{1,2} &\leq x_1 \\ E_{1,2} &\leq x_2. \end{align*}$$
Thanks,
Eli
0 -
Thank you for your answer!
If I wanted to use min_() would it work this way?
for i in I:
for ii in I:
k = model.addConstr(E[i, ii] == min_(x[i], x[ii]), name="k")0 -
Yes, that works. A few comments:
- For the case where \( \texttt{i} \) and \( \texttt{ii} \) are the same, a general constraint isn't necessary. You can instead add the constraint \( E_{i,i} = x_i \), since \( x_i = \min\{x_i, x_i\} \). Alternatively, use \( x_i \) directly whenever you would need \( E_{i,i}. \)
- You don't need two separate variables \( E_{i,j} \) and \( E_{j,i} \) for each \( i \neq j \), since \( \min\{x_i, x_j\} = \min\{x_j, x_i\} \). I recommend only adding variables \( E_{i,j} \) for \( i < j \). Then, if \( E_{j,i} \) is not defined (because \( j > i \)), just use \( E_{i,j} \) instead.
- Each constraint should have a unique name. All of these constraints have the same name, \( \texttt{'k'} \).
- I don't see a reason to store the constraint object in a Python variable \( \texttt{k} \), since \( \texttt{k} \) is overwritten many times.
Altogether:
import gurobipy as gp
model = gp.Model()
I = [1, 2, 5]
J = [(i, j) for i in I for j in I if i < j]
x = model.addVars(I, name='x')
E = model.addVars(J, name='E')
for i, j in J:
model.addConstr(E[i, j] == gp.min_(x[i], x[j]), name=f"k{i}_{j}")This produces a model with the following variables/constraints:
k1_2: E[1,2] = MIN ( x[1] , x[2] )
k1_5: E[1,5] = MIN ( x[1] , x[5] )
k2_5: E[2,5] = MIN ( x[2] , x[5] )0 -
Thank you for you help!
I tried using the same idea the following way:
from gurobipy import *
I = ["1", "5", "4", "9", "6", "8", "2", "3", "7"]Z = [(i, j) for i in I for j in I if i < j]
R = [(i, j, r) for i in I for j in I for r in I if i < j and j < r]model = Model("Base Model")
x = model.addVars(I, vtype=GRB.BINARY, name="x")
E = model.addVars(Z, Z, vtype=GRB.BINARY, name="E")
E3 = model.addVars(R, R, R, vtype=GRB.BINARY, name="E3")for i, j in Z:
model.addConstr(E[i, j] <= model.min_(x[i], x[j]))
for i, j, r in R:
model.addConstr(E3[i, j, r] <= model.min_(x[i], x[j], x[r]))But I am getting this error as if the value couldn't been found but the for loop seems to be working:
File "base.py", line 172, in <module>
model.addConstr(E[i, j] <= model.min_(x[i], x[j]))
KeyError: ('1', '5')0 -
\( \texttt{Z} \) and \( \texttt{R} \) are defined as lists of length-2 tuples and length-3 tuples, respectively:
>>> Z
[('1', '5'), ('1', '4'), ('1', '9'), ('1', '6'), ... ]
>>> R
[('1', '5', '9'), ('1', '5', '6'), ('1', '5', '8'), ... ]So, you only have to pass a single instance of \( \texttt{Z} \) and \( \texttt{R} \) to Model.addVars() when you define the \( \texttt{E} \) and \( \texttt{E3} \) variables, since the tuples in the list become the indices for the variables.
x = model.addVars(I, vtype=GRB.BINARY, name="x")
E = model.addVars(Z, vtype=GRB.BINARY, name="E")
E3 = model.addVars(R, vtype=GRB.BINARY, name="E3")Next, the min_() function is not a method of the Model class. Since you import everything from the \( \texttt{gurobipy} \) module's namespace into the main namespace, you should write \( \texttt{min_(...)} \) instead.
Lastly, the min_() function can only be used to set one variable equal to the minimum of others (and possibly some constants). Thus you can't directly use a \( \texttt{<=} \) constraint with the min_() function. In your case, it might be better to forgo the min_() function completely and instead add individual constraints that a particular \( \texttt{E} \) variable is less than or equal to the corresponding \( \texttt{x} \) variables. E.g.:
for i, j in Z:
model.addConstr(E[i, j] <= x[i])
model.addConstr(E[i, j] <= x[j])This is really adding the constraint \( E_{i,j} \leq \min\{x_i, x_j\} \), not \( E_{i,j} = \min\{x_i, x_j\} \). But it might be sufficient for your model, and it is what your current code is trying to do anyways.
0
Post is closed for comments.
Comments
6 comments