001 package net.sf.cpsolver.studentsct.filter;
002
003 import java.util.HashSet;
004
005 import net.sf.cpsolver.ifs.util.ToolBox;
006 import net.sf.cpsolver.studentsct.model.Student;
007
008 /**
009 * This student filter accepts every student with the given
010 * probability. The choice for each student is remembered,
011 * i.e., if the student is passed to the filter multiple times
012 * the same answer is returned.
013 *
014 * @version
015 * StudentSct 1.1 (Student Sectioning)<br>
016 * Copyright (C) 2007 Tomáš Müller<br>
017 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
018 * Lazenska 391, 76314 Zlin, Czech Republic<br>
019 * <br>
020 * This library is free software; you can redistribute it and/or
021 * modify it under the terms of the GNU Lesser General Public
022 * License as published by the Free Software Foundation; either
023 * version 2.1 of the License, or (at your option) any later version.
024 * <br><br>
025 * This library is distributed in the hope that it will be useful,
026 * but WITHOUT ANY WARRANTY; without even the implied warranty of
027 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
028 * Lesser General Public License for more details.
029 * <br><br>
030 * You should have received a copy of the GNU Lesser General Public
031 * License along with this library; if not, write to the Free Software
032 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
033 */
034 public class RandomStudentFilter implements StudentFilter {
035 private double iProb = 1.0;
036 private HashSet iAcceptedStudentIds = new HashSet();
037 private HashSet iRejectedStudentIds = new HashSet();
038
039 /**
040 * Constructor
041 * @param prob probability of acceptance of a student
042 */
043 public RandomStudentFilter(double prob) {
044 iProb = prob;
045 }
046
047 /**
048 * A student is accepted with the given probability
049 */
050 public boolean accept(Student student) {
051 Long studentId = new Long(student.getId());
052 if (iAcceptedStudentIds.contains(studentId)) return true;
053 if (iRejectedStudentIds.contains(studentId)) return false;
054 boolean accept = (Math.random()<iProb);
055 if (accept)
056 iAcceptedStudentIds.add(studentId);
057 else
058 iRejectedStudentIds.add(studentId);
059 return accept;
060 }
061
062 /**
063 * Set acceptance probability. Update the sets of accepted and rejected students accordingly.
064 * @param prob new acceptance probability
065 */
066 public void setProbability(double prob) {
067 iProb = prob;
068 int accept = (int)Math.round(prob*(iAcceptedStudentIds.size()+iRejectedStudentIds.size()));
069 while (iAcceptedStudentIds.size()<accept && !iRejectedStudentIds.isEmpty()) {
070 Long studentId = (Long)ToolBox.random(iRejectedStudentIds);
071 iRejectedStudentIds.remove(studentId);
072 iAcceptedStudentIds.add(studentId);
073 }
074 while (iAcceptedStudentIds.size()>accept && !iAcceptedStudentIds.isEmpty()) {
075 Long studentId = (Long)ToolBox.random(iAcceptedStudentIds);
076 iRejectedStudentIds.add(studentId);
077 iAcceptedStudentIds.remove(studentId);
078 }
079 }
080
081 }