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 }