OptaPlanner logo
  • Download
  • Learn
    • Documentation
    • Videos
    • Slides
    • Training

    • Use cases
    • Compatibility
    • Testimonials and case studies
  • Get help
  • Blog
  • Source
  • Team
  • Services
  • KIE
    • Drools
    • OptaPlanner
    • jBPM
    • Kogito
  • Star
  • T
  • L
  • F
  • YT
Fork me on GitHub

Upgrade recipe 6.2

OptaPlanner’s public API classes are backwards compatible (per series), but users often also use impl classes (which are documented in the reference manual too). This upgrade recipe minimizes the pain to upgrade your code and to take advantage of the newest features in OptaPlanner 8.

Legend

Every upgrade note has an indication how likely your code will be affected by that change:

  • Major Likely to affect your code.
  • Minor Unlikely to affect your code (especially if you followed the examples), unless you have hacks.
  • Impl detail Will not affect your code, unless you have very deep hacks.
  • Recommended Not a backward incompatible change, but you probably want to do this.
  • Readme Read this to better understand why the subsequent major changes were made.

Upgrade from an older version

To upgrade from an older version, first apply the previous upgrade recipes.

Note for Red Hat Decision Manager customers

The RHDM version differs from the OptaPlanner version:

RHDM version OptaPlanner version
7.8 7.39
7.9 7.44
7.1 7.48
7.11 8.5 (and 7.52)
7.12 8.11 (and 7.59)

From 6.1.0.Final to 6.2.0.Beta1

Custom ScoreDefinition: ScoreHolder.register*ConstraintMatch refactored

If you have a custom ScoreDefinition: the methods ScoreHolder.register*ConstraintMatch have been refactored.

Before in *.java:

public void addConstraintMatch(RuleContext kcontext, final int weight) {
    ...
    registerIntConstraintMatch(kcontext, 0, weight, new Runnable() {
        public void run() {
            ...
        }
    });
}

After in *.java:

public void addConstraintMatch(RuleContext kcontext, final int weight) {
    ...
    registerIntConstraintMatch(kcontext, 0, weight, new IntConstraintUndoListener() {
        public void undo() {
            ...
        }
    });
}

Custom Move: extract AbstractMove

If you have a custom Move implementation, now extract AbstractMove

Before in *.java:

public class CloudComputerChangeMove implements Move {...}

After in *.java:

public class CloudComputerChangeMove extends AbstractMove {...}

Custom Move: new method getSimpleMoveTypeDescription()

The interface Move has a new method getSimpleMoveTypeDescription(). Extend AbstractMove so to avoid having to implement it.

@ValueRangeProvider on an entity class: use pillar selectors as is

If you have a @ValueRangeProvider on an entity class (instead of the Solution class), then it’s now safe to use the <pillarChangeMoveSelector> and <pillarSwapMoveSelector> as is. It’s no longer needed to filter out swaps or changes which could put a value in an entity’s variable that’s not in its value range.

Before in *SolverConfig.xml and *BenchmarkConfig.xml:

  <pillarChangeMoveSelector>
    <filterClass>...ValidChangesOnlyPillarChangeMoveFilter</filterClass>
  </pillarChangeMoveSelector>
  <pillarSwapMoveSelector>
    <filterClass>...ValidSwapsOnlyPillarSwapMoveFilter</filterClass>
  </pillarSwapMoveSelector>

After in *SolverConfig.xml and *BenchmarkConfig.xml:

  <pillarChangeMoveSelector/>
  <pillarSwapMoveSelector/>

ConstraintMatchTotal natural comparison changed

ConstraintMatchTotal are now naturally compared by scoreLevel, then constraintPackage, then constraintName (instead of by constraintPackage, then constraintName, then scoreLevel) for readability.

IncrementalScoreCalculator: method buildScoreCorruptionAnalysis(…​) replaced

The optional method IncrementalScoreCalculator.buildScoreCorruptionAnalysis(IncrementalScoreCalculator) has been removed. Instead, to get a pretty score corruption analysis, implement the new interface ConstraintMatchAwareIncrementalScoreCalculator. This also enable your GUI to explain the score with an IncrementalScoreCalculator. See the example code in MachineReassignmentIncrementalScoreCalculator.getConstraintMatchTotals().

From 6.2.0.Beta1 to 6.2.0.Beta2

<deciderScoreComparatorFactory> removed

The element <deciderScoreComparatorFactory> (which was deprecated, not documented, broken and clearly marked as not backwards compatible) has been removed. Instead, use strategic oscillation.

Before in *SolverConfig.xml and *BenchmarkConfig.xml:

  <localSearch>
...
<forager>
  ...
  <deciderScoreComparatorFactory>
    ...
  </deciderScoreComparatorFactory>
</forager>
  </localSearch>

After in *SolverConfig.xml and *BenchmarkConfig.xml:

  <localSearch>
...
<forager>
  ...
  <finalistPodiumType>STRATEGIC_OSCILLATION</finalistPodiumType>
</forager>
  </localSearch>

ScoreBounder methods changed

