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

guyramirez guyramirez at hotmail.com
Mon Dec 5 23:38:29 EST 2011


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).

	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"
	when
		$intervalReq : IntervalRequirement($interval : interval, $position :
position, $staffingRequired : staffingRequired)
        $matchingShiftAssignments : ArrayList( size <= $staffingRequired )
        								from collect ( ShiftAssignment(shiftStartTime <= $interval,
shiftEndTime > $interval, position == $position) )
	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);
	}
	
	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;
	}

	@PlanningVariable
	@ValueRangeFromPlanningEntityProperty(propertyName =
"possibleShiftStartTimeLengthPairs")
	public TimeLengthPair getShiftStartTimeLengthPair() {
		return this.timeLengthPair;
	}

	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.



More information about the rules-users mailing list