I don't have a lot of experience programming, let alone with Drools, but I am doing a project similar to the one of vehicle routing. Almost everything works fine, except for some moves, depending on the random seed.
The problem is that, once the Heuristic phase is done, sometimes the local search phase makes some strange moves, like the next one:
Heuristic phase solution:
day 1: place 1 -> place 2 -> place 3 -> place 4 -> place 5 -> place 6
day 2: place 7 -> place 8 -> place 9 -> place 10
Local search move: place 5 moved to day 2
Solution:
day 1: place 1 -> place 2 -> place 3 -> place 4
day 2: place 5 -> place 6
The rest of places is left with no day (in the example it would be vehicle), and they are left as an unanchored chain:
place 7 -> place 8 -> place 9 -> place 10 -> place 7 -> etc
So, when the program looks for the day of any of them, it enters an infinite loop. Obviously, the problem is not how to get out of that loop (I'm not that noob), it is how to avoid those movements.
I use the same solver configuration as the example (changing the solver class etc.) so I don't understand why it does those moves. I think that I should code my own Move class, but I can't find examples of how to code it, nor the MoveFactory. I leave the solver.xml in a code block.
Links or tips that would help me learn to code a Move and a MoveFactory class would be helpful, as well as configuration tips to avoid that (if there are any).
Anyway, thank you all for your time and effort.
<?xml version="1.0" encoding="UTF-8"?>
<solver>
<!--<environmentMode>DEBUG</environmentMode>-->
<environmentMode>PRODUCTION</environmentMode>
<solutionClass>org.tourgune.planificador.bean.Turista</solutionClass>
<planningEntityClass>org.tourgune.planificador.bean.PuntoInteres</planningEntityClass>
<scoreDirectorFactory>
<scoreDefinitionType>HARD_AND_SOFT</scoreDefinitionType>
<scoreDrl>/org/tourgune/planificador/core/planificadorScoreRules.drl</scoreDrl>
</scoreDirectorFactory>
<termination>
<maximumMinutesSpend>4</maximumMinutesSpend>
</termination>
<constructionHeuristic>
<constructionHeuristicType>FIRST_FIT</constructionHeuristicType>
</constructionHeuristic>
<localSearch>
<selector>
<selector>
<moveFactoryClass>org.drools.planner.core.move.generic.GenericChainedChangeMoveFactory</moveFactoryClass>
</selector>
<selector>
<moveFactoryClass>org.drools.planner.core.move.generic.GenericChainedChangePartMoveFactory</moveFactoryClass>
</selector>
<!-- TODO needs a GenericChainedSwapMoveFactory and probably even a GenericChainedSwapPartMoveFactory -->
</selector>
<acceptor>
<planningEntityTabuSize>10</planningEntityTabuSize>
</acceptor>
<forager>
<minimalAcceptedSelection>0</minimalAcceptedSelection>
</forager>
</localSearch>
<!--<localSearch>-->
<!--<selector>-->
<!--<selector>-->
<!--<moveFactoryClass>org.drools.planner.core.move.generic.GenericChainedChangeMoveFactory</moveFactoryClass>-->
<!--</selector>-->
<!--<selector>-->
<!--<moveFactoryClass>org.drools.planner.core.move.generic.GenericChainedChangePartMoveFactory</moveFactoryClass>-->
<!--</selector>-->
<!--</selector>-->
<!--<acceptor>-->
<!--<simulatedAnnealingStartingTemperature>10</simulatedAnnealingStartingTemperature>-->
<!--</acceptor>-->
<!--<forager>-->
<!--<minimalAcceptedSelection>4</minimalAcceptedSelection>-->
<!--</forager>-->
<!--</localSearch>-->
</solver>