Skip to content

Commit

Permalink
chore: improve score corruption error message (#822)
Browse files Browse the repository at this point in the history
  • Loading branch information
triceo authored May 3, 2024
1 parent 21043f8 commit a649452
Show file tree
Hide file tree
Showing 38 changed files with 429 additions and 385 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public String getPhaseTypeString() {

@Override
public void solve(SolverScope<Solution_> solverScope) {
var phaseScope = new ConstructionHeuristicPhaseScope<>(solverScope);
var phaseScope = new ConstructionHeuristicPhaseScope<>(solverScope, phaseIndex);
phaseStarted(phaseScope);

var solutionDescriptor = solverScope.getSolutionDescriptor();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import ai.timefold.solver.core.impl.heuristic.move.Move;
import ai.timefold.solver.core.impl.heuristic.move.NoChangeMove;
import ai.timefold.solver.core.impl.heuristic.selector.move.generic.ChangeMove;
import ai.timefold.solver.core.impl.phase.scope.SolverLifecyclePoint;
import ai.timefold.solver.core.impl.score.director.InnerScoreDirector;
import ai.timefold.solver.core.impl.solver.scope.SolverScope;
import ai.timefold.solver.core.impl.solver.termination.Termination;
Expand Down Expand Up @@ -135,11 +136,11 @@ protected <Score_ extends Score<Score_>> void doMove(ConstructionHeuristicMoveSc
});
if (assertExpectedUndoMoveScore) {
scoreDirector.assertExpectedUndoMoveScore(moveScope.getMove(),
(Score_) moveScope.getStepScope().getPhaseScope().getLastCompletedStepScope().getScore());
(Score_) moveScope.getStepScope().getPhaseScope().getLastCompletedStepScope().getScore(),
SolverLifecyclePoint.of(moveScope));
}
logger.trace("{} Move index ({}), score ({}), move ({}).",
logIndentation,
moveScope.getMoveIndex(), moveScope.getScore(), moveScope.getMove());
logIndentation, moveScope.getMoveIndex(), moveScope.getScore(), moveScope.getMove());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,16 @@
/**
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation
*/
public class ConstructionHeuristicMoveScope<Solution_> extends AbstractMoveScope<Solution_> {

private final ConstructionHeuristicStepScope<Solution_> stepScope;
public final class ConstructionHeuristicMoveScope<Solution_> extends AbstractMoveScope<Solution_> {

public ConstructionHeuristicMoveScope(ConstructionHeuristicStepScope<Solution_> stepScope,
int moveIndex, Move<Solution_> move) {
super(moveIndex, move);
this.stepScope = stepScope;
super(stepScope, moveIndex, move);
}

@Override
public ConstructionHeuristicStepScope<Solution_> getStepScope() {
return stepScope;
return (ConstructionHeuristicStepScope<Solution_>) super.getStepScope();
}

// ************************************************************************
// Calculated methods
// ************************************************************************

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
/**
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation
*/
public class ConstructionHeuristicPhaseScope<Solution_> extends AbstractPhaseScope<Solution_> {
public final class ConstructionHeuristicPhaseScope<Solution_> extends AbstractPhaseScope<Solution_> {

private ConstructionHeuristicStepScope<Solution_> lastCompletedStepScope;

public ConstructionHeuristicPhaseScope(SolverScope<Solution_> solverScope) {
super(solverScope, false);
public ConstructionHeuristicPhaseScope(SolverScope<Solution_> solverScope, int phaseIndex) {
super(solverScope, phaseIndex, false);
lastCompletedStepScope = new ConstructionHeuristicStepScope<>(this, -1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation
*/
public class ConstructionHeuristicStepScope<Solution_> extends AbstractStepScope<Solution_> {
public final class ConstructionHeuristicStepScope<Solution_> extends AbstractStepScope<Solution_> {

private final ConstructionHeuristicPhaseScope<Solution_> phaseScope;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public String getPhaseTypeString() {
@Override
public void solve(SolverScope<Solution_> solverScope) {
SortedSet<ExhaustiveSearchNode> expandableNodeQueue = new TreeSet<>(nodeComparator);
ExhaustiveSearchPhaseScope<Solution_> phaseScope = new ExhaustiveSearchPhaseScope<>(solverScope);
ExhaustiveSearchPhaseScope<Solution_> phaseScope = new ExhaustiveSearchPhaseScope<>(solverScope, phaseIndex);
phaseScope.setExpandableNodeQueue(expandableNodeQueue);
phaseStarted(phaseScope);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import ai.timefold.solver.core.impl.heuristic.move.Move;
import ai.timefold.solver.core.impl.heuristic.selector.entity.mimic.ManualEntityMimicRecorder;
import ai.timefold.solver.core.impl.heuristic.selector.move.MoveSelector;
import ai.timefold.solver.core.impl.phase.scope.SolverLifecyclePoint;
import ai.timefold.solver.core.impl.score.director.InnerScoreDirector;
import ai.timefold.solver.core.impl.solver.recaller.BestSolutionRecaller;
import ai.timefold.solver.core.impl.solver.scope.SolverScope;
Expand Down Expand Up @@ -132,15 +133,15 @@ private <Score_ extends Score<Score_>> void doMove(ExhaustiveSearchStepScope<Sol
moveNode.setUndoMove(undoMove);
processMove(stepScope, moveNode);
undoMove.doMoveOnly(scoreDirector);
var executionPoint = SolverLifecyclePoint.of(stepScope, moveNode.getTreeId());
if (assertExpectedUndoMoveScore) {
// In BRUTE_FORCE a stepScore can be null because it was not calculated
if (stepScope.getStartingStepScore() != null) {
scoreDirector.assertExpectedUndoMoveScore(move, (Score_) stepScope.getStartingStepScore());
scoreDirector.assertExpectedUndoMoveScore(move, (Score_) stepScope.getStartingStepScore(), executionPoint);
}
}
LOGGER.trace("{} Move treeId ({}), score ({}), expandable ({}), move ({}).",
logIndentation,
moveNode.getTreeId(), moveNode.getScore(), moveNode.isExpandable(), moveNode.getMove());
logIndentation, executionPoint.treeId(), moveNode.getScore(), moveNode.isExpandable(), moveNode.getMove());
}

private <Score_ extends Score<Score_>> void processMove(ExhaustiveSearchStepScope<Solution_> stepScope,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@
/**
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation
*/
public class ExhaustiveSearchPhaseScope<Solution_> extends AbstractPhaseScope<Solution_> {
public final class ExhaustiveSearchPhaseScope<Solution_> extends AbstractPhaseScope<Solution_> {

private List<ExhaustiveSearchLayer> layerList;
private SortedSet<ExhaustiveSearchNode> expandableNodeQueue;
private Score bestPessimisticBound;

private ExhaustiveSearchStepScope<Solution_> lastCompletedStepScope;

public ExhaustiveSearchPhaseScope(SolverScope<Solution_> solverScope) {
super(solverScope, false);
public ExhaustiveSearchPhaseScope(SolverScope<Solution_> solverScope, int phaseIndex) {
super(solverScope, phaseIndex, false);
lastCompletedStepScope = new ExhaustiveSearchStepScope<>(this, -1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/**
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation
*/
public class ExhaustiveSearchStepScope<Solution_> extends AbstractStepScope<Solution_> {
public final class ExhaustiveSearchStepScope<Solution_> extends AbstractStepScope<Solution_> {

private final ExhaustiveSearchPhaseScope<Solution_> phaseScope;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public String getPhaseTypeString() {

@Override
public void solve(SolverScope<Solution_> solverScope) {
LocalSearchPhaseScope<Solution_> phaseScope = new LocalSearchPhaseScope<>(solverScope);
LocalSearchPhaseScope<Solution_> phaseScope = new LocalSearchPhaseScope<>(solverScope, phaseIndex);
phaseStarted(phaseScope);

if (solverScope.isMetricEnabled(SolverMetric.MOVE_COUNT_PER_STEP)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import ai.timefold.solver.core.impl.localsearch.scope.LocalSearchMoveScope;
import ai.timefold.solver.core.impl.localsearch.scope.LocalSearchPhaseScope;
import ai.timefold.solver.core.impl.localsearch.scope.LocalSearchStepScope;
import ai.timefold.solver.core.impl.phase.scope.SolverLifecyclePoint;
import ai.timefold.solver.core.impl.score.director.InnerScoreDirector;
import ai.timefold.solver.core.impl.solver.scope.SolverScope;
import ai.timefold.solver.core.impl.solver.termination.Termination;
Expand Down Expand Up @@ -121,12 +122,11 @@ protected <Score_ extends Score<Score_>> void doMove(LocalSearchMoveScope<Soluti
});
if (assertExpectedUndoMoveScore) {
scoreDirector.assertExpectedUndoMoveScore(moveScope.getMove(),
(Score_) moveScope.getStepScope().getPhaseScope().getLastCompletedStepScope().getScore());
(Score_) moveScope.getStepScope().getPhaseScope().getLastCompletedStepScope().getScore(),
SolverLifecyclePoint.of(moveScope));
}
logger.trace("{} Move index ({}), score ({}), accepted ({}), move ({}).",
logIndentation,
moveScope.getMoveIndex(), moveScope.getScore(), moveScope.getAccepted(),
moveScope.getMove());
logIndentation, moveScope.getMoveIndex(), moveScope.getScore(), moveScope.getAccepted(), moveScope.getMove());
}

protected void pickMove(LocalSearchStepScope<Solution_> stepScope) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,17 @@
/**
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation
*/
public class LocalSearchMoveScope<Solution_> extends AbstractMoveScope<Solution_> {

private final LocalSearchStepScope<Solution_> stepScope;
public final class LocalSearchMoveScope<Solution_> extends AbstractMoveScope<Solution_> {

private Boolean accepted = null;

public LocalSearchMoveScope(LocalSearchStepScope<Solution_> stepScope, int moveIndex, Move<Solution_> move) {
super(moveIndex, move);
this.stepScope = stepScope;
super(stepScope, moveIndex, move);
}

@Override
public LocalSearchStepScope<Solution_> getStepScope() {
return stepScope;
return (LocalSearchStepScope<Solution_>) super.getStepScope();
}

public Boolean getAccepted() {
Expand All @@ -31,8 +28,4 @@ public void setAccepted(Boolean accepted) {
this.accepted = accepted;
}

// ************************************************************************
// Calculated methods
// ************************************************************************

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
/**
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation
*/
public class LocalSearchPhaseScope<Solution_> extends AbstractPhaseScope<Solution_> {
public final class LocalSearchPhaseScope<Solution_> extends AbstractPhaseScope<Solution_> {

private LocalSearchStepScope<Solution_> lastCompletedStepScope;

public LocalSearchPhaseScope(SolverScope<Solution_> solverScope) {
super(solverScope);
public LocalSearchPhaseScope(SolverScope<Solution_> solverScope, int phaseIndex) {
super(solverScope, phaseIndex);
lastCompletedStepScope = new LocalSearchStepScope<>(this, -1);
lastCompletedStepScope.setTimeGradient(0.0);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation
*/
public class LocalSearchStepScope<Solution_> extends AbstractStepScope<Solution_> {
public final class LocalSearchStepScope<Solution_> extends AbstractStepScope<Solution_> {

private final LocalSearchPhaseScope<Solution_> phaseScope;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public String getPhaseTypeString() {

@Override
public void solve(SolverScope<Solution_> solverScope) {
CustomPhaseScope<Solution_> phaseScope = new CustomPhaseScope<>(solverScope);
CustomPhaseScope<Solution_> phaseScope = new CustomPhaseScope<>(solverScope, phaseIndex);
phaseStarted(phaseScope);
for (CustomPhaseCommand<Solution_> customPhaseCommand : customPhaseCommandList) {
solverScope.checkYielding();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@
/**
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation
*/
public class CustomPhaseScope<Solution_> extends AbstractPhaseScope<Solution_> {
public final class CustomPhaseScope<Solution_> extends AbstractPhaseScope<Solution_> {

private CustomStepScope<Solution_> lastCompletedStepScope;

public CustomPhaseScope(SolverScope<Solution_> solverScope) {
this(solverScope, false);
public CustomPhaseScope(SolverScope<Solution_> solverScope, int phaseIndex) {
this(solverScope, phaseIndex, false);
}

public CustomPhaseScope(SolverScope<Solution_> solverScope, boolean phaseSendsBestSolutionEvents) {
super(solverScope, phaseSendsBestSolutionEvents);
public CustomPhaseScope(SolverScope<Solution_> solverScope, int phaseIndex, boolean phaseSendsBestSolutionEvents) {
super(solverScope, phaseIndex, phaseSendsBestSolutionEvents);
lastCompletedStepScope = new CustomStepScope<>(this, -1);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
/**
* @param <Solution_> the solution type, the class with the {@link PlanningSolution} annotation
*/
public class CustomStepScope<Solution_> extends AbstractStepScope<Solution_> {
public final class CustomStepScope<Solution_> extends AbstractStepScope<Solution_> {

private final CustomPhaseScope<Solution_> phaseScope;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,21 @@
*/
public abstract class AbstractMoveScope<Solution_> {

protected final AbstractStepScope<Solution_> stepScope;
protected final int moveIndex;
protected final Move<Solution_> move;

protected Score<?> score = null;

public AbstractMoveScope(int moveIndex, Move<Solution_> move) {
protected AbstractMoveScope(AbstractStepScope<Solution_> stepScope, int moveIndex, Move<Solution_> move) {
this.stepScope = stepScope;
this.moveIndex = moveIndex;
this.move = move;
}

public abstract AbstractStepScope<Solution_> getStepScope();
public AbstractStepScope<Solution_> getStepScope() {
return stepScope;
}

public int getMoveIndex() {
return moveIndex;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public abstract class AbstractPhaseScope<Solution_> {
protected final transient Logger logger = LoggerFactory.getLogger(getClass());

protected final SolverScope<Solution_> solverScope;
protected final int phaseIndex;
protected final boolean phaseSendingBestSolutionEvents;

protected Long startingSystemTimeMillis;
Expand All @@ -31,30 +32,36 @@ public abstract class AbstractPhaseScope<Solution_> {
protected int bestSolutionStepIndex;

/**
* As defined by #AbstractPhaseScope(SolverScope, boolean),
* As defined by #AbstractPhaseScope(SolverScope, int, boolean)
* with the phaseSendingBestSolutionEvents parameter set to true.
*/
protected AbstractPhaseScope(SolverScope<Solution_> solverScope) {
this(solverScope, true);
protected AbstractPhaseScope(SolverScope<Solution_> solverScope, int phaseIndex) {
this(solverScope, phaseIndex, true);
}

/**
*
* @param solverScope never null
* @param phaseIndex the index of the phase, >= 0
* @param phaseSendingBestSolutionEvents set to false if the phase only sends one best solution event at the end,
* or none at all;
* this is typical for construction heuristics,
* whose result only matters when it reached its natural end.
*/
protected AbstractPhaseScope(SolverScope<Solution_> solverScope, boolean phaseSendingBestSolutionEvents) {
protected AbstractPhaseScope(SolverScope<Solution_> solverScope, int phaseIndex, boolean phaseSendingBestSolutionEvents) {
this.solverScope = solverScope;
this.phaseIndex = phaseIndex;
this.phaseSendingBestSolutionEvents = phaseSendingBestSolutionEvents;
}

public SolverScope<Solution_> getSolverScope() {
return solverScope;
}

public int getPhaseIndex() {
return phaseIndex;
}

public boolean isPhaseSendingBestSolutionEvents() {
return phaseSendingBestSolutionEvents;
}
Expand Down Expand Up @@ -206,7 +213,7 @@ public int getNextStepIndex() {

@Override
public String toString() {
return getClass().getSimpleName(); // TODO add + "(" + phaseIndex + ")"
return getClass().getSimpleName() + "(" + phaseIndex + ")";
}

}
Loading

0 comments on commit a649452

Please sign in to comment.