gurobipy.NLExpr#
- class NLExpr#
Gurobi nonlinear expression object. An
NLExpr
stores an expression tree, and makes it possible to formulate nonlinear programming (NLP) and mixed integer nonlinear programming (MINLP) models in Python using symbolic math.You will generally build nonlinear expressions by starting from
Var
objects and applying Python operators, nonlinear functions, or a combination of both. In general, anNLExpr
will only be created for expressions that cannot be captured by aLinExpr
orQuadExpr
. Specifically, formulating an expression which is not a polynomial of degree at most 2 will result in anNLExpr
.The following example lists the object types of various expressions constructed from
Var
objects:from gurobipy import nlfunc ... x = model.addVar(name="x") # Var y = model.addVar(name="y") # Var z = model.addVar(name="z") # Var expr1 = 2.0 * x # LinExpr expr2 = 2.0 * x * y # QuadExpr expr3 = 2.0 * x * y * z # NLExpr expr4 = x / y # NLExpr expr5 = nlfunc.sin(x) # NLExpr
Nonlinear expressions are used to build nonlinear general constraints. They are typically temporary objects which are passed immediately to either
Model.addConstr
orModel.addGenConstrNL
to add a constraint to the model. Such constraints are always equality constraints with a resultant variable on the left side of the expression. In Python code these constraints can be added using either method:model.addConstr(z == nlfunc.sqrt(x + y)) model.addGenConstrNL(z, x / y)
Nonlinear Inequality Constraints
It is not possible to use
<=
or>=
operators to specify nonlinear inequality constraints usingNLExpr
objects. However, you can formulate an equivalent constraint by creating a bounded resultant variable. For example, the following code constrains that \(log(x) \le 1\):x = model.addVar() res = model.addVar(lb=-GRB.INFINITY, ub=1.0) model.addGenConstrNL(res, nlfunc.log(x))
More control over expression creation
If you want more control over the expression trees generated, you can ‘opt-in’ to the nonlinear world using the
.nl
property ofVar
andMVar
objects. This is considered advanced usage. In the vast majority of cases, you do not need to consider how a nonlinear expression is represented internally.The
.nl
property returns anNLExpr
object representing its object. Any arithmetic operations involving that object will also result in anNLExpr
:x = model.addVar() # Var expr1 = x + 1.0 # LinExpr expr2 = x.nl # NLExpr expr3 = x.nl + 1.0 # NLExpr
The implications are subtle, but can have an impact on how a constraint is handled by the solver. For example, the following two constraints represent the same expression \((x + y)^2\) but have a different internal representation in the solver:
c1 = model.addGenConstrNL(z, (x - y) ** 2) c2 = model.addGenConstrNL(z, (x.nl - y.nl) ** 2)
Specifically, the first case captures a quadratic expression in expanded form \(x^2 - 2xy + y^2\). The second case captures a nonlinear expression with \(x - y\) as a node in the expression tree which is explicitly squared.
Domain restrictions of operators
Some subtleties arise from certain arithmetic operators not being applicable to the whole domain that an operand may have (e.g., division by zero). Refer to the additional information for the divide operator and the power operator for all the details.
- copy()#
Returns a copy of this nonlinear expression
- Returns:
A new
NLExpr
object