Optimisation-as-a-Service
Update, October 2026: the service has been substantially reworked since this was written. Using the Optimisation Service describes the current setup. The example code below is kept current.
The main benefit with ojAlgo’s suite of mathematical optimisation solvers is that it’s open source pure Java. It allows to solve mathematical optimisation problems directly in the JVM – no dependencies, no license management, no native code libraries or service calls.
Another benefit is that if it, later, turns out the capabilities of a commercial native code solver are required; you can just plug it in. You do of course then need to install that software as well as pay for and manage the license, but you do not need to change any of the Java code.
Now Optimatika introduces another alternative – Optimisation-as-a-Service. It frees you from the burdon of setting up and maintaining a server running optimisation code. Everything required to use this service is already in ojAlgo (v52.0.0 and later).
Calling this service does not require dealing with JSON, XML or anything like that. Using the service is just a matter of configuring to use that “solver” rather than the usual ones.
The server running the service is packaged as a Docker image – easy to deploy anywhere. There is a test/demo service available. Below is example code that demonstrates how to use Optimatika’s Optimisation-as-a-Service. If you run the code the optimisation problem is solved by that test/demo service.
Example Code
OptimisationAsAService.javaimport java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import org.ojalgo.OjAlgoUtils;
import org.ojalgo.netio.BasicLogger;
import org.ojalgo.optimisation.ExpressionsBasedModel;
import org.ojalgo.optimisation.Optimisation;
import org.ojalgo.optimisation.Optimisation.Environment;
import org.ojalgo.optimisation.Optimisation.Result;
import org.ojalgo.optimisation.Optimisation.Sense;
import org.ojalgo.optimisation.Variable;
import se.optimatika.optimisation.service.client.OptClientV1;
/**
* A program that shows how to use Optimatika's Optimisation-as-a-Service.
*
* @see https://www.ojalgo.org/2026/10/using-the-optimisation-service/
* @see https://www.ojalgo.org/2022/10/optimisation-as-a-service/
*/
public class OptimisationAsAService {
public static void main(final String[] args) throws InterruptedException, ExecutionException {
BasicLogger.debug();
BasicLogger.debug(OptimisationAsAService.class);
BasicLogger.debug(OjAlgoUtils.getTitle());
BasicLogger.debug(OjAlgoUtils.getDate());
BasicLogger.debug();
/*
* Create a client for the optimisation service.
*/
OptClientV1 client = OptClientV1.newInstance("https://optimisation-test-service-840974723912.europe-north2.run.app");
/*
* Verify the service is up and running.
*/
if (!client.isServiceAvailable()) {
BasicLogger.error("Service is not available!");
return;
}
BasicLogger.debug("Service environment: {}", client.getServiceEnvironment());
/*
* If you already have a working model built using ojAlgo's ExpressionsBasedModel you can use that as
* is. Here's how:
*/
Environment environment = Optimisation.newEnvironment();
/*
* Even if you never used Optimisation.Environment before, there is always an implicit default
* environment. What we did here is simply to create a separate environment to use explicitly. Then
* configure that to use a remote solver.
*/
environment.setRemoteSolver(client::putOnQueue, client::pollResult);
/*
* Finally, use the environment as the model factory.
*/
ExpressionsBasedModel model = environment.newModel();
/*
* Let's just build a trivial model...
*/
Variable varA = model.newVariable("A").lower(0).weight(10);
Variable varB = model.newVariable("B").lower(0).weight(-10);
model.newExpression("SumIs2").set(varA, 1).set(varB, 1).level(2);
/*
* Now, to actually solve remotely, call model.submit(Sense)
*/
Future<Result> max = model.submit(Sense.MAX);
/*
* Submitting a large MIP model to solve remotely, it may take a while before you get the response.
*/
Result result = max.get();
BasicLogger.debug();
BasicLogger.debug("Maximised => state={}, value={}", result.getState(), result.getValue());
BasicLogger.debug("A={}, B={}", result.get(0), result.get(1));
Future<Result> min = model.submit(Sense.MIN);
result = min.get();
BasicLogger.debug("Minimised => state={}, value={}", result.getState(), result.getValue());
BasicLogger.debug("A={}, B={}", result.get(0), result.get(1));
// To summarise what you need to do in code:
//
// 1) Create the model instance using an environment configured to solve remotely
// 2) Solve using model.submit(Sense) rather than model.minimise() or model.maximise()
//
// Nothing else!
}
}
The service endpoint used in the example above is for test and demonstration purposes only. That means NOT for production use! It may be restricted or removed, at any time, without warning. At the time of writing this post it is fully functional and unrestricted (running on a low spec server). Most likely there will always be some kind of test service endpoint available, but that will be with limited capabilities. Optimisation-as-a-Service is a commercial product/service. If you’d like access to an unrestricted service instance for (private) production use, you should look at the Optimisation Service.
- ← Previous
ojAlgo v52 - Next →
The Memory Estimator