001 package net.sf.cpsolver.exam.reports;
002
003 import java.util.Enumeration;
004 import java.util.Iterator;
005
006 import net.sf.cpsolver.exam.model.Exam;
007 import net.sf.cpsolver.exam.model.ExamInstructor;
008 import net.sf.cpsolver.exam.model.ExamModel;
009 import net.sf.cpsolver.exam.model.ExamOwner;
010 import net.sf.cpsolver.exam.model.ExamPeriod;
011 import net.sf.cpsolver.exam.model.ExamPlacement;
012 import net.sf.cpsolver.exam.model.ExamRoomPlacement;
013 import net.sf.cpsolver.ifs.util.CSVFile;
014 import net.sf.cpsolver.ifs.util.CSVFile.CSVField;
015
016 /**
017 * Export instructor direct, back-to-back, and more than two exams a day conflicts
018 * into a CSV file.
019 * <br><br>
020 * Usage:<br>
021 * <code>
022 * new ExamInstructorConflicts(model).report().save(file);
023 * </code>
024 * <br><br>
025 *
026 * @version
027 * ExamTT 1.1 (Examination Timetabling)<br>
028 * Copyright (C) 2008 Tomáš Müller<br>
029 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
030 * Lazenska 391, 76314 Zlin, Czech Republic<br>
031 * <br>
032 * This library is free software; you can redistribute it and/or
033 * modify it under the terms of the GNU Lesser General Public
034 * License as published by the Free Software Foundation; either
035 * version 2.1 of the License, or (at your option) any later version.
036 * <br><br>
037 * This library is distributed in the hope that it will be useful,
038 * but WITHOUT ANY WARRANTY; without even the implied warranty of
039 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
040 * Lesser General Public License for more details.
041 * <br><br>
042 * You should have received a copy of the GNU Lesser General Public
043 * License along with this library; if not, write to the Free Software
044 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
045 */
046 public class ExamInstructorConflicts {
047 private ExamModel iModel = null;
048
049 /**
050 * Constructor
051 * @param model examination timetabling model
052 */
053 public ExamInstructorConflicts(ExamModel model) {
054 iModel = model;
055 }
056
057 /**
058 * generate report
059 */
060 public CSVFile report() {
061 CSVFile csv = new CSVFile();
062 csv.setHeader(new CSVField[] {
063 new CSVField("Instructor"),
064 new CSVField("Type"),
065 new CSVField("Section/Course"),
066 new CSVField("Period"),
067 new CSVField("Day"),
068 new CSVField("Time"),
069 new CSVField("Room"),
070 new CSVField("Distance")
071 });
072 for (Enumeration e=iModel.getInstructors().elements();e.hasMoreElements();) {
073 ExamInstructor instructor = (ExamInstructor)e.nextElement();
074 for (Enumeration f=iModel.getPeriods().elements();f.hasMoreElements();) {
075 ExamPeriod period = (ExamPeriod)f.nextElement();
076 int nrExams = instructor.getExams(period).size();
077 if (nrExams>1) {
078 String sections = "";
079 String rooms = "";
080 String periods = String.valueOf(period.getIndex()+1);
081 String periodDays = period.getDayStr();
082 String periodTimes = period.getTimeStr();
083 for (Iterator i=instructor.getExams(period).iterator();i.hasNext();) {
084 Exam exam = (Exam)i.next();
085 ExamPlacement placement = (ExamPlacement)exam.getAssignment();
086 String roomsThisExam = "";
087 for (Iterator j=placement.getRoomPlacements().iterator();j.hasNext();) {
088 ExamRoomPlacement room = (ExamRoomPlacement)j.next();
089 if (roomsThisExam.length()>0) roomsThisExam+=", ";
090 roomsThisExam+=room.getName();
091 }
092 boolean first = true;
093 for (Enumeration g=exam.getOwners(instructor).elements();g.hasMoreElements();){
094 ExamOwner owner = (ExamOwner)g.nextElement();
095 if (sections.length()>0) {
096 sections+="\n"; rooms+="\n";
097 periods+="\n"; periodDays+="\n"; periodTimes+="\n";
098 }
099 sections += owner.getName();
100 if (first) rooms += roomsThisExam;
101 first = false;
102 }
103 if (exam.getOwners(instructor).isEmpty()) {
104 sections += exam.getName();
105 rooms += roomsThisExam;
106 }
107 }
108 csv.addLine(new CSVField[] {
109 new CSVField(instructor.getName()),
110 new CSVField("direct"),
111 new CSVField(sections),
112 new CSVField(periods),
113 new CSVField(periodDays),
114 new CSVField(periodTimes),
115 new CSVField(rooms)
116 });
117 }
118 if (nrExams>0) {
119 if (period.next()!=null && !instructor.getExams(period.next()).isEmpty() && (!iModel.isDayBreakBackToBack() || period.next().getDay()==period.getDay())) {
120 for (Iterator i=instructor.getExams(period).iterator();i.hasNext();) {
121 Exam ex1 = (Exam)i.next();
122 for (Iterator j=instructor.getExams(period.next()).iterator();j.hasNext();) {
123 Exam ex2 = (Exam)j.next();
124 ExamPlacement placement = (ExamPlacement)ex1.getAssignment();
125 String sections = "";
126 String rooms = "";
127 String roomsThisExam = "";
128 String periods = String.valueOf(period.getIndex()+1);
129 String periodDays = period.getDayStr();
130 String periodTimes = period.getTimeStr();
131 for (Iterator k=placement.getRoomPlacements().iterator();k.hasNext();) {
132 ExamRoomPlacement room = (ExamRoomPlacement)k.next();
133 if (roomsThisExam.length()>0) roomsThisExam+=", ";
134 roomsThisExam+=room.getName();
135 }
136 boolean first = true;
137 for (Enumeration g=ex1.getOwners(instructor).elements();g.hasMoreElements();){
138 ExamOwner owner = (ExamOwner)g.nextElement();
139 if (sections.length()>0) {
140 sections+="\n"; rooms+="\n";
141 periods+="\n"; periodDays+="\n"; periodTimes+="\n";
142 }
143 sections += owner.getName();
144 if (first) rooms += roomsThisExam;
145 first = false;
146 }
147 if (ex1.getOwners(instructor).isEmpty()) {
148 sections += ex1.getName();
149 rooms += roomsThisExam;
150 }
151 placement = (ExamPlacement)ex2.getAssignment();
152 roomsThisExam = "";
153 for (Iterator k=placement.getRoomPlacements().iterator();k.hasNext();) {
154 ExamRoomPlacement room = (ExamRoomPlacement)k.next();
155 if (roomsThisExam.length()>0) roomsThisExam+=", ";
156 roomsThisExam+=room.getName();
157 }
158 first = true;
159 for (Enumeration g=ex2.getOwners(instructor).elements();g.hasMoreElements();){
160 ExamOwner owner = (ExamOwner)g.nextElement();
161 sections+="\n"; rooms+="\n"; periods+="\n"; periodDays+="\n"; periodTimes+="\n";
162 sections += owner.getName();
163 if (first) {
164 rooms += roomsThisExam;
165 periods += String.valueOf(period.next().getIndex()+1);
166 periodDays += period.next().getDayStr();
167 periodTimes += period.next().getTimeStr();
168 }
169 first = false;
170 }
171 if (ex2.getOwners(instructor).isEmpty()) {
172 sections+="\n"; rooms+="\n"; periods+="\n"; periodDays+="\n"; periodTimes+="\n";
173 sections += ex2.getName();
174 rooms += roomsThisExam;
175 periods += String.valueOf(period.next().getIndex()+1);
176 periodDays += period.next().getDayStr();
177 periodTimes += period.next().getTimeStr();
178 }
179 String distStr="";
180 if (iModel.getBackToBackDistance()>=0) {
181 int dist = ((ExamPlacement)ex1.getAssignment()).getDistance((ExamPlacement)ex2.getAssignment());
182 if (dist>0) distStr = String.valueOf(dist);
183 }
184 csv.addLine(new CSVField[] {
185 new CSVField(instructor.getName()),
186 new CSVField("back-to-back"),
187 new CSVField(sections),
188 new CSVField(periods),
189 new CSVField(periodDays),
190 new CSVField(periodTimes),
191 new CSVField(rooms),
192 new CSVField(distStr)
193 });
194 }
195 }
196 }
197 }
198 if (period.next()==null || period.next().getDay()!=period.getDay()) {
199 int nrExamsADay = instructor.getExamsADay(period.getDay()).size();
200 if (nrExamsADay>2) {
201 String sections = "";
202 String periods = "";
203 String periodDays = "";
204 String periodTimes = "";
205 String rooms = "";
206 for (Iterator i=instructor.getExamsADay(period.getDay()).iterator();i.hasNext();) {
207 Exam exam = (Exam)i.next();
208 ExamPlacement placement = (ExamPlacement)exam.getAssignment();
209 String roomsThisExam = "";
210 for (Iterator k=placement.getRoomPlacements().iterator();k.hasNext();) {
211 ExamRoomPlacement room = (ExamRoomPlacement)k.next();
212 if (roomsThisExam.length()>0) roomsThisExam+=", ";
213 roomsThisExam+=room.getName();
214 }
215 boolean first = true;
216 for (Enumeration g=exam.getOwners(instructor).elements();g.hasMoreElements();){
217 ExamOwner owner = (ExamOwner)g.nextElement();
218 if (sections.length()>0) {
219 sections+="\n"; rooms+="\n";
220 periods+="\n"; periodDays+="\n"; periodTimes+="\n";
221 }
222 sections += owner.getName();
223 if (first) {
224 periods += (placement.getPeriod().getIndex()+1);
225 periodDays += placement.getPeriod().getDayStr();
226 periodTimes += placement.getPeriod().getTimeStr();
227 rooms += roomsThisExam;
228 }
229 first = false;
230 }
231 if (exam.getOwners(instructor).isEmpty()) {
232 if (sections.length()>0) {
233 sections+="\n"; rooms+="\n";
234 periods+="\n"; periodDays+="\n"; periodTimes+="\n";
235 }
236 sections += exam.getName();
237 periods += (placement.getPeriod().getIndex()+1);
238 periodDays += placement.getPeriod().getDayStr();
239 periodTimes += placement.getPeriod().getTimeStr();
240 rooms += roomsThisExam;
241 }
242 }
243 csv.addLine(new CSVField[] {
244 new CSVField(instructor.getName()),
245 new CSVField("more-2-day"),
246 new CSVField(sections),
247 new CSVField(periods),
248 new CSVField(periodDays),
249 new CSVField(periodTimes),
250 new CSVField(rooms)
251 });
252 }
253 }
254 }
255 }
256 return csv;
257 }
258 }