001 package net.sf.cpsolver.exam.reports;
002
003 import java.text.DecimalFormat;
004 import java.util.List;
005
006 import net.sf.cpsolver.exam.model.Exam;
007 import net.sf.cpsolver.exam.model.ExamModel;
008 import net.sf.cpsolver.exam.model.ExamPlacement;
009 import net.sf.cpsolver.exam.model.ExamStudent;
010 import net.sf.cpsolver.ifs.util.CSVFile;
011 import net.sf.cpsolver.ifs.util.CSVFile.CSVField;
012
013 /**
014 * Export student more than two exams a day conflicts between triplets of exams
015 * into a CSV file. <br>
016 * <br>
017 * Usage:<br>
018 * <code>
019 * new ExamStudentMoreTwoADay(model).report().save(file);
020 * </code> <br>
021 * <br>
022 *
023 * @version ExamTT 1.2 (Examination Timetabling)<br>
024 * Copyright (C) 2008 - 2010 Tomas Muller<br>
025 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
026 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
027 * <br>
028 * This library is free software; you can redistribute it and/or modify
029 * it under the terms of the GNU Lesser General Public License as
030 * published by the Free Software Foundation; either version 3 of the
031 * License, or (at your option) any later version. <br>
032 * <br>
033 * This library is distributed in the hope that it will be useful, but
034 * WITHOUT ANY WARRANTY; without even the implied warranty of
035 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
036 * Lesser General Public License for more details. <br>
037 * <br>
038 * You should have received a copy of the GNU Lesser General Public
039 * License along with this library; if not see
040 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
041 */
042 public class ExamStudentMoreTwoADay {
043 private ExamModel iModel = null;
044
045 /**
046 * Constructor
047 *
048 * @param model
049 * examination timetabling model
050 */
051 public ExamStudentMoreTwoADay(ExamModel model) {
052 iModel = model;
053 }
054
055 /**
056 * generate report
057 */
058 public CSVFile report() {
059 CSVFile csv = new CSVFile();
060 csv.setHeader(new CSVField[] { new CSVField("Exam 1"), new CSVField("Enrl 1"), new CSVField("Period 1"),
061 new CSVField("Date 1"), new CSVField("Time 1"), new CSVField("Exam 2"), new CSVField("Enrl 2"),
062 new CSVField("Period 2"), new CSVField("Time 2"), new CSVField("Exam 3"), new CSVField("Enrl 3"),
063 new CSVField("Period 3"), new CSVField("Time 3"), new CSVField("More-2-Day"),
064 new CSVField("More-2-Day [%]") });
065 DecimalFormat df = new DecimalFormat("0.0");
066 for (Exam ex1 : iModel.variables()) {
067 ExamPlacement p1 = ex1.getAssignment();
068 if (p1 == null)
069 continue;
070 for (Exam ex2 : iModel.variables()) {
071 if (ex2.equals(ex1))
072 continue;
073 ExamPlacement p2 = ex2.getAssignment();
074 if (p2 == null || p2.getPeriod().getDay() != p1.getPeriod().getDay()
075 || p2.getPeriod().getIndex() < p1.getPeriod().getIndex())
076 continue;
077 if (p1.getPeriod().equals(p2.getPeriod()) && ex1.getId() >= ex2.getId())
078 continue;
079 List<ExamStudent> students = ex1.getJointEnrollments().get(ex2);
080 if (students == null || students.isEmpty())
081 continue;
082 for (Exam ex3 : iModel.variables()) {
083 if (ex3.equals(ex2) || ex3.equals(ex1))
084 continue;
085 ExamPlacement p3 = ex3.getAssignment();
086 if (p3 == null || p3.getPeriod().getDay() != p2.getPeriod().getDay()
087 || p3.getPeriod().getIndex() < p2.getPeriod().getIndex())
088 continue;
089 if (p1.getPeriod().equals(p3.getPeriod()) && ex1.getId() >= ex3.getId())
090 continue;
091 if (p2.getPeriod().equals(p3.getPeriod()) && ex2.getId() >= ex3.getId())
092 continue;
093 int m2d = 0;
094 for (ExamStudent h : ex3.getStudents())
095 if (students.contains(h))
096 m2d++;
097 if (m2d == 0)
098 continue;
099 csv.addLine(new CSVField[] {
100 new CSVField(ex1.getName()),
101 new CSVField(ex1.getStudents().size()),
102 new CSVField(p1.getPeriod().getIndex() + 1),
103 new CSVField(p1.getPeriod().getDayStr()),
104 new CSVField(p1.getPeriod().getTimeStr()),
105 new CSVField(ex2.getName()),
106 new CSVField(ex2.getStudents().size()),
107 new CSVField(p2.getPeriod().getIndex() + 1),
108 new CSVField(p2.getPeriod().getTimeStr()),
109 new CSVField(ex3.getName()),
110 new CSVField(ex3.getStudents().size()),
111 new CSVField(p3.getPeriod().getIndex() + 1),
112 new CSVField(p3.getPeriod().getTimeStr()),
113 new CSVField(m2d),
114 new CSVField(df.format(100.0
115 * m2d
116 / Math.min(Math.min(ex1.getStudents().size(), ex2.getStudents().size()), ex3
117 .getStudents().size()))) });
118 }
119 }
120 }
121 return csv;
122 }
123 }