During my debugging, I notice the call to getWorkingFacts() doesn't include the planning entities. To make sure, I've run the NQueens example (that use the same construction heuristic) : the call to getWorkingFacts() include the planning entities.<div>
<br></div><div>After more debugging, I figure out the problem. The ValueRange of my PlanningEntity include 'null'. I use null for un-assigned shift. In PlanningVariableDescriptor.java:149, the check for initialized variable return False if the value is null. Then my planning entity is wrongly identify as not initialized and the SolutionDescriptor.java:135 doesn't include it in the facts list.</div>
<div><br></div><div>So how do I fix it ?</div><div><br><div class="gmail_quote">2011/12/7 Geoffrey De Smet <span dir="ltr"><<a href="mailto:ge0ffrey.spam@gmail.com" target="_blank">ge0ffrey.spam@gmail.com</a>></span><br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<u></u><div text="#000000" bgcolor="#ffffff">
<br>
<br>Op 07-12-11 02:18, Patrik Dufresne schreef:<div><blockquote type="cite">I'm still experimenting with Drools Planner and I also
have the exact same issue :<blockquote style="margin:0pt 0pt 0pt 40px;border:medium none;padding:0px">
<div>
<div>
<div>
<div>java.lang.IllegalStateException: The presumedScore
(0hard/-1soft) is corrupted because it is not the
realScore (0hard/0soft).</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>Presumed workingMemory:</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div> Score rule (soft-ReduceNullAssignment) has count
(1) and weight total (1).</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>Real workingMemory:</div>
</div>
</div>
</div>
<div>
<div>at
org.drools.planner.core.solution.director.DefaultSolutionDirector.assertWorkingScore(DefaultSolutionDirector.java:157)</div>
</div>
<div>
<div>at
org.drools.planner.core.solver.DefaultSolverScope.assertWorkingScore(DefaultSolverScope.java:105)</div>
</div>
<div>
<div>at
org.drools.planner.core.phase.AbstractSolverPhaseScope.assertWorkingScore(AbstractSolverPhaseScope.java:132)</div>
</div>
<div>
<div>at
org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:69)</div>
</div>
<div>
<div>at
org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:166)</div>
</div>
<div>
<div>at
org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:138)</div>
</div>
<div>
<div>
<div>...</div>
</div>
</div>
<div><br>
</div>
</blockquote>
<div>I've read this (<a href="https://issues.jboss.org/browse/JBRULES-3301" target="_blank">https://issues.jboss.org/browse/JBRULES-3301</a>),
but it didn't help :</div>
<ul>
<li>I'm using IntConstraintOccurrence</li>
<li>I double check the soft constraint named
"soft-ReduceNullAssignment" -- it's include all the cause.</li>
<li>I'm using Drools 5.3</li>
</ul>
<div>After more digging, I think something is missing in
DefaultSolutionDirector.java:153. The facts are added, but the
planningEntity are not added.</div>
</blockquote></div>They are added:<br>
<br> for (Object fact : getWorkingFacts()) {<br> tmpWorkingMemory.insert(fact);<br> }<br>
<br> public Collection<Object> getWorkingFacts() {<br> return solutionDescriptor.getAllFacts(workingSolution); //
returns the problem facts + the initiliazed planningEntity's<div><br> }<br>
<br>
<blockquote type="cite">
<div>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.</div>
</blockquote></div>That's weird.<br>
<br>Could you try this with the latest drools-planner-core
5.4.0.SNAPSHOT from the jboss nexus repository too?<br>You'll have to branch and upgrade your local code:<br>
<a href="https://github.com/droolsjbpm/drools-planner/blob/master/drools-planner-distribution/src/main/assembly/filtered-resources/UpgradeFromPreviousVersionRecipe.txt" target="_blank">https://github.com/droolsjbpm/drools-planner/blob/master/drools-planner-distribution/src/main/assembly/filtered-resources/UpgradeFromPreviousVersionRecipe.txt</a><br>
<br>As a side affect, you'll notice that the exception message will be
much much clearer too, which will help in discovering the problem.<div><div><br>
<blockquote type="cite">
<div><br>
</div>
<div>Here is the my rule :</div>
<blockquote style="margin:0pt 0pt 0pt 40px;border:medium none;padding:0px">
<div>
<div>rule "soft-ReduceNullAssignment"</div>
</div>
<div>when</div>
<div>$planif : PlanifEventAssignment( employee == null )</div>
<div>then</div>
<div>
<div> insertLogical(new
IntConstraintOccurrence("soft-ReduceNullAssignment",</div>
</div>
<div>
<div> <span style="white-space:pre-wrap"> </span>ConstraintType.NEGATIVE_SOFT,</div>
</div>
<div>
<div> 1,</div>
</div>
<div>
<div> $planif));</div>
</div>
<div>
<div>end</div>
</div>
</blockquote>
<div><br>
</div>
<div>Thanks</div>
<div><br>
<div class="gmail_quote">On Tue, Dec 6, 2011 at 11:12 AM,
Geoffrey De Smet <span dir="ltr"><<a href="mailto:ge0ffrey.spam@gmail.com" target="_blank">ge0ffrey.spam@gmail.com</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>Op 06-12-11 05:38, guyramirez schreef:<br>
<div>
<div>> Still the same issue, starting with
the construction heuristic phase. Please<br>> let me know if you need more explanations in what I
am trying to do.<br>><br>> Here is the error. Please note that there is only
one planning entity<br>> (ShiftAssignment) object instance in this test.<br>><br>> Total Staffing required: 8<br>> 2011-12-05 22:21:49,627 [main] INFO Solver
started: time spend (0), score<br>> (null), new best score (null), random seed (0).<br>> ShiftAssignment: emp. id: 10 [st: 100, dur: 3]<br>> ShiftAssignment: emp. id: 10 [st: 100, dur: 2]<br>> ShiftAssignment: emp. id: 10 [st: 100, dur: 4]<br>
> ShiftAssignment: emp. id: 10 [st: 100, dur: 1]<br>> 2011-12-05 22:21:49,678 [main] TRACE Building
ConstraintOccurrence summary<br>> 2011-12-05 22:21:49,678 [main] TRACE Adding
ConstraintOccurrence<br>>
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>> 101, position id: 1, staffingRequired: 2,
[ShiftAssignment: emp. id: 10 [st:<br>> 100, dur: 1]]]=1)<br>> 2011-12-05 22:21:49,678 [main] TRACE Adding
ConstraintOccurrence<br>>
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>> 103, position id: 1, staffingRequired: 2, []]=2)<br>> 2011-12-05 22:21:49,678 [main] TRACE Adding
ConstraintOccurrence<br>>
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>> 102, position id: 1, staffingRequired: 2, []]=2)<br>> 2011-12-05 22:21:49,678 [main] TRACE Adding
ConstraintOccurrence<br>>
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>> 100, position id: 1, staffingRequired: 2,
[ShiftAssignment: emp. id: 10 [st:<br>> 100, dur: 1], ShiftAssignment: emp. id: 10 [st:
100, dur: 1]]]=0)<br>> 2011-12-05 22:21:49,678 [main] TRACE Building
ConstraintOccurrence summary<br>> 2011-12-05 22:21:49,678 [main] TRACE Adding
ConstraintOccurrence<br>>
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>> 101, position id: 1, staffingRequired: 2, []]=2)<br>> 2011-12-05 22:21:49,678 [main] TRACE Adding
ConstraintOccurrence<br>>
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>> 103, position id: 1, staffingRequired: 2, []]=2)<br>> 2011-12-05 22:21:49,678 [main] TRACE Adding
ConstraintOccurrence<br>>
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>> 100, position id: 1, staffingRequired: 2,
[ShiftAssignment: emp. id: 10 [st:<br>> 100, dur: 1]]]=1)<br>> 2011-12-05 22:21:49,678 [main] TRACE Adding
ConstraintOccurrence<br>>
(intervalRequirementCovered/NEGATIVE_HARD:[IntervalRequirement:
interval:<br>> 102, position id: 1, staffingRequired: 2, []]=2)<br>> Exception in thread "main"
java.lang.IllegalStateException: The<br>> presumedScore (-5hard/-1soft) is corrupted because
it is not the realScore<br>> (-7hard/-1soft).<br>> Presumed workingMemory:<br>> Score rule (intervalRequirementCovered) has
count (4) and weight total<br>> (5).<br>> Real workingMemory:<br>> Score rule (intervalRequirementCovered) has
count (4) and weight total<br>> (7).<br>
</div>
</div>So the score rule intervalRequirementCovered is to blame.<br>
<div>> at<br>>
org.drools.planner.core.solution.director.DefaultSolutionDirector.assertWorkingScore(DefaultSolutionDirector.java:157)<br>> at<br>>
org.drools.planner.core.solver.DefaultSolverScope.assertWorkingScore(DefaultSolverScope.java:105)<br>> at<br>>
org.drools.planner.core.phase.AbstractSolverPhaseScope.assertWorkingScore(AbstractSolverPhaseScope.java:132)<br>> at<br>>
org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.decideNextStep(DefaultGreedyDecider.java:65)<br>> at<br>>
org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:62)<br>> at<br>>
org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:166)<br>> at<br>>
org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:138)<br>> at
com.lfsoscience.planner.LfsoPlannerMain.execute(LfsoPlannerMain.java:36)<br>> at
com.lfsoscience.planner.LfsoPlannerMain.main(LfsoPlannerMain.java:27)<br>><br>><br>><br>> The drl:<br>> rule "intervalRequirementCovered"<br>
</div>Let's take a look<br>
<div>> when<br>> $intervalReq :
IntervalRequirement($interval : interval, $position :<br>> position, $staffingRequired : staffingRequired)<br>> $matchingShiftAssignments : ArrayList(
size<= $staffingRequired )<br>>
from collect (
ShiftAssignment(shiftStartTime<= $interval,<br>> shiftEndTime> $interval, position == $position) )<br>
</div>I never used "from collect" in my examples yet.<br>You probably stumbled upon a "statefull memory corruption
bug" in drools.<br>
<br>First try this alternative way:<br>
<div><br> $intervalReq : IntervalRequirement($interval :
interval,<br>$position : position, $staffingRequired :
staffingRequired)<br>
</div> $matchingShiftAssignmentSize : Number(intValue <=<br>$staffingRequired) from accumulate(<br> $x : ShiftAssignment(shiftStartTime <=
$interval,<br>shiftEndTime > $interval, position == $position),<br> count($x)<br> )<br>
<br>If that works, file a ticket in <a href="http://issues.jboss.org" target="_blank">issues.jboss.org</a>
for the project JBRULES<br>about "statefull working memory corruption by using collect"<br>and include that rule and - if possible - testdata how to
reproduce it.<br>
<div>
<div>> then<br>> #actions<br>> insertLogical(new
IntConstraintOccurrence("intervalRequirementCovered",<br>> ConstraintType.NEGATIVE_HARD,<br>>
$staffingRequired - $matchingShiftAssignments.size(),<br>> $intervalReq,
$matchingShiftAssignments));<br>> end<br>> rule "hardConstraintsBroken"<br>> salience -1 // Do the other rules first
(optional, for performance)<br>> when<br>> $hardTotal : Number() from accumulate(<br>> IntConstraintOccurrence(constraintType
==<br>> ConstraintType.NEGATIVE_HARD, $weight : weight),
sum($weight)<br>> )<br>> then<br>>
scoreCalculator.setHardConstraintsBroken($hardTotal.intValue());<br>> end<br>> rule "softConstraintsBroken"<br>> when<br>> eval(true)<br>> then<br>>
scoreCalculator.setSoftConstraintsBroken(1);<br>> end<br>><br>><br>><br>> The Planning Entity:<br>><br>> @PlanningEntity<br>> public class ShiftAssignment implements Cloneable {<br>> private Employee employee;<br>
> private int day;<br>> private Position position;<br>> private TimeLengthPair timeLengthPair = null;<br>> // Immutable object. Does not need to be
cloned when calling clone<br>> private List<TimeLengthPair>
possibleShiftStartTimeLengthPairList;<br>> private Set<TimeLengthPair>
possibleShiftStartTimeLengthPairSet;<br>><br>><br>> public ShiftAssignment(Employee employee, int
day, Position position,<br>> Set<TimeLengthPair>
shiftStartTimeLengthPairs) {<br>> this.employee = employee;<br>> this.day = day;<br>> this.position = position;<br>>
this.possibleShiftStartTimeLengthPairSet = new<br>>
HashSet<TimeLengthPair>(shiftStartTimeLengthPairs);<br>> }<br>><br>> public int getShiftStartTime() {<br>> return this.timeLengthPair != null ?
this.timeLengthPair.getStartTime() :<br>> -1;<br>> }<br>><br>> public int getShiftEndTime() {<br>> return this.timeLengthPair != null ?
this.timeLengthPair.getStartTime() +<br>> this.timeLengthPair.getLength() : -1;<br>> }<br>><br>> public void
setShiftStartTimeLengthPair(TimeLengthPair
timeLengthPair) {<br>> this.timeLengthPair = timeLengthPair;<br>> System.out.println(this);<br>> }<br>
</div>
</div>looks good<br>
<div>><br>> public void
addPossibleShiftStartTimeLengthPair(TimeLengthPair<br>> timeLengthPair) {<br>>
this.possibleShiftStartTimeLengthPairSet.add(timeLengthPair);<br>> // Clear the list since the Set has
changed. The list will be recreated<br>> from the set when needed (see
getPossibleShiftStartTimeLengthPairs())<br>>
this.possibleShiftStartTimeLengthPairList = null;<br>> }<br>
</div>this isn't called during planning I presume?<br>
<div>> @PlanningVariable<br>>
@ValueRangeFromPlanningEntityProperty(propertyName =<br>> "possibleShiftStartTimeLengthPairs")<br>> public TimeLengthPair
getShiftStartTimeLengthPair() {<br>> return this.timeLengthPair;<br>> }<br>
</div>looks good<br>
<div>
<div>> public
List<TimeLengthPair>
getPossibleShiftStartTimeLengthPairs() {<br>> if
(this.possibleShiftStartTimeLengthPairList == null) {<br>>
this.possibleShiftStartTimeLengthPairList = new<br>>
ArrayList<TimeLengthPair>(this.possibleShiftStartTimeLengthPairSet);<br>> }<br>> return
this.possibleShiftStartTimeLengthPairList;<br>> }<br>><br>> public Employee getEmployee() {<br>> return this.employee;<br>> }<br>><br>> public int getDay() {<br>
> return this.day;<br>> }<br>><br>> public Position getPosition() {<br>> return this.position;<br>> }<br>><br>> public boolean solutionEquals(Object o) {<br>
> if (this == o) {<br>> return true;<br>> } else if (o instanceof ShiftAssignment) {<br>> ShiftAssignment other =
(ShiftAssignment) o;<br>> return new EqualsBuilder()<br>> .append(this.employee,
other.employee)<br>> .append(this.position,
other.position)<br>> .append(this.timeLengthPair,
other.timeLengthPair)<br>> .isEquals();<br>> } else {<br>> return false;<br>> }<br>> }<br>><br>> public int solutionHashCode() {<br>> HashCodeBuilder hashCodeBuilder = new
HashCodeBuilder();<br>> hashCodeBuilder.append(getClass())<br>> .append(this.employee)<br>> .append(this.position)<br>> .append(this.timeLengthPair);<br>
> return hashCodeBuilder.toHashCode();<br>> }<br>><br>> @Override<br>> public Object clone() throws
CloneNotSupportedException {<br>> return super.clone();<br>> }<br>><br>> @Override<br>> public String toString() {<br>> StringBuilder sb = new
StringBuilder();<br>> sb.append("ShiftAssignment: ")<br>> .append("emp. id:
").append(this.employee.getId())<br>> .append(" ")<br>> .append(this.timeLengthPair
!= null ? this.timeLengthPair.toString() :<br>> "Not Initialized");<br>> return sb.toString();<br>> }<br>><br>> @Override<br>> public int hashCode() {<br>> return solutionHashCode();<br>
> // return super.hashCode();<br>> }<br>><br>> @Override<br>> public boolean equals(Object obj) {<br>> return solutionEquals(obj);<br>> // return super.equals(obj);<br>
> }<br>> }<br>><br>><br>> --<br>> View this message in context: <a href="http://drools.46999.n3.nabble.com/Planner-5-3-Final-presumedScore-is-corrupted-when-using-update-on-the-rules-working-memory-tp3546932p3563446.html" target="_blank">http://drools.46999.n3.nabble.com/Planner-5-3-Final-presumedScore-is-corrupted-when-using-update-on-the-rules-working-memory-tp3546932p3563446.html</a><br>
> Sent from the Drools: User forum mailing list
archive at Nabble.com.<br>> _______________________________________________<br>> rules-users mailing list<br>> <a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>> <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
><br>
<br>
</div>
</div>
<div>--<br>With kind regards,<br>Geoffrey De Smet<br>
<br>
<br>
</div>
<div>
<div>_______________________________________________<br>rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
</div>
</div>
</blockquote>
</div>
<br>
<br clear="all">
<div><br>
</div>-- <br>Patrik Dufresne<br>
</div>
<pre><fieldset></fieldset>
_______________________________________________
rules-users mailing list
<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a>
</pre>
</blockquote>
<br>
<pre cols="72">--
With kind regards,
Geoffrey De Smet</pre>
</div></div></div>
<br>_______________________________________________<br>rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br>Patrik Dufresne<br>
</div>