001package net.sf.cpsolver.studentsct.heuristics.selection; 002 003import java.util.Set; 004 005import net.sf.cpsolver.ifs.heuristics.NeighbourSelection; 006import net.sf.cpsolver.ifs.heuristics.RoundRobinNeighbourSelection; 007import net.sf.cpsolver.ifs.model.Neighbour; 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.ifs.util.ToolBox; 013import net.sf.cpsolver.studentsct.model.Enrollment; 014import net.sf.cpsolver.studentsct.model.Request; 015import 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 Tomáš Müller<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 */ 066public 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}