001    package net.sf.cpsolver.coursett.model;
002    
003    import java.util.Enumeration;
004    import java.util.HashSet;
005    import java.util.Hashtable;
006    import java.util.Iterator;
007    import java.util.Set;
008    import java.util.Vector;
009    
010    import net.sf.cpsolver.ifs.util.FastVector;
011    
012    /**
013     * Configuration. Each course can have multiple configurations. 
014     * A student needs to be enrolled into classes of one of the configurations.
015     * 
016     * @version
017     * CourseTT 1.1 (University Course Timetabling)<br>
018     * Copyright (C) 2006 Tomáš Müller<br>
019     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
020     * Lazenska 391, 76314 Zlin, Czech Republic<br>
021     * <br>
022     * This library is free software; you can redistribute it and/or
023     * modify it under the terms of the GNU Lesser General Public
024     * License as published by the Free Software Foundation; either
025     * version 2.1 of the License, or (at your option) any later version.
026     * <br><br>
027     * This library is distributed in the hope that it will be useful,
028     * but 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.
031     * <br><br>
032     * You should have received a copy of the GNU Lesser General Public
033     * License along with this library; if not, write to the Free Software
034     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
035     */
036    
037    public class Configuration {
038            private Long iConfigId = null;
039            private Long iOfferingId = null;
040            private Hashtable iTopLectures = new Hashtable();
041            private Vector iAltConfigurations = null;
042            private int iLimit = -1;
043            
044            public Configuration(Long offeringId, Long configId, int limit) {
045                    iOfferingId = offeringId;
046                    iConfigId = configId;
047                    iLimit = limit;
048            }
049            
050            public Long getOfferingId() { return iOfferingId; }
051            public Long getConfigId() { return iConfigId; }
052            
053            public void addTopLecture(Lecture lecture) {
054                    Set lectures = (Set)iTopLectures.get(lecture.getSchedulingSubpartId());
055                    if (lectures==null) {
056                            lectures = new HashSet();
057                            iTopLectures.put(lecture.getSchedulingSubpartId(), lectures);
058                    }
059                    lectures.add(lecture);
060            }
061            
062            public Enumeration getTopSubpartIds() {
063                    return iTopLectures.keys();
064            }
065            
066            public Set getTopLectures(Long subpartId) {
067                    return (Set)iTopLectures.get(subpartId);
068            }
069            
070            public void setAltConfigurations(Vector altConfigurations) {
071                    iAltConfigurations = altConfigurations;
072            }
073            
074            public void addAltConfiguration(Configuration configuration) {
075                    if (iAltConfigurations==null)
076                            iAltConfigurations = new FastVector();
077                    iAltConfigurations.addElement(configuration);
078            }
079    
080            
081            public Vector getAltConfigurations() {
082                    return iAltConfigurations;
083            }
084            
085            public Set students() {
086                    Set students = new HashSet();
087                    for (Enumeration e=iTopLectures.elements();e.hasMoreElements();) {
088                            HashSet lectures = (HashSet)e.nextElement();
089                            for (Iterator i=lectures.iterator();i.hasNext();) {
090                                    Lecture l = (Lecture)i.next();
091                                    students.addAll(l.students());
092                            }
093                    }
094                    return students;
095            }
096    
097            public boolean hasConflict(Student student) {
098                    for (Iterator i=student.getLectures().iterator();i.hasNext();) {
099                    Lecture lecture = (Lecture)i.next();
100                    if (lecture.getAssignment()==null || !this.equals(lecture.getConfiguration())) continue;
101                    if (student.countConflictPlacements((Placement)lecture.getAssignment())>0) return true;
102                    for (Iterator j=student.getLectures().iterator();j.hasNext();) {
103                            Lecture x = (Lecture)j.next();
104                            if (x.getAssignment()==null || x.equals(lecture)) continue;
105                            if (lecture.jenrlConstraint(x).isInConflict()) return true;
106                    }
107                    }
108                    return false;
109            }
110            
111            public int getLimit() {
112            if (iLimit<0) {
113                double totalWeight = 0.0;
114                for (Iterator i=students().iterator();i.hasNext();) {
115                    Student s = (Student)i.next();
116                    totalWeight += s.getOfferingWeight(getOfferingId());
117                }
118                iLimit = (int)Math.round(totalWeight);
119            }
120                    return iLimit;
121            }
122            
123            public int hashCode() { return getConfigId().hashCode(); }
124            public boolean equals(Object o) {
125                    if (o==null || !(o instanceof Configuration)) return false;
126                    return getConfigId().equals(((Configuration)o).getConfigId());
127            }
128    }