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, an NLExpr will only be created for expressions that cannot be captured by a LinExpr or QuadExpr. Specifically, formulating an expression which is not a polynomial of degree at most 2 will result in an NLExpr.

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 can be used to formulate nonlinear constraints and nonlinear objectives.

Nonlinear Constraints

Nonlinear constraints can be added to the model using Model.addNLConstr. Both equality and inequality constraints are supported:

model.addNLConstr(nlfunc.sin(x) + y, GRB.LESS_EQUAL, 5.0)
model.addNLConstr(z - nlfunc.sqrt(x + y), GRB.EQUAL, 0.0)

Alternatively, you can use the (deprecated) Model.addGenConstrNL method to add a nonlinear equality constraint in the classical resultant variable form:

model.addGenConstrNL(z, x / y)

Nonlinear Objectives

A nonlinear expression can be added to the objective by passing an NLExpr to Model.setNLObj:

model.setNLObj(nlfunc.sin(x) + nlfunc.log(y))

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 of Var and MVar 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 an NLExpr object representing its object. Any arithmetic operations involving that object will also result in an NLExpr:

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