JOpt.TourOptimizer for Developers

By Slashdot Staff

Embedding advanced tour and resource optimization into your own software.

JOpt is the optimization technology from DNA Evolutions for developers who need to solve complex routing, scheduling, dispatching and resource allocation problems inside existing software systems. It is not a frontend planning tool and not a SaaS dashboard. JOpt.TourOptimizer is a backend optimization engine: you send tasks, resources and constraints, and the engine returns feasible, optimized schedules.

For development teams, the key point is simple: JOpt is designed to be embedded. It can run as a native Java SDK or as a Docker based REST service with OpenAPI support, making it usable from Java, Python, C Sharp, JavaScript, TypeScript or any stack that can call HTTP APIs.

What JOpt Solves

Most logistics systems already store orders, vehicles, drivers, customers and addresses. What they often lack is a reliable decision engine that answers operational planning questions.

Which vehicle should serve which order?

Which technician can handle which job?

Which tour is feasible under time windows, skills, capacities and working hours?

How can a plan be recalculated when new orders arrive or disruptions happen?

JOpt.TourOptimizer targets operational planning problems such as vehicle routing, capacitated routing, time window routing, pickup and delivery, multi depot planning, heterogeneous fleets and workforce scheduling with skills and eligibility rules.

A typical JOpt project follows a clean pipeline: addresses are converted into coordinates, routing data provides realistic travel times, and TourOptimizer creates feasible optimized schedules. DNA Evolutions structures this as a product family with JOpt.GeoCoder, JOpt.RoutePlanner and JOpt.TourOptimizer.

Developer Stack

JOpt.TourOptimizer is built around a Java core. Developers can integrate it in two main ways.

Java SDKREST and OpenAPI
The Java SDK is the best path when the host  application is Java based and the optimizer should  run in process. It gives maximum control, direct  access to the model and full feature coverage.In this setup, JOpt.TourOptimizer runs as a  Dockerized backend service. Clients send JSON  payloads and receive optimization results through  HTTP APIs.

Why Developers Choose JOpt.TourOptimizer

The main USP is not only route calculation. Route calculation answers how to travel from A to B. JOpt.TourOptimizer answers which resources should execute which tasks in which sequence while respecting operational constraints.

That distinction matters. In real dispatching systems, distance is only one part of the problem. Plans must also respect time windows, skills, vehicle capacities, depots, working hours, pickup and delivery relations, territories, service durations, customer rules and business priorities.

JOpt is designed as a platform component rather than a closed planning application. It can be embedded into ERP systems, TMS platforms, field service software, custom dispatching systems or SaaS products.

How Fast Can You Set It Up?

For a technical proof of concept, setup can be fast if test data is available. With the Java SDK, developers can clone the example repository, open it as a Maven project and run example classes directly.

GitHub Project -> JOpt.TourOptimizer-Examples

With REST, developers can start the Docker service and call the API from any language.Here you find the prebuilt mage. You can just pull the image, start the container, and call the API.

Docker Image -> dnaevolutions/jopt_touroptimizer

A minimal local REST setup can look like this:

docker run -d --rm --name jopt-touroptimizer \
 -p 8081:8081 \
 -e SPRING_PROFILES_ACTIVE=cors \
 dnaevolutions/jopt_touroptimizer:latest

After startup, the Swagger UI is available on the local REST server and can be used to inspect endpoints and test optimization payloads.

The main effort is usually not starting the engine. The real project work is mapping business data into a clean optimization model.

ORDERSbecome nodesVEHICLESbecome resources
RULESbecome constraintsOUTPUTroutes, schedules and KPIs

Example: First Optimization with JOpt Java.SDK

The official first optimization tutorial builds a complete JOpt.TourOptimizer problem step by step: configure optimization properties, add nodes, add resources, subscribe to optimization events and start the optimization asynchronously. (see the GitHub link above)

FirstOptimizationExample.java
public class FirstOptimizationExample extends Optimization {
 public static void main(String[] args)
 throws InterruptedException, ExecutionException, InvalidLicenceException { new FirstOptimizationExample().example();
  }

 public void example()
 throws InterruptedException, ExecutionException, InvalidLicenceException {
 FirstOptimizationExample.addProperties(this);
 FirstOptimizationExample.addNodes(this);
 FirstOptimizationExample.addResources(this);
 FirstOptimizationExample.attachToObservables(this);
 FirstOptimizationExample.startAndPresentResult(this);
 }
}

1. Configure Optimization Properties

JOpt can run with default properties, but the tutorial shows how developers can explicitly configure solver behavior such as Simulated Annealing iterations and Genetic Evolution generation count.

addProperties()
private static void addProperties(IOptimization opti) {
 Properties props = new Properties();

 props.setProperty("JOpt.Algorithm.PreOptimization.SA.NumIterations", "10000");
props.setProperty("JOptExitCondition.JOptGenerationCount", "2000");

 opti.addElement(props);
}

2. Add Nodes

Nodes represent stops, jobs or customer visits. In the tutorial, each node has a geo position, opening hours, a visit duration and an importance value.

