[rules-users] Drools Planner: entity was never added to this ScoreDirector?

Geoffrey De Smet ge0ffrey.spam at gmail.com
Sat May 5 05:29:38 EDT 2012


Cedric is referring to this issue:
   https://issues.jboss.org/browse/JBRULES-3461
Currently, the following implementation should be respected for entities:
- solutionHashCode() must include the variables, and hashCode() must not 
include the variables
(same for solutionEquals() and equals() of course)
1) Check if your code follows that?
2) Does your code follow the equals() and hashCode() contract of Java?

I agree with you guys that a changing hashcode might have caused this.
- The entity X is inserted into a Set or Map with a hashcode A.
- While it's in that Set or Map, the entity X changes which also changes 
it's hashcode value to B.
- This effectively corrupts the Set or Map, because X is still in bucket 
A%n, while it should be in bucket B%n,
so the Set or Map will report that it doesn't contain X.

That fact that uncommented equals() and hashcode() together doesn't fix 
it, means that:
a) either the superclass has an equals/hashcode problem
b) either it's not a hashcode related problem
c) the 2 Meeting entities are different instances, that represent the 
same entity. This is only possible if you create or remove entities in 
moves. => In this case you cannot rely on object identity and you must 
implement an equals/hashcode implementation based on at least some sort 
of id (for example a database primary key or uuid).

> It seems to happen randomly, with different entities each time
If environmentMode == REPRODICBLE or DEBUG or TRACE (so not PRODUCTION)
and you're not using simulated annealing (~ timegradient based), then 2 
runs should be exactly the same always (more info in manual on 
environmentMode).

So, if they are still not in that case, the only thing I can think of 
that differs between runs is the memory addresses of the entity 
instances which are used in object identity.
Object.hashCode() is implemented to return the memory address. 
Object.equals() returns true if it's the same memory address. The memory 
address doesn't change during 1 run, but it differs from run to run.
So how can that explain that "randomly" behavior? Because in a Map of 
capacity 10, the hashCode() gets % 10, so about 1 out of 10 instances 
with different hashCode()s do end up in the same bucket (and this 
differs from run to run).

3) Can you turn on environmentMode TRACE, just to verify that it doesn't 
fail on anything else sooner?

> I couldn't find an easy way to add a knowledge session logger in 
> planner, but that might also be useful.
I don't think there is an easy way at this time. Feel free to create a 
jira issue that DroolsScoreDirector or DroolsScoreDirectorFactory should 
support that.

