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