<html><body><div style="color:#000; background-color:#fff; font-family:tahoma, new york, times, serif;font-size:10pt"><div><span>I did not really start on one example. I have scrolled through several to try to figure out how to do it, then started from scratch for the POJO's and Rules. <br></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>The config file was copies from one of the examples because it contained too many things that were hard to get right in the beginning.</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>I know that is a risk but I needed to start somewhere.</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style:
 normal;"><br><span></span></div><br><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>3) What does "The workingMemory has 2 ConstraintOccurrence(s) in excess:" really mean?</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;">&nbsp;&nbsp;&nbsp; - Are the constraints there more than once?</div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;">&nbsp;&nbsp;&nbsp; - has this something to do with the equals and hashcode (which I did implement (see below))?</div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span><br></span></div><div style="color:
 rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span class="tab">&nbsp;&nbsp;&nbsp; </span><span>About the compensation action: is it already available on 5.4.0 final? Should I try that?</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span><br></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>4) I have been looking to the equals and hashcode, though found many examples that implement solutionEquals and solutionHashcode instead.</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>&nbsp;&nbsp;&nbsp; Currently I implemented them like
 this:</span></div><br><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>&nbsp;&nbsp;&nbsp; @Override<br>&nbsp;&nbsp;&nbsp; public int hashCode() {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return id.hashCode(); //(*)<br>&nbsp;&nbsp;&nbsp; }<br><br>&nbsp;&nbsp;&nbsp; @Override<br>&nbsp;&nbsp;&nbsp; public boolean equals(Object o) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (this == o) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return true;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (id == null || !(o instanceof MaintenanceTask)) {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return false;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; } else {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; MaintenanceTask other = (MaintenanceTask) o;<br>&nbsp;&nbsp;&nbsp;
 &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; return id.equals(other.id);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; }</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><br><span></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><br></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>&nbsp; &nbsp; (*) id
 is a String property which is passed into the entity object through the
 constructor and upon cloning it is passed from the clone source to the 
clone target:</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;">&nbsp;&nbsp;&nbsp;<span class="tab">&nbsp;&nbsp;&nbsp;&nbsp;</span> public MaintenanceTask clone() {<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="tab">&nbsp;&nbsp;&nbsp; </span>System.out.println("Cloning task " + id);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="tab">&nbsp;&nbsp;&nbsp; </span>MaintenanceTask clone = new MaintenanceTask(job, id);<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="tab">&nbsp;&nbsp;&nbsp; </span>clone.period = this.period;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="tab">&nbsp;&nbsp;&nbsp; </span>clone.technician = this.technician;<br>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span class="tab">&nbsp;&nbsp;&nbsp; </span>return clone;<br>&nbsp;&nbsp;&nbsp; <span class="tab">&nbsp;&nbsp;&nbsp;
 </span>}<br><span></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>&nbsp;&nbsp;&nbsp; <br></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span><br></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>&nbsp; &nbsp; I am still confused about:<br></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>&nbsp;&nbsp;&nbsp; - Which ones do I need to implement (equals or solutionEquals, ...)?</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif;
 background-color: transparent; font-style: normal;"><span>&nbsp;&nbsp;&nbsp; - Should an entity and a cloned entity have the same result for both equals and hashcode? (I guess so)</span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>&nbsp;&nbsp;&nbsp; - Should only the entity objects have such implementations? (Planning variables are never cloned, right?)<br></span></div><div style="color: rgb(0, 0, 0); font-size: 13.3333px; font-family: tahoma,new york,times,serif; background-color: transparent; font-style: normal;"><span>&nbsp;&nbsp; </span><br></div><div>&nbsp;</div><div>-----------------<br>http://www.codessentials.com - Your essential software, for free!<br>Follow us at http://twitter.com/#!/Codessentials<br></div>  <div style="font-family: tahoma, new york, times, serif; font-size: 10pt;"> <div style="font-family: times new roman, new
 york, times, serif; font-size: 12pt;"> <div dir="ltr"> <font face="Arial" size="2"> <hr size="1">  <b><span style="font-weight:bold;">From:</span></b> Geoffrey De Smet &lt;ge0ffrey.spam@gmail.com&gt;<br> <b><span style="font-weight: bold;">To:</span></b> Rules Users List &lt;rules-users@lists.jboss.org&gt; <br> <b><span style="font-weight: bold;">Sent:</span></b> Monday, September 3, 2012 10:44 AM<br> <b><span style="font-weight: bold;">Subject:</span></b> Re: [rules-users] Best model for planning? technicians, airplanes and shifts =&gt; insertLogical problems<br> </font> </div> <br>
