UniTime / cpsolver

Local-search based solver of Constraint Satisfaction and Optimization Problems
http://www.cpsolver.org
GNU Lesser General Public License v3.0
61 stars 35 forks source link

Round Robin prevents from terminating if no neighbour is selected #18

Closed H3ADLESS closed 4 years ago

H3ADLESS commented 4 years ago

Hey there,

I have just spend some time to detect why my custom solver didn't terminate. It's probably a good idea to return null, if all registered neighbourSelections fail to find a neighbour or check for terminationCondition. Adding a random selection helps preventing this issue.

Maybe there are other ways to avoid this problem? Probably the most selections will at some point return a valid neighbour.

This is the relating code of RoundRobinNeighbourSelection

public Neighbour<V, T> selectNeighbour(Solution<V, T> solution) {
        while (true) {
            int selectionIndex = getSelectionIndex();
            NeighbourSelection<V, T> selection = iSelections.get(selectionIndex % iSelections.size());
            Neighbour<V, T> neighbour = selection.selectNeighbour(solution);
            if (neighbour != null)
                return neighbour;
            changeSelection(selectionIndex);
        }
    }
tomas-muller commented 4 years ago

For a NeighbourSelection, returning null is an indication that the neighborhood has been exhausted and the search should progress with the next one. For example, the BranchBoundSelection (that is used by the student sectioning solver, and that tries to find the best possible schedule for each student while everything else is fixed) returns null when all student has been tried. Please note that the NeighbourSelection.init(Solver) is called before the selection is used. It is, for instance, used to reset the list of students that will be tried during the next phase (consecutive calling of NeighbourSelection. selectNeighbour(solution), until null is returned).

It is not, however, expected that all neighbor selections would keep returning null values and nothing else. That said, it would be possible to add a termination condition check within or just before the changeSelection called.