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