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