The ScoreBounder methods calculateOptimisticBound() and calculatePessimisticBound() no longer have an uninitializedVariableCount parameter. Instead, if all the variables for a branch and bound algorithm are initialized, those methods are no longer called to determine the bounds (because the bound is the working score). If the uninitializedVariableCount is still needed for some reason, use the ScoreDirector to calculate it accurately.

ScoreDirector.getConstraintMatchTotals() behaviour changed

Before calling ScoreDirector.getConstraintMatchTotals(), it’s no longer expected to call ScoreDirector.calculateScore() first.

From 6.2.0.CR1 to 6.2.0.CR2

CompositeMove now uses a Move array

CompositeMove now uses a Move array instead of a List<Move> for performance reasons.

Before in *.java:

... = CompositeMove.buildMove(Arrays.asList(moveA, moveB, ...));

After in *.java:

... = CompositeMove.buildMove(moveA, moveB, ...);

Before in *.java:

... = new CompositeMove(moveList); // Not recommended

After in *.java:

... = new CompositeMove(moves); // Not recommended

InverseRelationShadowVariableListener renamed

InverseRelationShadowVariableListener renamed to SingletonInverseVariableListener. It and InverseRelationShadowVariableDescriptor moved to the package …​impl.domain.variable.inverserelation.

From 6.2.0.CR3 to 6.2.0.CR4

New anchor shadow variable support

There is now out-of-the-box support for a shadow variable representing the anchor of a chained variable. For example, in a VRP each Customer (= entity) needs to know to which Vehicle (= anchor) it belongs. This declarative support allows built-in selectors to reuse that knowledge without duplicating the calculation.

Before in *.java:

@PlanningEntity
public class Customer implements Standstill {
    @PlanningVariable(...)
    public Standstill getPreviousStandstill() {...}
    @CustomShadowVariable(variableListenerClass = VehicleUpdatingVariableListener.class,
            sources = {@CustomShadowVariable.Source(variableName = "previousStandstill")})
    public Vehicle getVehicle() {...}
}
public class VehicleUpdatingVariableListener implements VariableListener<Customer> {
    ...
}

After in *.java:

@PlanningEntity
public class Customer implements Standstill {
    @PlanningVariable(...)
    public Standstill getPreviousStandstill() {...}
    @AnchorShadowVariable(sourceVariableName = "previousStandstill")
    public Vehicle getVehicle() {...}
}

From 6.2.0.CR4 to 6.2.0.Final

<twoOptMoveSelector> replaced

The undocumented, experimental <twoOptMoveSelector> has been replaced by <tailChainSwapMoveSelector>, which is documented.

VRP: Nearby Selection

To scale VRP cases, Nearby Selection is critical. It is now finally completely supported and documented.

Latest release
  • 8.23.0.Final released
    Thu 23 June 2022
Upcoming events
    Add event / Archive
Latest blog posts
  • Run OptaPlanner workloads on OpenShift, part I.
    Thu 9 June 2022
    Radovan Synek
  • OptaPlanner deprecates score DRL
    Thu 26 May 2022
    Lukáš Petrovický
  • Real-time planning meets SolverManager
    Mon 7 March 2022
    Radovan Synek
  • OptaPlanner documentation turns over a new leaf
    Tue 26 October 2021
    Radovan Synek
  • Order picking optimization in warehouses and supermarkets with OptaPlanner
    Thu 14 October 2021
    Walter Medvedeo
  • Monitor OptaPlanner solvers through Micrometer
    Tue 12 October 2021
    Christopher Chianelli
  • A new AI constraint solver for Python: OptaPy
    Tue 5 October 2021
    Christopher Chianelli
  • Blog archive
Latest videos
  • Host your OptaPlanner app on OpenShift (Kubernetes)
    Mon 7 February 2022
    Geoffrey De Smet
  • OptaPlanner - A fast, easy-to-use, open source AI constraint solver for software developers
    Mon 31 January 2022
  • Order picking planning with OptaPlanner
    Fri 31 December 2021
    Anna Dupliak
  • AI lesson scheduling on Quarkus with OptaPlanner
    Thu 18 November 2021
    Geoffrey De Smet
  • Maintenance scheduling
    Fri 12 November 2021
    Geoffrey De Smet
  • Optimized order picking in warehouses and supermarkets
    Tue 26 October 2021
    Walter Medvedeo
  • A modern OO/FP constraint solver
    Tue 14 September 2021
    Geoffrey De Smet
  • Video archive

OptaPlanner is open. All dependencies of this project are available under the Apache Software License 2.0 or a compatible license. OptaPlanner is trademarked.

This website was built with JBake and is open source.

Community

  • Blog
  • Get Help
  • Team
  • Governance
  • Academic research

Code

  • Build from source
  • Issue tracker
  • Release notes
  • Upgrade recipes
  • Logo and branding

KIE projects

  • Drools rule engine
  • OptaPlanner constraint solver
  • jBPM workflow engine
  • Kogito Business Automation platform
CC by 3.0 | Privacy Policy
Sponsored by Red Hat