Skip to main content

MIO in Python, Multiplying decision variables and arrays




  • Eli Towle
    Gurobi Staff Gurobi Staff

    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 method, though this may not work so cleanly for your particular constraints:

    m.addConstr( >= 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!


  • Parisa Keshavarz
    First Comment
    First Question

    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.


  • Eli Towle
    Gurobi Staff Gurobi Staff

    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!



Please sign in to leave a comment.