@Override
 public void stepEnded(AbstractStepScope stepScope) {
   if (!stepScope.isSolutionInitialized()) {
     return;
   }
   AbstractSolverPhaseScope solverPhaseScope = stepScope.getSolverPhaseScope();
   DefaultSolverScope solverScope = solverPhaseScope.getSolverScope();
   Score newScore = stepScope.getScore();
   Score bestScore = solverScope.getBestScore();
   boolean bestScoreImproved;
   if (bestScore == null) {
     bestScoreImproved = true;
     solverScope.setStartingInitializedScore(newScore);
   } else {
     bestScoreImproved = newScore.compareTo(bestScore) > 0;
   }
   stepScope.setBestScoreImproved(bestScoreImproved);
   if (bestScoreImproved) {
     solverPhaseScope.setBestSolutionStepIndex(stepScope.getStepIndex());
     Solution newBestSolution = stepScope.createOrGetClonedSolution();
     updateBestSolution(solverScope, newBestSolution);
   } else if (assertBestScoreIsUnmodified) {
     solverScope.assertScore(solverScope.getBestSolution());
   }
 }
 public double calculatePhaseTimeGradient(AbstractSolverPhaseScope solverPhaseScope) {
   Score startingInitializedScore = solverPhaseScope.getStartingScore();
   Score bestScore = solverPhaseScope.getBestScore();
   return solverPhaseScope
       .getScoreDefinition()
       .calculateTimeGradient(startingInitializedScore, scoreAttained, bestScore);
 }
  public void runCacheType(SelectorCacheType cacheType, int timesCalled) {
    CachingMoveSelector moveSelector = new CachingMoveSelector(cacheType);
    MoveSelector childMoveSelector = mock(MoveSelector.class);
    final List<Move> moveList =
        Arrays.<Move>asList(new DummyMove("a1"), new DummyMove("a2"), new DummyMove("a3"));
    when(childMoveSelector.iterator())
        .thenAnswer(
            new Answer<Object>() {
              public Object answer(InvocationOnMock invocation) throws Throwable {
                return moveList.iterator();
              }
            });
    when(childMoveSelector.isContinuous()).thenReturn(false);
    when(childMoveSelector.isNeverEnding()).thenReturn(false);
    when(childMoveSelector.getSize()).thenReturn((long) moveList.size());
    when(childMoveSelector.getRandomProbabilityWeight()).thenReturn(7L);
    moveSelector.setChildMoveSelector(childMoveSelector);
    verify(childMoveSelector, times(1)).isNeverEnding();

    DefaultSolverScope solverScope = mock(DefaultSolverScope.class);
    moveSelector.solvingStarted(solverScope);

    AbstractSolverPhaseScope phaseScopeA = mock(AbstractSolverPhaseScope.class);
    when(phaseScopeA.getSolverScope()).thenReturn(solverScope);
    moveSelector.phaseStarted(phaseScopeA);

    AbstractStepScope stepScopeA1 = mock(AbstractStepScope.class);
    when(stepScopeA1.getSolverPhaseScope()).thenReturn(phaseScopeA);
    moveSelector.stepStarted(stepScopeA1);
    runAsserts(moveSelector);
    moveSelector.stepEnded(stepScopeA1);

    AbstractStepScope stepScopeA2 = mock(AbstractStepScope.class);
    when(stepScopeA2.getSolverPhaseScope()).thenReturn(phaseScopeA);
    moveSelector.stepStarted(stepScopeA2);
    runAsserts(moveSelector);
    moveSelector.stepEnded(stepScopeA2);

    moveSelector.phaseEnded(phaseScopeA);

    AbstractSolverPhaseScope phaseScopeB = mock(AbstractSolverPhaseScope.class);
    when(phaseScopeB.getSolverScope()).thenReturn(solverScope);
    moveSelector.phaseStarted(phaseScopeB);

    AbstractStepScope stepScopeB1 = mock(AbstractStepScope.class);
    when(stepScopeB1.getSolverPhaseScope()).thenReturn(phaseScopeB);
    moveSelector.stepStarted(stepScopeB1);
    runAsserts(moveSelector);
    moveSelector.stepEnded(stepScopeB1);

    AbstractStepScope stepScopeB2 = mock(AbstractStepScope.class);
    when(stepScopeB2.getSolverPhaseScope()).thenReturn(phaseScopeB);
    moveSelector.stepStarted(stepScopeB2);
    runAsserts(moveSelector);
    moveSelector.stepEnded(stepScopeB2);

    AbstractStepScope stepScopeB3 = mock(AbstractStepScope.class);
    when(stepScopeB3.getSolverPhaseScope()).thenReturn(phaseScopeB);
    moveSelector.stepStarted(stepScopeB3);
    runAsserts(moveSelector);
    moveSelector.stepEnded(stepScopeB3);

    moveSelector.phaseEnded(phaseScopeB);

    moveSelector.solvingEnded(solverScope);

    verify(childMoveSelector, times(timesCalled)).iterator();
    verify(childMoveSelector, times(timesCalled)).getSize();
    verify(childMoveSelector, times(timesCalled)).getRandomProbabilityWeight();
  }
  public void runCacheType(SelectionCacheType cacheType, int timesCalled) {
    EntitySelector childEntitySelector =
        SelectorTestUtils.mockEntitySelector(
            TestdataEntity.class,
            new TestdataEntity("e1"),
            new TestdataEntity("e2"),
            new TestdataEntity("e3"));

    CachingEntitySelector entitySelector =
        new CachingEntitySelector(childEntitySelector, cacheType);
    verify(childEntitySelector, times(1)).isNeverEnding();

    DefaultSolverScope solverScope = mock(DefaultSolverScope.class);
    entitySelector.solvingStarted(solverScope);

    AbstractSolverPhaseScope phaseScopeA = mock(AbstractSolverPhaseScope.class);
    when(phaseScopeA.getSolverScope()).thenReturn(solverScope);
    entitySelector.phaseStarted(phaseScopeA);

    AbstractStepScope stepScopeA1 = mock(AbstractStepScope.class);
    when(stepScopeA1.getSolverPhaseScope()).thenReturn(phaseScopeA);
    entitySelector.stepStarted(stepScopeA1);
    runAsserts(entitySelector);
    entitySelector.stepEnded(stepScopeA1);

    AbstractStepScope stepScopeA2 = mock(AbstractStepScope.class);
    when(stepScopeA2.getSolverPhaseScope()).thenReturn(phaseScopeA);
    entitySelector.stepStarted(stepScopeA2);
    runAsserts(entitySelector);
    entitySelector.stepEnded(stepScopeA2);

    entitySelector.phaseEnded(phaseScopeA);

    AbstractSolverPhaseScope phaseScopeB = mock(AbstractSolverPhaseScope.class);
    when(phaseScopeB.getSolverScope()).thenReturn(solverScope);
    entitySelector.phaseStarted(phaseScopeB);

    AbstractStepScope stepScopeB1 = mock(AbstractStepScope.class);
    when(stepScopeB1.getSolverPhaseScope()).thenReturn(phaseScopeB);
    entitySelector.stepStarted(stepScopeB1);
    runAsserts(entitySelector);
    entitySelector.stepEnded(stepScopeB1);

    AbstractStepScope stepScopeB2 = mock(AbstractStepScope.class);
    when(stepScopeB2.getSolverPhaseScope()).thenReturn(phaseScopeB);
    entitySelector.stepStarted(stepScopeB2);
    runAsserts(entitySelector);
    entitySelector.stepEnded(stepScopeB2);

    AbstractStepScope stepScopeB3 = mock(AbstractStepScope.class);
    when(stepScopeB3.getSolverPhaseScope()).thenReturn(phaseScopeB);
    entitySelector.stepStarted(stepScopeB3);
    runAsserts(entitySelector);
    entitySelector.stepEnded(stepScopeB3);

    entitySelector.phaseEnded(phaseScopeB);

    entitySelector.solvingEnded(solverScope);

    verify(childEntitySelector, times(1)).solvingStarted(solverScope);
    verify(childEntitySelector, times(2)).phaseStarted(Matchers.<AbstractSolverPhaseScope>any());
    verify(childEntitySelector, times(5)).stepStarted(Matchers.<AbstractStepScope>any());
    verify(childEntitySelector, times(5)).stepEnded(Matchers.<AbstractStepScope>any());
    verify(childEntitySelector, times(2)).phaseEnded(Matchers.<AbstractSolverPhaseScope>any());
    verify(childEntitySelector, times(1)).solvingEnded(solverScope);
    verify(childEntitySelector, times(timesCalled)).iterator();
    verify(childEntitySelector, times(timesCalled)).getSize();
  }
 public boolean isPhaseTerminated(AbstractSolverPhaseScope solverPhaseScope) {
   Score bestScore = solverPhaseScope.getBestScore();
   return isTerminated(bestScore);
 }