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

Geoffrey De Smet ge0ffrey.spam at gmail.com
Tue Dec 6 11:12:14 EST 2011



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





More information about the rules-users mailing list