# Python API Overview

##

Python API Overview

This section documents the Gurobi Python interface. It begins with an overview of the global functions, which can be called without referencing any Python objects. It then discusses the different types of objects that are available in the interface, and the most important methods on those objects. Finally, it gives a comprehensive presentation of all of the available classes and methods.

If you are new to the Gurobi Optimizer, we suggest that you start with the Quick Start Guide or the Example Tour. These documents provide concrete examples of how to use the classes and methods described here.

**Important note for AIX users:** due to limited Python support on
AIX, our AIX port does not include the Python interface.

Global Functions

The Gurobi shell contains a set of Global Functions that can be called without referring to any Gurobi objects. The most important of these functions is probably the read function, which allows you to read a model from a file. Other useful global functions are system, which allows you to issue shell commands from within the Gurobi shell, models, which gives you a list of the currently loaded models, and disposeDefaultEnv, which disposes of the default environment. Other global functions allow you to read, modify, or write Gurobi parameters (readParams, setParam, and writeParams).

Models

Most actions in the Gurobi Python interface are performed by calling methods on Gurobi objects. The most commonly used object is the Model. A model consists of a set of decision variables (objects of class Var or MVar), a linear or quadratic objective function on these variables (specified using Model.setObjective), and a set of constraints on these variables (objects of class Constr, MConstr, QConstr, SOS, or GenConstr). Each variable has an associated lower bound, upper bound, and type (continuous, binary, etc.). Each linear or quadratic constraint has an associated sense (less-than-or-equal, greater-than-or-equal, or equal), and right-hand side value. Refer to this section for more information on variables, constraints, and objectives.

An optimization model may be specified all at once, by loading the model from a file (using the previously mentioned read function), or it may be built incrementally, by first constructing an empty object of class Model and then subsequently calling Model.addVar, Model.addVars, or Model.addMVar to add additional variables, and Model.addConstr, Model.addConstrs, Model.addLConstr, Model.addQConstr, Model.addSOS, or any of the Model.addGenConstrXxx methods to add additional constraints.

Linear constraints are specified by building linear expressions (objects of class LinExpr or MLinExpr), and then specifying relationships between these expressions (for example, requiring that one expression be equal to another). Quadratic constraints are built in a similar fashion, but using quadratic expressions (objects of class QuadExpr or MQuadExpr) instead. General constraints are built using a set of dedicated methods, or a set of general constraint helper functions plus overloaded operators.

Models are dynamic entities; you can always add or remove variables or constraints.

We often refer to the *class* of an optimization model. A
model with a linear objective function, linear constraints, and
continuous variables is a *Linear Program (LP)*. If the
objective is quadratic, the model is a *Quadratic Program
(QP)*. If any of the constraints are quadratic, the model is a
*Quadratically-Constrained Program (QCP)*. We will
sometimes refer to a few special cases of QCP:
QCPs with convex constraints,
QCPs with non-convex constraints,
*bilinear programs*,
and *Second-Order Cone Programs (SOCP)*.
If the model contains any integer variables,
semi-continuous variables, semi-integer variables, Special Ordered Set
(SOS) constraints, or general constraints, the model is a
*Mixed Integer Program (MIP)*. We'll also sometimes discuss
special cases of MIP, including *Mixed Integer Linear Programs
(MILP)*, *Mixed Integer Quadratic Programs (MIQP)*,
*Mixed Integer Quadratically-Constrained Programs (MIQCP)*, and
*Mixed Integer Second-Order Cone Programs (MISOCP)*. The
Gurobi Optimizer handles all of these model classes.

Environments

Environments play a much smaller role in the Gurobi Python interface than they do in our other language APIs, mainly because the Python interface has a default environment. Unless you explicitly pass your own environment to routines that require an environment, the default environment will be used.

The main situation where you may want to create your own environment is when you want precise control over when the resources associated with an environment (specifically, a licensing token or a Compute Server) are released. If you use your own environment to create models (using read or the Model constructor), then the resources associated with the environment will be released as soon your program no longer references your environment or any models created with that environment.

Note that you can manually remove the reference to the default environment, thus making it available for garbage collection, by calling disposeDefaultEnv. After calling this, and after all models built within the default environment are garbage collected, the default environment will be garbage collected as well. A new default environment will be created automatically if you call a routine that needs one.

For more advanced use cases, you can use an empty environment to create an uninitialized environment and then, programmatically, set all required options for your specific requirements. For further details see the Environment section.

Solving a Model

Once you have built a model, you can call
Model.optimize to
compute a solution. By default,
optimize
will use the
concurrent optimizer
to solve LP models, the barrier algorithm to solve QP models
with convex objectives and
QCP models with convex constraints,
and the branch-and-cut algorithm otherwise.
The solution is stored in a set of *attributes* of the model, which
can be subsequently queried (we will return to this topic shortly).

