You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 10 Next »

The root page 15DOTs60ia13:Tutorial could not be found in space 15.S60 SSIM: Software Tools for Operations Research.

The Java Interface to CPLEX

The use of CPLEX in Java is based around the class IloCplex (documented here). The basic idea is that you create an IloCplex object for your optimization problem, then add variables, the objective, and constraints using methods in the class IloCplex. The IloCplex object can produce IloNumVar objects and their subclass IloIntVar objects, when are then used as arguments to further methods from IloCplex to make the objective and constraints. The IloCplex interface is somewhat confusing. It is very large, has lots of redundant methods, and lots of methods that appear to be the same but produce very different results. We now summarize the methods of IloCplex which will be of use to us:

Name

Return Type

Arguments

Description

boolVar

IloIntVar

 

Creates and returns a new Boolean variable (domain 0,1).

boolVarArray

IloIntVar[]

int n

Creates and returns an array of n new Boolean variables (domain 0,1)

linearIntExpr

IloLinearIntExpr

 

Creates and returns an integer linear expression initialized as 0 (zero).

addGe

IloRange

IloNumExpr e, double v

Creates and returns a range representing the constraint \( e \geq v \)

addEq

IloRange

IloNumExpr e, double v

Creates and returns a range representing the constraint \( e = v \)

addMinimize

IloObjective

IloNumExpr e

Creates and returns an objective to minimize the expression and adds it to the invoking model.

Warning

For an IloCplex cplex, an IloNumExpr e and a double v, calling cplex.addGe(e,v) and cplex.addGe(v,e) are both allowed but do not produce the same result! The first gives the constraint \( e \geq v \) while the second gives the constraint \( v \geq e \) .

Warning

For an IloCplex cplex, an IloNumExpr e and a double v, calling cplex.ge(e,v) and cplex.addGe(e,v) are both allowed but do not produce the same result! While both return an object for the constraint \( e \geq v \) , only the latter adds the constraint to the model! We will actually have use cplex.ge(e,v) later when we add constraints through callbacks instead of adding them directly to the model.

Notice that the various numeric expressions are arguments for these functions. The inheritance relationship between the different classes of numeric expressions is a little complicated, but well designed. They are summarized in the chart below, with an arrow from interface A to interface B if A implements B (is a subinterface, like a subclass).

Full Size

We will use a few method from IloLinearIntExpr to build up sums.

Name

Return Type

Arguments

Description

addTerm

void

IloIntVar v, int c

Adds the new term \( c\cdot v \) to a scalar product. This method can create duplicate terms \( \cdots + a_i * x + ... + a_k * x + \cdots \) that could be joined to a single term \( \cdots + (a_i + a_k) * x + \cdots \) . Duplicates do not generate errors but require more memory and more running time.

The interface for IloLinearNumExpr is similar.

Using CPLEX in TspIpSolver

First, we need to set up the objective and the degree constraints. First, add the following fields to the class

private IloCplex cplex;
private TspInstance<V,E> tspInstance;
private final ImmutableBiMap<E,IloIntVar> edgeVariables;

and initialize them, as below.

	public TspIpSolver(TspInstance<V,E> tspInstance, EnumSet<Option> options) throws IloException{
		this.options = options;
		this.tspInstance = tspInstance;
		this.cplex = new IloCplex();
		UndirectedGraph<V,E> graph = tspInstance.getGraph(); //for convenience, we will be using this a lot
		this.edgeVariables = Util.makeBinaryVariables(cplex, graph.getEdges());
		//the degree constraints
		//the objective		
	}

The constraints and objective still need to be added to the cplex object. Try adding them yourself! The following methods should be useful for making the constraints:

  • From Util, public static <T> IloLinearIntExpr integerSum(IloCplex cplex, BiMap<T,IloIntVar> variables, Iterable<T> set)
    • For each element \( e \) of set, finds the corresponding variable \( x_e \) and returns \( \sum_{e \in \text{set}} x_e \)
  • From IloCplex, public IloRange addEq(IloNumExpr e, double v)
    • Adds the equality constraint e = v
  • From UndirectedGraph<V,E>, public Collection<E> getIncidentEdges(V vertex)
    • returns the edges of the graph that are incident to vertex

If you are unfamiliar with Java, consider viewing the solution for the constraint, then trying the objective yourself.
Solution

For the objective, we need the functions:

  • From Util, public static <T> IloLinearNumExpr sum(IloCplex cplex, BiMap<T,IloIntVar> variables, Iterable<T> set, Function<? super T,? extends Number> coefficients)
    • For every element \( e \) of set, gets the corresponding variable \( x_e \) from variables and the number \( d_e \) from coefficients and returns an expression for \( \sum_{e \in \text{set}} d_e x_e \) .

Solution

  • No labels