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 }