I need to run a calculation into memory at the end of each move and then update the score based on this. The outcome of the calculation needs to be stateful as its referenced elsewhere (stored on the solution).
The documentation suggests this should be a PlanningEntity updated as a ShadowVariable with a VariableListener on the main entity but of course this naturally triggers per entity change, re-calculating unnecessarily.
Further info:
1) Sounds like you should use a shadow variable. Do note you still need a normal constraint too update the score according to that shadow variable's state.
Do note that you can have a shadow entity class that is a singleton (per problem solution) which has a single shadow variable that is updated if any planning entity changes. Use @PlanningEntityProperty
(without Collection
) on a @PlanningSolution
class's field.
At the end of a move, each Move calls triggerShadowVariableListeners()
, not in the middle. So if you're worried about performance, you shouldn't be.
If you're worried about correctness - because the number of calls affects your calculation - well don't design/implement it that way...
2) ProblemFacts can't change during solving (not counting real-time planning). Not a single field of them. Otherwise it's a PlanningEntity.
0) MoveListener doesn't exist, intentionally (for good reasons), not even internally (even the very internal PhaseLifecycleListener only listens to steps, not moves).