9
$\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.

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

$\endgroup$
2

2 Answers 2

4
$\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$
5
$\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$
5
  • $\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$ Sep 10, 2019 at 21:10
  • $\begingroup$ @SantiagoAm16 I edited the code, hopefully it covers all the details now. $\endgroup$ Sep 10, 2019 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$ Sep 11, 2019 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$ Sep 11, 2019 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$ Sep 11, 2019 at 21:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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