Search code examples
multithreadingoptaplanner

Optaplanner multithreading attempt yielded "missing rebase" on custom move


I updated from 7.5 to 7.9 Optaplanner libraries for use with a variant of the nurserostering code, and used the release notes (for example, some method names changed) to successfully rebuild and re-run. Then, I added the "moveThreadCount" xml line (for multithreading) to my solver config xml. <moveThreadCount>AUTO</moveThreadCount>

Running then immediately threw an error: Caused by: java.lang.UnsupportedOperationException: The custom move class (class westgranite.staffrostering.solver.move.EmployeeChangeMove) doesn't implement the rebase() method, so multithreaded solving is impossible.

I do have a number of custom moves. I did not see any reference to the need to add a rebase() method in the release notes, nor do I see a reference to rebase() in the current (newer) documentation section on building custom moves. https://docs.optaplanner.org/7.12.0.Final/optaplanner-docs/html_single/index.html#customMoves

Would someone please point me the right way? Thanks!


Solution

  • I would suggest reading this excellent blog post: http://www.optaplanner.org/blog/2018/07/03/AGiantLeapForwardWithMultithreadedIncrementalSolving.html as it gives a more in depth explanation of how multithreaded solving works.

    I also suggest to read the javadoc on the rebase method, it should point you in the right direction: https://docs.optaplanner.org/7.12.0.Final/optaplanner-javadoc/org/optaplanner/core/impl/heuristic/move/Move.html#rebase-org.optaplanner.core.impl.score.director.ScoreDirector-

    Here's an example:

    public class CloudComputerChangeMove extends AbstractMove<CloudBalance> {
    
        private CloudProcess cloudProcess;
        private CloudComputer toCloudComputer;
    
        ...
    
        @Override
        public CloudComputerChangeMove rebase(ScoreDirector<CloudBalance> destinationScoreDirector) {
            return new CloudComputerChangeMove(
                    destinationScoreDirector.lookUpWorkingObject(cloudProcess),
                    destinationScoreDirector.lookUpWorkingObject(toCloudComputer));
        }
    
    }