001 package net.sf.cpsolver.coursett.criteria.additional;
002
003 import java.util.Collection;
004 import java.util.Map;
005
006 import net.sf.cpsolver.coursett.constraint.JenrlConstraint;
007 import net.sf.cpsolver.coursett.criteria.StudentConflict;
008 import net.sf.cpsolver.coursett.model.Lecture;
009 import net.sf.cpsolver.coursett.model.Placement;
010 import net.sf.cpsolver.coursett.model.Student;
011 import net.sf.cpsolver.ifs.criteria.Criterion;
012 import net.sf.cpsolver.ifs.util.DataProperties;
013
014 /**
015 * Instructor student conflicts. This criterion penalizes cases when an instructor (of a class) is attending some
016 * other class as a student and there is a conflict between the two classes.
017 * <br>
018 * To enable instructor student conflicts, set solver parameter Global.LoadStudentInstructorConflicts to true. Also
019 * student course requests should be used in this case (to be able to match an instructor external id to a student
020 * external id).
021 * <br>
022 * Instructor student conflicts are weighted by Comparator.InstructorStudentConflictWeight.
023 *
024 * <br>
025 *
026 * @version CourseTT 1.2 (University Course Timetabling)<br>
027 * Copyright (C) 2006 - 2013 Tomas Muller<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 */
045 public class InstructorStudentConflict extends StudentConflict {
046
047 /**
048 * Only count students that are instructors assigned to one of the two classes and enrolled in the other.
049 */
050 @Override
051 protected double jointEnrollment(JenrlConstraint jenrl) {
052 double ret = 0.0;
053 for (Student student: jenrl.getInstructors())
054 ret += student.getJenrlWeight(jenrl.first(), jenrl.second());
055 return ret;
056 }
057
058 @Override
059 public boolean inConflict(Placement p1, Placement p2) {
060 return super.inConflict(p1, p2) && instructor(p1, p2);
061 }
062
063 /**
064 * True if there is at least one student teaching one of the two placements and enrolled in the other.
065 */
066 public boolean instructor(Placement p1, Placement p2) {
067 JenrlConstraint jenrl = (p1 == null || p2 == null ? null : p1.variable().jenrlConstraint(p2.variable()));
068 if (jenrl == null) return false;
069 return jenrl.getNrInstructors() > 0;
070 }
071
072 /**
073 *
074 */
075 @Override
076 public void incJenrl(JenrlConstraint jenrl, double studentWeight, Double conflictPriority, Student student) {
077 if (super.inConflict(jenrl.first().getAssignment(), jenrl.second().getAssignment()) && student.getInstructor() != null
078 && (student.getInstructor().variables().contains(jenrl.first()) || student.getInstructor().variables().contains(jenrl.second())))
079 iValue += studentWeight;
080 }
081
082 @Override
083 public double getWeightDefault(DataProperties config) {
084 return config.getPropertyDouble("Comparator.InstructorStudentConflictWeight", 10.0 * config.getPropertyDouble("Comparator.StudentConflictWeight", 1.0));
085 }
086
087 @Override
088 public String getPlacementSelectionWeightName() {
089 return "Placement.NrInstructorStudConfsWeight";
090 }
091
092 @Override
093 public void getInfo(Map<String, String> info) {
094 super.getInfo(info);
095 double conf = getValue();
096 if (conf > 0.0) {
097 Criterion<Lecture, Placement> c = getModel().getCriterion(InstructorStudentHardConflict.class);
098 double hard = (c == null ? 0.0 : c.getValue());
099 info.put("Instructor student conflicts", sDoubleFormat.format(conf) + (hard > 0.0 ? " [hard: " + sDoubleFormat.format(hard) + "]" : ""));
100 }
101 }
102
103 @Override
104 public void getInfo(Map<String, String> info, Collection<Lecture> variables) {
105 super.getInfo(info, variables);
106 double conf = getValue(variables);
107 if (conf > 0.0) {
108 Criterion<Lecture, Placement> c = getModel().getCriterion(InstructorStudentHardConflict.class);
109 double hard = (c == null ? 0.0 : c.getValue(variables));
110 info.put("Instructor student conflicts", sDoubleFormat.format(conf) + (hard > 0.0 ? " [hard: " + sDoubleFormat.format(hard) + "]" : ""));
111 }
112 }
113
114 }