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-corr...
Sent from the Drools: User forum mailing list archive at
Nabble.com.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
--
With kind regards,
Geoffrey De Smet