Op 05-05-12 04:35, Cedric Hurst schreef:
> yeah, i have a solutionEquals() and solutionHashCode() as well. I 
> tried dumping my hashCode() and equals() methods on the PlanningEntity 
> but that didn't seem to have much effect.  My hashCode() and 
> solutionHashCode() values now both change when I assign a different 
> supplier, but planner still can't seem to find the entity in working 
> memory.
>
> -- 
> Build Smarter Software.
>
> Spantree Technology Group, LLC
> 813 W Randolph St, Suite 301
> email:[hidden email] </user/SendEmail.jtp?type=node&node=3963892&i=0>| 
> phone:<a href="tel:773.359.3865" value="+17733593865" 
> target="_blank">773.359.3865
> http://www.spantree.net <http://www.spantree.net/>
>
> On Friday, May 4, 2012 at 8:51 PM, Christopher Dolan [via Drools] wrote:
>
>> Try just commenting out your .equals() and .hashCode() methods. My 
>> experience was that Planner is unexpectedly sensitive to hashcode 
>> algorithms, and identity equality just worked best. I ended up 
>> implementing a solutionEquals like some of the example code.
>> Chris
>>
>> ------------------------------------------------------------------------
>> *From:* [hidden email] 
>> </user/SendEmail.jtp?type=node&node=3963850&i=0> [[hidden email] 
>> </user/SendEmail.jtp?type=node&node=3963850&i=1>] on behalf of Cedric 
>> Hurst [[hidden email] </user/SendEmail.jtp?type=node&node=3963850&i=2>]
>> *Sent:* Friday, May 04, 2012 5:09 PM
>> *To:* [hidden email] </user/SendEmail.jtp?type=node&node=3963850&i=3>
>> *Subject:* [rules-users] Drools Planner: entity was never added to 
>> this ScoreDirector?
>>
>> Hi all,
>>
>> I'm working on a Drools Planner 5.4.0.CR1 implementation for a 
>> scheduling app.
>>
>> First, some background:
>>
>> The solution class is 'Schedule' and the PlanningEntity is 'Meeting'. 
>> Meetings consist of timeslots (or 'slots'), and two participants in 
>> complimentary roles 'planners' and 'suppliers'. Since there are more 
>> planners than suppliers, I've structured the Schedule model so that 
>> its meeting collection is basically the cross-product of slots and 
>> planners. Suppliers are configured as the @PlanningVariable in a 
>> meeting. The meeting list in the schedule is also annotated as a 
>> @PlanningEntityCollectionProperty. I've structured three 
>> MoveFactories that add, subtract or swap suppliers from meeting to 
>> meeting.
>>
>> That part works fairly well, however, when I try to try to run my 
>> solution through a Solver, I am inevitably plagued with a dreaded 
>> message like this:
>>
>> 	java.lang.IllegalArgumentException: The entity (Meeting[slot: 26, planner: 29C2E0FF-00EE-409F-B05B-B175B30A6B45, supplier: BB25B297-54FA-45BD-923A-C209848E74B4,
>> 	hashCode: 1219749520, solutionHashCode: -1086095971, slotHashCode: 436282962, plannerHashCode: -2037841459]) was never added to this ScoreDirector.
>> 		at org.drools.planner.core.score.director.drools.DroolsScoreDirector.afterAllVariablesChanged(DroolsScoreDirector.java:110)
>> 		at org.drools.planner.core.score.director.drools.DroolsScoreDirector.afterVariableChanged(DroolsScoreDirector.java:120)
>> 		at com.somecompany.scheduler.moves.AddSupplierToMeetingMove.doMove(AddSupplierToMeetingMove.groovy:36)
>> 		at org.drools.planner.core.localsearch.decider.DefaultDecider.doMove(DefaultDecider.java:128)
>> 		at org.drools.planner.core.localsearch.decider.DefaultDecider.decideNextStep(DefaultDecider.java:103)
>> 		at org.drools.planner.core.localsearch.DefaultLocalSearchSolverPhase.solve(DefaultLocalSearchSolverPhase.java:57)
>> 		at org.drools.planner.core.solver.DefaultSolver.runSolverPhases(DefaultSolver.java:183)
>> 		at org.drools.planner.core.solver.DefaultSolver.solve(DefaultSolver.java:151)
>> 		at org.spockframework.util.GroovyRuntimeUtil.invokeMethod(GroovyRuntimeUtil.java:100)
>> 		at com.somecompany.scheduler.solver.SolverSpec.should solve schedule(SolverSpec.groovy:59)
>>
>> It seems to happen randomly, with different entities each time, but 
>> I've not yet had a successful run of a full solve cycle without 
>> hitting it a least once. Unfortunately, it kills my whole process.
>>
>> I've step debugged through the planner internals and verified that 
>> all the meetings are getting added to the working memory, including 
>> the offending one:
>>
>> 	2012-05-04 16:30:17,379 INFO  com.somecompany.scheduler.solver.SolverSpec  - Meeting[slot: 26, planner: 29C2E0FF-00EE-409F-B05B-B175B30A6B45, supplier:
>> 	FEA76C13-C9E2-42EC-977C-BCBB0BD1FFA0, hashCode: 1219749520, solutionHashCode: -574491332, slotHashCode: 436282962, plannerHashCode: -2037841459]
>>
>> I was pretty certain my issue has to do with the meeting's hashCode 
>> value, but as you'll see they're exactly the same in working memory 
>> as they are when . I'm using commons HashCodeBuilder and 
>> EqualsBuilder to check only the fixed slot and planner values. The 
>> solutionHashCode changes based on the slot, planner and supplier-- 
>> supplier being the @PlanningVariable. I've pasted the full log, with 
>> trace enabled, here for review:
>>
>> https://gist.github.com/raw/93752853a0996ae1c016/d0ca35f5c531a2fa25e6a106c90257b015500931/solver-error.log 
>>
>>
>> The error is listed at 2012-05-04 16:30:37,168.
>>
>> The original meeting in working memory is listed at 2012-05-04 
>> 16:30:17,379 (toward the middle of entries with that timestamp).
>>
>> I couldn't find an easy way to add a knowledge session logger in 
>> planner, but that might also be useful.
>>
>>
>> ------------------------------------------------------------------------
>> View this message in context: Drools Planner: entity was never added 
>> to this ScoreDirector? 
>> <http://drools.46999.n3.nabble.com/Drools-Planner-entity-was-never-added-to-this-ScoreDirector-tp3963528.html>
>> Sent from the Drools: User forum mailing list archive 
>> <http://drools.46999.n3.nabble.com/Drools-User-forum-f47000.html> at 
>> Nabble.com <http://Nabble.com>.
>>
>> _______________________________________________
>> rules-users mailing list
>> [hidden email] </user/SendEmail.jtp?type=node&node=3963850&i=4>
>> https://lists.jboss.org/mailman/listinfo/rules-users
>>
>>
>> ------------------------------------------------------------------------
>> If you reply to this email, your message will be added to the 
>> discussion below:
>> http://drools.46999.n3.nabble.com/Drools-Planner-entity-was-never-added-to-this-ScoreDirector-tp3963528p3963850.html 
>>
>> To unsubscribe from Drools Planner: entity was never added to this 
>> ScoreDirector?, click here.
>> NAML 
>> <http://drools.46999.n3.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml> 
>>
>
>
> ------------------------------------------------------------------------
> View this message in context: Re: [rules-users] Drools Planner: entity 
> was never added to this ScoreDirector? 
> <http://drools.46999.n3.nabble.com/Re-rules-users-Drools-Planner-entity-was-never-added-to-this-ScoreDirector-tp3963892.html>
> Sent from the Drools: User forum mailing list archive 
> <http://drools.46999.n3.nabble.com/Drools-User-forum-f47000.html> 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

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.jboss.org/pipermail/rules-users/attachments/20120505/bfac5b1c/attachment-0001.html 


More information about the rules-users mailing list