I'm still experimenting with Drools Planner and I also have the exact same issue :
java.lang.IllegalStateException: The presumedScore (0hard/-1soft) is corrupted because it is not the realScore (0hard/0soft). Presumed workingMemory: Score rule (soft-ReduceNullAssignment) has count (1) and weight total (1). Real workingMemory: at org.drools.planner.core.solution.director.DefaultSolutionDirector.assertWorkingScore(DefaultSolutionDirector.java:157) at org.drools.planner.core.solver.DefaultSolverScope.assertWorkingScore(DefaultSolverScope.java:105) at org.drools.planner.core.phase.AbstractSolverPhaseScope.assertWorkingScore(AbstractSolverPhaseScope.java:132) at org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:69) at org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:166) at org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:138) ... I've read this (https://issues.jboss.org/browse/JBRULES-3301), but it didn't help : - I'm using IntConstraintOccurrence - I double check the soft constraint named "soft-ReduceNullAssignment" -- it's include all the cause. - I'm using Drools 5.3 After more digging, I think something is missing in DefaultSolutionDirector.java:153. The facts are added, but the planningEntity are not added. So when the score calculation is running, there is two different result. I'v place a breakpoint at DefaultSolutionDirector.java:157 and looking in tmpWorkingMemory->defaultEntryPoint->objectStore->identifyMap->table, I don't see the planningEntity. Here is the my rule : rule "soft-ReduceNullAssignment" when $planif : PlanifEventAssignment( employee == null ) then insertLogical(new IntConstraintOccurrence("soft-ReduceNullAssignment", ConstraintType.NEGATIVE_SOFT, 1, $planif)); end Thanks On Tue, Dec 6, 2011 at 11:12 AM, Geoffrey De Smet <ge0ffrey.s...@gmail.com>wrote: > > > Op 06-12-11 05:38, guyramirez schreef: > > Still the same issue, starting with the construction heuristic phase. > Please > > let me know if you need more explanations in what I am trying to do. > > > > Here is the error. Please note that there is only one planning entity > > (ShiftAssignment) object instance in this test. > > > > Total Staffing required: 8 > > 2011-12-05 22:21:49,627 [main] INFO Solver started: time spend (0), > score > > (null), new best score (null), random seed (0). > > ShiftAssignment: emp. id: 10 [st: 100, dur: 3] > > ShiftAssignment: emp. id: 10 [st: 100, dur: 2] > > ShiftAssignment: emp. id: 10 [st: 100, dur: 4] > > ShiftAssignment: emp. id: 10 [st: 100, dur: 1] > > 2011-12-05 22:21:49,678 [main] TRACE Building ConstraintOccurrence > summary > > 2011-12-05 22:21:49,678 [main] TRACE Adding ConstraintOccurrence > > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement: interval: > > 101, position id: 1, staffingRequired: 2, [ShiftAssignment: emp. id: 10 > [st: > > 100, dur: 1]]]=1) > > 2011-12-05 22:21:49,678 [main] TRACE Adding ConstraintOccurrence > > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement: interval: > > 103, position id: 1, staffingRequired: 2, []]=2) > > 2011-12-05 22:21:49,678 [main] TRACE Adding ConstraintOccurrence > > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement: interval: > > 102, position id: 1, staffingRequired: 2, []]=2) > > 2011-12-05 22:21:49,678 [main] TRACE Adding ConstraintOccurrence > > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement: interval: > > 100, position id: 1, staffingRequired: 2, [ShiftAssignment: emp. id: 10 > [st: > > 100, dur: 1], ShiftAssignment: emp. id: 10 [st: 100, dur: 1]]]=0) > > 2011-12-05 22:21:49,678 [main] TRACE Building ConstraintOccurrence > summary > > 2011-12-05 22:21:49,678 [main] TRACE Adding ConstraintOccurrence > > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement: interval: > > 101, position id: 1, staffingRequired: 2, []]=2) > > 2011-12-05 22:21:49,678 [main] TRACE Adding ConstraintOccurrence > > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement: interval: > > 103, position id: 1, staffingRequired: 2, []]=2) > > 2011-12-05 22:21:49,678 [main] TRACE Adding ConstraintOccurrence > > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement: interval: > > 100, position id: 1, staffingRequired: 2, [ShiftAssignment: emp. id: 10 > [st: > > 100, dur: 1]]]=1) > > 2011-12-05 22:21:49,678 [main] TRACE Adding ConstraintOccurrence > > (intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement: interval: > > 102, position id: 1, staffingRequired: 2, []]=2) > > Exception in thread "main" java.lang.IllegalStateException: The > > presumedScore (-5hard/-1soft) is corrupted because it is not the > realScore > > (-7hard/-1soft). > > Presumed workingMemory: > > Score rule (intervalRequirementCovered) has count (4) and weight total > > (5). > > Real workingMemory: > > Score rule (intervalRequirementCovered) has count (4) and weight total > > (7). > So the score rule intervalRequirementCovered is to blame. > > at > > > org.drools.planner.core.solution.director.DefaultSolutionDirector.assertWorkingScore(DefaultSolutionDirector.java:157) > > at > > > org.drools.planner.core.solver.DefaultSolverScope.assertWorkingScore(DefaultSolverScope.java:105) > > at > > > org.drools.planner.core.phase.AbstractSolverPhaseScope.assertWorkingScore(AbstractSolverPhaseScope.java:132) > > at > > > org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.decideNextStep(DefaultGreedyDecider.java:65) > > at > > > org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:62) > > at > > > org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:166) > > at > > > org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:138) > > at > com.lfsoscience.planner.LfsoPlannerMain.execute(LfsoPlannerMain.java:36) > > at > com.lfsoscience.planner.LfsoPlannerMain.main(LfsoPlannerMain.java:27) > > > > > > > > The drl: > > rule "intervalRequirementCovered" > Let's take a look > > when > > $intervalReq : IntervalRequirement($interval : interval, > $position : > > position, $staffingRequired : staffingRequired) > > $matchingShiftAssignments : ArrayList( size<= $staffingRequired > ) > > > from collect ( ShiftAssignment(shiftStartTime<= $interval, > > shiftEndTime> $interval, position == $position) ) > I never used "from collect" in my examples yet. > You probably stumbled upon a "statefull memory corruption bug" in drools. > > First try this alternative way: > > $intervalReq : IntervalRequirement($interval : interval, > $position : position, $staffingRequired : staffingRequired) > $matchingShiftAssignmentSize : Number(intValue <= > $staffingRequired) from accumulate( > $x : ShiftAssignment(shiftStartTime <= $interval, > shiftEndTime > $interval, position == $position), > count($x) > ) > > If that works, file a ticket in issues.jboss.org for the project JBRULES > about "statefull working memory corruption by using collect" > and include that rule and - if possible - testdata how to reproduce it. > > then > > #actions > > insertLogical(new > IntConstraintOccurrence("intervalRequirementCovered", > > ConstraintType.NEGATIVE_HARD, > > $staffingRequired - > $matchingShiftAssignments.size(), > > $intervalReq, > $matchingShiftAssignments)); > > end > > rule "hardConstraintsBroken" > > salience -1 // Do the other rules first (optional, for > performance) > > when > > $hardTotal : Number() from accumulate( > > IntConstraintOccurrence(constraintType == > > ConstraintType.NEGATIVE_HARD, $weight : weight), sum($weight) > > ) > > then > > scoreCalculator.setHardConstraintsBroken($hardTotal.intValue()); > > end > > rule "softConstraintsBroken" > > when > > eval(true) > > then > > scoreCalculator.setSoftConstraintsBroken(1); > > end > > > > > > > > The Planning Entity: > > > > @PlanningEntity > > public class ShiftAssignment implements Cloneable { > > private Employee employee; > > private int day; > > private Position position; > > private TimeLengthPair timeLengthPair = null; > > // Immutable object. Does not need to be cloned when calling clone > > private List<TimeLengthPair> possibleShiftStartTimeLengthPairList; > > private Set<TimeLengthPair> possibleShiftStartTimeLengthPairSet; > > > > > > public ShiftAssignment(Employee employee, int day, Position > position, > > Set<TimeLengthPair> shiftStartTimeLengthPairs) { > > this.employee = employee; > > this.day = day; > > this.position = position; > > this.possibleShiftStartTimeLengthPairSet = new > > HashSet<TimeLengthPair>(shiftStartTimeLengthPairs); > > } > > > > public int getShiftStartTime() { > > return this.timeLengthPair != null ? > this.timeLengthPair.getStartTime() : > > -1; > > } > > > > public int getShiftEndTime() { > > return this.timeLengthPair != null ? > this.timeLengthPair.getStartTime() + > > this.timeLengthPair.getLength() : -1; > > } > > > > public void setShiftStartTimeLengthPair(TimeLengthPair > timeLengthPair) { > > this.timeLengthPair = timeLengthPair; > > System.out.println(this); > > } > looks good > > > > public void addPossibleShiftStartTimeLengthPair(TimeLengthPair > > timeLengthPair) { > > > this.possibleShiftStartTimeLengthPairSet.add(timeLengthPair); > > // Clear the list since the Set has changed. The list will > be recreated > > from the set when needed (see getPossibleShiftStartTimeLengthPairs()) > > this.possibleShiftStartTimeLengthPairList = null; > > } > this isn't called during planning I presume? > > @PlanningVariable > > @ValueRangeFromPlanningEntityProperty(propertyName = > > "possibleShiftStartTimeLengthPairs") > > public TimeLengthPair getShiftStartTimeLengthPair() { > > return this.timeLengthPair; > > } > looks good > > public List<TimeLengthPair> > getPossibleShiftStartTimeLengthPairs() { > > if (this.possibleShiftStartTimeLengthPairList == null) { > > this.possibleShiftStartTimeLengthPairList = new > > ArrayList<TimeLengthPair>(this.possibleShiftStartTimeLengthPairSet); > > } > > return this.possibleShiftStartTimeLengthPairList; > > } > > > > public Employee getEmployee() { > > return this.employee; > > } > > > > public int getDay() { > > return this.day; > > } > > > > public Position getPosition() { > > return this.position; > > } > > > > public boolean solutionEquals(Object o) { > > if (this == o) { > > return true; > > } else if (o instanceof ShiftAssignment) { > > ShiftAssignment other = (ShiftAssignment) o; > > return new EqualsBuilder() > > .append(this.employee, other.employee) > > .append(this.position, other.position) > > .append(this.timeLengthPair, other.timeLengthPair) > > .isEquals(); > > } else { > > return false; > > } > > } > > > > public int solutionHashCode() { > > HashCodeBuilder hashCodeBuilder = new HashCodeBuilder(); > > hashCodeBuilder.append(getClass()) > > .append(this.employee) > > .append(this.position) > > .append(this.timeLengthPair); > > return hashCodeBuilder.toHashCode(); > > } > > > > @Override > > public Object clone() throws CloneNotSupportedException { > > return super.clone(); > > } > > > > @Override > > public String toString() { > > StringBuilder sb = new StringBuilder(); > > sb.append("ShiftAssignment: ") > > .append("emp. id: ").append(this.employee.getId()) > > .append(" ") > > .append(this.timeLengthPair != null ? > this.timeLengthPair.toString() : > > "Not Initialized"); > > return sb.toString(); > > } > > > > @Override > > public int hashCode() { > > return solutionHashCode(); > > // return super.hashCode(); > > } > > > > @Override > > public boolean equals(Object obj) { > > return solutionEquals(obj); > > // return super.equals(obj); > > } > > } > > > > > > -- > > View this message in context: > http://drools.46999.n3.nabble.com/Planner-5-3-Final-presumedScore-is-corrupted-when-using-update-on-the-rules-working-memory-tp3546932p3563446.html > > Sent from the Drools: User forum mailing list archive at Nabble.com. > > _______________________________________________ > > rules-users mailing list > > rules-users@lists.jboss.org > > https://lists.jboss.org/mailman/listinfo/rules-users > > > > -- > With kind regards, > Geoffrey De Smet > > > _______________________________________________ > rules-users mailing list > rules-users@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/rules-users > -- Patrik Dufresne
_______________________________________________ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users