Op 03-09-12 10:21, Michiel Vermandel schreef:<br>&gt; Hi Geoffrey,<br>&gt;<br>&gt; Thanks for the support so far.<br>&gt; I understand that you do not provide full support on this level.<br>&gt; Though I have the feeling that this is really<br>&gt; - a very basic solution setup<br>&gt; - a beginners-mistake and since I'm looking into it now for about 3 days<br>&gt; (since I started with planner) it seems to be not obvious to find for a<br>&gt; beginner.<br>&gt; So I was trying my luck in offering the code.<br>&gt; It could be an opportunity to enrich the documentation ;-) ;-)<br><br>Good point, the score corruption problem is often a beginner problem and <br>it's a PITA. I 'll write some more docs about.<br><br>Do note that your 3 day implementation should be able to scale out to <br>10000 planes pretty easily, so hang in there :)<br>I fear you might have started copying from the wrong example nqueens (if <br>you did that) :/ Nurse rostering is a far
 more similar to this kind of <br>problem. I am not sure which example to promote in the docs: the nqueens <br>is simple enough to explain things on, but it's too simple to copy from <br>for real world stuff :/ Feedback welcome.<br><br>&gt;<br>&gt;<br>&gt; Ok,<br>&gt;<br>&gt; 1) adding the $t2 results in the same sort of exception, only<br>&gt; planningEntity seems different:<br>&gt;<br>&gt; with insertLogical(new<br>&gt; UnweightedConstraintOccurrence("tasksInSameJobMustBeInSamePeriod", $t1,<br>&gt; $t2));<br>&gt;<br>&gt; Exception in thread "main" java.lang.IllegalStateException: Score<br>&gt; corruption: the workingScore (-2) is not the uncorruptedScore (0):<br>&gt;&nbsp; &nbsp; The workingMemory has 2 ConstraintOccurrence(s) in excess:<br>&gt;&nbsp; &nbsp; &nbsp; tasksInSameJobMustBeInSamePeriod/NEGATIVE_HARD:[Maintenance of<br>&gt; Boeing 737 - PJ23.I#1 73111693, Maintenance of Boeing 737 - PJ23.I#2<br>&gt; 427578167]<br>&gt;&nbsp; &nbsp; &nbsp;
 tasksInSameJobMustBeInSamePeriod/NEGATIVE_HARD:[Maintenance of<br>&gt; Boeing 737 - PJ23.I#2 427578167, Maintenance of Boeing 737 - PJ23.I#1<br>&gt; 73111693]<br>&gt;&nbsp; &nbsp; Check the score rules who created those ConstraintOccurrences. Verify<br>&gt; that each ConstraintOccurrence's causes and weight is correct.<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt; org.drools.planner.core.score.director.AbstractScoreDirector.assertWorkingScore(AbstractScoreDirector.java:101)<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt; org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.doMove(DefaultGreedyDecider.java:110)<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt; org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.decideNextStep(DefaultGreedyDecider.java:78)<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt;
 org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:63)<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt; org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:183)<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt; org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:151)<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt; be.axi.planner.domain.MaintenancePlanning.main(MaintenancePlanning.java:27)<br>&gt;<br>&gt; with insertLogical(new<br>&gt; UnweightedConstraintOccurrence("tasksInSameJobMustBeInSamePeriod", $t1));<br>&gt;<br>&gt; Exception in thread "main" java.lang.IllegalStateException: Score<br>&gt; corruption: the workingScore (-2) is not the uncorruptedScore (0):<br>&gt;&nbsp; &nbsp; The workingMemory has 2 ConstraintOccurrence(s) in excess:<br>&gt;&nbsp; &nbsp; &nbsp; tasksInSameJobMustBeInSamePeriod/NEGATIVE_HARD:[Maintenance of<br>&gt; Airbus A350 - XJ34.I#2
 778813475]<br>&gt;&nbsp; &nbsp; &nbsp; tasksInSameJobMustBeInSamePeriod/NEGATIVE_HARD:[Maintenance of<br>&gt; Airbus A350 - XJ34.I#0 225744121]<br>&gt;&nbsp; &nbsp; Check the score rules who created those ConstraintOccurrences. Verify<br>&gt; that each ConstraintOccurrence's causes and weight is correct.<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt; org.drools.planner.core.score.director.AbstractScoreDirector.assertWorkingScore(AbstractScoreDirector.java:101)<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt; org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.doMove(DefaultGreedyDecider.java:110)<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt; org.drools.planner.core.constructionheuristic.greedyFit.decider.DefaultGreedyDecider.decideNextStep(DefaultGreedyDecider.java:78)<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt; org.drools.planner.core.constructionheuristic.greedyFit.DefaultGreedyFitSolverPhase.solve(DefaultGreedyFitSolverPhase.java:63)<br>&gt;&nbsp;
 &nbsp; &nbsp; at<br>&gt; org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:183)<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt; org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:151)<br>&gt;&nbsp; &nbsp; &nbsp; at<br>&gt; be.axi.planner.domain.MaintenancePlanning.main(MaintenancePlanning.java:27)<br>&gt;<br>&gt;<br>&gt; 2) You suggested to replace UnweightedConstraintOccurrence with<br>&gt; IntConstraintOccurrence. I will.<br>&gt; UnweightedConstraintOccurrence is used in the very basic Queens example<br>&gt; though...<br><br>Yep, my mistake.<br><br>&gt;<br>&gt; 3) Where is the best place to read about what insertLogical and<br>&gt; IntConstraintOccurrence really do?<br>&gt; What is the purpose of the Cause -objects, which should be passed?<br>&gt; =&gt; where is the best place to find explanation about this?<br>&gt; (<a href="http://docs.jboss.org/drools/release/5.4.0.Final/drools-planner-docs/html_single/"
 target="_blank">http://docs.jboss.org/drools/release/5.4.0.Final/drools-planner-docs/html_single/</a><br>&gt; doesn't really enlighten me on that part)<br><br>Look for "insertLogical" in the Drools Expert guide:<br> <br><a href="http://docs.jboss.org/drools/release/5.4.0.Final/drools-expert-docs/html_single/index.html" target="_blank">http://docs.jboss.org/drools/release/5.4.0.Final/drools-expert-docs/html_single/index.html</a><br><br>When rules do an insertLogical of an object A, it's discarded if another <br>object B in the WorkingMemory equals object A (through equals() and <br>through hashcode()). Because the ConstraintOccurrences need to be unique <br>so they aren't discarded, they ruleId, constraintType and causes are <br>used for equals()/hashcode().<br><br>Future work: "compensation action"<br>Recently, drools introduced something called "compensation action",<br>which can probably replace the use insertLogical(ConstraintOccurrence) <br>and make
 the causes parameter obsolete.<br>It's also faster.<br>My first experiments look very promising, but I haven't got time yet to <br>experiment with it on all examples and make it easy for users to use.<br><br>It would allow us to do something like this in the then part of a rule:<br>&nbsp;  hardAndSoftScoreHelper.addHardScore(-5);<br>or<br>&nbsp;  hardAndSoftScoreHelper.addSoftScore(- $sum);<br>or<br>&nbsp;  simpleScoreHelper.addScore(-7);<br><br>No need for causes, insertLogicals, no equals/hashcode() worries, much <br>more flexible, ...<br><br><br>4) Does your MaintenanceTask implement equals()/hashcode() other than <br>Object's original implementation?<br><br><br>&gt;<br>&gt; Thanks in advance.<br>&gt;<br><br>yw<br><br>_______________________________________________<br>rules-users mailing list<br><a ymailto="mailto:rules-users@lists.jboss.org" href="mailto:rules-users@lists.jboss.org">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></body></html>