001package net.sf.cpsolver.studentsct.model; 002 003import java.util.ArrayList; 004import java.util.HashSet; 005import java.util.List; 006import java.util.Set; 007 008import net.sf.cpsolver.coursett.model.RoomLocation; 009import net.sf.cpsolver.coursett.model.TimeLocation; 010import net.sf.cpsolver.studentsct.StudentSectioningModel; 011 012 013/** 014 * Representation of a request of a student for free time. This class directly 015 * implements {@link Assignment} API, with the appropriate free time. <br> 016 * <br> 017 * 018 * @version StudentSct 1.2 (Student Sectioning)<br> 019 * Copyright (C) 2007 - 2010 Tomáš Müller<br> 020 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 021 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 022 * <br> 023 * This library is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU Lesser General Public License as 025 * published by the Free Software Foundation; either version 3 of the 026 * License, or (at your option) any later version. <br> 027 * <br> 028 * This library is distributed in the hope that it will be useful, but 029 * 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. <br> 032 * <br> 033 * You should have received a copy of the GNU Lesser General Public 034 * License along with this library; if not see 035 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 036 */ 037public class FreeTimeRequest extends Request implements Assignment { 038 private TimeLocation iTime = null; 039 private HashSet<Enrollment> iEnrollments = new HashSet<Enrollment>(); 040 041 /** 042 * Constructor 043 * 044 * @param id 045 * request unique id 046 * @param priority 047 * request priority 048 * @param alternative 049 * true if the request is alternative (alternative request can be 050 * assigned instead of a non-alternative course requests, if it 051 * is left unassigned) 052 * @param student 053 * appropriate student 054 * @param time 055 * appropriate time location that is requested to be free 056 */ 057 public FreeTimeRequest(long id, int priority, boolean alternative, Student student, TimeLocation time) { 058 super(id, priority, alternative, student); 059 iTime = time; 060 } 061 062 /** Return requested time to be free */ 063 @Override 064 public TimeLocation getTime() { 065 return iTime; 066 } 067 068 /** Assignment API: free time request has no rooms */ 069 @Override 070 public int getNrRooms() { 071 return 0; 072 } 073 074 /** Assignment API: free time request has no rooms */ 075 @Override 076 public List<RoomLocation> getRooms() { 077 return new ArrayList<RoomLocation>(0); 078 } 079 080 /** 081 * True, if this assignment is overlapping in time and space with the given 082 * assignment. 083 */ 084 @Override 085 public boolean isOverlapping(Assignment assignment) { 086 if (isAllowOverlap() || assignment.isAllowOverlap()) return false; 087 if (getTime() == null || assignment.getTime() == null) 088 return false; 089 if (assignment instanceof FreeTimeRequest) 090 return false; 091 return getTime().hasIntersection(assignment.getTime()); 092 } 093 094 /** 095 * True, if this assignment is overlapping in time and space with the given 096 * set of assignments. 097 */ 098 @Override 099 public boolean isOverlapping(Set<? extends Assignment> assignments) { 100 if (isAllowOverlap()) 101 return false; 102 if (getTime() == null) 103 return false; 104 for (Assignment assignment : assignments) { 105 if (assignment.isAllowOverlap()) 106 continue; 107 if (assignment.getTime() == null) 108 continue; 109 if (assignment instanceof FreeTimeRequest) 110 return false; 111 if (getTime().hasIntersection(assignment.getTime())) 112 return true; 113 } 114 return false; 115 } 116 117 /** Create enrollment of this request */ 118 public Enrollment createEnrollment() { 119 HashSet<Assignment> assignments = new HashSet<Assignment>(); 120 assignments.add(this); 121 return new Enrollment(this, 0, null, assignments); 122 } 123 124 /** 125 * Create all possible enrollments of this request -- there is only one 126 * possible enrollment: {@link FreeTimeRequest#createEnrollment()} 127 */ 128 @Override 129 public List<Enrollment> computeEnrollments() { 130 List<Enrollment> enrollments = new ArrayList<Enrollment>(1); 131 enrollments.add(createEnrollment()); 132 return enrollments; 133 } 134 135 /** Enrollment with this assignment was assigned to a {@link Request}. */ 136 @Override 137 public void assigned(Enrollment enrollment) { 138 iEnrollments.add(enrollment); 139 } 140 141 /** Enrollment with this assignment was unassigned from a {@link Request}. */ 142 @Override 143 public void unassigned(Enrollment enrollment) { 144 iEnrollments.remove(enrollment); 145 } 146 147 /** Return the list of assigned enrollments that contains this assignment. */ 148 @Override 149 public Set<Enrollment> getEnrollments() { 150 return iEnrollments; 151 } 152 153 /** 154 * Request name: A for alternative, 1 + priority, Free Time, long name of 155 * requested time 156 */ 157 @Override 158 public String getName() { 159 return (isAlternative() ? "A" : "") + (1 + getPriority() + (isAlternative() ? -getStudent().nrRequests() : 0)) 160 + ". Free Time " + getTime().getDayHeader() + " " + getTime().getStartTimeHeader() + " - " + getTime().getEndTimeHeader(); 161 } 162 163 @Override 164 public String toString() { 165 return getName(); 166 } 167 168 /** Estimated bound for this request */ 169 @Override 170 public double getBound() { 171 return - getWeight() * ((StudentSectioningModel)getModel()).getStudentWeights().getBound(this); 172 } 173 174 /** Free time request generally allow overlaps. */ 175 @Override 176 public boolean isAllowOverlap() { 177 return (getModel() == null ? true : ((StudentSectioningModel)getModel()).getStudentWeights().isFreeTimeAllowOverlaps()); 178 } 179 180 /** Sections first, then by {@link FreeTimeRequest#getId()} */ 181 @Override 182 public int compareById(Assignment a) { 183 if (a instanceof FreeTimeRequest) { 184 return new Long(getId()).compareTo(((FreeTimeRequest)a).getId()); 185 } else { 186 return 1; 187 } 188 } 189 190 @Override 191 public int hashCode() { 192 return super.hashCode() ^ getTime().hashCode(); 193 } 194 195 196 @Override 197 public boolean equals(Object o) { 198 return super.equals(o) && (o instanceof CourseRequest) && getTime().equals(((FreeTimeRequest)o).getTime()); 199 } 200 201}