001 package net.sf.cpsolver.studentsct.model;
002
003 import java.util.Enumeration;
004 import java.util.Vector;
005
006 /**
007 * Representation of a student. Each student contains id, and a list of requests.
008 * <br><br>
009 * Last-like semester students are mark as dummy. Dummy students have lower value
010 * and generally should not block "real" students from getting requested courses.
011 * <br><br>
012 *
013 * @version
014 * StudentSct 1.1 (Student Sectioning)<br>
015 * Copyright (C) 2007 Tomáš Müller<br>
016 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
017 * Lazenska 391, 76314 Zlin, Czech Republic<br>
018 * <br>
019 * This library is free software; you can redistribute it and/or
020 * modify it under the terms of the GNU Lesser General Public
021 * License as published by the Free Software Foundation; either
022 * version 2.1 of the License, or (at your option) any later version.
023 * <br><br>
024 * This library is distributed in the hope that it will be useful,
025 * but WITHOUT ANY WARRANTY; without even the implied warranty of
026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
027 * Lesser General Public License for more details.
028 * <br><br>
029 * You should have received a copy of the GNU Lesser General Public
030 * License along with this library; if not, write to the Free Software
031 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
032 */public class Student {
033 private long iId;
034 private boolean iDummy = false;
035 private Vector iRequests = new Vector();
036 private Vector iAcadAreaClassifs = new Vector();
037 private Vector iMajors = new Vector();
038 private Vector iMinors = new Vector();
039
040 public static double sDummyStudentWeight = 0.5;
041
042 /** Constructor
043 * @param id student unique id
044 */
045 public Student(long id) {
046 iId = id;
047 }
048
049 /** Constructor
050 * @param id student unique id
051 * @param dummy dummy flag
052 */
053 public Student(long id, boolean dummy) {
054 iId = id;
055 iDummy = dummy;
056 }
057
058 /** Student unique id */
059 public long getId() {
060 return iId;
061 }
062 /** Set student unique id */
063 public void setId(long id) {
064 iId = id;
065 }
066
067 /** Student's course and free time requests */
068 public Vector getRequests() {
069 return iRequests;
070 }
071
072 /** Number of requests (alternative requests are ignored) */
073 public int nrRequests() {
074 int ret = 0;
075 for (Enumeration e=iRequests.elements();e.hasMoreElements();) {
076 Request r = (Request)e.nextElement();
077 if (!r.isAlternative()) ret++;
078 }
079 return ret;
080 }
081
082 /** Number of alternative requests */
083 public int nrAlternativeRequests() {
084 int ret = 0;
085 for (Enumeration e=iRequests.elements();e.hasMoreElements();) {
086 Request r = (Request)e.nextElement();
087 if (r.isAlternative()) ret++;
088 }
089 return ret;
090 }
091
092 /**
093 * True if the given request can be assigned to the student.
094 * A request cannot be assigned to a student when the student already has the
095 * desired number of requests assigned (i.e., number of non-alternative course
096 * requests).
097 **/
098 public boolean canAssign(Request request) {
099 if (request.isAssigned()) return true;
100 int alt = 0;
101 boolean found = false;
102 for (Enumeration e=iRequests.elements();e.hasMoreElements();) {
103 Request r = (Request)e.nextElement();
104 if (r.equals(request)) found = true;
105 boolean assigned = (r.isAssigned() || r.equals(request));
106 boolean course = (r instanceof CourseRequest);
107 boolean waitlist = (course && ((CourseRequest)r).isWaitlist());
108 if (r.isAlternative()) {
109 if (assigned || (!found && waitlist)) alt--;
110 } else {
111 if (course && !waitlist && !assigned) alt++;
112 }
113 }
114 return (alt>=0);
115 }
116
117 /**
118 * True if the student has assigned the desired number of requests (i.e., number of non-alternative course
119 * requests).
120 */
121 public boolean isComplete() {
122 int nrRequests = 0;
123 int nrAssignedRequests = 0;
124 for (Enumeration e=iRequests.elements();e.hasMoreElements();) {
125 Request r = (Request)e.nextElement();
126 if (!(r instanceof CourseRequest)) continue; //ignore free times
127 if (!r.isAlternative()) nrRequests++;
128 if (r.isAssigned()) nrAssignedRequests++;
129 }
130 return nrAssignedRequests==nrRequests;
131 }
132
133 /** Number of assigned COURSE requests */
134 public int nrAssignedRequests() {
135 int nrAssignedRequests = 0;
136 for (Enumeration e=iRequests.elements();e.hasMoreElements();) {
137 Request r = (Request)e.nextElement();
138 if (!(r instanceof CourseRequest)) continue; //ignore free times
139 if (r.isAssigned()) nrAssignedRequests++;
140 }
141 return nrAssignedRequests;
142 }
143
144 public String toString() {
145 return (isDummy()?"D":"")+"S["+getId()+"]";
146 }
147
148 /**
149 * Student's dummy flag. Dummy students have lower value
150 * and generally should not block "real" students from getting requested courses.
151 */
152 public boolean isDummy() {
153 return iDummy;
154 }
155
156 /**
157 * Set student's dummy flag. Dummy students have lower value
158 * and generally should not block "real" students from getting requested courses.
159 */
160 public void setDummy(boolean dummy) {
161 iDummy = dummy;
162 }
163
164 /**
165 * List of academic area - classification codes ({@link AcademicAreaCode}) for the given student
166 */
167 public Vector getAcademicAreaClasiffications() {
168 return iAcadAreaClassifs;
169 }
170
171 /**
172 * List of major codes ({@link AcademicAreaCode}) for the given student
173 */
174 public Vector getMajors() {
175 return iMajors;
176 }
177
178 /**
179 * List of major codes ({@link AcademicAreaCode}) for the given student
180 */
181 public Vector getMinors() {
182 return iMinors;
183 }
184
185 /**
186 * Compare two students for equality. Two students are considered equal if they have the same id.
187 */
188 public boolean equals(Object object) {
189 if (object==null || !(object instanceof Student)) return false;
190 return getId()==((Student)object).getId();
191 }
192
193 /**
194 * Hash code (base only on student id)
195 */
196 public int hashCode() {
197 return (int)(iId ^ (iId >>> 32));
198 }
199 }