001    package net.sf.cpsolver.coursett.model;
002    
003    import java.util.ArrayList;
004    import java.util.HashSet;
005    import java.util.HashMap;
006    import java.util.List;
007    import java.util.Map;
008    import java.util.Set;
009    
010    import net.sf.cpsolver.coursett.constraint.JenrlConstraint;
011    
012    /**
013     * Configuration. Each course can have multiple configurations. A student needs
014     * to be enrolled into classes of one of the configurations.
015     * 
016     * @version CourseTT 1.2 (University Course Timetabling)<br>
017     *          Copyright (C) 2006 - 2010 Tomas Muller<br>
018     *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
019     *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
020     * <br>
021     *          This library is free software; you can redistribute it and/or modify
022     *          it under the terms of the GNU Lesser General Public License as
023     *          published by the Free Software Foundation; either version 3 of the
024     *          License, or (at your option) any later version. <br>
025     * <br>
026     *          This library is distributed in the hope that it will be useful, but
027     *          WITHOUT ANY WARRANTY; without even the implied warranty of
028     *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
029     *          Lesser General Public License for more details. <br>
030     * <br>
031     *          You should have received a copy of the GNU Lesser General Public
032     *          License along with this library; if not see
033     *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
034     */
035    
036    public class Configuration {
037        private Long iConfigId = null;
038        private Long iOfferingId = null;
039        private HashMap<Long, Set<Lecture>> iTopLectures = new HashMap<Long, Set<Lecture>>();
040        private List<Configuration> iAltConfigurations = null;
041        private int iLimit = -1;
042    
043        public Configuration(Long offeringId, Long configId, int limit) {
044            iOfferingId = offeringId;
045            iConfigId = configId;
046            iLimit = limit;
047        }
048    
049        public Long getOfferingId() {
050            return iOfferingId;
051        }
052    
053        public Long getConfigId() {
054            return iConfigId;
055        }
056    
057        public void addTopLecture(Lecture lecture) {
058            Set<Lecture> lectures = iTopLectures.get(lecture.getSchedulingSubpartId());
059            if (lectures == null) {
060                lectures = new HashSet<Lecture>();
061                iTopLectures.put(lecture.getSchedulingSubpartId(), lectures);
062            }
063            lectures.add(lecture);
064        }
065        
066        public Map<Long, Set<Lecture>> getTopLectures() {
067            return iTopLectures;
068        }
069    
070        public Set<Long> getTopSubpartIds() {
071            return iTopLectures.keySet();
072        }
073    
074        public Set<Lecture> getTopLectures(Long subpartId) {
075            return iTopLectures.get(subpartId);
076        }
077    
078        public void setAltConfigurations(List<Configuration> altConfigurations) {
079            iAltConfigurations = altConfigurations;
080        }
081    
082        public void addAltConfiguration(Configuration configuration) {
083            if (iAltConfigurations == null)
084                iAltConfigurations = new ArrayList<Configuration>();
085            iAltConfigurations.add(configuration);
086        }
087    
088        public List<Configuration> getAltConfigurations() {
089            return iAltConfigurations;
090        }
091    
092        public Set<Student> students() {
093            Set<Student> students = new HashSet<Student>();
094            for (Set<Lecture> lectures: iTopLectures.values()) {
095                for (Lecture l : lectures) {
096                    students.addAll(l.students());
097                }
098            }
099            return students;
100        }
101    
102        public boolean hasConflict(Student student) {
103            for (Lecture lecture : student.getLectures()) {
104                if (lecture.getAssignment() == null || !this.equals(lecture.getConfiguration()))
105                    continue;
106                if (student.countConflictPlacements(lecture.getAssignment()) > 0)
107                    return true;
108                for (Lecture x : student.getLectures()) {
109                    if (x.getAssignment() == null || x.equals(lecture))
110                        continue;
111                    JenrlConstraint jenrl = lecture.jenrlConstraint(x);
112                    if (jenrl != null && jenrl.isInConflict())
113                        return true;
114                }
115            }
116            return false;
117        }
118    
119        public int getLimit() {
120            if (iLimit < 0) {
121                double totalWeight = 0.0;
122                for (Student s : students()) {
123                    totalWeight += s.getOfferingWeight(getOfferingId());
124                }
125                iLimit = (int) Math.round(totalWeight);
126            }
127            return iLimit;
128        }
129    
130        @Override
131        public int hashCode() {
132            return getConfigId().hashCode();
133        }
134    
135        @Override
136        public boolean equals(Object o) {
137            if (o == null || !(o instanceof Configuration))
138                return false;
139            return getConfigId().equals(((Configuration) o).getConfigId());
140        }
141    }