Search code examples
optaplanner

OptaPlanner, in VariableListener change shadow variable of other entity


Working on my project based on optaplanner example taskassigning. In the example, StartTimeUpdatingVariableListener updateStartTime() changes the time of the source-task. Will it be OK, right in the function, change the shadow variable of the previous task instead of the source task? Because in my scenario, each task has a waiting time (shadow variable), only when a new task is added, the previous task's waiting time can be calculated. Different source task will bring different waiting time to its previous task. Eventually the sum of all employees' waiting time will be minimized in rule. Looking at the example, in the listener, only the source task time is updated, and is surrounded by beforeVariableChanged and afterVariableChanged. Will there be any problem to update other task's shadow variable?


Solution

  • You can't create cycles that would cause infinite loops.


    Across different shadow variable declarations

    A custom shadow variable (VariableListener) can trigger another custom shadow variable (VariableListener), for example in the image below C triggers E. So the VariableListener of C that changes variable C, triggers (delayed) events on the VariableListener of E.

    shadow variable order

    But the dependency tree cannot contain a cycle, OptaPlanner validates this through the sources attribute.

    Notice how all the variable listeners methods of C are called before the first of E is called. They are delayed. OptaPlanner give you this guarantee behind the scenes.


    For a single shadow variable declaration

    The VariableListener for C is triggered when A or B changes. So when it changes a C variable, no new trigger events for that VariableListeners are created.

    When a single A variable changes, one event is triggered on the VariableListener for C, which can change multiple C variables. The loop that changes those multiple C variable must not be an infinite loop.

    In practice, with VRP and task assignment scheduling, I 've found that they only way to guarantee the absence of an infinite loop is to only make changes forward in time. So in a chained model, follow the next variables, but not the previous.