Java Interface

This section will work through a simple Java example in order to illustrate the use of the Gurobi Java interface. The example builds a model, optimizes it, and outputs the optimal objective value. This section assumes that you are already familiar with the Java programming language. If not, a variety of books and web sites are available for learning the language (for example, the online Java tutorials).

Our example optimizes the following model:

maximize x + y + 2 z    
subject to x + 2 y + 3 z $\leq$ 4
  x + y     $\geq$ 1
  x, y, z binary  
Note that this is the same model that was modeled and optimized in the C Interface section.

Example Mip1.java

This is the complete source code for our example (also available in <installdir>/examples/java/Mip1.java)...

import gurobi.*;

public class Mip1 {
  public static void main(String[] args) {
    try {
      GRBEnv    env   = new GRBEnv("mip1.log");
      GRBModel  model = new GRBModel(env);

      // Create variables

      GRBVar x = model.addVar(0.0, 1.0, 0.0, GRB.BINARY, "x");
      GRBVar y = model.addVar(0.0, 1.0, 0.0, GRB.BINARY, "y");
      GRBVar z = model.addVar(0.0, 1.0, 0.0, GRB.BINARY, "z");

      // Integrate new variables

      model.update();

      // Set objective: maximize x + y + 2 z

      GRBLinExpr expr = new GRBLinExpr();
      expr.addTerm(1.0, x); expr.addTerm(1.0, y); expr.addTerm(2.0, z);
      model.setObjective(expr, GRB.MAXIMIZE);

      // Add constraint: x + 2 y + 3 z <= 4

      expr = new GRBLinExpr();
      expr.addTerm(1.0, x); expr.addTerm(2.0, y); expr.addTerm(3.0, z);
      model.addConstr(expr, GRB.LESS_EQUAL, 4.0, "c0");

      // Add constraint: x + y >= 1

      expr = new GRBLinExpr();
      expr.addTerm(1.0, x); expr.addTerm(1.0, y);
      model.addConstr(expr, GRB.GREATER_EQUAL, 1.0, "c1");

      // Optimize model

      model.optimize();

      System.out.println(x.get(GRB.StringAttr.VarName)
                         + " " +x.get(GRB.DoubleAttr.X));
      System.out.println(y.get(GRB.StringAttr.VarName)
                         + " " +y.get(GRB.DoubleAttr.X));
      System.out.println(z.get(GRB.StringAttr.VarName)
                         + " " +z.get(GRB.DoubleAttr.X));

      System.out.println("Obj: " + model.get(GRB.DoubleAttr.ObjVal));

      // Dispose of model and environment

      model.dispose();
      env.dispose();

    } catch (GRBException e) {
      System.out.println("Error code: " + e.getErrorCode() + ". " +
                         e.getMessage());
    }
  }
}

Example details

Let us now walk through the example, line by line, to understand how it achieves the desired result of optimizing the indicated model.

The example begins by importing the Gurobi classes (import gurobi.*). Gurobi Java applications should always start with this line.

Creating the environment

The first executable statement in our example obtains a Gurobi environment (using the GRBEnv() constructor):

   GRBEnv env = new GRBEnv("mip1.log");
Later calls to create an optimization model will always require an environment, so environment creation is typically the first step in a Gurobi application. The constructor argument specifies the name of the log file.

Creating the model

Once an environment has been created, the next step is to create a model. A Gurobi model holds a single optimization problem. It consists of a set of variables, a set of constraints, and the associated attributes (variable bounds, objective coefficients, variable integrality types, constraint senses, constraint right-hand side values, etc.). The first step towards building a model that contains all of this information is to create an empty model object:

  GRBModel model = new GRBModel(env);
The constructor takes the previously created environment as its argument.

Adding variables to the model

The next step in our example is to add variables to the model.

  // Create variables
  GRBVar x = model.addVar(0.0, 1.0, 0.0, GRB.BINARY, "x");
  GRBVar y = model.addVar(0.0, 1.0, 0.0, GRB.BINARY, "y");
  GRBVar z = model.addVar(0.0, 1.0, 0.0, GRB.BINARY, "z");
Variables are added through the addVar() method on a model object. A variable is always associated with a particular model.

