001    package net.sf.cpsolver.studentsct.heuristics.selection;
002    
003    import net.sf.cpsolver.ifs.heuristics.NeighbourSelection;
004    import net.sf.cpsolver.ifs.heuristics.ValueSelection;
005    import net.sf.cpsolver.ifs.heuristics.VariableSelection;
006    import net.sf.cpsolver.ifs.model.Neighbour;
007    import net.sf.cpsolver.ifs.model.SimpleNeighbour;
008    import net.sf.cpsolver.ifs.solution.Solution;
009    import net.sf.cpsolver.ifs.solver.Solver;
010    import net.sf.cpsolver.ifs.util.DataProperties;
011    import net.sf.cpsolver.ifs.util.Progress;
012    import net.sf.cpsolver.studentsct.model.Enrollment;
013    import 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 Tomas Muller<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     */
059    public 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    }