<div dir="ltr"><div><div><div>Hi everybody.<br></div>I have a problem with chained planning variables.<br></div>I&#39;m using optaplanner 5.5.0.Final.<br></div>I have a planning entity like:<br><br>@PlanningEntity()<br>public class Case implements Chained {<br>

    private Chained previous;<br>    @PlanningVariable(chained = true)<br>    @ValueRanges({<br>            @ValueRange(type = ValueRangeType.FROM_SOLUTION_PROPERTY, solutionProperty = &quot;doctors&quot;),<br>   
         @ValueRange(type = ValueRangeType.FROM_SOLUTION_PROPERTY, 
solutionProperty = &quot;cases&quot;, excludeUninitializedPlanningEntity = true) 
})<br>    public Chained getPrevious() {<br>        return previous;<br>    }<br>}<br clear="all"><div><br></div><div>A fact class:<br>public class Doctor implements Chained {<br>   ...<br>}<br></div><div><br></div><div>

An a solution class:<br>public class Plan extends implements Solution&lt;HardAndSoftScore&gt; {<br>    private List&lt;Doctor&gt; doctors;<br>    private List&lt;Case&gt; cases;<br>    private HardAndSoftScore score;<br>
<br>
    @PlanningEntityCollectionProperty<br>    public List&lt;Case&gt; getCases() {<br>        return cases;<br>    }<br><br>    public Collection&lt;? extends Object&gt; getProblemFacts() {<br>        return new ArrayList&lt;Doctor&gt;(doctors);<br>

    }<br>}<br><br>
</div><div>The equals / hashCode / clone methods are inspired on the TravelingSalesmanTour example.<br>
</div><div><br></div><div>I want that Optaplanner generates chains like:<br></div><div>DoctorA &lt;- Case1 &lt;- Case2<br></div><div>DoctorB &lt;- Case3<br><br></div><div>This model tries to represent a list of Cases assigned to each Doctor.<br>

</div><div>Suppose I build a solution like:<br><br>Plan plan = new Plan();<br></div><div>plan.setDoctors(DoctorA, DoctorB); //pseudo-code<br></div><div>plan.setCases(Case1, Case2); //pseudo-code<br><br></div><div>Then I build a solver:<br>

Solver solver = getSolverFactory().buildSolver();<br>solver.setPlanningProblem(plan);<br>solver.solve();<br>Plan bestPlan = (Plan) solver.getBestSolution();<br><br></div><div>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:<br></div><div>DoctorA  <br></div><div>DoctorB &lt;- Case1 &lt;- Case2<br></div><div><br></div><div>But Optaplanner seems to test only chains with DoctorA, so the result of calling getBestSolution() is:<br>

DoctorA &lt;- Case1 &lt;- Case2<br>
</div><div><br>
I guess that Optaplanner only test chains whit DoctorA, becouse it logs lines like:<br>
...<br>
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]] =&gt; Case [id=1, 
previous=Case [id=2, previous=Doctor [id=1]]]).<br>
...<br>
</div><div>That is, no lines whith &quot;DoctorB&quot; are logged. <br>If the doctor list is inverted, the same problem happen (the DoctorA is no processed). That is:<br><br>Plan plan = new Plan();<br>
<div>plan.setDoctors(DoctorB, DoctorA); //pseudo-code<br></div>
<div>plan.setCases(Case1, Case2); //pseudo-code<br>Solver solver = getSolverFactory().buildSolver();<br>solver.setPlanningProblem(plan);<br>solver.solve(); // DoctorA is not part of chains<br></div><br>
<br>
</div><div>I guess the problem is on the solver configuration, specifically on the localSearch configuration:<br>
<br>
&lt;localSearch&gt;<br>
        &lt;unionMoveSelector&gt;<br>
            &lt;changeMoveSelector&gt;<br>
                &lt;valueSelector/&gt;<br>
            &lt;/changeMoveSelector&gt;<br>
            &lt;swapMoveSelector /&gt;<br>
            &lt;subChainChangeMoveSelector&gt;<br>
                &lt;selectReversingMoveToo&gt;true&lt;/selectReversingMoveToo&gt;<br>
            &lt;/subChainChangeMoveSelector&gt;<br>
            &lt;subChainSwapMoveSelector&gt;<br>
                &lt;selectReversingMoveToo&gt;true&lt;/selectReversingMoveToo&gt;<br>
            &lt;/subChainSwapMoveSelector&gt;<br>
        &lt;/unionMoveSelector&gt;<br>
        &lt;acceptor&gt;<br>
            &lt;planningEntityTabuSize&gt;9&lt;/planningEntityTabuSize&gt;<br>
        &lt;/acceptor&gt;<br>
        &lt;forager&gt;<br>
            &lt;minimalAcceptedSelection&gt;2000&lt;/minimalAcceptedSelection&gt;<br>
        &lt;/forager&gt;<br>
    &lt;/localSearch&gt;<br>
<br>
</div><div>I tried some alternatives to this configuration, but with no success.<br>
<br>
</div><div>Do you know what I am doing wrong?<br>
<br>
</div><div>Thanks a lot.<br>
<br>
</div>Regards</div>