Parametrizing sense of constraints when using MVar and MLinExpr
AnsweredConsider the following code (Gurobi 9.0.2, Python 3.7, Windows 10):
import gurobipy as gbp
import numpy as np
m = gbp.Model()
x = m.addMVar(3)
m.update()
a = np.array([1,2,3])
m.addConstr(a @ x, gbp.GRB.LESS_EQUAL, 0)
Output:
GurobiError: Invalid argument to Model.addConstr
Version that works:
m.addConstr(a @ x <= 0)
Question 1
When working with matrix variables and expressions, how to create constraints with the sense given as Python variable? In other words, given variable _sense equal to "<" or ">", how to create a constraint where _sense determines its sense?
Question 2
How to find explicit information about Gurobi API for Python? In this particular example, I was debugging my code for more than half an hour (and spent quite some time searching for docs) before accidentally coming across the correct variant. Nowhere in the description of addConstr() it is written that it does not accept lhs produced using MVar. Nowhere in the description of addMVar() it is written that using MVar makes an expression invalid as the lhs of constraints. This essential information can neither be found in related, more "technical" pages, e.g. MLinExpr().
With gurobipy, it is often the case where most essential information is hidden somewhere among technicalities, dissolved in examples, or explicitly formulated only in forum replies. Do I search in wrong places? Is there another source of structured and searchable documentation? Should I study source code? Is gurobipy a community version of some commercially supported API? I constantly have an impression that I miss something important about Gurobi and Python in the global sense.
-
Official comment
This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?. -
Hi Dmitry,
For your first question, you can use Model.addMConstrs() to do this. In this case, \( \texttt{A} \) should be a 2D ndarray and the RHS a 1D ndarray:
import gurobipy as gp
import numpy as np
m = gp.Model()
x = m.addMVar(3)
A = np.array([[1, 2, 3]])
b = np.zeros(1)
m.addMConstrs(A, x, gp.GRB.LESS_EQUAL, b)For your second question, this is a bit subtle. Many of the Gurobi Python classes have analogous classes specific to the matrix API. For example, the matrix API uses MVar instead of Var, MLinExpr instead of LinExpr, and MQuadExpr instead of QuadExpr. These are separate classes. The documentation for Model.addConstr() states that the \( \texttt{lhs} \) keyword argument should be a Var, LinExpr, or QuadExpr object, not MVar, MLinExpr, or MQuadExpr:
>>> type(A @ x)
<class 'gurobipy.MLinExpr'>You can alternatively pass a TempConstr object to the Model.addConstr() method. These can be created from any of the above classes. For example:
>>> type(A @ x <= b)
<class 'gurobipy.TempConstr'>The same version of gurobipy is available to all Gurobi users. Specifically what part of the Gurobi Python API were you looking to learn more about? You can find many code examples here that show off specific features. For a more "structured" documentation, you could always use the full reference manual, located in your Gurobi installation directory as \( \texttt{refman.pdf} \). This is a PDF version of the website documentation.
For learning about the matrix API, the documentation for MVar, MLinExpr, MQuadExpr are good places to start, though it sounds like you've read all of these. The matrix API is new with the release of Gurobi 9.0.0 in late 2019. It's under active development, and we're happy to hear any of your feedback about how it could be easier to use.
Thanks,
Eli
1
Post is closed for comments.
Comments
2 comments