001package net.sf.cpsolver.coursett.model;
002
003import java.util.ArrayList;
004import java.util.HashSet;
005import java.util.HashMap;
006import java.util.List;
007import java.util.Map;
008import java.util.Set;
009
010import 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 Tomáš Müller<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
036public 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}