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