The first and second arguments to the addVar() call are the variable lower and upper bounds, respectively. The third argument is the linear objective coefficient (zero here - we'll set the objective later). The fourth argument is the variable type. Our variables are all binary in this example. The final argument is the name of the variable.

The addVar() method has been overloaded to accept several different argument lists. Please refer to the Gurobi Reference Manual for further details.

Updating the model - lazy modification

Model modifications in the Gurobi optimizer are done in a lazy fashion, meaning that the effects of the modifications are not seen immediately. This approach makes it easier to perform a sequence of model modifications, since the model doesn't change while it is being modified. However, lazy modifications do require you to manually integrate model changes when needed. This is done with the update method:

  // Integrate new variables
  model.update();

Setting the objective

The next step in the example is to set the optimization objective:

  // Set objective: maximize x + y + 2 z

  GRBLinExpr expr = new GRBLinExpr();
  expr.addTerm(1.0, x); expr.addTerm(1.0, y); expr.addTerm(2.0, z);
  model.setObjective(expr, GRB.MAXIMIZE);
The objective must be a linear or quadratic function of the variables in the model. In our example, we build our objective by first constructing an empty linear expression and adding three terms to it.

The second argument to setObjective indicates that the optimization sense is maximization.

Adding constraints to the model

The next step in the example is to add the constraints. The first constraint is added here:

  // Add constraint: x + 2 y + 3 z <= 4
  GRBLinExpr expr;

  expr = new GRBLinExpr();
  expr.addTerm(1.0, x); expr.addTerm(2.0, y); expr.addTerm(3.0, z);
  model.addConstr(expr, GRB.LESS_EQUAL, 4.0, "c0");
As with variables, constraints are always associated with a specific model. They are created using the addConstr() or addConstrs() methods on the model object.

The first argument to addConstr() is the left-hand side of the constraint. We built the left-hand side by first creating an empty linear expression object, and then adding three terms to it. The second argument is the constraint sense (GRB_LESS_EQUAL, GRB_GREATER_EQUAL, or GRB_EQUAL). The third argument is the right-hand side (a constant in our example). The final argument is the constraint name. Several signatures are available for addConstr(). Please consult the Gurobi Reference Manual for details.

The second constraint is created in a similar manner:

  // Add constraint: x + y >= 1

  expr = new GRBLinExpr();
  expr.addTerm(1.0, x); expr.addTerm(1.0, y);
  model.addConstr(expr, GRB.GREATER_EQUAL, 1.0, "c1");

Optimizing the model

Now that the model has been built, the next step is to optimize it:

  // Optimize model
  model.optimize();
This routine performs the optimization and populates several internal model attributes (including the status of the optimization, the solution, etc.).

Reporting results - attributes

Once the optimization is complete, we can query the values of the attributes. In particular, we can query the VarName and X attributes to obtain the name and solution value for each variable:

  System.out.println(x.get(GRB.StringAttr.VarName)
                     + " " +x.get(GRB.DoubleAttr.X));
  System.out.println(y.get(GRB.StringAttr.VarName)
                     + " " +y.get(GRB.DoubleAttr.X));
  System.out.println(z.get(GRB.StringAttr.VarName)
                     + " " +z.get(GRB.DoubleAttr.X));

We can also query the ObjVal attribute on the model to obtain the objective value for the current solution:

  System.out.println("Obj: " + model.get(GRB.DoubleAttr.ObjVal));

The names and types of all model, variable, and constraint attributes can be found in the Attributes section of the Gurobi Reference Manual.

Cleaning up

The example concludes with dispose calls:

  model.dispose();
  env.dispose();
These reclaim the resources associated with the model and environment. Garbage collection would reclaim these eventually, but if your program doesn't exit immediately after performing the optimization, it is best to reclaim them explicitly.

Note that all models associated with an environment must be disposed before the environment itself is disposed.

Error handling

Errors in the Gurobi Java interface are handled through the Java exception mechanism. In the example, all Gurobi statements are enclosed inside a try block, and any associated errors would be caught by the catch block.

Building and running the example

To build and run the example, please refer to the files in <installdir>/examples/build. For Windows platforms, this directory contains runjava.bat, a simple script to compile and run a java example. Say runjava Mip1 to run this example. For Linux or Mac OS platforms, the <installdir>/examples/build directory contains an example Makefile. Typing make Mip1 will build and run this example.

The Java example directory <installdir>/examples/java contains a number of examples. We encourage you to browse and modify them in order to become more familiar with the Gurobi Java interface. We also encourage you to read the Gurobi Example Tour for more information.