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. 
017     * The provided variable and value selection is used for the 
018     * number of iterations equal to the number of all 
019     * variables in the problem. If a complete solution is found, 
020     * the neighbour selection is stopped (it returns null).
021     *  
022     * <br><br>
023     * Parameters:
024     * <br>
025     * <table border='1'><tr><th>Parameter</th><th>Type</th><th>Comment</th></tr>
026     * <tr><td>Neighbour.StandardIterations</td><td>{@link Long}</td><td>Number of iterations to perform. If -1, number of iterations is set to the number of unassigned variables.</td></tr>
027     * </table>
028     * <br><br>
029     * 
030     * @version
031     * StudentSct 1.1 (Student Sectioning)<br>
032     * Copyright (C) 2007 Tomáš Müller<br>
033     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
034     * Lazenska 391, 76314 Zlin, Czech Republic<br>
035     * <br>
036     * This library is free software; you can redistribute it and/or
037     * modify it under the terms of the GNU Lesser General Public
038     * License as published by the Free Software Foundation; either
039     * version 2.1 of the License, or (at your option) any later version.
040     * <br><br>
041     * This library is distributed in the hope that it will be useful,
042     * but WITHOUT ANY WARRANTY; without even the implied warranty of
043     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
044     * Lesser General Public License for more details.
045     * <br><br>
046     * You should have received a copy of the GNU Lesser General Public
047     * License along with this library; if not, write to the Free Software
048     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
049     */
050    public class StandardSelection implements NeighbourSelection {
051        private static org.apache.log4j.Logger sLog = org.apache.log4j.Logger.getLogger(StandardSelection.class);
052        private long iIteration = 0;
053        private ValueSelection iValueSelection = null;
054        private VariableSelection iVariableSelection = null;
055        protected long iNrIterations = -1;
056        
057        /**
058         * Constructor (variable and value selection are expected to be already initialized). 
059         * @param properties configuration
060         * @param variableSelection variable selection
061         * @param valueSelection value selection
062         */
063        public StandardSelection(DataProperties properties, VariableSelection variableSelection, ValueSelection valueSelection) {
064            iVariableSelection = variableSelection;
065            iValueSelection = valueSelection;
066        }
067        
068        /** Initialization */
069        public void init(Solver solver) {
070            iIteration = solver.currentSolution().getIteration();
071            iNrIterations = solver.getProperties().getPropertyLong("Neighbour.StandardIterations", -1);
072            if (iNrIterations>0)
073                Progress.getInstance(solver.currentSolution().getModel()).setPhase("Ifs...", iNrIterations);
074        }
075        
076        /**
077         * Employ the provided {@link VariableSelection} and {@link ValueSelection} and return the 
078         * selected value as {@link SimpleNeighbour}. The selection is stopped (null is returned) 
079         * after the number of iterations equal to the number of variables in the problem
080         * or when a complete solution is found.
081         */
082        public Neighbour selectNeighbour(Solution solution) {
083            if (iNrIterations<0) {
084                iNrIterations = solution.getModel().unassignedVariables().size();
085                Progress.getInstance(solution.getModel()).setPhase("Ifs...", iNrIterations);
086            }
087            if (solution.getModel().unassignedVariables().isEmpty() || solution.getIteration()>=iIteration+iNrIterations) return null;
088            Progress.getInstance(solution.getModel()).incProgress();
089            for (int i=0;i<10;i++) {
090                Request request = (Request)iVariableSelection.selectVariable(solution);
091                Enrollment enrollment = (request==null?null:(Enrollment)iValueSelection.selectValue(solution, request));
092                if (enrollment!=null && !enrollment.variable().getModel().conflictValues(enrollment).contains(enrollment))
093                    return new SimpleNeighbour(request, enrollment);
094            }
095            return null;
096        }
097    
098    }