Interface InnerScoreDirector<Solution_,Score_ extends Score<Score_>>

Type Parameters:
Solution_ - the solution type, the class with the PlanningSolution annotation
Score_ - the score type to go with the solution
All Superinterfaces:
AutoCloseable, ScoreDirector<Solution_>
All Known Implementing Classes:
AbstractScoreDirector, DrlScoreDirector, EasyScoreDirector, IncrementalScoreDirector

public interface InnerScoreDirector<Solution_,Score_ extends Score<Score_>> extends ScoreDirector<Solution_>, AutoCloseable
  • Method Details

    • setWorkingSolution

      void setWorkingSolution(Solution_ workingSolution)
      The working solution must never be the same instance as the best solution, it should be a (un)changed clone.
      Parameters:
      workingSolution - never null
    • calculateScore

      Score_ calculateScore()
      Calculates the Score and updates the working solution accordingly.
      Returns:
      never null, the Score of the working solution
    • isConstraintMatchEnabled

      boolean isConstraintMatchEnabled()
      Returns:
      true if getConstraintMatchTotalMap() and getIndictmentMap() can be called
    • getConstraintMatchTotalMap

      Map<String,ConstraintMatchTotal<Score_>> getConstraintMatchTotalMap()
      Explains the Score of calculateScore() by splitting it up per Constraint.

      The sum of ConstraintMatchTotal.getScore() equals calculateScore().

      Call calculateScore() before calling this method, unless that method has already been called since the last PlanningVariable changes.

      Returns:
      never null, the key is the constraintId (to create one, use ConstraintMatchTotal.composeConstraintId(String, String)).
      Throws:
      IllegalStateException - if isConstraintMatchEnabled() returns false
      See Also:
    • getIndictmentMap

      Map<Object,Indictment<Score_>> getIndictmentMap()
      Explains the impact of each planning entity or problem fact on the Score. An Indictment is basically the inverse of a ConstraintMatchTotal: it is a Score total for each constraint justification.

      The sum of ConstraintMatchTotal.getScore() differs from calculateScore() because each ConstraintMatch.getScore() is counted for each constraint justification.

      Call calculateScore() before calling this method, unless that method has already been called since the last PlanningVariable changes.

      Returns:
      never null, the key is a problem fact or a planning entity
      Throws:
      IllegalStateException - if isConstraintMatchEnabled() returns false
      See Also:
    • overwriteConstraintMatchEnabledPreference

      void overwriteConstraintMatchEnabledPreference(boolean constraintMatchEnabledPreference)
      Parameters:
      constraintMatchEnabledPreference - false if a ScoreDirector implementation should not do ConstraintMatch tracking even if it supports it.
    • getWorkingEntityListRevision

      long getWorkingEntityListRevision()
      Returns:
      used to check isWorkingEntityListDirty(long) later on
    • doAndProcessMove

      Score_ doAndProcessMove(Move<Solution_> move, boolean assertMoveScoreFromScratch)
      Parameters:
      move - never null
      assertMoveScoreFromScratch - true will hurt performance
      Returns:
      never null
    • doAndProcessMove

      void doAndProcessMove(Move<Solution_> move, boolean assertMoveScoreFromScratch, Consumer<Score_> moveProcessor)
      Parameters:
      move - never null
      assertMoveScoreFromScratch - true will hurt performance
      moveProcessor - never null, use this to store the score as well as call the acceptor and forager
    • isWorkingEntityListDirty

      boolean isWorkingEntityListDirty(long expectedWorkingEntityListRevision)
      Parameters:
      expectedWorkingEntityListRevision - an
      Returns:
      true if the entityList might have a different set of instances now
    • requiresFlushing

      boolean requiresFlushing()
      Some score directors (such as the Drools-based) keep a set of changes that they only apply when calculateScore() is called. Until that happens, this set accumulates and could possibly act as a memory leak.
      Returns:
      true if the score director can potentially cause a memory leak due to unflushed changes.
    • getScoreDirectorFactory

      InnerScoreDirectorFactory<Solution_,Score_> getScoreDirectorFactory()
      Returns:
      never null
    • getSolutionDescriptor

      SolutionDescriptor<Solution_> getSolutionDescriptor()
      Returns:
      never null
    • getScoreDefinition

      ScoreDefinition<Score_> getScoreDefinition()
      Returns:
      never null
    • cloneWorkingSolution

      Solution_ cloneWorkingSolution()
      Returns a planning clone of the solution, which is not a shallow clone nor a deep clone nor a partition clone.
      Returns:
      never null, planning clone
    • cloneSolution

      Solution_ cloneSolution(Solution_ originalSolution)
      Returns a planning clone of the solution, which is not a shallow clone nor a deep clone nor a partition clone.
      Parameters:
      originalSolution - never null
      Returns:
      never null, planning clone
    • getCalculationCount

      long getCalculationCount()
      Returns:
      at least 0L
    • resetCalculationCount

      void resetCalculationCount()
    • incrementCalculationCount

      void incrementCalculationCount()
    • getSupplyManager

      SupplyManager getSupplyManager()
      Returns:
      never null
    • clone

      Clones this ScoreDirector and its working solution. Use ScoreDirector.getWorkingSolution() to retrieve the working solution of that clone.

      This is heavy method, because it usually breaks incremental score calculation. Use it sparingly. Therefore it's best to clone lazily by delaying the clone call as long as possible.

      Returns:
      never null
    • createChildThreadScoreDirector

      InnerScoreDirector<Solution_,Score_> createChildThreadScoreDirector(ChildThreadType childThreadType)
    • setAllChangesWillBeUndoneBeforeStepEnds

      void setAllChangesWillBeUndoneBeforeStepEnds(boolean allChangesWillBeUndoneBeforeStepEnds)
      Do not waste performance by propagating changes to step (or higher) mechanisms.
      Parameters:
      allChangesWillBeUndoneBeforeStepEnds - true if all changes will be undone
    • assertExpectedWorkingScore

      void assertExpectedWorkingScore(Score_ expectedWorkingScore, Object completedAction)
      Asserts that if the Score is calculated for the current working solution in the current ScoreDirector (with possibly incremental calculation residue), it is equal to the parameter expectedWorkingScore.

      Used to assert that skipping calculateScore() (when the score is otherwise determined) is correct.

      Parameters:
      expectedWorkingScore - never null
      completedAction - sometimes null, when assertion fails then the completedAction's Object.toString() is included in the exception message
    • assertShadowVariablesAreNotStale

      void assertShadowVariablesAreNotStale(Score_ expectedWorkingScore, Object completedAction)
      Asserts that if all VariableListeners are forcibly triggered, and therefore all shadow variables are updated if needed, that none of the shadow variables of the working solution change, Then also asserts that the Score calculated for the working solution afterwards is equal to the parameter expectedWorkingScore.

      Used to assert that the shadow variables' state is consistent with the genuine variables' state.

      Parameters:
      expectedWorkingScore - never null
      completedAction - sometimes null, when assertion fails then the completedAction's Object.toString() is included in the exception message
    • assertWorkingScoreFromScratch

      void assertWorkingScoreFromScratch(Score_ workingScore, Object completedAction)
      Asserts that if the Score is calculated for the current working solution in a fresh ScoreDirector (with no incremental calculation residue), it is equal to the parameter workingScore.

      Furthermore, if the assert fails, a score corruption analysis might be included in the exception message.

      Parameters:
      workingScore - never null
      completedAction - sometimes null, when assertion fails then the completedAction's Object.toString() is included in the exception message
      See Also:
    • assertPredictedScoreFromScratch

      void assertPredictedScoreFromScratch(Score_ predictedScore, Object completedAction)
      Asserts that if the Score is calculated for the current working solution in a fresh ScoreDirector (with no incremental calculation residue), it is equal to the parameter predictedScore.

      Furthermore, if the assert fails, a score corruption analysis might be included in the exception message.

      Parameters:
      predictedScore - never null
      completedAction - sometimes null, when assertion fails then the completedAction's Object.toString() is included in the exception message
      See Also:
    • assertExpectedUndoMoveScore

      void assertExpectedUndoMoveScore(Move<Solution_> move, Score_ beforeMoveScore)
      Asserts that if the Score is calculated for the current working solution in the current ScoreDirector (with incremental calculation residue), it is equal to the parameter beforeMoveScore.

      Furthermore, if the assert fails, a score corruption analysis might be included in the exception message.

      Parameters:
      move - never null
      beforeMoveScore - never null
    • assertNonNullPlanningIds

      void assertNonNullPlanningIds()
      Asserts that none of the planning facts from ScoreDirector.getWorkingSolution() have PlanningIds with a null value.
    • close

      void close()
      Needs to be called after use because some implementations need to clean up their resources.
      Specified by:
      close in interface AutoCloseable
    • beforeVariableChanged

      void beforeVariableChanged(VariableDescriptor<Solution_> variableDescriptor, Object entity)
    • afterVariableChanged

      void afterVariableChanged(VariableDescriptor<Solution_> variableDescriptor, Object entity)
    • changeVariableFacade

      void changeVariableFacade(VariableDescriptor<Solution_> variableDescriptor, Object entity, Object newValue)
    • beforeListVariableElementAssigned

      void beforeListVariableElementAssigned(ListVariableDescriptor<Solution_> variableDescriptor, Object element)
      Call this for each element that will be assigned (added to a list variable of one entity without being removed from a list variable of another entity).
      Parameters:
      variableDescriptor - the list variable descriptor
      element - the assigned element
    • afterListVariableElementAssigned

      void afterListVariableElementAssigned(ListVariableDescriptor<Solution_> variableDescriptor, Object element)
      Call this for each element that was assigned (added to a list variable of one entity without being removed from a list variable of another entity).
      Parameters:
      variableDescriptor - the list variable descriptor
      element - the assigned element
    • beforeListVariableElementUnassigned

      void beforeListVariableElementUnassigned(ListVariableDescriptor<Solution_> variableDescriptor, Object element)
      Call this for each element that will be unassigned (removed from a list variable of one entity without being added to a list variable of another entity).
      Parameters:
      variableDescriptor - the list variable descriptor
      element - the unassigned element
    • afterListVariableElementUnassigned

      void afterListVariableElementUnassigned(ListVariableDescriptor<Solution_> variableDescriptor, Object element)
      Call this for each element that was unassigned (removed from a list variable of one entity without being added to a list variable of another entity).
      Parameters:
      variableDescriptor - the list variable descriptor
      element - the unassigned element
    • beforeListVariableChanged

      void beforeListVariableChanged(ListVariableDescriptor<Solution_> variableDescriptor, Object entity, int fromIndex, int toIndex)
      Notify the score director before a list variable changes.

      The list variable change includes:

      • Changing position (index) of one or more elements.
      • Removing one or more elements from the list variable.
      • Adding one or more elements to the list variable.
      • Any mix of the above.
      For the sake of variable listeners' efficiency, the change notification requires an index range that contains elements affected by the change. The range starts at fromIndex (inclusive) and ends at toIndex (exclusive).

      The range has to comply with the following contract:

      1. fromIndex must be greater than or equal to 0; toIndex must be less than or equal to the list variable size.
      2. toIndex must be greater than or equal to fromIndex.
      3. The range must contain all elements that are going to be changed.
      4. The range is allowed to contain elements that are not going to be changed.
      5. The range may be empty (fromIndex equals toIndex) if none of the existing list variable elements are going to be changed.

      beforeListVariableElementUnassigned(ListVariableDescriptor, Object) must be called for each element that will be unassigned (removed from a list variable of one entity without being added to a list variable of another entity).

      Parameters:
      variableDescriptor - descriptor of the list variable being changed
      entity - the entity owning the list variable being changed
      fromIndex - low endpoint (inclusive) of the changed range
      toIndex - high endpoint (exclusive) of the changed range
    • afterListVariableChanged

      void afterListVariableChanged(ListVariableDescriptor<Solution_> variableDescriptor, Object entity, int fromIndex, int toIndex)
      Notify the score director after a list variable changes.

      The list variable change includes:

      • Changing position (index) of one or more elements.
      • Removing one or more elements from the list variable.
      • Adding one or more elements to the list variable.
      • Any mix of the above.
      For the sake of variable listeners' efficiency, the change notification requires an index range that contains elements affected by the change. The range starts at fromIndex (inclusive) and ends at toIndex (exclusive).

      The range has to comply with the following contract:

      1. fromIndex must be greater than or equal to 0; toIndex must be less than or equal to the list variable size.
      2. toIndex must be greater than or equal to fromIndex.
      3. The range must contain all elements that have changed.
      4. The range is allowed to contain elements that have not changed.
      5. The range may be empty (fromIndex equals toIndex) if none of the existing list variable elements have changed.

      afterListVariableElementUnassigned(ListVariableDescriptor, Object) must be called for each element that was unassigned (removed from a list variable of one entity without being added to a list variable of another entity).

      Parameters:
      variableDescriptor - descriptor of the list variable being changed
      entity - the entity owning the list variable being changed
      fromIndex - low endpoint (inclusive) of the changed range
      toIndex - high endpoint (exclusive) of the changed range
    • forceTriggerVariableListeners

      void forceTriggerVariableListeners()
      Unlike ScoreDirector.triggerVariableListeners() which only triggers notifications already in the queue, this triggers every variable listener on every genuine variable. This is useful in SolutionManager.update(Object) to fill in shadow variable values.