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