Try our new documentation site (beta).
Java API Overview
This section documents the Gurobi Java interface. This manual begins with a quick overview of the classes exposed in the interface and the most important methods on those classes. It then continues with 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.
Environments
The first step in using the Gurobi Java interface is to create an environment object. Environments are represented using the GRBEnv class. An environment acts as the container for all data associated with a set of optimization runs. You will generally only need one environment object in your program.
Models
You can create one or more optimization models within an environment. Each model is represented as an object of class GRBModel. A model consists of a set of decision variables (objects of class GRBVar), a linear or quadratic objective function on these variables (specified using GRBModel.setObjective), and a set of constraints on these variables (objects of class GRBConstr, GRBQConstr, or GRBSOS). 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.
Linear constraints are specified by building linear expressions (objects of class GRBLinExpr), 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 GRBQuadExpr) instead.
An optimization model may be specified all at once, by loading the model from a file (using the appropriate GRBModel constructor), or built incrementally, by first constructing an empty object of class GRBModel and then subsequently calling GRBModel.addVar or GRBModel.addVars to add additional variables, and GRBModel.addConstr or GRBModel.addQConstr to add additional constraints. 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'll sometimes also discuss a special case of QCP, the Second-Order Cone Program (SOCP). If the model contains any integer variables, semi-continuous variables, semi-integer variables, or Special Ordered Set (SOS) 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.
Solving a Model
Once you have built a model, you can call GRBModel.optimize to compute a solution. By default, optimize will use the concurrent optimizer to solve LP models, the barrier algorithm to solve QP and QCP models, and the branch-and-cut algorithm to solve mixed integer models. The solution is stored in a set of attributes of the model. These attributes can be queried using a set of attribute query methods on the GRBModel, GRBVar, GRBConstr, and GRBQConstr classes.
The Gurobi algorithms keep careful track of the state of the model, so calls to GRBModel.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 GRBModel.reset.
After a MIP model has been solved, you can call GRBModel.fixedModel to compute the associated fixed model. This model is identical to the input model, except that all integer variables are fixed to their values in the MIP solution. In some applications, it is useful to compute information on this continuous version of the MIP model (e.g., dual variables, sensitivity information, etc.).
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 GRBModel.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 GRBModel.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 are queried using
GRBVar.get,
GRBConstr.get,
GRBQConstr.get, or
GRBModel.get,
and modified using
GRBVar.set,
GRBConstr.set,
GRBQConstr.set, or
GRBModel.set.
Attributes are grouped into a set of enums by type
(GRB.CharAttr,
GRB.DoubleAttr,
GRB.IntAttr,
GRB.StringAttr).
The get()
and set()
methods are overloaded, so the
type of the attribute determines the type of the returned value.
Thus, constr.get(GRB_DoubleAttr_RHS)
returns a double,
while constr.get(GRB_CharAttr_Sense)
returns a char.
If you wish to retrieve attribute values for a set of variables or constraints, it is usually more efficient to use the array methods on the associated GRBModel object. Method GRBModel.get includes signatures that allow you to query or modify attribute values for one-, two-, and three-dimensional arrays of variables or constraints.
The full list of attributes can be found in the Attributes section.
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 chgCoeff method on a GRBModel object to change individual matrix coefficients. 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 GRBModel.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 GRBLinExpr or
GRBQuadExpr object),
and then pass that expression to method
GRBModel.setObjective.
If you wish to modify the objective, you can simply call
setObjective
again with a new GRBLinExpr
or
GRBQuadExpr
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 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 very important item to note about attribute and model modifications in the Gurobi optimizer is that they are performed in a lazy fashion, meaning that they don't actually affect the model until the next call to optimize or update on that model object. This approach provides the advantage that the model remains unchanged while you are in the process of making multiple modifications. The downside, of course, is that you have to remember to call update in order to see the effect of your changes.
If you forget to call update, your program won't crash. The most common symptom of a missing update is a NOT_IN_MODEL exception, which indicates that the object you are trying to reference isn't in the model yet.
If you find the need to call update inconvenient, you can adjust the behavior of lazy updates with the UpdateMode parameter. By setting this parameter to 1, you can use newly added variables and constraints immediately for building or modifying the model. This setting does have a few downsides, though. It causes Gurobi to use a small amount of additional internal storage, and it introduces a small performance overhead. In addition, this setting may cause Gurobi to make less aggressive use of warm-start information when you modify a model and resolve it using simplex.
Managing Parameters
The Gurobi optimizer provides a set of parameters to 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 GRBEnv.set. Current values may also be retrieved with GRBEnv.get. Parameters can be of type int, double, or String. You can also read a set of parameter settings from a file using GRBEnv.readParams, or write the set of changed parameters using GRBEnv.writeParams.
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 GRBModel.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 each model gets its own copy of the environment when it is created. Parameter changes to the original environment therefore have no effect on existing models. Use GRBModel.getEnv to retrieve the environment associated with a particular model if you want to change a parameter for that model.
The full list of Gurobi parameters can be found in the Parameters section.
Memory Management
Users typically do not need to concern themselves with memory management in Java, since it is handled automatically by the garbage collector. The Gurobi Java interface utilizes the same garbage collection mechanism as other Java programs, but there are a few specifics of our memory management that users should be aware of.
In general, Gurobi objects live in the same Java heap as other Java
objects. When they are no longer referenced, they become candidates
for garbage collection, and are returned to the pool of free space at
the next invocation of the garbage collector. Two important exceptions
are the
GRBEnv and
GRBModel objects.
A GRBModel
object has a small amount of memory associated with
it in the Java heap, but the majority of the space associated with a
model lives in the heap of the Gurobi native code library (the Gurobi
DLL in Windows, or the Gurobi shared library in Linux or Mac). The
Java heap manager is unaware of the memory associated with the model
in the native code library, so it does not consider this memory usage
when deciding whether to invoke the garbage collector. When the
garbage collector eventually collects the Java GRBModel
object, the memory associated with the model in the Gurobi native
code library will be freed, but this collection may come later than
you might want. Similar considerations apply to the GRBEnv
object.
If you are writing a Java program that makes use of multiple Gurobi
models or environments, we recommend that you call
GRBModel.dispose
when you are done using the associated GRBModel
object,
and
GRBEnv.dispose
when you are done using the associated
GRBEnv
object and after you have called
GRBModel.dispose on
all of the models created using that GRBEnv
object.
Native Code
As noted earlier, the Gurobi Java interface is a thin layer that sits
on top of our native code library (the Gurobi DLL on Windows, and the
Gurobi shared library on Linux or Mac). Thus, an application that
uses the Gurobi Java library will load the Gurobi native code library
at runtime. In order for this happen, you need to make sure that two
things are true. First, you need to make sure that the native code
library is available in the search path of the target machine (PATH
on Windows, LD_LIBRARY_PATH
on Linux,
or DYLD_LIBRARY_PATH
on Mac). These
paths are set up as part of the installation of the Gurobi Optimizer,
but may not be configured appropriately on a machine where the full
Gurobi Optimizer has not been installed. Second, you need to be sure
that the Java JVM and the Gurobi native library use the same object
format. In particular, you need to use the 32-bit Gurobi native
library with a 32-bit Java JVM, and similarly the 64-bit Gurobi native
library with a 64-bit Java JVM.
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. If you would like to direct output to a file as well as to the screen, specify the log file name in the GRBEnv constructor. You can modify the LogFile parameter if you wish to redirect the log to a different file after creating the environment object. The frequency of logging output can be controlled with the DisplayInterval parameter, and logging can be turned off entirely with the OutputFlag parameter. A detailed description of the Gurobi log file can be found in the Logging section.
More detailed progress monitoring can be done through the
GRBCallback class.
The
GRBModel.setCallback method
allows you to receive a periodic callback from the Gurobi optimizer.
You do this by sub-classing
the GRBCallback abstract class,
and writing your own Callback()
method on this class. You can
call
GRBCallback.getDoubleInfo,
GRBCallback.getIntInfo,
GRBCallback.getStringInfo,
or
GRBCallback.getSolution
from within the callback to obtain additional information about the
state of the optimization.
Modifying Solver Behavior - Callbacks
Callbacks can also be used to modify the behavior of the Gurobi optimizer. The simplest control callback is GRBCallback.abort, which asks the optimizer to terminate at the earliest convenient point. Method GRBCallback.setSolution allows you to inject a feasible solution (or partial solution) during the solution of a MIP model. Methods GRBCallback.addCut and GRBCallback.addLazy allow you to add cutting planes and lazy constraints during a MIP optimization, respectively.
Error Handling
All of the methods in the Gurobi Java library can throw an exception
of type GRBException. When an
exception occurs, additional information on the error can be obtained
by retrieving the error code (using method
GRBException.getErrorCode),
or by retrieving the exception message (using method
GRBException.getMessage
from the parent class). The list of
possible error return codes can be found in the Error
Codes section.