The Gurobi algorithms keep careful track of the state of the model, so calls to Model.optimize will only perform further optimization if relevant data has changed since the model was last optimized. If you would like to discard previously computed solution information and restart the optimization from scratch without changing the model, you can call Model.reset.

After a MIP model has been solved, you can call
Model.fixed
to compute the associated *fixed* model. This model is
identical to the original, except that the integer variables are fixed
to their values in the MIP solution. If your model contains SOS
constraints, some continuous variables that appear in these
constraints may be fixed as well. In some applications, it can be
useful to compute information on this fixed model (e.g., dual
variables, sensitivity information, etc.), although you should be
careful in how you interpret this information.

Multiple Solutions, Objectives, and Scenarios

By default, the Gurobi Optimizer assumes that your goal is to find one proven optimal solution to a single model with a single objective function. Gurobi provides the following features that allow you to relax these assumptions:

- Solution Pool: Allows you to find more solutions.
- Multiple Scenarios: Allows you to find solutions to multiple, related models.
- Multiple Objectives: Allows you to specify multiple objective functions and control the trade-off between them.

Infeasible Models

You have a few options if a model is found to be infeasible. You can try to diagnose the cause of the infeasibility, attempt to repair the infeasibility, or both. To obtain information that can be useful for diagnosing the cause of an infeasibility, call Model.computeIIS to compute an Irreducible Inconsistent Subsystem (IIS). This method can be used for both continuous and MIP models, but you should be aware that the MIP version can be quite expensive. This method populates a set of IIS attributes.

To attempt to repair an infeasibility, call Model.feasRelaxS or Model.feasRelax to compute a feasibility relaxation for the model. This relaxation allows you to find a solution that minimizes the magnitude of the constraint violation.

Querying and Modifying Attributes

Most of the information associated with a Gurobi model is stored in a
set of attributes. Some attributes are associated with the variables
of the model, some with the constraints of the model, and some with
the model itself. To give a simple example, solving an optimization
model causes the `x`

variable attribute to be populated.
Attributes such as `x`

that are computed by the Gurobi optimizer
cannot be modified directly by the user, while others, such as the
variable lower bound (the `lb`

attribute) can.

Attributes can be accessed in two ways in the Python interface. The
first is to use the `getAttr()`

and `setAttr()`

methods,
which are available on variables
(Var.getAttr/
Var.setAttr),
matrix variables
(MVar.getAttr/
MVar.setAttr),
linear constraints
(Constr.getAttr/
Constr.setAttr),
matrix constraints
(MConstr.getAttr/
MConstr.setAttr),
quadratic constraints
(QConstr.getAttr/
QConstr.setAttr),
SOSs (SOS.getAttr),
general constraints
(GenConstr.getAttr/
GenConstr.setAttr), and
models (Model.getAttr/
Model.setAttr).
These are called with the attribute name as the first argument (e.g.,
`var.getAttr("x")`

or `constr.setAttr("rhs", 0.0)`

). The
full list of available attributes can be found in the
Attributes section of this manual.

Attributes can also be accessed more directly: you can follow an
object name by a period, followed by the name of an attribute of that
object. Note that upper/lower case is ignored when referring to
attributes. Thus, `b = constr.rhs`

is equivalent to
`b = constr.getAttr("rhs")`

, and `constr.rhs = 0.0`

is equivalent
to `constr.setAttr("rhs", 0.0)`

.

Additional Model Modification Information

Most modifications to an existing model are done through the attribute interface (e.g., changes to variable bounds, constraint right-hand sides, etc.). The main exceptions are modifications to the constraint matrix and to the objective function.

The constraint matrix can be modified in a few ways. The first is to call the Model.chgCoeff method. This method can be used to modify the value of an existing non-zero, to set an existing non-zero to zero, or to create a new non-zero. The constraint matrix is also modified when you remove a variable or constraint from the model (through the Model.remove method). The non-zero values associated with the deleted constraint or variable are removed along with the constraint or variable itself.

The model objective function can also be modified in a few ways. The
easiest is to build an expression that captures the objective function
(a LinExpr,
MLinExpr,
QuadExpr, or
MQuadExpr object),
and then pass that expression to method
Model.setObjective.
If you wish to modify the objective, you can simply call
`setObjective`

again with a new `LinExpr`

or
`QuadExpr`

object.

For linear objective functions, an alternative to `setObjective`

is to use the `Obj`

variable attribute to modify
individual linear objective coefficients.

If your variables have piecewise-linear objectives, you can specify
them using the Model.setPWLObj
method. Call this method once for each relevant variable. The Gurobi
simplex solver includes algorithmic support for convex
piecewise-linear objective functions, so for continuous models you
should see a substantial performance benefit from using this feature.
To clear a previously specified piecewise-linear objective function,
simply set the `Obj`

attribute on the corresponding variable to
0.

Lazy Updates

