Search code examples
javadroolsoptaplanner

Optaplanner - drools uses old shadow variables


I am using VRP problem example with some changes. One is calculating arrival and destination time for all tasks. Another is nessesity for some of pairs of tasks to have same arrival time. And after updating arrival time I "move" parallel tasks - and change theirs date. So move step can change task's shadow variable on another vehicle.

But drools rule validating if arrival of two tasks is the same does not see this change. It's like they do not change object at all. What am I doing wrong? Maybe my aproach is wrong?

Parallel tasks are not marked as ShadowVaraible or PlanningVariable.

Listener:

public class ArrivalTimeUpdatingVariableListener implements VariableListener<Task> {

    @Override
    public void afterEntityAdded(ScoreDirector scoreDirector, Task task) {
        updateTaskAssignmentTimes(scoreDirector);
    }

    @Override
    public void afterVariableChanged(ScoreDirector scoreDirector, Task task) {
        updateTaskAssignmentTimes(scoreDirector);
    }

    (...)

    scoreDirector.beforeVariableChanged(task, "arrivalTime");
    task.setArrivalTime(task.getArrivalTime() + diff);
    scoreDirector.afterVariableChanged(task, "arrivalTime");

    (...)

}

Task:

@PlanningEntity(difficultyWeightFactoryClass = DepotAngleTaskDifficultyWeightFactory.class)
public class Task extends AbstractPersistable implements Standstill {

    (...)

    @CustomShadowVariable(variableListenerClass = ArrivalTimeUpdatingVariableListener.class, sources = {@PlanningVariableReference(variableName = "previousStandstill")})
    private Long arrivalTime;

    @CustomShadowVariable(variableListenerClass = ArrivalTimeUpdatingVariableListener.class, sources = {@PlanningVariableReference(variableName = "previousStandstill")})
    private Long departureTime;

    (...)

}

drl:

rule "Parallel task soft relation"
when
    $task : Task(assigned, relations.tasksParallel.size() > 0, $tasksParallel : relations.tasksParallel)
    Task(assigned, $tasksParallel.contains(id), doesNotHaveSameArrivalTime($task))
then
    scoreHolder.addHardConstraintMatch(kcontext, -1088);
end

Solution

  • I had @CustomShadowVariable annotation on field and used lombok with it. When I put annotation on getter (manually created) then rules starts working...