[rules-users] Planner 5.3.Final - "presumedScore is corrupted" when using "update" on the rules working memory => shadow proxies problems?

Patrik Dufresne ikus060 at gmail.com
Tue Dec 6 20:18:59 EST 2011


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.spam at 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 at lists.jboss.org
> > https://lists.jboss.org/mailman/listinfo/rules-users
> >
>
> --
> With kind regards,
> Geoffrey De Smet
>
>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>



-- 
Patrik Dufresne
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20111206/0d7095c2/attachment.html 


More information about the rules-users mailing list