diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/AbstractSelector.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/AbstractSelector.java index fdedc4cfda4..df5da84b72a 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/AbstractSelector.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/AbstractSelector.java @@ -26,7 +26,7 @@ public abstract class AbstractSelector implements Selector @Override public void solvingStarted(SolverScope solverScope) { - workingRandom = solverScope.getWorkingRandom(); + workingRandom = solverScope.getMoveGeneratorWorkingRandom(); phaseLifecycleSupport.fireSolvingStarted(solverScope); } diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveSelector.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveSelector.java index 4d999214e6b..1acb99ed565 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveSelector.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/RuinRecreateMoveSelector.java @@ -55,7 +55,7 @@ public boolean isNeverEnding() { public void solvingStarted(SolverScope solverScope) { super.solvingStarted(solverScope); this.solverScope = solverScope; - this.workingRandom = solverScope.getWorkingRandom(); + this.workingRandom = solverScope.getMoveGeneratorWorkingRandom(); } @Override diff --git a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveSelector.java b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveSelector.java index c41a21ddd86..a291e7cd7ad 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveSelector.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/ruin/ListRuinRecreateMoveSelector.java @@ -70,7 +70,7 @@ public void solvingStarted(SolverScope solverScope) { this.listVariableStateSupply = solverScope.getScoreDirector() .getSupplyManager() .demand(listVariableDescriptor.getStateDemand()); - this.workingRandom = solverScope.getWorkingRandom(); + this.workingRandom = solverScope.getMoveGeneratorWorkingRandom(); } @Override diff --git a/core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/simulatedannealing/SimulatedAnnealingAcceptor.java b/core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/simulatedannealing/SimulatedAnnealingAcceptor.java index a8833327aed..fddc88627dd 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/simulatedannealing/SimulatedAnnealingAcceptor.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/simulatedannealing/SimulatedAnnealingAcceptor.java @@ -75,7 +75,7 @@ public boolean isAccepted(LocalSearchMoveScope moveScope) { } acceptChance *= acceptChanceLevel; } - return moveScope.getWorkingRandom().nextDouble() < acceptChance; + return moveScope.getSolverWorkingRandom().nextDouble() < acceptChance; } @Override diff --git a/core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/tabu/AbstractTabuAcceptor.java b/core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/tabu/AbstractTabuAcceptor.java index 893ff43a3a4..e3b7709661c 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/tabu/AbstractTabuAcceptor.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/tabu/AbstractTabuAcceptor.java @@ -143,7 +143,7 @@ public boolean isAccepted(LocalSearchMoveScope moveScope) { return false; } var acceptChance = calculateFadingTabuAcceptChance(tabuStepCount - workingTabuSize); - var accepted = moveScope.getWorkingRandom().nextDouble() < acceptChance; + var accepted = moveScope.getSolverWorkingRandom().nextDouble() < acceptChance; if (accepted) { logger.trace("{} Proposed move ({}) is fading tabu with acceptChance ({}) and is accepted.", logIndentation, diff --git a/core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/forager/AcceptedLocalSearchForager.java b/core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/forager/AcceptedLocalSearchForager.java index f751a18212e..a238cfe2cde 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/forager/AcceptedLocalSearchForager.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/localsearch/decider/forager/AcceptedLocalSearchForager.java @@ -121,7 +121,7 @@ public LocalSearchMoveScope pickMove(LocalSearchStepScope if (finalistList.size() == 1 || !breakTieRandomly) { return finalistList.get(0); } - int randomIndex = stepScope.getWorkingRandom().nextInt(finalistList.size()); + int randomIndex = stepScope.getSolverWorkingRandom().nextInt(finalistList.size()); return finalistList.get(randomIndex); } diff --git a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/NeighborhoodsBasedMoveRepository.java b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/NeighborhoodsBasedMoveRepository.java index ee7afd1041f..91e175d7111 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/NeighborhoodsBasedMoveRepository.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/neighborhood/NeighborhoodsBasedMoveRepository.java @@ -73,7 +73,7 @@ public void solvingStarted(SolverScope solverScope) { @Override public void phaseStarted(AbstractPhaseScope phaseScope) { - workingRandom = phaseScope.getWorkingRandom(); + workingRandom = phaseScope.getMoveGeneratorWorkingRandom(); phaseScope.getScoreDirector().setMoveRepository(this); } diff --git a/core/src/main/java/ai/timefold/solver/core/impl/phase/scope/AbstractMoveScope.java b/core/src/main/java/ai/timefold/solver/core/impl/phase/scope/AbstractMoveScope.java index 604360f09e5..ab94b248766 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/phase/scope/AbstractMoveScope.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/phase/scope/AbstractMoveScope.java @@ -66,8 +66,12 @@ public Solution_ getWorkingSolution() { return getStepScope().getWorkingSolution(); } - public RandomGenerator getWorkingRandom() { - return getStepScope().getWorkingRandom(); + public RandomGenerator getMoveGeneratorWorkingRandom() { + return getStepScope().getMoveGeneratorWorkingRandom(); + } + + public RandomGenerator getSolverWorkingRandom() { + return getStepScope().getSolverWorkingRandom(); } @Override diff --git a/core/src/main/java/ai/timefold/solver/core/impl/phase/scope/AbstractPhaseScope.java b/core/src/main/java/ai/timefold/solver/core/impl/phase/scope/AbstractPhaseScope.java index 60a9cdf0e41..707ba60ad3f 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/phase/scope/AbstractPhaseScope.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/phase/scope/AbstractPhaseScope.java @@ -239,8 +239,12 @@ public > void assertShadowVariablesAreNotStale(Inne innerScoreDirector.assertShadowVariablesAreNotStale(workingScore, completedAction); } - public RandomGenerator getWorkingRandom() { - return getSolverScope().getWorkingRandom(); + public RandomGenerator getMoveGeneratorWorkingRandom() { + return getSolverScope().getMoveGeneratorWorkingRandom(); + } + + public RandomGenerator getSolverWorkingRandom() { + return getSolverScope().getSolverWorkingRandom(); } public boolean isBestSolutionInitialized() { diff --git a/core/src/main/java/ai/timefold/solver/core/impl/phase/scope/AbstractStepScope.java b/core/src/main/java/ai/timefold/solver/core/impl/phase/scope/AbstractStepScope.java index 5f2e85e50bb..569533216b6 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/phase/scope/AbstractStepScope.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/phase/scope/AbstractStepScope.java @@ -66,8 +66,12 @@ public Solution_ getWorkingSolution() { return getPhaseScope().getWorkingSolution(); } - public RandomGenerator getWorkingRandom() { - return getPhaseScope().getWorkingRandom(); + public RandomGenerator getMoveGeneratorWorkingRandom() { + return getPhaseScope().getMoveGeneratorWorkingRandom(); + } + + public RandomGenerator getSolverWorkingRandom() { + return getPhaseScope().getSolverWorkingRandom(); } public Solution_ cloneWorkingSolution() { diff --git a/core/src/main/java/ai/timefold/solver/core/impl/solver/AbstractSolver.java b/core/src/main/java/ai/timefold/solver/core/impl/solver/AbstractSolver.java index d2b1b96afc3..6b8c89d5936 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/solver/AbstractSolver.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/solver/AbstractSolver.java @@ -48,7 +48,7 @@ public abstract class AbstractSolver implements Solver { protected final UniversalTermination globalTermination; protected final List> phaseList; - private RandomGenerator.@Nullable SplittableGenerator savedRandom; + private RandomGenerator.@Nullable SplittableGenerator savedMoveGeneratorRandom; // ************************************************************************ // Constructors and simple getters/setters @@ -131,16 +131,16 @@ public void stepStarted(AbstractStepScope stepScope) { globalTermination.stepStarted(stepScope); // To ensure reproducibility even when the number of random calls is not deterministic, // split the random at step start. - var delegatingRandom = ((DelegatingSplittableRandomGenerator) stepScope.getWorkingRandom()); - savedRandom = delegatingRandom.getDelegate(); + var delegatingRandom = ((DelegatingSplittableRandomGenerator) stepScope.getMoveGeneratorWorkingRandom()); + savedMoveGeneratorRandom = delegatingRandom.getDelegate(); delegatingRandom.setDelegate(delegatingRandom.split()); // Do not propagate to phases; the active phase does that for itself and they should not propagate further. } public void stepEnded(AbstractStepScope stepScope) { // Restore from the split random - var delegatingRandom = ((DelegatingSplittableRandomGenerator) stepScope.getWorkingRandom()); - delegatingRandom.setDelegate(Objects.requireNonNull(savedRandom)); + var delegatingRandom = ((DelegatingSplittableRandomGenerator) stepScope.getMoveGeneratorWorkingRandom()); + delegatingRandom.setDelegate(Objects.requireNonNull(savedMoveGeneratorRandom)); bestSolutionRecaller.stepEnded(stepScope); phaseLifecycleSupport.fireStepEnded(stepScope); globalTermination.stepEnded(stepScope); diff --git a/core/src/main/java/ai/timefold/solver/core/impl/solver/DefaultSolver.java b/core/src/main/java/ai/timefold/solver/core/impl/solver/DefaultSolver.java index 8541e0e6c01..af0fb3db649 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/solver/DefaultSolver.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/solver/DefaultSolver.java @@ -18,6 +18,7 @@ import ai.timefold.solver.core.impl.phase.Phase; import ai.timefold.solver.core.impl.score.director.InnerScoreDirector; import ai.timefold.solver.core.impl.score.director.ScoreDirectorFactory; +import ai.timefold.solver.core.impl.solver.random.DelegatingSplittableRandomGenerator; import ai.timefold.solver.core.impl.solver.recaller.BestSolutionRecaller; import ai.timefold.solver.core.impl.solver.scope.SolverScope; import ai.timefold.solver.core.impl.solver.termination.BasicPlumbingTermination; @@ -188,7 +189,7 @@ public void outerSolvingStarted(SolverScope solverScope) { solving.set(true); basicPlumbingTermination.resetTerminateEarly(); solverScope.setStartingSolverCount(0); - solverScope.setWorkingRandom(randomFactory.get()); + solverScope.setWorkingRandom((DelegatingSplittableRandomGenerator) randomFactory.get()); } @Override diff --git a/core/src/main/java/ai/timefold/solver/core/impl/solver/scope/SolverScope.java b/core/src/main/java/ai/timefold/solver/core/impl/solver/scope/SolverScope.java index 096557360de..39b3dd0b7aa 100644 --- a/core/src/main/java/ai/timefold/solver/core/impl/solver/scope/SolverScope.java +++ b/core/src/main/java/ai/timefold/solver/core/impl/solver/scope/SolverScope.java @@ -50,7 +50,8 @@ public class SolverScope { private Set solverMetricSet = Collections.emptySet(); private Tags monitoringTags; private int startingSolverCount; - private RandomGenerator workingRandom; + private RandomGenerator moveGeneratorWorkingRandom; + private RandomGenerator solverWorkingRandom; private InnerScoreDirector scoreDirector; private AbstractSolver solver; private DefaultProblemChangeDirector problemChangeDirector; @@ -143,12 +144,25 @@ public void setStartingSolverCount(int startingSolverCount) { this.startingSolverCount = startingSolverCount; } - public RandomGenerator getWorkingRandom() { - return workingRandom; + public RandomGenerator getMoveGeneratorWorkingRandom() { + return moveGeneratorWorkingRandom; } - public void setWorkingRandom(RandomGenerator workingRandom) { - this.workingRandom = workingRandom; + public RandomGenerator getSolverWorkingRandom() { + return solverWorkingRandom; + } + + /** + * Only used for tests + */ + public void setTestWorkingRandom(RandomGenerator workingRandom) { + this.moveGeneratorWorkingRandom = workingRandom; + this.solverWorkingRandom = workingRandom; + } + + public void setWorkingRandom(DelegatingSplittableRandomGenerator workingRandom) { + this.moveGeneratorWorkingRandom = workingRandom; + this.solverWorkingRandom = workingRandom.split(); } @SuppressWarnings("unchecked") @@ -354,9 +368,10 @@ public SolverScope createChildThreadSolverScope(ChildThreadType child childThreadSolverScope.solverMetricSet = solverMetricSet; childThreadSolverScope.startingSolverCount = startingSolverCount; // Experiments show that this trick to attain reproducibility doesn't break uniform distribution - var delegatingRandom = (DelegatingSplittableRandomGenerator) workingRandom; - childThreadSolverScope.workingRandom = + var delegatingRandom = (DelegatingSplittableRandomGenerator) moveGeneratorWorkingRandom; + childThreadSolverScope.moveGeneratorWorkingRandom = new DelegatingSplittableRandomGenerator(delegatingRandom.getSeed(), delegatingRandom.split()); + childThreadSolverScope.solverWorkingRandom = delegatingRandom.split(); childThreadSolverScope.scoreDirector = scoreDirector.createChildThreadScoreDirector(childThreadType); childThreadSolverScope.startingSystemTimeMillis.set(startingSystemTimeMillis.get()); resetAtomicLongTimeMillis(childThreadSolverScope.endingSystemTimeMillis); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/SelectorTestUtils.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/SelectorTestUtils.java index 1ea63a6df73..b0accb0d975 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/SelectorTestUtils.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/SelectorTestUtils.java @@ -219,7 +219,7 @@ public static > SolverScope s Selector... selectors) { SolverScope solverScope = new SolverScope<>(); solverScope.setScoreDirector(scoreDirector); - solverScope.setWorkingRandom(random); + solverScope.setTestWorkingRandom(random); listener.solvingStarted(solverScope); if (selectors != null) { for (var selector : selectors) { diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/entity/FromSolutionEntitySelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/entity/FromSolutionEntitySelectorTest.java index 3b6898891c8..646517a0bab 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/entity/FromSolutionEntitySelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/entity/FromSolutionEntitySelectorTest.java @@ -223,7 +223,7 @@ public void runRandomWithoutEntityListDirtyAndMinimumCacheType(SelectionCacheTyp Random workingRandom = new TestRandom(1, 0, 0, 2, 1, 2, 2, 1, 0); SolverScope solverScope = mock(SolverScope.class); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); when(solverScope.getScoreDirector()).thenReturn(scoreDirector); entitySelector.solvingStarted(solverScope); @@ -283,7 +283,7 @@ void randomWithEntityListDirty() { Random workingRandom = new TestRandom(1, 0, 0, 2, 1, 2, 2, 1, 0); SolverScope solverScope = mock(SolverScope.class); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); when(solverScope.getScoreDirector()).thenReturn(scoreDirector); entitySelector.solvingStarted(solverScope); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/entity/decorator/ProbabilityEntitySelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/entity/decorator/ProbabilityEntitySelectorTest.java index e05723a7747..2ccadcc4ff0 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/entity/decorator/ProbabilityEntitySelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/entity/decorator/ProbabilityEntitySelectorTest.java @@ -60,7 +60,7 @@ void randomSelection() { 1199.0 / 1234.0); SolverScope solverScope = mock(SolverScope.class); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); entitySelector.solvingStarted(solverScope); AbstractPhaseScope phaseScopeA = PlannerTestUtils.delegatingPhaseScope(solverScope); entitySelector.phaseStarted(phaseScopeA); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/entity/pillar/DefaultPillarSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/entity/pillar/DefaultPillarSelectorTest.java index a443bb65d80..9f5c1c72ff3 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/entity/pillar/DefaultPillarSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/entity/pillar/DefaultPillarSelectorTest.java @@ -181,7 +181,7 @@ void randomWithSubs() { TestRandom workingRandom = new TestRandom(0); SolverScope solverScope = mockSolverScope(); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); pillarSelector.solvingStarted(solverScope); AbstractPhaseScope phaseScopeA = PlannerTestUtils.delegatingPhaseScope(solverScope); @@ -265,7 +265,7 @@ void randomWithSubs_Size2() { 0, 0, 0, 0); // [b, d] SolverScope solverScope = mockSolverScope(); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); pillarSelector.solvingStarted(solverScope); AbstractPhaseScope phaseScopeA = PlannerTestUtils.delegatingPhaseScope(solverScope); @@ -315,7 +315,7 @@ void sequentialUnlimited() { ); SolverScope solverScope = mockSolverScope(); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); pillarSelector.solvingStarted(solverScope); AbstractPhaseScope phaseScopeA = PlannerTestUtils.delegatingPhaseScope(solverScope); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/list/ElementDestinationSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/list/ElementDestinationSelectorTest.java index 4f6311a356f..9129cfa54a6 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/list/ElementDestinationSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/list/ElementDestinationSelectorTest.java @@ -371,7 +371,7 @@ void randomPartiallyPinnedAndUnassigned() { var solverScope = new SolverScope(); solverScope.setScoreDirector(scoreDirector); - solverScope.setWorkingRandom(random); + solverScope.setTestWorkingRandom(random); var entitySelector = new FromSolutionEntitySelector<>( solutionDescriptor.findEntityDescriptorOrFail(TestdataPinnedUnassignedValuesListEntity.class), SelectionCacheType.PHASE, true); @@ -415,7 +415,7 @@ void randomUnassignedSingleEntity() { solverScope.setScoreDirector(scoreDirector); // This needs to use a real Random instance, otherwise the test never covers the situation where // the random value of 1 needs to be produced to get to the entity. - solverScope.setWorkingRandom(new Random(0)); + solverScope.setTestWorkingRandom(new Random(0)); var entitySelector = new FromSolutionEntitySelector<>( solutionDescriptor.findEntityDescriptorOrFail(TestdataAllowsUnassignedValuesListEntity.class), SelectionCacheType.PHASE, true); @@ -467,7 +467,7 @@ void randomFullyPinned() { var solverScope = new SolverScope(); solverScope.setScoreDirector(scoreDirector); - solverScope.setWorkingRandom(random); + solverScope.setTestWorkingRandom(random); selector.solvingStarted(solverScope); selector.phaseStarted(new LocalSearchPhaseScope<>(solverScope, 0)); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/UnionMoveSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/UnionMoveSelectorTest.java index d1a301e26fc..ff4ab3b5f04 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/UnionMoveSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/composite/UnionMoveSelectorTest.java @@ -104,7 +104,7 @@ void biasedRandomSelection() { 0.0, 999.0 / 1020.0); SolverScope solverScope = mock(SolverScope.class); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); moveSelector.solvingStarted(solverScope); AbstractPhaseScope phaseScopeA = PlannerTestUtils.delegatingPhaseScope(solverScope); moveSelector.phaseStarted(phaseScopeA); @@ -133,7 +133,7 @@ void uniformRandomSelection() { Random workingRandom = new TestRandom(0, 1, 1, 0, 0); SolverScope solverScope = mock(SolverScope.class); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); moveSelector.solvingStarted(solverScope); AbstractPhaseScope phaseScopeA = PlannerTestUtils.delegatingPhaseScope(solverScope); moveSelector.phaseStarted(phaseScopeA); @@ -162,7 +162,7 @@ void emptyUniformRandomSelection() { Random workingRandom = new TestRandom(1); SolverScope solverScope = mock(SolverScope.class); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); moveSelector.solvingStarted(solverScope); AbstractPhaseScope phaseScopeA = PlannerTestUtils.delegatingPhaseScope(solverScope); moveSelector.phaseStarted(phaseScopeA); @@ -195,7 +195,7 @@ void emptyBiasedRandomSelection() { Random workingRandom = new TestRandom(1); SolverScope solverScope = mock(SolverScope.class); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); moveSelector.solvingStarted(solverScope); AbstractPhaseScope phaseScopeA = PlannerTestUtils.delegatingPhaseScope(solverScope); moveSelector.phaseStarted(phaseScopeA); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/CachingMoveSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/CachingMoveSelectorTest.java index c70776256d2..437da7bb2f4 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/CachingMoveSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/CachingMoveSelectorTest.java @@ -121,7 +121,7 @@ public void runRandomSelection(SelectionCacheType cacheType, int timesCalled) { TestRandom workingRandom = new TestRandom(1, 0, 2); SolverScope solverScope = mock(SolverScope.class); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); moveSelector.solvingStarted(solverScope); AbstractPhaseScope phaseScopeA = PlannerTestUtils.delegatingPhaseScope(solverScope); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ProbabilityMoveSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ProbabilityMoveSelectorTest.java index 8d16512fe22..386954e3772 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ProbabilityMoveSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ProbabilityMoveSelectorTest.java @@ -57,7 +57,7 @@ void randomSelection() { 1199.0 / 1234.0); SolverScope solverScope = mock(SolverScope.class); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); moveSelector.solvingStarted(solverScope); AbstractPhaseScope phaseScopeA = PlannerTestUtils.delegatingPhaseScope(solverScope); moveSelector.phaseStarted(phaseScopeA); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ShufflingMoveSelectorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ShufflingMoveSelectorTest.java index 7505daab8d5..698ec6af01c 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ShufflingMoveSelectorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/decorator/ShufflingMoveSelectorTest.java @@ -45,7 +45,7 @@ public void run(SelectionCacheType cacheType, int timesCalled) { TestRandom workingRandom = new TestRandom(2, 0); SolverScope solverScope = mock(SolverScope.class); - when(solverScope.getWorkingRandom()).thenReturn(workingRandom); + when(solverScope.getMoveGeneratorWorkingRandom()).thenReturn(workingRandom); moveSelector.solvingStarted(solverScope); AbstractPhaseScope phaseScopeA = PlannerTestUtils.delegatingPhaseScope(solverScope); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/simulatedannealing/SimulatedAnnealingAcceptorTest.java b/core/src/test/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/simulatedannealing/SimulatedAnnealingAcceptorTest.java index f0dd4e7875e..b1cb1f03a04 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/simulatedannealing/SimulatedAnnealingAcceptorTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/localsearch/decider/acceptor/simulatedannealing/SimulatedAnnealingAcceptorTest.java @@ -33,11 +33,11 @@ void lateAcceptanceSize() { stepScope0.setTimeGradient(0.0); acceptor.stepStarted(stepScope0); var moveScope0 = buildMoveScope(stepScope0, -500); - solverScope.setWorkingRandom(new TestRandom(0.3)); + solverScope.setTestWorkingRandom(new TestRandom(0.3)); assertThat(acceptor.isAccepted(buildMoveScope(stepScope0, -1300))).isFalse(); - solverScope.setWorkingRandom(new TestRandom(0.3)); + solverScope.setTestWorkingRandom(new TestRandom(0.3)); assertThat(acceptor.isAccepted(buildMoveScope(stepScope0, -1200))).isTrue(); - solverScope.setWorkingRandom(new TestRandom(0.4)); + solverScope.setTestWorkingRandom(new TestRandom(0.4)); assertThat(acceptor.isAccepted(buildMoveScope(stepScope0, -1200))).isFalse(); assertThat(acceptor.isAccepted(moveScope0)).isTrue(); stepScope0.setStep(moveScope0.getMove()); @@ -50,11 +50,11 @@ void lateAcceptanceSize() { stepScope1.setTimeGradient(0.5); acceptor.stepStarted(stepScope1); var moveScope1 = buildMoveScope(stepScope1, -800); - solverScope.setWorkingRandom(new TestRandom(0.13)); + solverScope.setTestWorkingRandom(new TestRandom(0.13)); assertThat(acceptor.isAccepted(buildMoveScope(stepScope1, -700))).isTrue(); - solverScope.setWorkingRandom(new TestRandom(0.14)); + solverScope.setTestWorkingRandom(new TestRandom(0.14)); assertThat(acceptor.isAccepted(buildMoveScope(stepScope1, -700))).isFalse(); - solverScope.setWorkingRandom(new TestRandom(0.04)); + solverScope.setTestWorkingRandom(new TestRandom(0.04)); assertThat(acceptor.isAccepted(moveScope1)).isTrue(); stepScope1.setStep(moveScope1.getMove()); stepScope1.setScore(moveScope1.getScore()); @@ -62,7 +62,7 @@ void lateAcceptanceSize() { acceptor.stepEnded(stepScope1); phaseScope.setLastCompletedStepScope(stepScope1); - solverScope.setWorkingRandom(new TestRandom(0.01, 0.01)); + solverScope.setTestWorkingRandom(new TestRandom(0.01, 0.01)); var stepScope2 = new LocalSearchStepScope<>(phaseScope); stepScope2.setTimeGradient(1.0); acceptor.stepStarted(stepScope2); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/localsearch/decider/forager/AcceptedLocalSearchForagerTest.java b/core/src/test/java/ai/timefold/solver/core/impl/localsearch/decider/forager/AcceptedLocalSearchForagerTest.java index 7805e9c68bc..cc167efb8bd 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/localsearch/decider/forager/AcceptedLocalSearchForagerTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/localsearch/decider/forager/AcceptedLocalSearchForagerTest.java @@ -219,7 +219,7 @@ private static LocalSearchPhaseScope createPhaseScope() { when(scoreDirector.getScoreDefinition()).thenReturn(new SimpleScoreDefinition()); solverScope.setScoreDirector(scoreDirector); Random workingRandom = new TestRandom(1, 1); - solverScope.setWorkingRandom(workingRandom); + solverScope.setTestWorkingRandom(workingRandom); solverScope.setInitializedBestScore(SimpleScore.of(-10)); solverScope.setSolverMetricSet(EnumSet.of(SolverMetric.MOVE_EVALUATION_COUNT)); LocalSearchStepScope lastLocalSearchStepScope = new LocalSearchStepScope<>(phaseScope); diff --git a/core/src/test/java/ai/timefold/solver/core/impl/neighborhood/NeighborhoodsTest.java b/core/src/test/java/ai/timefold/solver/core/impl/neighborhood/NeighborhoodsTest.java index a94afe7c3b1..f8f78596209 100644 --- a/core/src/test/java/ai/timefold/solver/core/impl/neighborhood/NeighborhoodsTest.java +++ b/core/src/test/java/ai/timefold/solver/core/impl/neighborhood/NeighborhoodsTest.java @@ -99,7 +99,7 @@ void changeMoveBasedLocalSearch() { bestSolutionRecaller.setSolverEventSupport(solverEventSupport); var solverScope = new SolverScope(); solverScope.setSolver(solver); - solverScope.setWorkingRandom(new Random()); + solverScope.setTestWorkingRandom(new Random()); solverScope.setScoreDirector(scoreDirector); solverScope.setBestScore(score); solverScope.setBestSolution(scoreDirector.cloneSolution(solution)); diff --git a/core/src/test/java/ai/timefold/solver/core/testutil/PlannerTestUtils.java b/core/src/test/java/ai/timefold/solver/core/testutil/PlannerTestUtils.java index 4f8c99eb3c5..c41b6e9c5e7 100644 --- a/core/src/test/java/ai/timefold/solver/core/testutil/PlannerTestUtils.java +++ b/core/src/test/java/ai/timefold/solver/core/testutil/PlannerTestUtils.java @@ -217,7 +217,7 @@ public static , Y> SortedMap asSortedMap(X x1, Y y // ************************************************************************ /** - * Returns {@link AbstractPhaseScope} instance that will delegate to {@link SolverScope#getWorkingRandom()}. + * Returns {@link AbstractPhaseScope} instance that will delegate to {@link SolverScope#getMoveGeneratorWorkingRandom()}. * * @param solverScope never null * @param generic type of the solution @@ -233,7 +233,8 @@ public AbstractStepScope getLastCompletedStepScope() { } /** - * Returns {@link AbstractPhaseScope} instance that will delegate to {@link AbstractPhaseScope#getWorkingRandom()}. + * Returns {@link AbstractPhaseScope} instance that will delegate to + * {@link AbstractPhaseScope#getMoveGeneratorWorkingRandom()}. * * @param phaseScope never null * @param generic type of the solution