Interface InnerScoreDirector<Solution_,Score_ extends Score<Score_>>
-
- Type Parameters:
Solution_- the solution type, the class with thePlanningSolutionannotationScore_- the score type to go with the solution
- All Superinterfaces:
AutoCloseable,ScoreDirector<Solution_>
- All Known Implementing Classes:
AbstractScoreDirector,EasyScoreDirector,IncrementalScoreDirector
public interface InnerScoreDirector<Solution_,Score_ extends Score<Score_>> extends ScoreDirector<Solution_>, AutoCloseable
-
-
Method Summary
All Methods Instance Methods Abstract Methods Modifier and Type Method Description voidafterListVariableChanged(ListVariableDescriptor<Solution_> variableDescriptor, Object entity, int fromIndex, int toIndex)Notify the score director after a list variable changes.voidafterListVariableElementAssigned(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).voidafterListVariableElementUnassigned(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).voidafterVariableChanged(VariableDescriptor<Solution_> variableDescriptor, Object entity)voidassertExpectedUndoMoveScore(Move<Solution_> move, Score_ beforeMoveScore)Asserts that if theScoreis calculated for the currentworking solutionin the currentScoreDirector(with incremental calculation residue), it is equal to the parameterbeforeMoveScore.voidassertExpectedWorkingScore(Score_ expectedWorkingScore, Object completedAction)Asserts that if theScoreis calculated for the currentworking solutionin the currentScoreDirector(with possibly incremental calculation residue), it is equal to the parameterexpectedWorkingScore.voidassertNonNullPlanningIds()Asserts that none of the planning facts fromScoreDirector.getWorkingSolution()havePlanningIds with a null value.voidassertPredictedScoreFromScratch(Score_ predictedScore, Object completedAction)Asserts that if theScoreis calculated for the currentworking solutionin a freshScoreDirector(with no incremental calculation residue), it is equal to the parameterpredictedScore.voidassertShadowVariablesAreNotStale(Score_ expectedWorkingScore, Object completedAction)Asserts that if allVariableListeners are forcibly triggered, and therefore all shadow variables are updated if needed, that none of the shadow variables of theworking solutionchange, Then also asserts that theScorecalculated for theworking solutionafterwards is equal to the parameterexpectedWorkingScore.voidassertWorkingScoreFromScratch(Score_ workingScore, Object completedAction)Asserts that if theScoreis calculated for the currentworking solutionin a freshScoreDirector(with no incremental calculation residue), it is equal to the parameterworkingScore.voidbeforeListVariableChanged(ListVariableDescriptor<Solution_> variableDescriptor, Object entity, int fromIndex, int toIndex)Notify the score director before a list variable changes.voidbeforeListVariableElementAssigned(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).voidbeforeListVariableElementUnassigned(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).voidbeforeVariableChanged(VariableDescriptor<Solution_> variableDescriptor, Object entity)Score_calculateScore()Calculates theScoreand updates theworking solutionaccordingly.voidchangeVariableFacade(VariableDescriptor<Solution_> variableDescriptor, Object entity, Object newValue)InnerScoreDirector<Solution_,Score_>clone()Clones thisScoreDirectorand itsworking solution.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.Solution_cloneWorkingSolution()Returns a planning clone of the solution, which is not a shallow clone nor a deep clone nor a partition clone.voidclose()Needs to be called after use because some implementations need to clean up their resources.InnerScoreDirector<Solution_,Score_>createChildThreadScoreDirector(ChildThreadType childThreadType)Score_doAndProcessMove(Move<Solution_> move, boolean assertMoveScoreFromScratch)voiddoAndProcessMove(Move<Solution_> move, boolean assertMoveScoreFromScratch, Consumer<Score_> moveProcessor)booleanexpectShadowVariablesInCorrectState()Inverse shadow variables have a fail-fast for cases where the shadow variable doesn't actually point to its correct inverse.voidforceTriggerVariableListeners()UnlikeScoreDirector.triggerVariableListeners()which only triggers notifications already in the queue, this triggers every variable listener on every genuine variable.longgetCalculationCount()Map<String,ConstraintMatchTotal<Score_>>getConstraintMatchTotalMap()Map<Object,Indictment<Score_>>getIndictmentMap()Explains the impact of each planning entity or problem fact on theScore.ScoreDefinition<Score_>getScoreDefinition()InnerScoreDirectorFactory<Solution_,Score_>getScoreDirectorFactory()SolutionDescriptor<Solution_>getSolutionDescriptor()SupplyManagergetSupplyManager()longgetWorkingEntityListRevision()voidincrementCalculationCount()booleanisConstraintMatchEnabled()booleanisWorkingEntityListDirty(long expectedWorkingEntityListRevision)voidoverwriteConstraintMatchEnabledPreference(boolean constraintMatchEnabledPreference)booleanrequiresFlushing()Some score directors (such as the Drools-based) keep a set of changes that they only apply whencalculateScore()is called.voidresetCalculationCount()voidsetAllChangesWillBeUndoneBeforeStepEnds(boolean allChangesWillBeUndoneBeforeStepEnds)Do not waste performance by propagating changes to step (or higher) mechanisms.voidsetWorkingSolution(Solution_ workingSolution)Theworking solutionmust never be the same instance as thebest solution, it should be a (un)changed clone.-
Methods inherited from interface ai.timefold.solver.core.api.score.director.ScoreDirector
afterEntityAdded, afterEntityRemoved, afterListVariableChanged, afterListVariableElementAssigned, afterListVariableElementUnassigned, afterProblemFactAdded, afterProblemFactRemoved, afterProblemPropertyChanged, afterVariableChanged, beforeEntityAdded, beforeEntityRemoved, beforeListVariableChanged, beforeListVariableElementAssigned, beforeListVariableElementUnassigned, beforeProblemFactAdded, beforeProblemFactRemoved, beforeProblemPropertyChanged, beforeVariableChanged, getWorkingSolution, lookUpWorkingObject, lookUpWorkingObjectOrReturnNull, triggerVariableListeners
-
-
-
-
Method Detail
-
setWorkingSolution
void setWorkingSolution(Solution_ workingSolution)
Theworking solutionmust never be the same instance as thebest solution, it should be a (un)changed clone.- Parameters:
workingSolution- never null
-
calculateScore
Score_ calculateScore()
Calculates theScoreand updates theworking solutionaccordingly.- Returns:
- never null, the
Scoreof theworking solution
-
isConstraintMatchEnabled
boolean isConstraintMatchEnabled()
- Returns:
- true if
getConstraintMatchTotalMap()andgetIndictmentMap()can be called
-
getConstraintMatchTotalMap
Map<String,ConstraintMatchTotal<Score_>> getConstraintMatchTotalMap()
Explains theScoreofcalculateScore()by splitting it up perConstraint.The sum of
ConstraintMatchTotal.getScore()equalscalculateScore().Call
calculateScore()before calling this method, unless that method has already been called since the lastPlanningVariablechanges.- Returns:
- never null, the key is the
constraintId(to create one, useConstraintMatchTotal.composeConstraintId(String, String)). - Throws:
IllegalStateException- ifisConstraintMatchEnabled()returns false- See Also:
getIndictmentMap()
-
getIndictmentMap
Map<Object,Indictment<Score_>> getIndictmentMap()
Explains the impact of each planning entity or problem fact on theScore. AnIndictmentis basically the inverse of aConstraintMatchTotal: it is aScoretotal for eachconstraint justification.The sum of
ConstraintMatchTotal.getScore()differs fromcalculateScore()because eachConstraintMatch.getScore()is counted for eachconstraint justification.Call
calculateScore()before calling this method, unless that method has already been called since the lastPlanningVariablechanges.- Returns:
- never null, the key is a
problem factor aplanning entity - Throws:
IllegalStateException- ifisConstraintMatchEnabled()returns false- See Also:
getConstraintMatchTotalMap()
-
overwriteConstraintMatchEnabledPreference
void overwriteConstraintMatchEnabledPreference(boolean constraintMatchEnabledPreference)
- Parameters:
constraintMatchEnabledPreference- false if aScoreDirectorimplementation should not doConstraintMatchtracking 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 nullassertMoveScoreFromScratch- true will hurt performance- Returns:
- never null
-
doAndProcessMove
void doAndProcessMove(Move<Solution_> move, boolean assertMoveScoreFromScratch, Consumer<Score_> moveProcessor)
- Parameters:
move- never nullassertMoveScoreFromScratch- true will hurt performancemoveProcessor- 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 whencalculateScore()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.
-
expectShadowVariablesInCorrectState
boolean expectShadowVariablesInCorrectState()
Inverse shadow variables have a fail-fast for cases where the shadow variable doesn't actually point to its correct inverse. This is very useful to pinpoint improperly initialized solutions.However,
SolutionManager.update(Object)exists precisely for the purpose of initializing solutions. And when this API is used, the fail-fast must not be triggered as it is guaranteed and expected that the inverse relationships will be wrong. In fact, they will be null.For this case and this case only, this method is allowed to return false. All other cases must return true, otherwise a very valuable fail-fast is lost.
- Returns:
- false if the fail-fast on shadow variables should not be triggered
-
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
InnerScoreDirector<Solution_,Score_> clone()
Clones thisScoreDirectorand itsworking solution. UseScoreDirector.getWorkingSolution()to retrieve theworking solutionof 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 theScoreis calculated for the currentworking solutionin the currentScoreDirector(with possibly incremental calculation residue), it is equal to the parameterexpectedWorkingScore.Used to assert that skipping
calculateScore()(when the score is otherwise determined) is correct.- Parameters:
expectedWorkingScore- never nullcompletedAction- sometimes null, when assertion fails then the completedAction'sObject.toString()is included in the exception message
-
assertShadowVariablesAreNotStale
void assertShadowVariablesAreNotStale(Score_ expectedWorkingScore, Object completedAction)
Asserts that if allVariableListeners are forcibly triggered, and therefore all shadow variables are updated if needed, that none of the shadow variables of theworking solutionchange, Then also asserts that theScorecalculated for theworking solutionafterwards is equal to the parameterexpectedWorkingScore.Used to assert that the shadow variables' state is consistent with the genuine variables' state.
- Parameters:
expectedWorkingScore- never nullcompletedAction- sometimes null, when assertion fails then the completedAction'sObject.toString()is included in the exception message
-
assertWorkingScoreFromScratch
void assertWorkingScoreFromScratch(Score_ workingScore, Object completedAction)
Asserts that if theScoreis calculated for the currentworking solutionin a freshScoreDirector(with no incremental calculation residue), it is equal to the parameterworkingScore.Furthermore, if the assert fails, a score corruption analysis might be included in the exception message.
- Parameters:
workingScore- never nullcompletedAction- sometimes null, when assertion fails then the completedAction'sObject.toString()is included in the exception message- See Also:
InnerScoreDirectorFactory.assertScoreFromScratch(Solution_)
-
assertPredictedScoreFromScratch
void assertPredictedScoreFromScratch(Score_ predictedScore, Object completedAction)
Asserts that if theScoreis calculated for the currentworking solutionin a freshScoreDirector(with no incremental calculation residue), it is equal to the parameterpredictedScore.Furthermore, if the assert fails, a score corruption analysis might be included in the exception message.
- Parameters:
predictedScore- never nullcompletedAction- sometimes null, when assertion fails then the completedAction'sObject.toString()is included in the exception message- See Also:
InnerScoreDirectorFactory.assertScoreFromScratch(Solution_)
-
assertExpectedUndoMoveScore
void assertExpectedUndoMoveScore(Move<Solution_> move, Score_ beforeMoveScore)
Asserts that if theScoreis calculated for the currentworking solutionin the currentScoreDirector(with incremental calculation residue), it is equal to the parameterbeforeMoveScore.Furthermore, if the assert fails, a score corruption analysis might be included in the exception message.
- Parameters:
move- never nullbeforeMoveScore- never null
-
assertNonNullPlanningIds
void assertNonNullPlanningIds()
Asserts that none of the planning facts fromScoreDirector.getWorkingSolution()havePlanningIds with a null value.
-
close
void close()
Needs to be called after use because some implementations need to clean up their resources.- Specified by:
closein interfaceAutoCloseable
-
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 descriptorelement- 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 descriptorelement- 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 descriptorelement- 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 descriptorelement- 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.
fromIndex(inclusive) and ends attoIndex(exclusive).The range has to comply with the following contract:
fromIndexmust be greater than or equal to 0;toIndexmust be less than or equal to the list variable size.toIndexmust be greater than or equal tofromIndex.- The range must contain all elements that are going to be changed.
- The range is allowed to contain elements that are not going to be changed.
- The range may be empty (
fromIndexequalstoIndex) 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 changedentity- the entity owning the list variable being changedfromIndex- low endpoint (inclusive) of the changed rangetoIndex- 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.
fromIndex(inclusive) and ends attoIndex(exclusive).The range has to comply with the following contract:
fromIndexmust be greater than or equal to 0;toIndexmust be less than or equal to the list variable size.toIndexmust be greater than or equal tofromIndex.- The range must contain all elements that have changed.
- The range is allowed to contain elements that have not changed.
- The range may be empty (
fromIndexequalstoIndex) 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 changedentity- the entity owning the list variable being changedfromIndex- low endpoint (inclusive) of the changed rangetoIndex- high endpoint (exclusive) of the changed range
-
forceTriggerVariableListeners
void forceTriggerVariableListeners()
UnlikeScoreDirector.triggerVariableListeners()which only triggers notifications already in the queue, this triggers every variable listener on every genuine variable. This is useful inSolutionManager.update(Object)to fill in shadow variable values.
-
-