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