001    package net.sf.cpsolver.studentsct.heuristics.selection;
002    
003    import java.util.HashSet;
004    
005    import net.sf.cpsolver.ifs.heuristics.NeighbourSelection;
006    import net.sf.cpsolver.ifs.heuristics.RoundRobinNeighbourSelection;
007    import net.sf.cpsolver.ifs.model.Neighbour;
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.ifs.util.ToolBox;
013    import net.sf.cpsolver.studentsct.model.Student;
014    
015    /**
016     * Random unassignment of some problematic students. Problematic students
017     * are to be provided by a neighbour selection that was used before this one by
018     * {@link RoundRobinNeighbourSelection}.
019     * 
020     * <br><br>
021     * In each step a problematic student is randomly selected with the given probabilty.
022     * Null is returned otherwise (the controll is passed to the next {@link NeighbourSelection}).
023     *
024     * <br><br>
025     * Parameters:
026     * <br>
027     * <table border='1'><tr><th>Parameter</th><th>Type</th><th>Comment</th></tr>
028     * <tr><td>Neighbour.RandomUnassignmentOfProblemStudentProb</td><td>{@link Double}</td><td>Probability of a random selection of a student from the given set of problematic students.</td></tr>
029     * </table>
030     * <br><br>
031     * 
032     * @version
033     * StudentSct 1.1 (Student Sectioning)<br>
034     * Copyright (C) 2007 Tomáš Müller<br>
035     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
036     * Lazenska 391, 76314 Zlin, Czech Republic<br>
037     * <br>
038     * This library is free software; you can redistribute it and/or
039     * modify it under the terms of the GNU Lesser General Public
040     * License as published by the Free Software Foundation; either
041     * version 2.1 of the License, or (at your option) any later version.
042     * <br><br>
043     * This library is distributed in the hope that it will be useful,
044     * but WITHOUT ANY WARRANTY; without even the implied warranty of
045     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
046     * Lesser General Public License for more details.
047     * <br><br>
048     * You should have received a copy of the GNU Lesser General Public
049     * License along with this library; if not, write to the Free Software
050     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
051    */
052    public class RndUnProblStudSelection extends RandomUnassignmentSelection {
053        private ProblemStudentsProvider iProblemStudentsProvider = null;
054        private HashSet iProblemStudents = null;
055        
056        /**
057         * Constructor
058         * @param properties configuration
059         * @param psp a class that provides the set of problematic students
060         */
061        public RndUnProblStudSelection(DataProperties properties, ProblemStudentsProvider psp) {
062            super(properties);
063            iProblemStudentsProvider = psp;
064            iRandom = properties.getPropertyDouble("Neighbour.RandomUnassignmentOfProblemStudentProb", 0.9);
065        }
066        
067        /** Initialization -- {@link ProblemStudentsProvider#getProblemStudents()} is called */
068        public void init(Solver solver) {
069            iProblemStudents = iProblemStudentsProvider.getProblemStudents();
070            Progress.getInstance(solver.currentSolution().getModel()).setPhase("Random unassignment of problematic students...", 1);
071        }
072        
073        /**
074         * With the given probabilty, a problematic student is randomly selected to be unassigned.
075         * Null is returned otherwise.
076         */
077        public Neighbour selectNeighbour(Solution solution) {
078            if (!iProblemStudents.isEmpty() && Math.random()<iRandom) {
079                Student student = (Student)ToolBox.random(iProblemStudents);
080                iProblemStudents.remove(student);
081                return new UnassignStudentNeighbour(student);
082            }
083            Progress.getInstance(solution.getModel()).incProgress();
084            return null;
085        }
086    }