@Override public void solve(DefaultSolverScope<Solution_> solverScope) { ConstructionHeuristicPhaseScope<Solution_> phaseScope = new ConstructionHeuristicPhaseScope<>(solverScope); phaseStarted(phaseScope); for (Placement placement : entityPlacer) { ConstructionHeuristicStepScope<Solution_> stepScope = new ConstructionHeuristicStepScope<>(phaseScope); stepStarted(stepScope); decider.decideNextStep(stepScope, placement); if (stepScope.getStep() == null) { if (termination.isPhaseTerminated(phaseScope)) { logger.trace( " Step index ({}), time spent ({}) terminated without picking a nextStep.", stepScope.getStepIndex(), stepScope.getPhaseScope().calculateSolverTimeMillisSpentUpToNow()); } else if (stepScope.getSelectedMoveCount() == 0L) { logger.warn( " No doable selected move at step index ({}), time spent ({})." + " Terminating phase early.", stepScope.getStepIndex(), stepScope.getPhaseScope().calculateSolverTimeMillisSpentUpToNow()); } else { throw new IllegalStateException( "The step index (" + stepScope.getStepIndex() + ") has selected move count (" + stepScope.getSelectedMoveCount() + ") but failed to pick a nextStep (" + stepScope.getStep() + ")."); } // Although stepStarted has been called, stepEnded is not called for this step break; } doStep(stepScope); stepEnded(stepScope); phaseScope.setLastCompletedStepScope(stepScope); if (termination.isPhaseTerminated(phaseScope)) { break; } } phaseEnded(phaseScope); }
private void doStep(ConstructionHeuristicStepScope<Solution_> stepScope) { Move nextStep = stepScope.getStep(); nextStep.doMove(stepScope.getScoreDirector()); predictWorkingStepScore(stepScope, nextStep); }