001    package net.sf.cpsolver.exam.reports;
002    
003    import java.text.DecimalFormat;
004    import java.util.Enumeration;
005    import java.util.Vector;
006    
007    import net.sf.cpsolver.exam.model.Exam;
008    import net.sf.cpsolver.exam.model.ExamModel;
009    import net.sf.cpsolver.exam.model.ExamPlacement;
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 into a CSV file.
015     * <br><br>
016     * Usage:<br>
017     * <code>
018     * &nbsp;&nbsp;&nbsp;&nbsp;new ExamStudentMoreTwoADay(model).report().save(file);
019     * </code>
020     * <br><br>
021     * 
022     * @version
023     * ExamTT 1.1 (Examination Timetabling)<br>
024     * Copyright (C) 2008 Tomáš Müller<br>
025     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
026     * Lazenska 391, 76314 Zlin, Czech Republic<br>
027     * <br>
028     * This library is free software; you can redistribute it and/or
029     * modify it under the terms of the GNU Lesser General Public
030     * License as published by the Free Software Foundation; either
031     * version 2.1 of the License, or (at your option) any later version.
032     * <br><br>
033     * This library is distributed in the hope that it will be useful,
034     * but 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.
037     * <br><br>
038     * You should have received a copy of the GNU Lesser General Public
039     * License along with this library; if not, write to the Free Software
040     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
041     */
042    public class ExamStudentMoreTwoADay {
043        private ExamModel iModel = null;
044        
045        /**
046         * Constructor
047         * @param model examination timetabling model
048         */
049        public ExamStudentMoreTwoADay(ExamModel model) {
050            iModel = model;
051        }
052        
053        /**
054         * generate report
055         */
056        public CSVFile report() {
057            CSVFile csv = new CSVFile();
058            csv.setHeader(new CSVField[] {
059                    new CSVField("Exam 1"),
060                    new CSVField("Enrl 1"),
061                    new CSVField("Period 1"),
062                    new CSVField("Date 1"),
063                    new CSVField("Time 1"),
064                    new CSVField("Exam 2"),
065                    new CSVField("Enrl 2"),
066                    new CSVField("Period 2"),
067                    new CSVField("Time 2"),
068                    new CSVField("Exam 3"),
069                    new CSVField("Enrl 3"),
070                    new CSVField("Period 3"),
071                    new CSVField("Time 3"),
072                    new CSVField("More-2-Day"),
073                    new CSVField("More-2-Day [%]")
074            });
075            DecimalFormat df = new DecimalFormat("0.0");
076            for (Enumeration e=iModel.variables().elements();e.hasMoreElements();) {
077                Exam ex1 = (Exam)e.nextElement();
078                ExamPlacement p1 = (ExamPlacement)ex1.getAssignment();
079                if (p1==null) continue;
080                for (Enumeration f=iModel.variables().elements();f.hasMoreElements();) {
081                    Exam ex2 = (Exam)f.nextElement();
082                    if (ex2.equals(ex1)) continue;
083                    ExamPlacement p2 = (ExamPlacement)ex2.getAssignment();
084                    if (p2==null || p2.getPeriod().getDay()!=p1.getPeriod().getDay() || p2.getPeriod().getIndex()<p1.getPeriod().getIndex()) continue;
085                    if (p1.getPeriod().equals(p2.getPeriod()) && ex1.getId()>=ex2.getId()) continue;
086                    Vector students = (Vector)ex1.getJointEnrollments().get(ex2);
087                    if (students==null || students.isEmpty()) continue;
088                    for (Enumeration g=iModel.variables().elements();g.hasMoreElements();) {
089                        Exam ex3 = (Exam)g.nextElement();
090                        if (ex3.equals(ex2) || ex3.equals(ex1)) continue;
091                        ExamPlacement p3 = (ExamPlacement)ex3.getAssignment();
092                        if (p3==null || p3.getPeriod().getDay()!=p2.getPeriod().getDay() || p3.getPeriod().getIndex()<p2.getPeriod().getIndex()) continue;
093                        if (p1.getPeriod().equals(p3.getPeriod()) && ex1.getId()>=ex3.getId()) continue;
094                        if (p2.getPeriod().equals(p3.getPeriod()) && ex2.getId()>=ex3.getId()) continue;
095                        int m2d = 0;
096                        for (Enumeration h=ex3.getStudents().elements();h.hasMoreElements();) 
097                            if (students.contains(h.nextElement())) m2d++;
098                        if (m2d==0) 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*m2d/Math.min(Math.min(ex1.getStudents().size(),ex2.getStudents().size()),ex3.getStudents().size())))
115                            });
116                    }
117                }
118            }
119            return csv;
120        }
121    }