001package org.cpsolver.studentsct.heuristics.selection;
002
003import java.util.Set;
004
005import org.cpsolver.ifs.heuristics.NeighbourSelection;
006import org.cpsolver.ifs.heuristics.ValueSelection;
007import org.cpsolver.ifs.heuristics.VariableSelection;
008import org.cpsolver.ifs.model.Neighbour;
009import org.cpsolver.ifs.model.SimpleNeighbour;
010import org.cpsolver.ifs.solution.Solution;
011import org.cpsolver.ifs.solver.Solver;
012import org.cpsolver.ifs.util.DataProperties;
013import org.cpsolver.ifs.util.Progress;
014import org.cpsolver.studentsct.model.Enrollment;
015import org.cpsolver.studentsct.model.Request;
016
017
018/**
019 * Use the provided variable and value selection for some time. The provided
020 * variable and value selection is used for the number of iterations equal to
021 * the number of all variables in the problem. If a complete solution is found,
022 * the neighbour selection is stopped (it returns null).
023 * 
024 * <br>
025 * <br>
026 * Parameters: <br>
027 * <table border='1' summary='Related Solver Parameters'>
028 * <tr>
029 * <th>Parameter</th>
030 * <th>Type</th>
031 * <th>Comment</th>
032 * </tr>
033 * <tr>
034 * <td>Neighbour.StandardIterations</td>
035 * <td>{@link Long}</td>
036 * <td>Number of iterations to perform. If -1, number of iterations is set to
037 * the number of unassigned variables.</td>
038 * </tr>
039 * </table>
040 * <br>
041 * <br>
042 * 
043 * @version StudentSct 1.3 (Student Sectioning)<br>
044 *          Copyright (C) 2007 - 2014 Tomas Muller<br>
045 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
046 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
047 * <br>
048 *          This library is free software; you can redistribute it and/or modify
049 *          it under the terms of the GNU Lesser General Public License as
050 *          published by the Free Software Foundation; either version 3 of the
051 *          License, or (at your option) any later version. <br>
052 * <br>
053 *          This library is distributed in the hope that it will be useful, but
054 *          WITHOUT ANY WARRANTY; without even the implied warranty of
055 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
056 *          Lesser General Public License for more details. <br>
057 * <br>
058 *          You should have received a copy of the GNU Lesser General Public
059 *          License along with this library; if not see
060 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
061 */
062public class StandardSelection implements NeighbourSelection<Request, Enrollment> {
063    private long iIteration = 0;
064    private ValueSelection<Request, Enrollment> iValueSelection = null;
065    private VariableSelection<Request, Enrollment> iVariableSelection = null;
066    protected long iNrIterations = -1;
067
068    /**
069     * Constructor (variable and value selection are expected to be already
070     * initialized).
071     * 
072     * @param properties
073     *            configuration
074     * @param variableSelection
075     *            variable selection
076     * @param valueSelection
077     *            value selection
078     */
079    public StandardSelection(DataProperties properties, VariableSelection<Request, Enrollment> variableSelection,
080            ValueSelection<Request, Enrollment> valueSelection) {
081        iVariableSelection = variableSelection;
082        iValueSelection = valueSelection;
083    }
084
085    /** Initialization */
086    @Override
087    public void init(Solver<Request, Enrollment> solver) {
088        iIteration = 0;
089        iNrIterations = solver.getProperties().getPropertyLong("Neighbour.StandardIterations", -1);
090        if (iNrIterations > 0)
091            Progress.getInstance(solver.currentSolution().getModel()).setPhase("Ifs...", iNrIterations);
092    }
093
094    /**
095     * Employ the provided {@link VariableSelection} and {@link ValueSelection}
096     * and return the selected value as {@link SimpleNeighbour}. The selection
097     * is stopped (null is returned) after the number of iterations equal to the
098     * number of variables in the problem or when a complete solution is found.
099     */
100    @Override
101    public Neighbour<Request, Enrollment> selectNeighbour(Solution<Request, Enrollment> solution) {
102        if (iNrIterations < 0) {
103            iNrIterations = solution.getModel().nrUnassignedVariables(solution.getAssignment());
104            Progress.getInstance(solution.getModel()).setPhase("Ifs...", iNrIterations);
105        }
106        if (solution.getModel().unassignedVariables(solution.getAssignment()).isEmpty() || ++iIteration >= iNrIterations)
107            return null;
108        Progress.getInstance(solution.getModel()).incProgress();
109        for (int i = 0; i < 10; i++) {
110            Request request = iVariableSelection.selectVariable(solution);
111            if (request == null) continue;
112            Enrollment enrollment = iValueSelection.selectValue(solution, request);
113            if (enrollment == null) continue;
114            Set<Enrollment> conflicts = enrollment.variable().getModel().conflictValues(solution.getAssignment(), enrollment);
115            if (!conflicts.contains(enrollment))
116                return new SimpleNeighbour<Request, Enrollment>(request, enrollment, conflicts);
117        }
118        return null;
119    }
120
121}