Repository navigation
feat: weighted move selection for neighborhoods - #2812
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Active issues can cause exhausted weighted neighborhoods to throw, valid explicit provider selections to fail, and wrapped samplers to produce unstable provider IDs.
3 open issues
What changed in this PR
This PR adds weighted move selection to the preview Neighborhoods API. It connects selection strategies to Local Search phases and adds configuration support across the solver, Spring Boot, and Quarkus.
Changes:
- Adds selection strategies, lifecycle contexts, and move-provider IDs.
- Adds solver-level and phase-level settings, custom properties, and shared random choosers.
- Adds integration discovery, tests, XML schema updates, and user documentation.
| File | Description |
|---|---|
| tools/benchmark/src/main/resources/benchmark.xsd | Updated as part of this pull request. |
| spring-integration/spring-boot-integration-test/src/test/resources/solver-full.xml | Updated as part of this pull request. |
| spring-integration/spring-boot-integration-test/src/test/java/ai/timefold/solver/spring/boot/it/TimefoldSolverTestResourceIntegrationTest.java | Updated as part of this pull request. |
| spring-integration/spring-boot-autoconfigure/src/test/resources/ai/timefold/solver/spring/boot/autoconfigure/neighborhoodSinglePhaseLevelSolverConfig.xml | Updated as part of this pull request. |
| spring-integration/spring-boot-autoconfigure/src/test/resources/ai/timefold/solver/spring/boot/autoconfigure/neighborhoodPhaseLevelSolverConfig.xml | Updated as part of this pull request. |
| spring-integration/spring-boot-autoconfigure/src/test/java/ai/timefold/solver/spring/boot/autoconfigure/TimefoldSolverNeighborhoodAutoConfigurationTest.java | Updated as part of this pull request. |
| spring-integration/spring-boot-autoconfigure/src/test/java/ai/timefold/solver/spring/boot/autoconfigure/neighborhood/single/TestdataSpringNeighborhoodProvider.java | Updated as part of this pull request. |
| spring-integration/spring-boot-autoconfigure/src/test/java/ai/timefold/solver/spring/boot/autoconfigure/neighborhood/single/TestdataSpringMoveSelectionStrategy.java | Updated as part of this pull request. |
| spring-integration/spring-boot-autoconfigure/src/test/java/ai/timefold/solver/spring/boot/autoconfigure/neighborhood/NeighborhoodSpringTestConfiguration.java | Updated as part of this pull request. |
| spring-integration/spring-boot-autoconfigure/src/test/java/ai/timefold/solver/spring/boot/autoconfigure/neighborhood/MultipleNeighborhoodSpringTestConfiguration.java | Updated as part of this pull request. |
| spring-integration/spring-boot-autoconfigure/src/test/java/ai/timefold/solver/spring/boot/autoconfigure/neighborhood/multiple/TestdataOtherSpringNeighborhoodProvider.java | Updated as part of this pull request. |
| spring-integration/spring-boot-autoconfigure/src/test/java/ai/timefold/solver/spring/boot/autoconfigure/neighborhood/multiple/TestdataOtherSpringMoveSelectionStrategy.java | Updated as part of this pull request. |
| spring-integration/spring-boot-autoconfigure/src/main/java/ai/timefold/solver/spring/boot/autoconfigure/TimefoldSolverAutoConfiguration.java | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/test/resources/ai/timefold/solver/quarkus/neighborhoodSinglePhaseLevelSolverConfig.xml | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/test/resources/ai/timefold/solver/quarkus/neighborhoodPhaseLevelSolverConfig.xml | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/TimefoldProcessorNeighborhoodUnusedTest.java | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/TimefoldProcessorNeighborhoodPhaseLevelTest.java | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/TimefoldProcessorNeighborhoodNamedSolversTest.java | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/TimefoldProcessorNeighborhoodMultipleTest.java | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/TimefoldProcessorNeighborhoodIgnoredTest.java | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/TimefoldProcessorNeighborhoodDetectionTest.java | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/testdomain/neighborhood/TestdataQuarkusNeighborhoodProvider.java | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/testdomain/neighborhood/TestdataQuarkusMoveSelectionStrategy.java | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/testdomain/neighborhood/OtherQuarkusNeighborhoodProvider.java | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/test/java/ai/timefold/solver/quarkus/testdomain/neighborhood/OtherQuarkusMoveSelectionStrategy.java | Updated as part of this pull request. |
| quarkus-integration/quarkus/deployment/src/main/java/ai/timefold/solver/quarkus/deployment/TimefoldProcessor.java | Updated as part of this pull request. |
| docs/src/modules/ROOT/pages/running-timefold-solver/library/spring-boot.adoc | Updated as part of this pull request. |
| docs/src/modules/ROOT/pages/running-timefold-solver/library/quarkus.adoc | Updated as part of this pull request. |
| docs/src/modules/ROOT/pages/optimization-algorithms/neighborhoods.adoc | Updated as part of this pull request. |
| core/src/test/resources/ai/timefold/solver/core/config/solver/testSolverConfigWithoutNamespace.xml | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/neighborhood/selection/FixedWeightMoveSelectionStrategyTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/UnassignMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/TwoOptListMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/SwapMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/SubPillarUnassignMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/SubPillarSwapMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/SubPillarChangeMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/SubListUnassignMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/SubListSwapMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/SubListChangeMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/PillarUnassignMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/PillarSwapMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/PillarChangeMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/MassUnassignMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/MassListUnassignMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/MassListChangeMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/MassListAssignMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/MassChangeMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/MassAssignMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/ListUnassignMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/ListTailSwapMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/ListSwapMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/ListChangeMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/ListAssignMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/ChangeMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/AssignMoveProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/impl/solver/SolverLevelClassDetectorTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/impl/solver/random/UniformRandomChooserTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/impl/solver/random/BiasedRandomChooserTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/impl/score/director/ScoreDirectorFactoryFactoryTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/impl/neighborhood/stream/DefaultNeighborhoodTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/impl/neighborhood/stream/DefaultNeighborhoodBuilderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/impl/neighborhood/selection/StrategyUnionMoveIteratorTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/impl/neighborhood/NeighborhoodsTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/impl/neighborhood/DefaultNeighborhoodProviderTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/impl/neighborhood/bias/MixedMoveSelectorSplitBiasIT.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/impl/neighborhood/bias/FixedWeightMoveSelectionStrategyBiasIT.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/UnionMoveSelectorTest.java | Updated as part of this pull request. |
| core/src/test/java/ai/timefold/solver/core/config/solver/SolverConfigTest.java | Updated as part of this pull request. |
| core/src/main/resources/solver.xsd | Updated as part of this pull request. |
| core/src/main/java/module-info.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/Samplers.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/Sampler.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/PillarSampler.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/DefaultSampler.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/selection/StepContext.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/selection/PhaseContext.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/selection/package-info.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/selection/MoveSource.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/selection/MoveSelectionStrategy.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/selection/FixedWeightMoveSelectionStrategy.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/NeighborhoodBuilder.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/MoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/UnassignMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/TwoOptListMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/SwapMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/SubPillarUnassignMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/SubPillarSwapMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/SubPillarChangeMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/SubListUnassignMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/SubListSwapMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/SubListChangeMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/PillarUnassignMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/PillarSwapMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/PillarChangeMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassUnassignMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassListUnassignMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassListChangeMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassListAssignMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassChangeMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassAssignMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ListUnassignMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ListTailSwapMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ListSwapMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ListChangeMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ListAssignMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ChangeMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/AssignMoveProvider.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/solver/SolverLevelClassDetector.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/solver/random/UniformRandomChooser.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/solver/random/BiasedRandomChooser.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/solver/DefaultSolverFactory.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/score/director/incremental/IncrementalScoreDirectorFactory.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/DefaultNeighborhoodBuilder.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/DefaultNeighborhood.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/neighborhood/selection/StrategyUnionMoveIterator.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/neighborhood/selection/DefaultMoveSource.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/neighborhood/selection/DefaultMoveSelectionContext.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/neighborhood/NeighborhoodsBasedMoveRepository.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/neighborhood/DefaultNeighborhoodTester.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/move/UniformRandomUnionMoveIterator.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/move/builtin/MoveProviderUtil.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/localsearch/DefaultLocalSearchPhaseFactory.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/UnionMoveSelector.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/BiasedRandomUnionMoveIterator.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/impl/heuristic/HeuristicConfigPolicy.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/config/util/ConfigUtils.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/config/solver/SolverConfig.java | Updated as part of this pull request. |
| core/src/main/java/ai/timefold/solver/core/config/localsearch/LocalSearchPhaseConfig.java | Updated as part of this pull request. |
| core/src/build/revapi-differences.json | Updated as part of this pull request. |
Review effort: Balanced
|
This pull request, as it stands, would leave the Solver documentation stale in the place below. An automated check found it and can be wrong. Upgrade note gives the wrong default ID for built-in move providers
Suggested edit: A move provider added with `add(moveProvider)` gets a default ID.
For a built-in move provider, the ID contains its variable and its settings;
the Javadoc of each built-in move provider describes it.
For your own move provider, the default ID is the simple name of its class,
or `custom` for a lambda or an anonymous class.
A neighborhood that adds two move providers with the same default ID,
such as two instances of your own move provider class or two lambdas,
now fails when it is built.The fix goes into this pull request. A new commit on the branch updates this comment. Drift that is still here when the group merges gets a docs pull request against Generated by Solver Docs Drift Review with Claude. |
zepfred
left a comment
There was a problem hiding this comment.
The changes look great to me. I have one question regarding the swap moves that are unrelated to these changes. It's possible we already know the answer, or we could run an experiment to see if it makes sense.
There was a problem hiding this comment.
🔵 Needs a closer look
Human assessment is needed because reflection-dependent sampler identification can break native neighborhood construction, compounded by subtle iterator-state sharing and subnormal-weight selection errors.
No open issues 🎉
1 resolved since last review
Review effort: Balanced
There was a problem hiding this comment.
🔵 Needs a closer look
Human assessment is needed to evaluate native-image startup failures caused by missing reflective setter invocation support and biased selection probabilities for equal subnormal weights.
No open issues 🎉
Review effort: Balanced

Looks large-ish on the surface, but actually only 40 % of this is impl code.
50 % is test coverage, and the rest is docs, XML etc.