    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}