001 package net.sf.cpsolver.studentsct.constraint; 002 003 import java.util.Enumeration; 004 import java.util.Set; 005 006 import net.sf.cpsolver.ifs.model.Constraint; 007 import net.sf.cpsolver.ifs.model.Value; 008 import net.sf.cpsolver.studentsct.model.Enrollment; 009 import net.sf.cpsolver.studentsct.model.Request; 010 011 /** 012 * This constraints ensures that a student is not enrolled into sections that are 013 * overlapping in time. 014 * 015 * <br><br> 016 * 017 * @version 018 * StudentSct 1.1 (Student Sectioning)<br> 019 * Copyright (C) 2007 Tomáš Müller<br> 020 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 021 * Lazenska 391, 76314 Zlin, Czech Republic<br> 022 * <br> 023 * This library is free software; you can redistribute it and/or 024 * modify it under the terms of the GNU Lesser General Public 025 * License as published by the Free Software Foundation; either 026 * version 2.1 of the License, or (at your option) any later version. 027 * <br><br> 028 * This library is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 031 * Lesser General Public License for more details. 032 * <br><br> 033 * You should have received a copy of the GNU Lesser General Public 034 * License along with this library; if not, write to the Free Software 035 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 036 */ 037 public class StudentConflict extends Constraint { 038 039 /** 040 * A given enrollment is conflicting when the student is enrolled into 041 * another course / free time request that has an assignment that is 042 * overlapping with one or more assignments of the given section. 043 * See {@link Enrollment#isOverlapping(Enrollment)} for more details. 044 * All such overlapping enrollments are added into the provided set of conflicts. 045 * @param value {@link Enrollment} that is being considered 046 * @param conflicts resultant list of conflicting enrollments 047 */ 048 public void computeConflicts(Value value, Set conflicts) { 049 //get enrollment 050 Enrollment enrollment = (Enrollment)value; 051 052 //for all assigned course requests -> if overlapping with this enrollment -> conflict 053 for (Enumeration e=assignedVariables().elements();e.hasMoreElements();) { 054 Request request = (Request)e.nextElement(); 055 if (request.equals(enrollment.getRequest())) continue; 056 if (enrollment.isOverlapping((Enrollment)request.getAssignment())) 057 conflicts.add(request.getAssignment()); 058 } 059 060 //if this enrollment cannot be assigned (student already has a full schedule) -> unassignd a lowest priority request 061 if (!enrollment.getStudent().canAssign(enrollment.getRequest())) { 062 Enrollment lowestPriorityEnrollment = null; 063 int lowestPriority = -1; 064 for (Enumeration e=assignedVariables().elements();e.hasMoreElements();) { 065 Request request = (Request)e.nextElement(); 066 if (request.equals(enrollment.getRequest())) continue; 067 if (lowestPriority<request.getPriority()) { 068 lowestPriority = request.getPriority(); 069 lowestPriorityEnrollment = (Enrollment)request.getAssignment(); 070 } 071 } 072 if (lowestPriorityEnrollment!=null) 073 conflicts.add(lowestPriorityEnrollment); 074 } 075 } 076 077 /** Two enrollments are consistent if they are not overlapping in time */ 078 public boolean isConsistent(Value value1, Value value2) { 079 Enrollment e1 = (Enrollment)value1; 080 Enrollment e2 = (Enrollment)value2; 081 return !e1.isOverlapping(e2); 082 } 083 084 /** 085 * A given enrollment is conflicting when the student is enrolled into 086 * another course / free time request that has an assignment that is 087 * overlapping with one or more assignments of the given section. 088 * See {@link Enrollment#isOverlapping(Enrollment)} for more details. 089 * @param value {@link Enrollment} that is being considered 090 * @return true, if the student is enrolled into another enrollment of a 091 * different request that is overlapping in time with the given enrollment 092 */ 093 public boolean inConflict(Value value) { 094 //get enrollment 095 Enrollment enrollment = (Enrollment)value; 096 097 //for all assigned course requests -> if overlapping with this enrollment -> conflict 098 for (Enumeration e=assignedVariables().elements();e.hasMoreElements();) { 099 Request request = (Request)e.nextElement(); 100 if (request.equals(enrollment.getRequest())) continue; 101 if (enrollment.isOverlapping((Enrollment)request.getAssignment())) 102 return true; 103 } 104 105 //if this enrollment cannot be assigned (student already has a full schedule) -> conflict 106 if (!enrollment.getStudent().canAssign(enrollment.getRequest())) 107 return true; 108 109 //nothing above -> no conflict 110 return false; 111 } 112 113 public String toString() { 114 return "StudentConflicts"; 115 } 116 }