001 package net.sf.cpsolver.studentsct.model;
002
003 import java.util.ArrayList;
004 import java.util.HashSet;
005 import java.util.List;
006 import java.util.Set;
007
008 import net.sf.cpsolver.coursett.model.RoomLocation;
009 import net.sf.cpsolver.coursett.model.TimeLocation;
010 import 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 Tomas Muller<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 */
037 public 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 }