Java Interface

This chapter walks through a simple Java example to illustrate the use of the COPT Java interface. In short words, the example creates an environment, builds a model, add variables and constraints, optimizes it, and then outputs the optimal objective value.

The example solves the following linear problem:

(4)\[\begin{split}\text{Maximize: } & \\ & 1.2 x + 1.8 y + 2.1 z \\ \text{Subject to: } & \\ & 1.5 x + 1.2 y + 1.8 z \leq 2.6 \\ & 0.8 x + 0.6 y + 0.9 z \geq 1.2 \\ \text{Bounds: } & \\ & 0.1 \leq x \leq 0.6 \\ & 0.2 \leq y \leq 1.5 \\ & 0.3 \leq z \leq 2.8 \\\end{split}\]

Note that this is the same problem that was modelled and optimized in chapter of C Interface.

Example details

Below is the source code solving the above problem using COPT Java interface.

Listing 5 Lp_ex1.java
 1/*
 2 * This file is part of the Cardinal Optimizer, all rights reserved.
 3 */
 4import copt.*;
 5
 6/*
 7 * This Java example solves the following LP model:
 8 *
 9 * Maximize:
10 *  1.2 x + 1.8 y + 2.1 z
11 *
12 * Subject to:
13 *  1.5 x + 1.2 y + 1.8 z <= 2.6
14 *  0.8 x + 0.6 y + 0.9 z >= 1.2
15 *
16 * where:
17 *  0.1 <= x <= 0.6
18 *  0.2 <= y <= 1.5
19 *  0.3 <= z <= 2.8
20 */
21public class Lp_ex1 {
22  public static void main(final String argv[]) {
23    try {
24      Envr env = new Envr();
25      Model model = env.createModel("lp_ex1");
26
27      /* 
28       * Add variables x, y, z
29       *
30       * obj: 1.2 x + 1.8 y + 2.1 z
31       *
32       * var:
33       *  0.1 <= x <= 0.6
34       *  0.2 <= y <= 1.5
35       *  0.3 <= z <= 2.8
36       */
37      Var x = model.addVar(0.1, 0.6, 1.2, copt.Consts.CONTINUOUS, "x");
38      Var y = model.addVar(0.2, 1.5, 1.8, copt.Consts.CONTINUOUS, "y");
39      Var z = model.addVar(0.3, 2.8, 2.1, copt.Consts.CONTINUOUS, "z");
40
41      /*
42       * Add two constraints using linear expression
43       *
44       * r0: 1.5 x + 1.2 y + 1.8 z <= 2.6
45       * r1: 0.8 x + 0.6 y + 0.9 z >= 1.2
46       */
47      Expr e0 = new Expr(x, 1.5);
48      e0.addTerm(y, 1.2);
49      e0.addTerm(z, 1.8);
50      model.addConstr(e0, copt.Consts.LESS_EQUAL, 2.6, "r0");
51
52      Expr e1 = new Expr(x, 0.8);
53      e1.addTerm(y, 0.6);
54      e1.addTerm(z, 0.9);
55      model.addConstr(e1, copt.Consts.GREATER_EQUAL, 1.2, "r1");
56
57      // Set parameters and attributes
58      model.setDblParam(copt.DblParam.TimeLimit, 10);
59      model.setObjSense(copt.Consts.MAXIMIZE);
60
61      // Solve problem
62      model.solve();
63
64      // Output solution
65      if (model.getIntAttr(copt.IntAttr.HasLpSol) != 0) {
66        System.out.println("\nFound optimal solution:");
67        VarArray vars = model.getVars();
68        for (int i = 0; i < vars.size(); i++) {
69          Var x = vars.getVar(i);
70          System.out.println("  " + x.getName() + " = " + x.get(copt.DblInfo.Value));
71        }
72        System.out.println("Obj = " + model.getDblAttr(copt.DblAttr.LpObjVal));
73      }
74
75      System.out.println("\nDone");
76    } catch (CoptException e) {
77      System.out.println("Error Code = " + e.getCode());
78      System.out.println(e.getMessage());
79    }
80  }
81}

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

Import COPT class

To use the Java interface of COPT, users need to import the Java interface class of COPT first.

import copt.*;

Creating environment and model

Essentially, any Java application using Cardinal Optimizer should start with a COPT environment, where user could add one or more models. Note that each model encapsulates a problem and corresponding data.

Furthermore, to create multiple problems, one can load them one by one in the same model, besides the naive option of creating multiple models in the environment.

      Envr env = new Envr();
      Model model = env.createModel("lp_ex1");

The above call instantiates a COPT environment and a model with name “lp_ex1”.

Adding variables

