protected BestSolutionRecaller buildBestSolutionRecaller(EnvironmentMode environmentMode) {
   BestSolutionRecaller bestSolutionRecaller = new BestSolutionRecaller();
   if (environmentMode.isNonIntrusiveFullAsserted()) {
     bestSolutionRecaller.setAssertBestScoreIsUnmodified(true);
   }
   return bestSolutionRecaller;
 }
 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 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);
 }
 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"));
 }