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}