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 }