[rules-users] Problem with chained planning variables

Geoffrey De Smet ge0ffrey.spam at gmail.com
Mon Oct 28 13:11:20 EDT 2013


On 28-10-13 17:27, Juan Ignacio Barisich wrote:
> Thanks Geoffrey. One more question:Is there a planned release date for 
> optaplanner 6.0.0.Final ?
When the rest of drools and jbpm and ready to release. We're on the same 
release train :)
But optaplanner 6 is ready for prime time, don't let the "CR5" suffix 
make you believe otherwise.
>
> Thanks again
>
>
>
> 2013/10/25 Geoffrey De Smet <ge0ffrey.spam at gmail.com 
> <mailto:ge0ffrey.spam at gmail.com>>
>
>     Upgrade to 6.0.0.CR5 (follow the upgrade recipe txt)
>     and take advantage of the new feature called "shadow variables"
>     (see docs).
>     Also see the VRP with timewindows example for an implementation
>     that uses shadow variables :)
>
>
>     On 25-10-13 00:27, Juan Ignacio Barisich wrote:
>>     Hi again. The problem was a score corruption issue. When I
>>     activate de mode debug:
>>
>>     <environmentMode>DEBUG</environmentMode>
>>
>>     some exceptions appear, like:
>>
>>     java.lang.IllegalStateException: Score corruption: the
>>     workingScore (0hard/-35soft) is not the uncorruptedScore
>>     (0hard/-31soft)...
>>
>>     I had to fix some rules, but I cant fix one in particular. When I
>>     looking at the example rules (with chained variables), the most
>>     are based only on the previous item of the chain, e.g.:
>>
>>     rule "distanceToPreviousAppearance"
>>         when
>>             $visit : Visit(previousAppearance != null,
>>     $distanceToPreviousAppearance : distanceToPreviousAppearance)
>>         then
>>             insertLogical(new
>>     IntConstraintOccurrence("distanceToPreviousAppearance",
>>     ConstraintType.NEGATIVE_SOFT,
>>     $distanceToPreviousAppearance,
>>                     $visit));
>>     end
>>
>>     When optaplanner do the moves while planning, the
>>     IntConstraintOccurrence works ok, because the drools engine
>>     "retracts" the IntConstraintOccurrence facts properly. But, in my
>>     case the score caculation must be based on the entire chain. That is:
>>
>>     I have some Doctors, and Cases (medical cases). I have to write a
>>     score rule for consider the delay of attention. So, each Case has
>>     a request time (when the patient calls) and a approximate
>>     duration of the case (in minutes). So, if I have the next chain:
>>
>>     Doctor1 -> Case1 (requestTime:8am, duration:60minutes) ->
>>     Case2(requestTime:8:30am, duration:30minutes) ->
>>     Case3(requestTime:8:30am, duration:30minutes)
>>
>>     the delay time for this solution must be: 30min(for Case2) +
>>     60min(for Case3) = 90 minutes. As yo see, you can't calculate the
>>     delay of one Case only as from its previous on the chain.
>>
>>     I must to implement a rule to calculate a soft constraint, to
>>     achive less-delay plannings. My first attempt looks like:
>>
>>     rule "delaySC"
>>         when
>>             $case : Case( )
>>             eval($case.getDelay() > 0)
>>         then
>>            insertLogical(new IntConstraintOccurrence("delaySC",
>>     ConstraintType.NEGATIVE_SOFT,
>>                     $case.getDelay(), $case));
>>     end
>>
>>     I have to do an eval(), because a delay can not be negative. The
>>     getDelay() method process the chain and calculates it. The
>>     problem of this attempt, an other similars, is when the
>>     optaplanner engine do the moves while solving, the
>>     IntConstraintOccurrence is not retracted and the score corruption
>>     exception appears.
>>
>>     The question is: ¿have you know similar scenarios, in which you
>>     have to process the entire chain to calculate the score of a
>>     solution?¿is there a way to solve this?
>>
>>     Thanks
>>
>>     Regards
>>
>>
>>
>>
>>
>>
>>
>>     2013/9/2 Juan Ignacio Barisich <juan.barisich at gmail.com
>>     <mailto:juan.barisich at gmail.com>>
>>
>>         Hi everybody.
>>         I have a problem with chained planning variables.
>>         I'm using optaplanner 5.5.0.Final.
>>         I have a planning entity like:
>>
>>         @PlanningEntity()
>>         public class Case implements Chained {
>>             private Chained previous;
>>             @PlanningVariable(chained = true)
>>             @ValueRanges({
>>                     @ValueRange(type =
>>         ValueRangeType.FROM_SOLUTION_PROPERTY, solutionProperty =
>>         "doctors"),
>>                     @ValueRange(type =
>>         ValueRangeType.FROM_SOLUTION_PROPERTY, solutionProperty =
>>         "cases", excludeUninitializedPlanningEntity = true) })
>>             public Chained getPrevious() {
>>                 return previous;
>>             }
>>         }
>>
>>         A fact class:
>>         public class Doctor implements Chained {
>>            ...
>>         }
>>
>>         An a solution class:
>>         public class Plan extends implements Solution<HardAndSoftScore> {
>>             private List<Doctor> doctors;
>>             private List<Case> cases;
>>             private HardAndSoftScore score;
>>
>>             @PlanningEntityCollectionProperty
>>             public List<Case> getCases() {
>>                 return cases;
>>             }
>>
>>             public Collection<? extends Object> getProblemFacts() {
>>                 return new ArrayList<Doctor>(doctors);
>>             }
>>         }
>>
>>         The equals / hashCode / clone methods are inspired on the
>>         TravelingSalesmanTour example.
>>
>>         I want that Optaplanner generates chains like:
>>         DoctorA <- Case1 <- Case2
>>         DoctorB <- Case3
>>
>>         This model tries to represent a list of Cases assigned to
>>         each Doctor.
>>         Suppose I build a solution like:
>>
>>         Plan plan = new Plan();
>>         plan.setDoctors(DoctorA, DoctorB); //pseudo-code
>>         plan.setCases(Case1, Case2); //pseudo-code
>>
>>         Then I build a solver:
>>         Solver solver = getSolverFactory().buildSolver();
>>         solver.setPlanningProblem(plan);
>>         solver.solve();
>>         Plan bestPlan = (Plan) solver.getBestSolution();
>>
>>         The problem is that, Optaplanner is not testing all the
>>         posible combinations of chains. I mean, suppose that we know
>>         that the better solution (based on the scoring rules) is:
>>         DoctorA
>>         DoctorB <- Case1 <- Case2
>>
>>         But Optaplanner seems to test only chains with DoctorA, so
>>         the result of calling getBestSolution() is:
>>         DoctorA <- Case1 <- Case2
>>
>>         I guess that Optaplanner only test chains whit DoctorA,
>>         becouse it logs lines like:
>>         ...
>>         DEBUG:
>>         org.drools.planner.core.localsearch.DefaultLocalSearchSolverPhase
>>         -     Step index (1), time spend (20002), score
>>         (1hard/2soft),     best score (1hard/2soft),
>>         accepted/selected move count (0/58187) for picked step (Case
>>         [id=2, previous=Doctor [id=1]] => Case [id=1, previous=Case
>>         [id=2, previous=Doctor [id=1]]]).
>>         ...
>>         That is, no lines whith "DoctorB" are logged.
>>         If the doctor list is inverted, the same problem happen (the
>>         DoctorA is no processed). That is:
>>
>>         Plan plan = new Plan();
>>         plan.setDoctors(DoctorB, DoctorA); //pseudo-code
>>         plan.setCases(Case1, Case2); //pseudo-code
>>         Solver solver = getSolverFactory().buildSolver();
>>         solver.setPlanningProblem(plan);
>>         solver.solve(); // DoctorA is not part of chains
>>
>>
>>         I guess the problem is on the solver configuration,
>>         specifically on the localSearch configuration:
>>
>>         <localSearch>
>>                 <unionMoveSelector>
>>                     <changeMoveSelector>
>>                         <valueSelector/>
>>                     </changeMoveSelector>
>>                     <swapMoveSelector />
>>         <subChainChangeMoveSelector>
>>         <selectReversingMoveToo>true</selectReversingMoveToo>
>>         </subChainChangeMoveSelector>
>>         <subChainSwapMoveSelector>
>>         <selectReversingMoveToo>true</selectReversingMoveToo>
>>         </subChainSwapMoveSelector>
>>                 </unionMoveSelector>
>>                 <acceptor>
>>         <planningEntityTabuSize>9</planningEntityTabuSize>
>>                 </acceptor>
>>                 <forager>
>>         <minimalAcceptedSelection>2000</minimalAcceptedSelection>
>>                 </forager>
>>             </localSearch>
>>
>>         I tried some alternatives to this configuration, but with no
>>         success.
>>
>>         Do you know what I am doing wrong?
>>
>>         Thanks a lot.
>>
>>         Regards
>>
>>
>>
>>
>>     _______________________________________________
>>     rules-users mailing list
>>     rules-users at lists.jboss.org  <mailto:rules-users at lists.jboss.org>
>>     https://lists.jboss.org/mailman/listinfo/rules-users
>
>
>     _______________________________________________
>     rules-users mailing list
>     rules-users at lists.jboss.org <mailto:rules-users at lists.jboss.org>
>     https://lists.jboss.org/mailman/listinfo/rules-users
>
>
>
>
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users

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


More information about the rules-users mailing list