Solving your first model in Java¶
Hexaly Optimizer is implemented in C++ language. Nevertheless, object-oriented APIs are provided for Java 8.0 (or superior), allowing a full integration of Hexaly Optimizer in your Java business applications. Hexaly Optimizer’s APIs are lightweight, with only a few classes to manipulate. Note that Hexaly Optimizer is a model-and-run math programming solver: having instantiated the model, no additional code has to be written in order to run the solver.
In this section, we show you how to model and solve your first problem in Java: the optimization of the shape of a bucket. With a limited surface of material (S=π), we try to build a bucket that holds the largest volume.
This small example is more precisely described in our example tour. Here our main goal is to learn how to write and launch a model.
Writing the model¶
Below is the Java program which models this non linear problem (see examples/optimal_bucket).
import java.io.*;
import com.hexaly.optimizer.*;
public class OptimalBucket {
private static final double PI = 3.14159265359;
// Hexaly Optimizer
private final HexalyOptimizer optimizer;
// Hexaly Program variables
private HxExpression R;
private HxExpression r;
private HxExpression h;
private HxExpression surface;
private HxExpression volume;
private OptimalBucket(HexalyOptimizer optimizer) {
this.optimizer = optimizer;
}
private void solve(int limit) {
// Declare the optimization model
HxModel model = optimizer.getModel();
HxExpression piConst = model.createConstant(PI);
// Numerical decisions
R = model.floatVar(0, 1);
r = model.floatVar(0, 1);
h = model.floatVar(0, 1);
// surface = PI*r^2 + PI*(R+r)*sqrt((R - r)^2 + h^2)
HxExpression s1 = model.prod(piConst, r, r);
HxExpression s2 = model.pow(model.sub(R, r), 2);
HxExpression s3 = model.pow(h, 2);
HxExpression s4 = model.sqrt(model.sum(s2, s3));
HxExpression s5 = model.sum(R, r);
HxExpression s6 = model.prod(piConst, s5, s4);
surface = model.sum(s1, s6);
// Surface must not exceed the surface of the plain disc
model.addConstraint(model.leq(surface, PI));
HxExpression v1 = model.pow(R, 2);
HxExpression v2 = model.prod(R, r);
HxExpression v3 = model.pow(r, 2);
// volume = PI*h/3*(R^2 + R*r + r^2)
volume = model.prod(piConst, model.div(h, 3), model.sum(v1, v2, v3));
// Maximize the volume
model.maximize(volume);
model.close();
// Parametrize the optimizer
optimizer.getParam().setTimeLimit(limit);
optimizer.solve();
}
/* Write the solution in a file with the following format:
* - surface and volume of the bucket
* - values of R, r and h */
private void writeSolution(String fileName) throws IOException {
try (PrintWriter output = new PrintWriter(fileName)) {
output.println(surface.getDoubleValue() + " " + volume.getDoubleValue());
output.println(R.getDoubleValue() + " " + r.getDoubleValue() + " " + h.getDoubleValue());
}
}
public static void main(String[] args) {
String outputFile = args.length > 0 ? args[0] : null;
String strTimeLimit = args.length > 1 ? args[1] : "2";
try (HexalyOptimizer optimizer = new HexalyOptimizer()) {
OptimalBucket model = new OptimalBucket(optimizer);
model.solve(Integer.parseInt(strTimeLimit));
if (outputFile != null) {
model.writeSolution(outputFile);
}
} catch (Exception ex) {
System.err.println(ex);
ex.printStackTrace();
System.exit(1);
}
}
}
After creating the Hexaly Optimizer environment HexalyOptimizer()
,
all the decision variables of the model, are declared with function
floatVar()
(or also boolVar()
, intVar()
, setVar()
,
listVar()
). Intermediate expressions can be built upon these decision
variables by using other operators or functions. For example, in the model
above: power (pow
), square root (sqrt
), less than or equal to (leq
).
Many other mathematical operators are available, allowing you to model and solve
highly-nonlinear combinatorial optimization problems. The functions
constraint
or maximize
are used for tagging expressions as constrained
or maximized.
Compiling and running the Java program¶
For compiling, Java Development Kit 8.0 (or superior) must be installed on your computer. On Windows, the above program is compiled and launched using the following lines:
javac OptimalBucket.java -cp %HX_HOME%\bin\hexaly.jar
java -cp %HX_HOME%\bin\hexaly.jar;. -Djava.library.path=%HX_HOME%\bin\ OptimalBucket
Note that on Windows, in a PowerShell window you would use the following lines:
javac OptimalBucket.java -cp $env:HX_HOME\bin\hexaly.jar
java "-Djava.library.path=$env:HX_HOME\bin\" -cp "$env:HX_HOME\bin\hexaly.jar;." OptimalBucket
On Linux or Mac OS, the above program is compiled and launched using the following lines:
javac OptimalBucket.java -cp /opt/hexaly_13_0/bin/hexaly.jar
java -cp /opt/hexaly_13_0/bin/hexaly.jar:. -Djava.library.path=/opt/hexaly_13_0/bin/ OptimalBucket
Then, the following trace will appear in your console:
Model: expressions = 26, decisions = 3, constraints = 1, objectives = 1
Param: time limit = 2 sec, no iteration limit
[objective direction ]: maximize
[ 0 sec, 0 itr]: 0
[ optimality gap ]: 100%
[ 0 sec, 42898 itr]: 0.68709
[ optimality gap ]: < 0.01%
42898 iterations performed in 0 seconds
Optimal solution:
obj = 0.68709
gap = < 0.01%
bounds = 0.687189
If no time limit is set, the search will continue until optimality is proven
(Optimal solution
message) or until you force the stop of the program by
pressing Ctrl+C
. The trace in console starts with the key
figures of the model: number of expressions, decisions, constraints
and objectives.
Once the search is finished, the total number of iterations and the elapsed time
are displayed, as well as the status and the value of the best solution
found. The solution status can be Inconsistent
, Infeasible
,
Feasible
or Optimal
.
If you have trouble compiling or launching the program, please have a look at the Installation & licensing. We invite users willing to go further with APIs to consult the Java API Reference.