Skip to content

Commit

Permalink
feat: reset stuck criterion after an improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
zepfred committed Feb 7, 2025
1 parent 6f568f8 commit 7d2d0f3
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ public boolean isSolverStuck(LocalSearchMoveScope<Solution_> moveScope) {
var triggered = evaluateCriterion(moveScope);
if (triggered) {
logger.info(
"Restart triggered with geometric factor {}, scaling factor of {}, best score ({})",
currentGeometricGrowFactor,
scalingFactor, moveScope.getStepScope().getPhaseScope().getBestScore());
"Restart triggered with geometric factor ({}), scaling factor of ({}), nextRestart ({}), best score ({})",
currentGeometricGrowFactor, scalingFactor, nextRestart,
moveScope.getStepScope().getPhaseScope().getBestScore());
currentGeometricGrowFactor = Math.ceil(currentGeometricGrowFactor * GEOMETRIC_FACTOR);
nextRestart = calculateNextRestart();
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class DiminishedReturnsStuckCriterion<Solution_, Score_ extends Score<Sco
private DiminishedReturnsTermination<Solution_, Score_> diminishedReturnsCriterion;

private boolean triggered;
private Score_ currentBestScore;

public DiminishedReturnsStuckCriterion() {
this(new DiminishedReturnsTermination<>(TIME_WINDOW_MILLIS, MINIMAL_IMPROVEMENT));
Expand All @@ -38,6 +39,7 @@ boolean evaluateCriterion(LocalSearchMoveScope<Solution_> moveScope) {

@Override
public void stepStarted(LocalSearchStepScope<Solution_> stepScope) {
currentBestScore = stepScope.getPhaseScope().getBestScore();
if (triggered) {
// We need to recreate the termination criterion as the time window has changed
diminishedReturnsCriterion = new DiminishedReturnsTermination<>(nextRestart, MINIMAL_IMPROVEMENT);
Expand All @@ -49,6 +51,15 @@ public void stepStarted(LocalSearchStepScope<Solution_> stepScope) {
@Override
public void stepEnded(LocalSearchStepScope<Solution_> stepScope) {
diminishedReturnsCriterion.stepEnded(stepScope);
if (currentBestScore.compareTo(stepScope.getPhaseScope().getBestScore()) < 0 && nextRestart > TIME_WINDOW_MILLIS) {
// If the solution has been improved after a restart,
// we reset the criterion and restart the evaluation of the metric
super.solvingStarted(stepScope.getPhaseScope().getSolverScope());
diminishedReturnsCriterion = new DiminishedReturnsTermination<>(nextRestart, MINIMAL_IMPROVEMENT);
diminishedReturnsCriterion.start(System.nanoTime(), stepScope.getPhaseScope().getBestScore());
logger.info("Stuck criterion reset, next restart ({}), previous best score({}), new best score ({})", nextRestart,
currentBestScore, stepScope.getPhaseScope().getBestScore());
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,33 @@ void isSolverStuck() {
assertThat(strategy.isSolverStuck(moveScope)).isTrue();
assertThat(strategy.nextRestart).isEqualTo(3L * TIME_WINDOW_MILLIS);
}

@Test
void reset() {
var solverScope = mock(SolverScope.class);
var phaseScope = mock(LocalSearchPhaseScope.class);
var stepScope = mock(LocalSearchStepScope.class);
var moveScope = mock(LocalSearchMoveScope.class);
var termination = mock(DiminishedReturnsTermination.class);

when(moveScope.getStepScope()).thenReturn(stepScope);
when(stepScope.getPhaseScope()).thenReturn(phaseScope);
when(phaseScope.getSolverScope()).thenReturn(solverScope);
when(moveScope.getScore()).thenReturn(SimpleScore.of(1));
when(phaseScope.getBestScore()).thenReturn(SimpleScore.of(1));
when(termination.isTerminated(anyLong(), any())).thenReturn(true);

// Restart
var strategy = new DiminishedReturnsStuckCriterion<>(termination);
strategy.solvingStarted(null);
strategy.phaseStarted(phaseScope);
assertThat(strategy.isSolverStuck(moveScope)).isTrue();
assertThat(strategy.nextRestart).isEqualTo(2L * TIME_WINDOW_MILLIS);

// Reset
strategy.stepStarted(stepScope);
when(phaseScope.getBestScore()).thenReturn(SimpleScore.of(2));
strategy.stepEnded(stepScope);
assertThat(strategy.nextRestart).isEqualTo(TIME_WINDOW_MILLIS);
}
}

0 comments on commit 7d2d0f3

Please sign in to comment.