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