This post aims to demonstrate how to make a solver usable from ExpressionsBasedModel
. To do that we first implement a very simple solver, and then the integration.
There are some very high-level ojAlgo concepts (interfaces) you should know about:
Optimisation.Model
– a description of an optimisation problem.Optimisation.Solver
– a specific algorithm implementation.Optimisation.Integration
– translates between a model’s general problem description and a solver’s specific data structure.
There needs to be one Optimisation.Integration
per Optimisation.Model
/ Optimisation.Solver
combination. It makes sense to have multiple solver implementations handling different kinds of problems, but only one tool to model them. In ojAlgo the modelling tool is ExpressionsBasedModel
.
Now imagine you have some existing 3:d party solver and you want to make that available to (usable from) ojAlgo’s ExpressionsBasedModel
. We need to create two classes – one that implements Optimisation.Solver
and another that implements Optimisation.Integration
. It’s important to distinguish between these two. The integration must be stateless. There will only ever be one instance created, that you register with the model. The solver implements the actual algorithm (delegating to the 3:d party solver). There’s typically a new solver instance created every time you solve a new problem.
Example Code
Console Output
class HookingUpSolver
ojAlgo
2025-02-08
Expected result: OPTIMAL 2.0 @ { 2.0, 1.0 }
0: NaN – { 0.0, 0.0 }
1: 0.8944271909999159 – { 1.0, 0.0 }
2: 0.0 – { 2.0, 1.0 }
Actual result: OPTIMAL 2.0 @ { 2, 1 }
Interpretation
Not that much to say. The solver output shows the initial solution, as well as the solutions after each iteration. With the second iteration the optimal solution is found.
Available 3:d Party Solver Integrations
There are multiple 3:d party solvers integrated with ojAlgo’s ExpressionsBasedModel
. ojAlgo itself has zero dependencies, so each of these are in a separate dependency artifact.
Gurobi
- Top quality commercial solver.
- Native code with a java interface.
- Can solve all types of problems you can model with
ExpressionsBasedModel
.
<!-- https://mvnrepository.com/artifact/org.ojalgo/ojalgo-gurobi --> <dependency> <groupId>org.ojalgo</groupId> <artifactId>ojalgo-gurobi</artifactId> <version>3.1.0</version> </dependency>
org.ojalgo.optimisation.solver.gurobi.SolverGurobi#INTEGRATION
CPLEX
https://www.ibm.com/products/ilog-cplex-optimization-studio
- Top quality commercial solver.
- Native code with a java interface.
- Can solve all types of problems you can model with
ExpressionsBasedModel
.
<!-- https://mvnrepository.com/artifact/org.ojalgo/ojalgo-cplex --> <dependency> <groupId>org.ojalgo</groupId> <artifactId>ojalgo-cplex</artifactId> <version>3.1.0</version> </dependency>
org.ojalgo.optimisation.solver.cplex.SolverCPLEX#INTEGRATION
OR-Tools
https://developers.google.com/optimization
- A collection of open source solvers, and also possible to use some commercial
- Native code with a java interface.
- Great support for LP, ok for MIP and I believe some support for QP. In addition to that it contains a constraint programming solver that is supposedly rather good.
<!-- https://mvnrepository.com/artifact/org.ojalgo/ojalgo-ortools --> <dependency> <groupId>org.ojalgo</groupId> <artifactId>ojalgo-ortools</artifactId> <version>2.0.0</version> </dependency>
org.ojalgo.optimisation.solver.ortools.SolverORTools#INTEGRATION
MOSEK
- Top quality commercial solver.
- Native code with a java interface.
- Can solve all types of problems you can model with
ExpressionsBasedModel
.
<!-- https://mvnrepository.com/artifact/org.ojalgo/ojalgo-mosek --> <dependency> <groupId>org.ojalgo</groupId> <artifactId>ojalgo-mosek</artifactId> <version>3.2.0</version> </dependency>
org.ojalgo.optimisation.solver.mosek.SolverMosek#INTEGRATION
Hipparchus
- Open Source
- Pure Java
- Hipparchus started as a fork of Apache Commons Math. It contains both LP and convex (QP) solvers. Not sure about its QP capability, but the built-in ojAlgo solvers should be better than Hipparchus’. For LP they definitely are.
<!-- https://mvnrepository.com/artifact/org.ojalgo/ojalgo-hipparchus --> <dependency> <groupId>org.ojalgo</groupId> <artifactId>ojalgo-hipparchus</artifactId> <version>2.0.0</version> </dependency>
org.ojalgo.optimisation.solver.hipparchus.SolverHipparchus#INTEGRATION
Apache Commons Math
https://commons.apache.org/proper/commons-math/
- Open source
- Pure Java
- Apache Commons Math (ACM) contains an LP solver. It offers no benefit over ojAlgo’s LP solver. In addition the ACM project seems to have problems. v3.6.1 is almost a decade old and v4.0.0 still only exists in beta (which is more than 2 years old). As far as I know the developers moved to Hipparchus.
<!-- https://mvnrepository.com/artifact/org.ojalgo/ojalgo-commons-math3 --> <dependency> <groupId>org.ojalgo</groupId> <artifactId>ojalgo-commons-math3</artifactId> <version>4.0.1</version> </dependency>
org.ojalgo.optimisation.solver.acm.SolverACM#INTEGRATION
JOptimizer
https://github.com/vincentk/joptimizer (not the original)
- Open source
- Pure Java
- A collection of solvers for convex optimisation problems. In theory JOptimizer should be able to solve some types of problems the standard ojAlgo solvers cannot (quadratically constrained). In practice we find that this library doesn’t work very well, and as far as we know the project is abandoned.
<!-- https://mvnrepository.com/artifact/org.ojalgo/ojalgo-joptimizer --> <dependency> <groupId>org.ojalgo</groupId> <artifactId>ojalgo-joptimizer</artifactId> <version>3.0.3</version> </dependency>
org.ojalgo.optimisation.solver.joptimizer.SolverJOptimizer#INTEGRATION
All of these 3:d party solver integrations are available, with source code, from https://mvnrepository.com/artifact/org.ojalgo
Even if the solvers are not of interest to you, the integration code may be. They serve as additional examples of how to write a 3:d party solver integration. Start by looking at the OR-Tools and CPLEX integrations.