pythonpython-3.xlinear-programminggurobiquadratic-programming

Gurobi implementing a constraint with the sum of the multiplication of sums with python


I am using gurobi with gurobipy to implement a linear programm.

While implementing the following constraint, I get a failur.

\forall i \in I: \forall j \in J: y_\text{i,j} \left [ \sum\limits_{a \in A} \left ( \sum\limits_{b \in B} x_\text{i,a,b} * \sum\limits_{b \in B} x_\text{j,a,b}   \right ) +1  \right ] = c_\text{i,j}

With and a and b as indices sets.

My minimal example looks like

import gurobipy as grb

m = grb.Model()

set_I = range(2)
set_J = range(2)
set_A = range(2)
set_B = range(2)

x_vars = {(i,a,b):m.addVar(vtype=grb.GRB.BINARY, name="x_{}_{}_{}".format(i,a,b)) for i in set_I for a in set_A for b in set_B}
y_vars = {(i,j): m.addVar(vtype=grb.GRB.BINARY, name="y_{}_{}".format(i,j)) for i in set_I for j in set_J}
c_vars = {(i,j): m.addVar(vtype=grb.GRB.CONTINUOUS, name="c_{}_{}".format(i,j)) for i in set_I for j in set_J}

for i in set_I:
    for j in set_J:
        m.addConstr(
            lhs=y_vars[i,j] * (grb.quicksum(grb.quicksum(x_vars[i,a,b] for a in set_A for b in set_B) * grb.quicksum(x_vars[j,a,b] for a in set_A for b in set_B))+1),
            sense=grb.GRB.GREATER_EQUAL,
            rhs=c_vars[i,j]
        )

and creates

Traceback (most recent call last):
  File ".\stackoverflow.py", line 17, in <module>
    lhs=y_vars[i,j] * (grb.quicksum(grb.quicksum(x_vars[i,a,b] for a in set_A for b in set_B) * grb.quicksum(x_vars[j,a,b] for a in set_A for b in set_B))+1),
  File "src\gurobipy\gurobi.pxi", line 3627, in gurobipy.quicksum
TypeError: 'gurobipy.QuadExpr' object is not iterable

Does anyone can help me to fix this problem and implement this constraint correctly?


Solution

  • You'll have to rework this. You can't do y*x*x as that is no longer quadratic. You can reformulate using extra variables and equations:

    z = x*x
    y*z 
    

    I suspect you also have to rewrite the quicksum(quicksum*quicksum) using loops.

    I agree that the error message is not very informative.