Toggle navigation OptaPlanner logo
  • Home
  • Download
  • Learn
    • Documentation
    • Videos
    • Slides
    • Training
    • Use cases
    • Compatibility
    • Testimonials and case studies
  • Get help
  • Source
  • Team
  • Services
  • Star
  • @OptaPlanner
  • Fb
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 6.2.

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.7 7.33
7.8 7.39
7.9 7.44

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 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.

Comments

Visit our forum to comment
Latest release
  • 8.1.0.Final released
    Fri 15 January 2021
Paid support and consulting

Want to talk to the experts? Red Hat offers certified binaries with enterprise consulting. Contact optaplanner-info for more information.

Upcoming events
  • KIE Live
    Worldwide - Tue 19 January 2021
    • OptaPlanner Shadow Variables for the Vehicle Routing Problem and Task Assignment by Geoffrey De Smet, Karina Varela, Alex Porcelli
  • Javaland
    Worldwide - Tue 16 March 2021
    • AI on Quarkus: I love it when an OptaPlan comes together by Geoffrey De Smet
Add event / Archive
Latest blog posts
  • Solve the facility location problem
    Fri 9 October 2020
     Jiří Locker
  • OptaPlanner Week 2020 recordings
    Mon 7 September 2020
     Geoffrey De Smet
  • Let’s OptaPlan your jBPM tasks (part 1) - Integrating the two worlds
    Fri 3 July 2020
     Walter Medvedeo
  • AI versus Covid-19: How Java helps nurses and doctors in this fight
    Fri 8 May 2020
     Christopher Chianelli
  • Workflow processes with AI scheduling
    Tue 5 May 2020
     Christopher Chianelli
  • Constraint Streams - Modern Java constraints without the Drools Rule Language
    Tue 7 April 2020
     Geoffrey De Smet
  • How to plan (and optimize) a Secret Santa
    Wed 18 December 2019
     Christopher Chianelli
Blog archive
Latest videos
  • YT Shadow variables
    Tue 19 January 2021
     Geoffrey De Smet
  • YT Domain modeling and design patterns
    Tue 17 November 2020
     Geoffrey De Smet
  • YT Quarkus insights: AI constraint solving
    Tue 20 October 2020
     Geoffrey De Smet
  • YT AI in kotlin
    Wed 23 September 2020
     Geoffrey De Smet
  • YT Planning agility: continuous planning, real-time planning and more
    Thu 3 September 2020
     Geoffrey De Smet
  • YT Quarkus and OptaPlanner: create a school timetable application
    Thu 3 September 2020
     Radovan Synek
  • YT Business use cases and the impact of OptaPlanner
    Thu 3 September 2020
     Satish Kale
Video archive

KIE projects

  • Drools rule engine
  • OptaPlanner constraint solver
  • jBPM workflow engine

Community

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

Code

  • Build from source
  • Submit a bug
  • License (Apache-2.0)
  • Release notes
  • Upgrade recipes
Sponsored by
Red Hat
More coder content at
Red Hat Developers
© Copyright 2006-2021, Red Hat, Inc. or third-party contributors - Privacy statement - Terms of use - Website info