@Override public void stepEnded(AbstractStepScope stepScope) { if (stepScope.isBestSolutionCloningDelayed()) { return; } AbstractSolverPhaseScope phaseScope = stepScope.getPhaseScope(); int uninitializedVariableCount = stepScope.getUninitializedVariableCount(); Score score = stepScope.getScore(); DefaultSolverScope solverScope = phaseScope.getSolverScope(); int bestUninitializedVariableCount = solverScope.getBestUninitializedVariableCount(); Score bestScore = solverScope.getBestScore(); boolean bestScoreImproved; if (uninitializedVariableCount == bestUninitializedVariableCount) { bestScoreImproved = score.compareTo(bestScore) > 0; } else { bestScoreImproved = uninitializedVariableCount < bestUninitializedVariableCount; } stepScope.setBestScoreImproved(bestScoreImproved); if (bestScoreImproved) { phaseScope.setBestSolutionStepIndex(stepScope.getStepIndex()); Solution newBestSolution = stepScope.createOrGetClonedSolution(); updateBestSolution(solverScope, newBestSolution, uninitializedVariableCount); } else if (assertBestScoreIsUnmodified) { solverScope.assertScoreFromScratch(solverScope.getBestSolution()); } }
private void checkProblemFactChanges() { BlockingQueue<ProblemFactChange> problemFactChangeQueue = basicPlumbingTermination.getProblemFactChangeQueue(); if (!problemFactChangeQueue.isEmpty()) { solverScope.setRestartSolver(true); solverScope.setWorkingSolutionFromBestSolution(); Score score = null; int count = 0; ProblemFactChange problemFactChange = problemFactChangeQueue.poll(); while (problemFactChange != null) { score = doProblemFactChange(problemFactChange); count++; problemFactChange = problemFactChangeQueue.poll(); } Solution newBestSolution = solverScope.getScoreDirector().cloneWorkingSolution(); // TODO BestSolutionRecaller.solverStarted() already calls countUninitializedVariables() int newBestUninitializedVariableCount = solverScope.getSolutionDescriptor().countUninitializedVariables(newBestSolution); bestSolutionRecaller.updateBestSolution( solverScope, newBestSolution, newBestUninitializedVariableCount); logger.info( "Done {} ProblemFactChange(s): new score ({}) possibly uninitialized. Restarting solver.", count, score); } }
public final void solve() { solving.set(true); basicPlumbingTermination.resetTerminateEarly(); solverScope.setRestartSolver(true); while (solverScope.isRestartSolver()) { solverScope.setRestartSolver(false); solvingStarted(solverScope); runSolverPhases(); solvingEnded(solverScope); checkProblemFactChanges(); } // Must be kept open for doProblemFactChange solverScope.getScoreDirector().dispose(); solving.set(false); }
public void constructCache(DefaultSolverScope solverScope) { cachedMoveList = moveListFactory.createMoveList(solverScope.getScoreDirector().getWorkingSolution()); logger.trace( " Created cachedMoveList with size ({}) in moveSelector({}).", cachedMoveList.size(), this); }
public void solvingEnded(DefaultSolverScope solverScope) { for (SolverPhase solverPhase : solverPhaseList) { solverPhase.solvingEnded(solverScope); } bestSolutionRecaller.solvingEnded(solverScope); long timeMillisSpend = solverScope.calculateTimeMillisSpend(); if (timeMillisSpend == 0L) { // Avoid divide by zero exception on a fast CPU timeMillisSpend = 1L; } long averageCalculateCountPerSecond = solverScope.getCalculateCount() * 1000L / timeMillisSpend; logger.info( "Solving ended: time spend ({}), best score ({}), average calculate count per second ({}).", timeMillisSpend, solverScope.getBestScoreWithUninitializedPrefix(), averageCalculateCountPerSecond); }
protected void runSolverPhases() { Iterator<SolverPhase> it = solverPhaseList.iterator(); while (!termination.isSolverTerminated(solverScope) && it.hasNext()) { SolverPhase solverPhase = it.next(); solverPhase.solve(solverScope); if (it.hasNext()) { solverScope.setWorkingSolutionFromBestSolution(); } } // TODO support doing round-robin of phases (only non-construction heuristics) }
public void processWorkingSolutionDuringMove( int uninitializedVariableCount, Score score, AbstractStepScope stepScope) { AbstractSolverPhaseScope phaseScope = stepScope.getPhaseScope(); DefaultSolverScope solverScope = phaseScope.getSolverScope(); int bestUninitializedVariableCount = solverScope.getBestUninitializedVariableCount(); Score bestScore = solverScope.getBestScore(); boolean bestScoreImproved; if (uninitializedVariableCount == bestUninitializedVariableCount) { bestScoreImproved = score.compareTo(bestScore) > 0; } else { bestScoreImproved = uninitializedVariableCount < bestUninitializedVariableCount; } // The method processWorkingSolutionDuringMove() is called 0..* times // bestScoreImproved is initialized on false before the first call here if (bestScoreImproved) { stepScope.setBestScoreImproved(bestScoreImproved); } if (bestScoreImproved) { phaseScope.setBestSolutionStepIndex(stepScope.getStepIndex()); Solution newBestSolution = solverScope.getScoreDirector().cloneWorkingSolution(); updateBestSolution(solverScope, newBestSolution, uninitializedVariableCount); } else if (assertBestScoreIsUnmodified) { solverScope.assertScoreFromScratch(solverScope.getBestSolution()); } }
public void constructCache(DefaultSolverScope solverScope) { cachedEntityMap = new TreeMap<Double, Object>(); ScoreDirector scoreDirector = solverScope.getScoreDirector(); double probabilityWeightOffset = 0L; // TODO Fail-faster if a non FromSolutionPropertyValueSelector is used for (Object value : childValueSelector) { double probabilityWeight = probabilityWeightFactory.createProbabilityWeight(scoreDirector, value); cachedEntityMap.put(probabilityWeightOffset, value); probabilityWeightOffset += probabilityWeight; } probabilityWeightTotal = probabilityWeightOffset; }
@Override public void solvingStarted(DefaultSolverScope solverScope) { super.solvingStarted(solverScope); if (anyChained) { SupplyManager supplyManager = solverScope.getScoreDirector().getSupplyManager(); for (GenuineVariableDescriptor variableDescriptor : variableDescriptors) { if (variableDescriptor.isChained()) { // TODO supply is demanded just to make sure it's there when it's demand again later. // Instead it should be remembered for later SingletonInverseVariableSupply inverseVariableSupply = supplyManager.demand(new SingletonInverseVariableDemand(variableDescriptor)); } } } }
@Override public void solvingStarted(DefaultSolverScope solverScope) { // Starting bestSolution is already set by Solver.setPlanningProblem() int uninitializedVariableCount = solverScope.getScoreDirector().countWorkingSolutionUninitializedVariables(); solverScope.setBestUninitializedVariableCount(uninitializedVariableCount); Score score = solverScope.calculateScore(); solverScope.setBestScore(score); solverScope.setBestSolutionTimeMillis(System.currentTimeMillis()); // The original bestSolution might be the final bestSolution and should have an accurate Score solverScope.getBestSolution().setScore(score); if (uninitializedVariableCount == 0) { solverScope.setStartingInitializedScore(score); } else { solverScope.setStartingInitializedScore(null); } }
public void updateBestSolution( DefaultSolverScope solverScope, Solution solution, int uninitializedVariableCount) { if (uninitializedVariableCount == 0) { if (!solverScope.isBestSolutionInitialized()) { solverScope.setStartingInitializedScore(solution.getScore()); } } solverScope.setBestUninitializedVariableCount(uninitializedVariableCount); solverScope.setBestSolution(solution); solverScope.setBestScore(solution.getScore()); solverScope.setBestSolutionTimeMillis(System.currentTimeMillis()); solverEventSupport.fireBestSolutionChanged(solution); }
public void solvingStarted(DefaultSolverScope solverScope) { if (solverScope.getBestSolution() == null) { throw new IllegalStateException( "The planningProblem must not be null." + " Use Solver.setPlanningProblem(Solution)."); } solverScope.setStartingSystemTimeMillis(System.currentTimeMillis()); solverScope.setScoreDirector(scoreDirectorFactory.buildScoreDirector()); solverScope.setWorkingRandom(randomFactory.createRandom()); solverScope.setWorkingSolutionFromBestSolution(); bestSolutionRecaller.solvingStarted(solverScope); for (SolverPhase solverPhase : solverPhaseList) { solverPhase.solvingStarted(solverScope); } logger.info( "Solving started: time spend ({}), score ({}), new best score ({}), random ({}).", solverScope.calculateTimeMillisSpend(), solverScope.getStartingInitializedScore(), solverScope.getBestScore(), (randomFactory != null ? randomFactory : "not fixed")); }
public void setPlanningProblem(Solution planningProblem) { solverScope.setBestSolution(planningProblem); }
// TODO this shouldn't change after the solve is done public long getTimeMillisSpend() { return solverScope.calculateTimeMillisSpend(); }
private Score doProblemFactChange(ProblemFactChange problemFactChange) { problemFactChange.doChange(solverScope.getScoreDirector()); Score score = solverScope.calculateScore(); logger.debug(" Done ProblemFactChange: new score ({}).", score); return score; }
public Solution getBestSolution() { return solverScope.getBestSolution(); }
public SolutionDescriptor getSolutionDescriptor() { return solverScope.getSolutionDescriptor(); }