addNodes()
private static void addNodes(IOptimization opti) {
 List weeklyOpeningHours = new ArrayList<>();

 weeklyOpeningHours.add(
 new OpeningHours(
 ZonedDateTime.of(2020, MAY.getValue(), 6, 8, 0, 0, 0, ZoneId.of("Europe/Berlin")), ZonedDateTime.of(2020, MAY.getValue(), 6, 17, 0, 0, 0,
ZoneId.of("Europe/Berlin"))));
 weeklyOpeningHours.add(
 new OpeningHours(
 ZonedDateTime.of(2020, MAY.getValue(), 7, 8, 0, 0, 0, ZoneId.of("Europe/Berlin")), ZonedDateTime.of(2020, MAY.getValue(), 7, 17, 0, 0, 0,
ZoneId.of("Europe/Berlin"))));

 Duration visitDuration = Duration.ofMinutes(20);
 int importance = 1;

 INode koeln =
 new TimeWindowGeoNode("Koeln", 50.9333, 6.95, weeklyOpeningHours, visitDuration, importance);
opti.addElement(koeln);

 INode essen =
 new TimeWindowGeoNode("Essen", 51.45, 7.01667, weeklyOpeningHours, visitDuration, importance);
opti.addElement(essen);

 INode dueren =
 new TimeWindowGeoNode("Dueren", 50.8, 6.48333, weeklyOpeningHours, visitDuration, importance);
opti.addElement(dueren);

 INode nuernberg =
 new TimeWindowGeoNode("Nuernberg", 49.4478, 11.0683, weeklyOpeningHours, visitDuration, importance);
opti.addElement(nuernberg);

 INode heilbronn =
 new TimeWindowGeoNode("Heilbronn", 49.1403, 9.22, weeklyOpeningHours, visitDuration, importance);
opti.addElement(heilbronn);

 INode wuppertal =
 new TimeWindowGeoNode("Wuppertal", 51.2667, 7.18333, weeklyOpeningHours, visitDuration, importance);
opti.addElement(wuppertal);

 INode aachen =
 new TimeWindowGeoNode("Aachen", 50.775346, 6.083887, weeklyOpeningHours, visitDuration, importance);
opti.addElement(aachen);
}

3. Add Resources

Resources represent the available capacity in the optimization problem, for example vehicles, drivers or technicians. In the tutorial, the resource is “Jack from Aachen”.

addResources()
private static void addResources(IOptimization opti) {
 List workingHours = new ArrayList<>();

 workingHours.add(
 new WorkingHours(
 ZonedDateTime.of(2020, MAY.getValue(), 6, 8, 0, 0, 0, ZoneId.of("Europe/Berlin")), ZonedDateTime.of(2020, MAY.getValue(), 6, 17, 0, 0, 0,
ZoneId.of("Europe/Berlin"))));

 workingHours.add(
 new WorkingHours(
 ZonedDateTime.of(2020, MAY.getValue(), 7, 8, 0, 0, 0, ZoneId.of("Europe/Berlin")), ZonedDateTime.of(2020, MAY.getValue(), 7, 17, 0, 0, 0,
ZoneId.of("Europe/Berlin"))));
 Duration maxWorkingTime = Duration.ofHours(9);
 Quantity maxDistanceKmW = Quantities.getQuantity(1200.0, KILO(METRE));

 IResource jack =
 new CapacityResource(
 "Jack from Aachen",
 50.775346,
 6.083887,
 maxWorkingTime,
 maxDistanceKmW,
 workingHours);

 opti.addElement(jack);
}

4. Subscribe to Optimization Events

JOpt exposes optimization events for progress, warnings, status updates and errors. This is useful when optimization runs are integrated into backend services, job queues or monitoring systems.

attachToObservables()
private static void attachToObservables(IOptimization opti) {
 opti.getOptimizationEvents()
 .progressSubject()
 .subscribe(p -> {
 System.out.println(p.getProgressString());
 });

opti.getOptimizationEvents()
 .warningSubject()
 .subscribe(w -> {
 System.out.println(w.toString());
 });

opti.getOptimizationEvents()
 .statusSubject()
 .subscribe(s -> {
 System.out.println(s.toString());
 });

opti.getOptimizationEvents()
 .errorSubject()
 .subscribe(e -> {
 System.out.println(e.toString());
 });
}

5. Start the Optimization

The tutorial starts the optimization asynchronously via startRunAsync() and then blocks on the resulting CompletableFuture to receive the final optimization result.

startAndPresentResult()
private static void startAndPresentResult(IOptimization opti)
 throws InvalidLicenceException, InterruptedException, ExecutionException {
 CompletableFuture resultFuture = opti.startRunAsync(); IOptimizationResult result = resultFuture.get();
 System.out.println(result);
}

This example shows the typical developer workflow: configure the optimizer, add nodes, add resources, subscribe to events and start the optimization run asynchronously. The same pattern can be used when JOpt.TourOptimizer is embedded into ERP, TMS, field service or dispatching backends.

AI and Developer Experience

The JOpt ecosystem also comes with AI assisted developer and configuration workflows. including a JOpt specific AI assistant for developers and managers, AI supported parameter configuration, fleet and customer assessments, and additional capabilities around sustainability, compliance and advanced analytics.

For developers, this is especially relevant because optimization projects often become complex during parameter tuning and result interpretation.

JOpt.TourOptimizer is not just a route calculator. It is a backend engine for building feasible, scalable and operationally useful planning functionality into ERP, TMS, field service, fleet management and dispatching platforms.

Conclusion

JOpt.TourOptimizer is a developer focused optimization engine for teams that need to embed routing, scheduling and dispatch intelligence into their own systems.

Its strongest value is the combination of Java SDK, Docker REST API, OpenAPI based integration, portable json snapshot modeling, hard constraints by architecture (not by penalty) and support for custom constraints. For developers, that means optimization logic can be added to an existing product architecture without forcing a new frontend, workflow or data ownership model.

Related Categories