I have a planning entity like:I'm using optaplanner 5.5.0.Final.Hi everybody.I have a problem with chained planning variables.
@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 <- Case2DoctorB <- Case3This 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-codeplan.setCases(Case1, Case2); //pseudo-codeThen 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:DoctorADoctorB <- Case1 <- Case2But 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-codeplan.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