One important item to note about model modification in the Gurobi
optimizer is that it is performed in a *lazy* fashion, meaning
that modifications don't affect the model immediately. Rather, they
are queued and applied later. If your program simply creates a model
and solves it, you will probably never notice this behavior. However,
if you ask for information about the model before your modifications
have been applied, the details of the lazy update approach may be
relevant to you.

As we just noted, model modifications (bound changes, right-hand side changes, objective changes, etc.) are placed in a queue. These queued modifications can be applied to the model in three different ways. The first is by an explicit call to Model.update. The second is by a call to Model.optimize. The third is by a call to Model.write to write out the model. The first case gives you fine-grained control over when modifications are applied. The second and third make the assumption that you want all pending modifications to be applied before you optimize your model or write it to disk.

Why does the Gurobi interface behave in this manner? There are a few reasons. The first is that this approach makes it much easier to perform multiple modifications to a model, since the model remains unchanged between modifications. The second is that processing model modifications can be expensive, particularly in a Compute Server environment, where modifications require communication between machines. Thus, it is useful to have visibility into exactly when these modifications are applied. In general, if your program needs to make multiple modifications to the model, you should aim to make them in phases, where you make a set of modifications, then update, then make more modifications, then update again, etc. Updating after each individual modification can be extremely expensive.

If you forget to call update, your program won't crash. Your query will simply return the value of the requested data from the point of the last update. If the object you tried to query didn't exist then, you'll get a NOT_IN_MODEL exception instead.

The semantics of lazy updates have changed since earlier Gurobi versions. While the vast majority of programs are unaffected by this change, you can use the UpdateMode parameter to revert to the earlier behavior if you run into an issue.

Managing Parameters

The Gurobi optimizer provides a set of parameters that allow you to
control many of the details of the optimization process. Factors like
feasibility and optimality tolerances, choices of algorithms,
strategies for exploring the MIP search tree, etc., can be controlled
by modifying Gurobi parameters before beginning the optimization.
Parameters are set using method
Model.setParam.
Current values may also be retrieved with
Model.getParamInfo.
You can also access parameters more directly through the
`Model.Params`

class. To set the
MIPGap
parameter to 0.0 for
model `m`

, for example, you can do either
`m.setParam('MIPGap', 0)`

or
`m.Params.MIPGap = 0`

.

You can read a set of parameter settings from a file using Model.read, or write the set of changed parameters using Model.write.

We also include an automated parameter tuning tool that explores many different sets of parameter changes in order to find a set that improves performance. You can call Model.tune to invoke the tuning tool on a model. Refer to the parameter tuning tool section for more information.

One thing we should note is that changing a parameter for one model has no effect on the parameter value for other models. Use the global setParam method to set a parameter for all loaded models.

The full list of Gurobi parameters can be found in the Parameters section.

Monitoring Progress - Logging and Callbacks

Progress of the optimization can be monitored through Gurobi logging. By default, Gurobi will send output to the screen. A few simple controls are available for modifying the default logging behavior. You can set the LogFile parameter if you wish to also direct the Gurobi log to a file. The frequency of logging output can be controlled with the DisplayInterval parameter, and logging can be turned off entirely with the OutputFlag parameter.

Log output is also sent to a Python logger named `gurobipy`

, at
level `INFO`

. You can use the Python `logging`

module to
connect to this log.

More detailed progress monitoring can be done through a callback
function. If you pass a function taking two arguments, `model`

and `where`

, to
Model.optimize, your function
will be called periodically from within the optimization. Your
callback can then
call Model.cbGet to
retrieve additional information on the state of the optimization. You
can refer to the Callback class
for additional information.

Modifying Solver Behavior - Callbacks

Callbacks can also be used to modify the behavior of the Gurobi
optimizer. The simplest control callback is
Model.terminate,
which asks the optimizer to terminate at the earliest convenient
point. Method
Model.cbSetSolution
allows you to inject a feasible solution (or partial solution) during
the solution of a MIP model. Methods
Model.cbCut
and
Model.cbLazy
allow you to add *cutting planes* and *lazy constraints*
during a MIP optimization, respectively.
Method Model.cbStopOneMultiObj allows you to interrupt the optimization process of one of the optimization steps in
a multi-objective MIP problem without stopping the hierarchical
optimization process.

Batch Optimization

Gurobi Compute Server enables programs to offload optimization computations onto dedicated servers. The Gurobi Cluster Manager adds a number of additional capabilities on top of this. One important one, batch optimization, allows you to build an optimization model with your client program, submit it to a Compute Server cluster (through the Cluster Manager), and later check on the status of the model and retrieve its solution. You can use a Batch object to make it easier to work with batches. For details on batches, please refer to the Batch Optimization section.

Error Handling

All of the methods in the Gurobi Python library can throw an exception
of type GurobiError. When an
exception occurs, additional information on the error can be obtained
by retrieving the `errno`

or `message`

members of the
`GurobiError`

object. A list of possible values for the
`errno`

field can be found in the Error
Code section.