The next step in our example is to add variables to the model. Variables are added through addVar() or addVars() method on the model object. A variable is always associated with a particular model.

      /* 
       * Add variables x, y, z
       *
       * obj: 1.2 x + 1.8 y + 2.1 z
       *
       * var:
       *  0.1 <= x <= 0.6
       *  0.2 <= y <= 1.5
       *  0.3 <= z <= 2.8
       */
      Var x = model.addVar(0.1, 0.6, 1.2, copt.Consts.CONTINUOUS, "x");
      Var y = model.addVar(0.2, 1.5, 1.8, copt.Consts.CONTINUOUS, "y");
      Var z = model.addVar(0.3, 2.8, 2.1, copt.Consts.CONTINUOUS, "z");

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. The fourth argument is the variable type. Our variables are all continuous 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 Java Modeling Classes of Java API reference for further details.

Adding constraints

The next step in the example is to add the linear constraints. As with variables, constraints are always associated with a specific model. They are created using addConstr() or addConstrs() methods on the model object.

      /*
       * Add two constraints using linear expression
       *
       * r0: 1.5 x + 1.2 y + 1.8 z <= 2.6
       * r1: 0.8 x + 0.6 y + 0.9 z >= 1.2
       */
      Expr e0 = new Expr(x, 1.5);
      e0.addTerm(y, 1.2);
      e0.addTerm(z, 1.8);
      model.addConstr(e0, copt.Consts.LESS_EQUAL, 2.6, "r0");

      Expr e1 = new Expr(x, 0.8);
      e1.addTerm(y, 0.6);
      e1.addTerm(z, 0.9);
      model.addConstr(e1, copt.Consts.GREATER_EQUAL, 1.2, "r1");

Two constraints here are created by building linear expressions incrementally. That is, an expression can be built by constructor of a variable and its coefficient, and then by addTerm() method.

Setting parameters and attributes

The next step in the example is to set parameters and attributes of the problem before optimization.

      // Set parameters and attributes
      model.setDblParam(copt.DblParam.TimeLimit, 10);
      model.setObjSense(copt.Consts.MAXIMIZE);

The setDblParam() call here with copt.DblParam.TimeLimit argument sets solver to optimize up to 10 seconds. The setObjSense() call with copt.Consts.MAXIMIZE argument sets objective sense as maximization.

Solving problem

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

      // Solve problem
      model.solve();

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

Outputting solution

After solving the problem, one can query the values of the attributes for various of purposes.

      // Output solution
      if (model.getIntAttr(copt.IntAttr.HasLpSol) != 0) {
        System.out.println("\nFound optimal solution:");
        VarArray vars = model.getVars();
        for (int i = 0; i < vars.size(); i++) {
          Var x = vars.getVar(i);
          System.out.println("  " + x.getName() + " = " + x.get(copt.DblInfo.Value));
        }
        System.out.println("Obj = " + model.getDblAttr(copt.DblAttr.LpObjVal));
      }

      System.out.println("\nDone");

Spcifically, one can query the copt.IntAttr.HasLpSol attribute on the model to know whether we have optimal LP solution; query the copt.DblInfo.Value attribute of a variable to obtain its solution value; query the copt.DblAttr.LpObjVal attribute on the model to obtain the objective value for the current solution.

The names and types of all model, variable, and constraint attributes can be found in Constants of Java API reference.

Error Handling

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

    } catch (CoptException e) {
      System.out.println("Error Code = " + e.getCode());
      System.out.println(e.getMessage());
    }

Build and Run

To build and run java example, users may refer to files under $COPT_HOME/examples/java. Specifically, We provide an example file in java and a script file to build. This single example runs on all platforms that support Java.

First of all, download and install Java 8 or above on your platform.

Java example detail

In the java example folder $COPT_HOME/examples/java, the easiest way to run the example is to enter the java example folder in console or terminal and then execute command 'sh run.sh'.

This java project has dependency on COPT java package copt_java.jar, which defines all java classes of COPT solver. In addition, copt_java.jar loads two shared libraries, that is, coptjniwrap.dll and copt_cpp.dll on Windows, libcoptjniwrap.so and libcopt_cpp.so on Linux, libcoptjniwrap.dylib and libcopt_cpp.dylib on Mac respectively. Note that coptjniwrap library is a JNI swig wrapper and acts as a bridge between COPT java package and native library copt_cpp, which declares and implements COPT constants, interfaces and methods. So users should make sure they are installed properly on runtime search paths.

In summary, to run java example, users should have COPT installed properly. Specifically, it requires two related COPT shared libaries existing on runtime search paths, and valid license files to run. Please refer to Install Guide for Cardinal Optimizer for further details.