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