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.getAssignment()!=null) 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.getAssignment()!=null || 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.getAssignment()!=null) 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.getAssignment()!=null) 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    }