001package net.sf.cpsolver.exam.criteria;
002
003import java.util.Set;
004
005import net.sf.cpsolver.exam.model.Exam;
006import net.sf.cpsolver.exam.model.ExamInstructor;
007import net.sf.cpsolver.exam.model.ExamPeriod;
008import net.sf.cpsolver.exam.model.ExamPlacement;
009import net.sf.cpsolver.ifs.util.DataProperties;
010
011/**
012 * Number of back-to-back instructor conflicts. I.e., number of cases when
013 * an exam is attended by an instructor that attends some other exam at
014 * the previous {@link ExamPeriod#prev()} or following
015 * {@link ExamPeriod#next()} period. If
016 * {@link StudentBackToBackConflicts#isDayBreakBackToBack()} is false, back-to-back conflicts
017 * are only considered between consecutive periods that are of the same day.
018 * <br><br>
019 * Back-to-back instructor conflict weight can be set by problem property
020 * Exams.InstructorBackToBackConflictWeight, or in the input xml file,
021 * property instructorBackToBackConflictWeight.
022 * 
023 * 
024 * <br>
025 * 
026 * @version ExamTT 1.2 (Examination Timetabling)<br>
027 *          Copyright (C) 2008 - 2012 Tomáš Müller<br>
028 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
029 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
030 * <br>
031 *          This library is free software; you can redistribute it and/or modify
032 *          it under the terms of the GNU Lesser General Public License as
033 *          published by the Free Software Foundation; either version 3 of the
034 *          License, or (at your option) any later version. <br>
035 * <br>
036 *          This library is distributed in the hope that it will be useful, but
037 *          WITHOUT ANY WARRANTY; without even the implied warranty of
038 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
039 *          Lesser General Public License for more details. <br>
040 * <br>
041 *          You should have received a copy of the GNU Lesser General Public
042 *          License along with this library; if not see
043 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
044 */
045public class InstructorBackToBackConflicts extends StudentBackToBackConflicts {
046
047    @Override
048    public String getWeightName() {
049        return "Exams.InstructorBackToBackConflictWeight";
050    }
051    
052    @Override
053    public String getXmlWeightName() {
054        return "instructorBackToBackConflictWeight";
055    }
056    
057    @Override
058    public double getWeightDefault(DataProperties config) {
059        return 10.0;
060    }
061    
062    @Override
063    public double getValue(ExamPlacement value, Set<ExamPlacement> conflicts) {
064        Exam exam = value.variable();
065        int penalty = 0;
066        for (ExamInstructor s : exam.getInstructors()) {
067            if (value.getPeriod().prev() != null) {
068                if (isDayBreakBackToBack() || value.getPeriod().prev().getDay() == value.getPeriod().getDay()) {
069                    Set<Exam> exams = s.getExams(value.getPeriod().prev());
070                    int nrExams = exams.size() + (exams.contains(exam) ? -1 : 0);
071                    penalty += nrExams;
072                }
073            }
074            if (value.getPeriod().next() != null) {
075                if (isDayBreakBackToBack() || value.getPeriod().next().getDay() == value.getPeriod().getDay()) {
076                    Set<Exam> exams = s.getExams(value.getPeriod().next());
077                    int nrExams = exams.size() + (exams.contains(exam) ? -1 : 0);
078                    penalty += nrExams;
079                }
080            }
081        }
082        return penalty;
083    }
084
085    @Override
086    public String getName() {
087        return "Instructor Back-To-Back Conflicts";
088    }
089    
090    @Override
091    public String toString() {
092        return "iBTB:" + sDoubleFormat.format(getValue());
093    }
094
095}