}
{composition-setup}
{section}
{column:width=300px}
{pagetree:root=Tutorial}
{column}
{column}
h1. The Java Interface to CPLEX
The use of CPLEX in Java is based around the class IloCplex (documented [here|http://pic.dhe.ibm.com/infocenter/cosinfoc/v12r5/index.jsp?topic=%2Filog.odms.cplex.help%2Frefjavacplex%2Fhtml%2Filog%2Fcplex%2FIloCplex.html]). 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|http://pic.dhe.ibm.com/infocenter/cosinfoc/v12r5/index.jsp?topic=%2Filog.odms.cplex.help%2Frefjavacplex%2Fhtml%2Filog%2Fconcert%2FIloNumVar.html] objects and their subclass [IloIntVar|http://pic.dhe.ibm.com/infocenter/cosinfoc/v12r5/index.jsp?topic=%2Filog.odms.cplex.help%2Frefjavacplex%2Fhtml%2Filog%2Fconcert%2FIloIntVar.html] objects, when are then used as arguments to further methods from IloCplex to make the objective and constraints. The IloCplex interface is pretty confusing. It is very large, has lots of redundant methods, and has 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 {mathinline} e \geq v{mathinline}, and adds constraint to model.|
|addEq|IloRange|IloNumExpr e, double v|Creates and returns a range representing the constraint {mathinline} e = v{mathinline}, and adds constraint to model.|
|ge|IloRange|IloNumExpr e, double v|Creates and returns a range representing the constraint {mathinline} e \geq v{mathinline} *without* adding constraint to model.|
|addMinimize|IloObjective|IloNumExpr e|Creates and returns an objective to minimize the expression and adds it to the invoking model.|
|sovle|boolean| |Solves the active model. Returns true if a feasible solution was found|
|getValue|double|IloNumVar var|Returns the solution value for var.|
|getValues|double|IloNumVar[] vars|Returns the solution values for each of vars.|
|getObjVal|double| |Returns the objective value of the current solution.|
{warning:title=Warning}
For an IloCplex cplex, an IloNumExpr e and a double v, calling * Column |
---|
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 pretty confusing. It is very large, has lots of redundant methods, and has 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 , and adds constraint to model. | addEq | IloRange | IloNumExpr e, double v | Creates and returns a range representing the constraint , and adds constraint to model. | ge | IloRange | IloNumExpr e, double v | Creates and returns a range representing the constraint without adding constraint to model. | addMinimize | IloObjective | IloNumExpr e | Creates and returns an objective to minimize the expression and adds it to the invoking model. | sovle | boolean | | Solves the active model. Returns true if a feasible solution was found | getValue | double | IloNumVar var | Returns the solution value for var. | getValues | double | IloNumVar[] vars | Returns the solution values for each of vars. | getObjVal | double | | Returns the objective value of the current solution. |
Warning |
---|
| For an IloCplex cplex, an IloNumExpr e and a double v, calling |
| * ** * * {mathinline} e \geq v{mathinline} while the second gives the constraint {mathinline}v \geq e{mathinline}.
{warning}
{warning:title=Warning}
For an IloCplex cplex, an IloNumExpr e and a double v, calling * while the second gives the constraint . |
Warning |
---|
| For an IloCplex cplex, an IloNumExpr e and a double v, calling cplex.ge(e,v) |
| * ** * * {mathinline} e \geq v{mathinline}, only the latter adds the constraint to the model. We will actually have use , only the latter adds the constraint to the model. We will actually have use cplex.ge(e,v) |
|
{warning}
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).
{gliffy:name=cplexNumericExpressionInheritance|align=left|size=M|version=1}
We will use a few methods from IloLinearIntExpr to build up sums.
||Name||Return Type||Arguments||Description||
|addTerm|void|IloIntVar v, int c|Adds the new term {mathinline}c\cdot v{mathinline} to a scalar product. This method can create duplicate terms {mathinline} \cdots + a_i \cdot x + \cdots + a_k
\cdot x + \cdots{mathinline} that could be joined to a single term {mathinline}\cdots + (a_i + a_k) \cdot x + \cdots{mathinline}. Duplicates do not generate errors but require more memory and more running time.|
The interface for IloLinearNumExpr is similar.
h1. A Short Example
Suppose we want to solve the following IP in CPLEX:
{mathdisplay}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). Gliffy Diagram |
---|
size | M |
---|
name | cplexNumericExpressionInheritance |
---|
|
We will use a few methods from IloLinearIntExpr to build up sums. Name | Return Type | Arguments | Description |
---|
addTerm | void | IloIntVar v, int c | Adds the new term to a scalar product. This method can create duplicate terms that could be joined to a single term . Duplicates do not generate errors but require more memory and more running time. |
The interface for IloLinearNumExpr is similar. A Short ExampleSuppose we want to solve the following IP in CPLEX: Mathdisplay |
---|
\begin{aligned}
&\min & x + 2y + 3z\\
&\text{subject to}& x + y + z &\geq 2\\
&& x,y,z &\in\{0,1\}
\end{aligned}
|
| {mathdisplay}
__ {{}} [ |Test Your Java, Eclipse and Cplex Installations]
{:=}_Solution_
{cloak:id=Ex1Solution|visible=false}
{code}
public class WarmUps {
public static void main(String[] args) {
try {
exerciseOne();
} catch (IloException e) {
throw new RuntimeException(e);
}
}
public static void exerciseOne() throws IloException{
IloCplex cplex = new IloCplex();
IloIntVar x = cplex.boolVar();
IloIntVar y = cplex.boolVar();
IloIntVar z = cplex.boolVar();
IloLinearIntExpr constraintSum = cplex.linearIntExpr();
constraintSum.addTerm(x,1);
constraintSum.addTerm(y,1);
constraintSum.addTerm(z,1);
cplex.addGe(constraintSum,2);
IloLinearIntExpr objectiveSum = cplex.linearIntExpr();
objectiveSum.addTerm(x,1);
objectiveSum.addTerm(y,2);
objectiveSum.addTerm(z,3);
cplex.addMinimize(objectiveSum);
cplex.solve();
System.out.println("x: " + cplex.getValue(x));
System.out.println("y: " + cplex.getValue(y));
System.out.println("z: " + cplex.getValue(z));
System.out.println("obj: " + cplex.getObjValue());
}
}
{code}
{cloak}
h1. Reading Integer Variable Values from CPLEX
After solving an LP that is integral or an IP, you often want to query a variable and take some action if the variable has value 1.0, and another action if the variable has value 0.0. However, due to [the nature of floating point arithmetic|http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems], there are often small rounding errors in the values produced by CPLEX. For example, to test if a variable is equal to zero, do not write
{code}Solution Cloak |
---|
visible | false |
---|
id | Ex1Solution |
---|
| |
Reading Integer Variable Values from CPLEXAfter solving an LP that is integral or an IP, you often want to query a variable and take some action if the variable has value 1.0, and another action if the variable has value 0.0. However, due to the nature of floating point arithmetic, there are often small rounding errors in the values produced by CPLEX. For example, to test if a variable is equal to zero, do not write Code Block |
---|
IloCplex cplex = new IloCplex();
IloIntVar var = cplex.boolVar();
//...
//solve some problem
//...
double val = cplex.getValue(var);
if(val == 0){
//take some action
}
|
| {code}
{} |
---|
IloCplex cplex = new IloCplex();
IloIntVar var = cplex.boolVar();
//...
//solve some problem
//...
double val = cplex.getValue(var);
if(Math.abs(val) < 0.00001){
//take some action
}
|
| {code}
__
||Name||Return Type||Arguments||Description||
|doubleToBoolean|boolean|double v|Returns true if {mathinline}|v-1| < \epsilon{mathinline}, false if {mathinline}|v| < \epsilon{mathinline}, and throws an exception otherwise. A static filed in the class Util sets {mathinline}\epsilon{mathinline}.|
h1. Performance Issues Reading Variable Values from CPLEX
Consider the following piece of code you can find in your _WarmUps.java_:
{code}Name | Return Type | Arguments | Description |
---|
doubleToBoolean | boolean | double v | Returns true if , false if , and throws an exception otherwise. A static filed in the class Util sets . |
Consider the following piece of code you can find in your WarmUps.java: Code Block |
---|
public static void testSpeed() throws IloException{
IloCplex cplex = new IloCplex();
IloIntVar[] variables = cplex.boolVarArray(2000000);
cplex.addMaximize(cplex.sum(variables));
cplex.solve();
{
System.err.println("testing group access");
long startTime = System.currentTimeMillis();
double sum = 0;
double[] vals = cplex.getValues(variables);
for(int i = 0; i < vals.length; i++){
sum+= vals[i];
}
long endTime = System.currentTimeMillis();
System.err.println("group: " + (endTime-startTime));
System.err.println(sum);
}
{
System.err.println("testing individual access");
long startTime = System.currentTimeMillis();
double sum = 0;
for(int i = 0; i < variables.length; i++){
double val = cplex.getValue(variables[i]);
sum+=val;
}
long endTime = System.currentTimeMillis();
System.err.println("individual: " + (endTime-startTime));
System.err.println(sum);
}
}
|
| {code}
{{}} {{}} {{}}
{warning:Warning}
The method {{ Warning |
---|
| The method getValue(IloNumVar |
| }} {{}} {{ }}
{warning}
{column}
{section} |