Release Notes
This chapter lists new and noteworthy updates in OptaPlanner releases. OptaPlanner follows a 3-week release cycle. Bug fixes and minor improvements are generally not announced, which is why some of the minor releases are not mentioned here.
For a step-by-step migration guide, see our upgrade recipe. We even provide a migration tool to make many of these changes automatically.
For release notes on OptaPlanner 7.x and older, please visit Release Notes on optaplanner.org.
OptaPlanner 8.x Release Notes
OptaPlanner 8.37.0.Final
PlanningListVariable
supports nearby selection
Nearby selection is now available for planning domains using a planning list variable.
AbstractScoreHibernateType and its subtypes become deprecated
The AbstractScoreHibernateType
as well as all its subtypes have been deprecated. The parallel OptaPlanner 9
releases are going to introduce Hibernate 6, which unfortunately breaks backward compatibility
of the CompositeUserType
that the AbstractScoreHibernateType
depends on.
The AbstractScoreHibernateType
and its subtypes remain available in the OptaPlanner 8 releases to provide
integration with Hibernate 5 but have been removed from the equivalent OptaPlanner 9.x release.
To integrate the PlanningScore
of your choice with Hibernate 6, either use the score converters available in the
org.optaplanner.persistence.jpa.api.score.buildin
package or implement the CompositeUserType
yourself.
OptaPlanner 8.36.0.Final
OptaWeb Vehicle Routing demo application abandoned
The codebase for OptaWeb Vehicle Routing demo application has been frozen and will no longer receive any updates.
We encourage users to check out the OptaPlanner Vehicle Routing Quickstart for a simple and straight-forward way of integrating OptaPlanner in your application.
OptaPlanner 8.35.0.Final
PlanningListVariable
gets support for K-Opt Moves
A new move selector for list variables, KOptListMoveSelector
, has been added.
The KOptListMoveSelector
selects a single entity, removes k
edges from its route, and add k
new edges from the removed edges' endpoints.
The KOptListMoveSelector
can help the solver escape local optima in vehicle routing problems.
Configuration options are available in the documentation.
SolutionManager
gets support for updating shadow variables
SolutionManager
(formerly ScoreManager
) methods such as explain(solution)
and update(solution)
received a new overload with an extra argument, SolutionUpdatePolicy
.
This has often been requested by users who load their solutions from persistent storage (such as a relational database), where these solutions do not include the information carried by shadow variables or even the score.
By calling these new overloads and picking the right policy,
OptaPlanner will automatically compute values for all the shadow variables in the given solution
and/or recalculate the score.
Similarly, ProblemChangeDirector
received a new method called `updateShadowVariables(), so that you can update shadow variables on demand in real-time planning.
OptaPlanner 8.34.0.Final
Performance improvements in pillar moves and nearby selection
OptaPlanner can now auto-detect situations where multiple pillar move selectors can share a pre-computed pillar cache and reuse it instead of recomputing it for each move selector.
Users who combine different pillar moves (such as PillarChangeMove
and PillarSwapMove
) should see significant benefits.
The same applies to users of nearby selection. OptaPlanner can now auto-detect situations where a pre-computed distance matrix can be shared between multiple move selectors, saving a considerable amount of memory and CPU processing time.
As a consequence, implementations of the following interfaces are expected to be stateless:
-
org.optaplanner.core.impl.heuristic.selector.common.nearby.NearbyDistanceMeter
-
org.optaplanner.core.impl.heuristic.selector.common.decorator.SelectionFilter
-
org.optaplanner.core.impl.heuristic.selector.common.decorator.SelectionProbabilityWeightFactory
-
org.optaplanner.core.impl.heuristic.selector.common.decorator.SelectionSorter
-
org.optaplanner.core.impl.heuristic.selector.common.decorator.SelectionSorterWeightFactory
In general, if solver configuration asks the user to implement an interface, the expectation is that the implementation will be stateless or at the very least not try to include external state. With the aforementioned performance improvements, failing to follow this requirement will result in subtle bugs and score corruption as the solver will now reuse these instances as it sees fit.
OptaPlanner 8.33.0.Final
Value range auto-detection
In most cases, links between planning variables and value ranges can now be auto-detected.
Therefore, @ValueRangeProvider
no longer needs to provide an id
property.
Likewise, planning variables no longer need to reference value range providers via valueRangeProviderRefs
property.
No code changes or configuration changes are required. Users who prefer clarity over brevity may continue to explicitly reference their value range providers.
OptaPlanner 8.32.0.Final
XStream support deprecated
Given that XStream has multiple CVEs against it and no recent releases,
we have decided to deprecate OptaPlanner’s support for serializing into XML using XStream.
To continue serializing into XML, please switch to the optaplanner-persistence-jaxb
module.
All classes in the optaplanner-persistence-xstream
, as well as the module itself, are now deprecated and will be removed in a future major version of OptaPlanner.
All examples in the optaplanner-examples
module have been refactored to JSON using the optaplanner-persistance-jackson
module.
Quickstarts were not affected by these changes, as they already were serializing into JSON.
OptaPlanner 8.31.0.Final
Several OptaPlanner examples removed from the distribution
In an ongoing effort to clean up code and reduce technical debt, the following examples were removed the optaplanner-examples
module:
-
Batch Scheduling,
-
Cheap Time,
-
Coach Shuttle Gathering,
-
Investment
-
and Rock Tour.
We believe these examples were rarely used if ever, and they did not showcase any unique feature of OptaPlanner that would not be showcased already in any of the 16 remaining examples and many quickstarts.
No OptaPlanner feature was removed or deprecated in the process.
Multiple entity classes with chained planning variables
Fixed a bug that prevented using two or more chained planning variables, each defined on a different planning entity class.
OptaPlanner 8.30.0.Final
OptaPlanner operator (experimental) is available in the distribution
While the OptaPlanner operator remains experimental, it has now become a part of the OptaPlanner distribution.
If you want to learn more about the operator, follow the Kubernetes demo.
OptaPlanner 8.29.0.Final
Custom justifications and indictments in Constraint Streams
With a new Constraint Streams API, it is now easy to define custom constraint justifications and indictments in your constraints:
protected Constraint vehicleCapacity(ConstraintFactory factory) {
return factory.forEach(Customer.class)
.filter(customer -> customer.getVehicle() != null)
.groupBy(Customer::getVehicle, sum(Customer::getDemand))
.filter((vehicle, demand) -> demand > vehicle.getCapacity())
.penalizeLong(HardSoftLongScore.ONE_HARD,
(vehicle, demand) -> demand - vehicle.getCapacity())
.justifyWith((vehicle, demand, score) ->
new VehicleDemandOveruse(vehicle, demand, score))
.indictWith((vehicle, demand) -> List.of(vehicle))
.asConstraint("vehicleCapacity");
}
Note the new methods: justifyWith(…)
and indictWith(…)
. To find out more, see customizing justifications and indictments.
Compatible with JDK 19
OpenJDK 19 was recently released and OptaPlanner is fully compatible with it.
We always test our releases against the long-term supported versions of the JDK, currently 11 and 17, as well as against the latest release. We encourage you to upgrade your JDK regularly to benefit from the enhancements that come with the new releases.
New @ShadowVariable
and @PiggybackShadowVariable
annotations replace the @CustomShadowVariable
@ShadowVariable
annotation is repeatable and allows to specify 1 listener per source variable.
@PiggybackShadowVariable
is a specialized annotation to mark shadow variables that are updated by another shadow variable’s listener.
The @CustomShadowVariable
has been deprecated.
Read more about custom shadow variables in the documentation.
Planning list variable
OptaPlanner now adds a limited support for planning list variables that can hold multiple planning values. The planning list variable provides an alternative approach to modeling planning problems that were previously modeled using the chained planning variable.
Both the planning list variable and the chained planning variable should be used with problems where the goal is to distribute a number of workload elements among limited resources in a specific order. For example, in vehicle routing, vehicles represent the limited resource and customers represent the workload elements.
The chained planning variable defines a recursive data structure, in which customers form chains ending with vehicles.
On the other hand, the planning list variable allows for a more intuitive model where each vehicle holds a list of customers it goes to.
It is defined using the new @PlaningListVariable
annotation.
The planning list variable is a new feature and lacks some advanced features, that are available with the chained planning variable. |
OptaPlanner 8.24.0.Final
OptaWeb Employee Rostering demo application abandoned
The codebase for OptaWeb Employee Rostering demo application has been frozen and will no longer receive any updates.
We encourage users to check out the OptaPlanner Employee Rostering Quickstart for a simple and straight-forward way of integrating OptaPlanner in your application.
OptaPlanner 8.23.0.Final
Score DRL deprecated in favor of Constraint Streams
Support for Score DRL has been deprecated and users are encouraged to migrate to Constraint Streams at their earliest convenience. Read the migration guide from score DRL to Constraint Streams. Score DRL is not going away in OptaPlanner 8.
OptaPlanner 8.17.0.Final
Real-time planning available on the SolverManager
The SolverManager
now accepts problem changes via the addProblemChange()
method,
allowing for real-time planning
without much boilerplate code.
OptaPlanner 8.12.0.Final
Documentation website
The latest final OptaPlanner documentation is now available on a new documentation website built using Antora. The single-HTML and PDF documentation will continue to be published in the archive.
OptaPlanner 8.10.0.Final
Support for Quarkus 2.0
OptaPlanner is now fully compatible with the recently released Quarkus 2.0.
OptaPlanner 8.7.0.Final
OptaPlanner quickstarts repository
There is a new quarkus-call-center
quickstart that shows real-time planning of incoming calls in a call center.
OptaPlanner 8.5.0.Final
Mapping in Constraint Streams
The Constraint Streams API received a major new functionality. You can now modify your streams using mapping functions.
Ready for OpenJDK 16
We have made some tweaks under the hood so that your experience with the recently released OpenJDK 16 continues to be smooth.
Inject and Autowire ConstraintVerifier in Quarkus and Spring Boot
You can now inject the Constraint Verifier in Quarkus and autowire the Constraint Verifier in Spring Boot, allowing you to test your constraint streams more easily.
OptaWebs on Quarkus
OptaWeb Vehicle Routing and OptaWeb Employee Rostering have been migrated from Spring Boot to Quarkus.
Other noteworthy changes done during the migration to Quarkus:
-
OptaWeb Vehicle Routing back end has a new RESTful API. Client-server communication, that was previously done using WebSockets, now uses a combination of REST calls and Server-Sent Events.
-
OptaWeb Employee Rostering now uses Constraint Streams instead of DRL for score calculation.
Faster domain accessors and cloning with Gizmo
We have added Gizmo generated domain accessors and solution cloners, which offer better performance than the reflection based domain accessors and solution cloners.
OptaPlanner 8.3.0.Final
Major performance improvements for Constraint Streams
The default implementation of the Constraint Streams API has seen major performance improvements. Use cases with tri and quad streams may experience order of magnitude speedups. Use cases with grouping are likely to experience some speedups too, albeit comparatively smaller.
Kudos to the Drools team for helping make this possible!
Constraint Streams groupBy()
overloads for multiple collectors
The Constraint Streams API has been extended to allow using more than 2 collectors in a single grouping. The following is now possible:
return constraintFactory.from(ProductPrice.class)
.groupBy(min(), max(), sum())
.penalize(..., SimpleScore.ONE, (minPrice, maxPrice, sumPrices) -> ...);
OptaPlanner 8.0.0.Final
OptaPlanner quickstarts repository
The new OptaPlanner Quickstarts repository contains pretty web demos for several use cases. It also shows you how to integrate OptaPlanner with different technologies:
-
School timetabling: Assign lessons to timeslots and rooms to produce a better schedule for teachers and students.
This application connects to a relational database and exposes a REST API, rendered by a pretty JavaScript UI.
-
quarkus-school-timetabling
: Java, Maven or Gradle, Quarkus, H2 -
spring-boot-school-timetabling
: Java, Maven or Gradle, Spring Boot, H2 -
kotlin-quarkus-school-timetabling
: Kotlin, Maven, Quarkus, H2
-
-
Facility location problem (FLP): Pick the best geographical locations for new stores, distribution centers, COVID-19 test centers or telco masts.
-
quarkus-facility-location
: Java, Maven, Quarkus
-
-
Factorio layout: Assign machines to assembly line locations to design the best factory layout.
-
quarkus-factorio-layout
: Java, Maven, Quarkus
-
-
Maintenance scheduling: Coming soon
Future Java compatibility
The OptaPlanner 8 API has been groomed to maximize compatibility with the latest OpenJDK and GraalVM releases and game-changing platforms such as Quarkus. Meanwhile, we still fully support OpenJDK 11 and platforms such as Spring Boot or plain Java.
For example, when running OptaPlanner in Java 11 or higher with a classpath,
OptaPlanner no longer triggers WARNING: An illegal reflective access operation has occurred
for XStream.
Code completion for solverConfig.xml and benchmarkConfig.xml through XSD
To validate XML configuration during development, add the new XML Schema Definition (XSD) on the solver or benchmark configuration:
<?xml version="1.0" encoding="UTF-8"?>
<solver xmlns="https://www.optaplanner.org/xsd/solver" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.optaplanner.org/xsd/solver https://www.optaplanner.org/xsd/solver/solver.xsd">
...
</solver>
This enables code completion for XML in most IDEs:
Improved Quarkus extension
The OptaPlanner Quarkus extension is now stable and displays no warnings when compiling Java to a native executable.
ScoreManager now supports score explanation
The ScoreManager
can now also explain why a solution has a certain score:
ScoreManager<TimeTable, HardSoftScore> scoreManager = ScoreManager.create(solverFactory);
...
ScoreExplanation<TimeTable, HardSoftScore> scoreExplanation = scoreManager.explain(timeTable);
System.out.println(scoreExplanation.getSummary());
...
Additionally, use scoreExplanation.getConstraintMatchTotalMap()
and scoreExplanation.getIndictmentMap()
to extract the ConstraintMatchTotal<HardSoftScore>
and Indictment<HardSoftScore>
information without triggering a new score calculation.