8
$\begingroup$

I'm new to Gurobi in Python and I was wondering if someone knows how to code some common structures of linear constraints. I'm trying to understand how you'll code something like the following constraints: \begin{alignat}2\sum_{i\in A\mid i\ne j}\sum_{j\in A\mid i\ne j}x_{ij}&\le10\tag1\\\sum_{i\in A\mid i\ne j}x_{ij}&\le10\quad\forall j\in B\tag2\\x_{ij}&\le10\quad\forall i\in A,j\in B\mid i\ne j\tag3.\end{alignat}

In FICO Xpress, the first constraint would be coded like:

sum(i in A, j in A | i<>j)x(i,j)<=10

But I don't know how to code such structures in Gurobi Python.

Thanks for your help!

If you can provide a code example, that would be great.

$\endgroup$
4
$\begingroup$

Let's define the model as m:

m = Model('AnyName')

Now the constraint can be added to the model:

m.addConstrs((xVar.sum('*',i) <= 10 for i in A, j in B, i<>j), "constraintName")

Source: https://www.gurobi.com/documentation/8.1/quickstart_mac/py_netflow_py_example.html

$\endgroup$
  • $\begingroup$ Thanks, for your answer! I'll assume that the sum("",i,j) part is the translation of Xpress' sum(i in A, j in A | i<>j), making that i<>j is the same as ("",i,j). Am I right? $\endgroup$ – SantiagoAm16 Sep 10 '19 at 21:10
  • $\begingroup$ @SantiagoAm16 I edited the code, hopefully it covers all the details now. $\endgroup$ – Oguz Toragay Sep 10 '19 at 22:37
  • 1
    $\begingroup$ I don't think i<>j is valid Python syntax and could not find that part in the provided source. Should it be i != j instead? $\endgroup$ – Robert Schwarz Sep 11 '19 at 7:02
  • $\begingroup$ @RobertSchwarz i was thinking the exact same, however, I think another form to write it would be with an if statement after the for statement in the sum. I’ll try both forms today and let you know. $\endgroup$ – SantiagoAm16 Sep 11 '19 at 11:53
  • $\begingroup$ Just tried to model one constraint in the above format, but apparently it doesn't work. I did it in this format: for i in range(NumOfJobs): m.addConstr(quicksum(z[j,i] for j in range(NumOfJobs)) == 1) And it works, but if I write: for i in range(NumOfJobs): m.addConstr(z.sum(j,'*') == 1 for j in range(NumOfJobs)) it doesn't works. I think both should equal the same. $\endgroup$ – SantiagoAm16 Sep 11 '19 at 21:20
2
$\begingroup$

The Python syntax could be like this:

  1. model.addConstr(sum(x[i,j] for i in A for j in A if i != j) <= 10, "firstConstraint")

  2. model.addConstrs(sum(x[i,j] for i in A if i != j) <= 10 for j in B, "secondConstraintClass")

  3. model.addConstr(x[i,j] <= 10 for i in A for j in B if i != j, "thirdConstraintClass")

where model is the gurobi API object in your code.

Note that addConstrs is for the case when you add many similar constraints indexed by a set, while addConstr is for when you add only one constraint at the time (note the for j in B after the inequality and before the comma in the second constraint where addConstrs is used).

You can check more about the addConstrs method in its documentation, including some examples and use cases.

For sums over large arrays or linear products, or when adding a linear product where the coefficients could be sparse, I'd recommend reading about the quicksum and LinExpr methods which can yield further efficiency.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.