MIO in Python, Multiplying decision variables and arrays
AnsweredHi all, I am trying to write a MIO in python but I am having some difficulties in writing one of the constraints.
I have defined aij to be a binary variable and xi is each row of a dataset which is an array with the size 1*3.
I need a to be a matrix so I can multiply each of its columns by xi but in gurobi decision variables are defined as dicts. How can I do this?
for tb in TB:
for j in range(1,p+1):
a[j,tb]= m.addVar(obj=0,vtype=GRB.BINARY, name="a[%s,%s]"%(j,tb))
-
Hi Parisa,
You should be able to do this by using the quicksum() function to calculate the inner product term. Consider the following (simplified) constraint:
\( a^\top x \geq 1 \)
We can create an example constraint of this form as follows:
import gurobipy as gp
n = 4
m = gp.Model()
a = m.addVars(n, vtype=gp.GRB.BINARY, name="a")
x = [i+1 for i in range(n)]
m.addConstr(gp.quicksum(a[i] * x[i] for i in range(n)) >= 1)This adds the following constraint to our model:
a[0] + 2 a[1] + 3 a[2] + 4 a[3] >= 1
That code snippet can be generalized to your constraints. It would look something like this (omitting the proper for loops):
a = m.addVars(M, N, vtype=gp.GRB.BINARY, name="a")
...
m.addConstr(gp.quicksum(a[m,j] * x[i, j] for j in range(N)) >= b[m] - (1 - z[i, t]))We could write this same constraint even more succinctly with the tupledict.prod() method, though this may not work so cleanly for your particular constraints:
m.addConstr(a.prod(x) >= 1)
Finally, I'll note that Gurobi 9.0 includes a Python matrix API. This matrix API can be used to add vectorized constraints like Ax <= b to your model, if you have (e.g.) a numpy array representing A and b. However, given how your constraints are structured, I don't think it would be too useful here.
I hope this helps. Thanks!
Eli
0 -
Thank you Eli, I will try that. I also have another question that I'm struggling with. I need to use argmax of a variable such as N[k,t] on each row, but since N is itself a variable, gurobi does not give a correct answer when I add np.argmax in the constraint and as far as I searched, there is not a build in function for argmax in gurobi.
I appreciate it if you could help me with this.
0 -
Hi Parisa,
You are correct, there is no built-in "argmax" function in Gurobi, nor does Gurobi accept arbitrary functions like np.argmax in its constraints or objective.
This should be possible to model using additional binary variables and constraints. Let's say we want to model \( w \in \arg\max_{i = 1, \ldots, n} x_i \). Let \( M \) be an upper bound on \( x_i \) for all \( i = 1, \ldots, n\), and let \( \ell_i \) be a lower bound for \( x_i \) for \( i = 1, \ldots, n \). We can model \( w \in \arg\max_{i = 1, \ldots, n} x_i \) with the following constraints:
$$\begin{alignat}{2}y &\geq x_i && i = 1, \ldots, n \\ y &\leq x_i + (M - \ell_i) (1 - z_i) \qquad && i = 1, \ldots, n \\ \sum_{i = 1}^n z_i &= 1 && \\ \sum_{i = 1}^n i z_i &= w&& \\ z &\in \{0, 1\}^n && \end{alignat}$$
The only way to satisfy the first three constraint sets is to set \( y = \max_{i = 1, \ldots, n} x_i \), \( z_k = 1 \) for \( k \in \arg\max_{i = 1, \ldots, n} x_i \), and \( z_i = 0 \) for all \( i \neq k \). Then, we have \( w = \sum_{i = 1}^n i z_i = k z_k = k \), as desired.
Note that this is a weak formulation due to the big-\(M\) constraints. Additionally, you cannot use the variable \( w \) as the index of another variable in your model formulation.
I hope this helps. Thanks!
Eli
0
Please sign in to leave a comment.
Comments
3 comments