java - Variablelistener corruption with anchorshadowedvariable in optaplanner -
i trying solve planning problem time window vehicule routing problem.
so looking solution containing list of tasks. tasks can assigneed 1 of 2 workers.
my task class looks (i didn't cut/paste getters , setters here) :
@planningentity(difficultycomparatorclass = taskdifficultycomparator.class) public class task implements location { private string location; private localtime arrivaltime; private location previouslocation; private task nexttask; private startlocal startlocal; private duration taskduration = duration.ofminutes(20); private localtime readytime; private localtime duetime; @planningvariable(valuerangeproviderrefs = {"tasks", "startlocal"}, graphtype = planningvariablegraphtype.chained) public location getpreviouslocation() { return previouslocation; } public void setpreviouslocation(location previouslocation) { this.previouslocation = previouslocation; } @override public string {return location;} @override public void setlocation(string location) {this.location = location;} public int gettimetogoto(location location) { .... } @anchorshadowvariable(sourcevariablename = "previouslocation") public startlocal getstartlocal() { return startlocal; } public void setstartlocal(startlocal startlocal) { this.startlocal = startlocal; } @customshadowvariable(variablelistenerclass = arrivaltimevariablelistener.class, sources = {@customshadowvariable.source(variablename = "previouslocation")}) public localtime getarrivaltime() { return arrivaltime; } public void setarrivaltime(localtime arrivaltime) { this.arrivaltime = arrivaltime; } }
and variable listener class :
public class arrivaltimevariablelistener implements variablelistener<task> { @override public void beforeentityadded(scoredirector scoredirector, task task) {} @override public void afterentityadded(scoredirector scoredirector, task task) { updatearrivaltime(scoredirector, task); } @override public void beforevariablechanged(scoredirector scoredirector, task task) { } @override public void aftervariablechanged(scoredirector scoredirector, task task) { updatearrivaltime(scoredirector, task); } @override public void beforeentityremoved(scoredirector scoredirector, task task) { } @override public void afterentityremoved(scoredirector scoredirector, task task) { } private void updatearrivaltime(scoredirector scoredirector, task task){ localtime arrivaltimeinthislocation = calculatearrivaltime(task); task shadowtask = task; while (shadowtask != null) { scoredirector.beforevariablechanged(shadowtask, "arrivaltime"); shadowtask.setarrivaltime(arrivaltimeinthislocation); scoredirector.aftervariablechanged(shadowtask, "arrivaltime"); shadowtask = shadowtask.getnexttask(); if(shadowtask!=null)arrivaltimeinthislocation = calculatearrivaltime(shadowtask); } } @visiblefortesting static public localtime calculatearrivaltime(task task){ localtime whenarriveatpreviouslocation = task.getpreviouslocation().getarrivaltime(); int secondstogo = task.gettimetogoto(task.getpreviouslocation()); long secondstocompletelasttask = 0; if(task.getpreviouslocation() instanceof task){ secondstocompletelasttask = ((task) task.getpreviouslocation()).gettaskduration().getseconds(); } localtime whenarriveinthislocationasap = whenarriveatpreviouslocation. plusseconds(secondstocompletelasttask). plusseconds(secondstogo); if(whenarriveinthislocationasap.isafter(task.getreadytime())){ return whenarriveinthislocationasap; } return task.getreadytime(); } }
when try solve problem have following error :
variablelistener corruption: entity (task s shadow variable (task.arrivaltime)'s corrupted value (09:32) changed uncorrupted value (09:33) after variablelisteners triggered without changes genuine variables. variablelistener class shadow variable (task.arrivaltime) forgot update when 1 of sources changed after completedaction (initial score calculated).
i know issue duplicate of this one. read (very very) carrefully answer of sof question, , can't understand doing wrong.
i understood, role of variable listener in use case update "arrivaltime" of tasks following tasks change. isn't ?
add updatearrivaltime()
method beforevaluechanged()
.
my guess you're on full_assert
.
Comments
Post a Comment