Op 07-12-11 02:18, Patrik Dufresne schreef:
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.
They are added:

         for (Object fact : getWorkingFacts()) {
            tmpWorkingMemory.insert(fact);
        }

    public Collection<Object> getWorkingFacts() {
return solutionDescriptor.getAllFacts(workingSolution); // returns the problem facts + the initiliazed planningEntity's
    }

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.
That's weird.

Could you try this with the latest drools-planner-core 5.4.0.SNAPSHOT from the jboss nexus repository too?
You'll have to branch and upgrade your local code:
https://github.com/droolsjbpm/drools-planner/blob/master/drools-planner-distribution/src/main/assembly/filtered-resources/UpgradeFromPreviousVersionRecipe.txt

As a side affect, you'll notice that the exception message will be much much clearer too, which will help in discovering the problem.

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 <[email protected] <mailto:[email protected]>> 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
    <http://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
    > [email protected] <mailto:[email protected]>
    > https://lists.jboss.org/mailman/listinfo/rules-users
    >

    --
    With kind regards,
    Geoffrey De Smet


    _______________________________________________
    rules-users mailing list
    [email protected] <mailto:[email protected]>
    https://lists.jboss.org/mailman/listinfo/rules-users




--
Patrik Dufresne


_______________________________________________
rules-users mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/rules-users

--
With kind regards,
Geoffrey De Smet

_______________________________________________
rules-users mailing list
[email protected]
https://lists.jboss.org/mailman/listinfo/rules-users

Reply via email to