001package org.cpsolver.coursett.criteria.additional; 002 003import java.util.Collection; 004import java.util.HashSet; 005import java.util.Map; 006import java.util.Set; 007 008import org.cpsolver.coursett.constraint.InstructorConstraint; 009import org.cpsolver.coursett.constraint.SoftInstructorConstraint; 010import org.cpsolver.coursett.criteria.TimetablingCriterion; 011import org.cpsolver.coursett.model.Lecture; 012import org.cpsolver.coursett.model.Placement; 013import org.cpsolver.coursett.model.TimetableModel; 014import org.cpsolver.ifs.assignment.Assignment; 015import org.cpsolver.ifs.util.DataProperties; 016 017/** 018 * Instructor conflict counting criterion. Used by the {@link SoftInstructorConstraint}. 019 * 020 * @version CourseTT 1.3 (University Course Timetabling)<br> 021 * Copyright (C) 2006 - 2014 Tomáš Müller<br> 022 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 023 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 024 * <br> 025 * This library is free software; you can redistribute it and/or modify 026 * it under the terms of the GNU Lesser General Public License as 027 * published by the Free Software Foundation; either version 3 of the 028 * License, or (at your option) any later version. <br> 029 * <br> 030 * This library is distributed in the hope that it will be useful, but 031 * WITHOUT ANY WARRANTY; without even the implied warranty of 032 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 033 * Lesser General Public License for more details. <br> 034 * <br> 035 * You should have received a copy of the GNU Lesser General Public 036 * License along with this library; if not see 037 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 038 */ 039public class InstructorConflict extends TimetablingCriterion { 040 041 public InstructorConflict() { 042 setValueUpdateType(ValueUpdateType.NoUpdate); 043 } 044 045 @Override 046 public double getWeightDefault(DataProperties config) { 047 return config.getPropertyDouble("Comparator.InstructorConflictWeight", 100.0); 048 } 049 050 @Override 051 public String getPlacementSelectionWeightName() { 052 return "Placement.InstructorConflictWeight"; 053 } 054 055 protected int penalty(Assignment<Lecture, Placement> assignment, Placement value) { 056 int ret = 0; 057 for (InstructorConstraint ic: value.variable().getInstructorConstraints()) { 058 if (ic instanceof SoftInstructorConstraint) 059 ret += ((SoftInstructorConstraint)ic).getConflicts(assignment, value); 060 } 061 return ret; 062 } 063 064 @Override 065 public double getValue(Assignment<Lecture, Placement> assignment, Placement value, Set<Placement> conflicts) { 066 double ret = penalty(assignment, value); 067 if (conflicts != null) 068 for (Placement conflict: conflicts) 069 ret -= penalty(assignment, conflict); 070 return ret; 071 } 072 073 @Override 074 public double getValue(Assignment<Lecture, Placement> assignment, Collection<Lecture> variables) { 075 double ret = 0; 076 Set<InstructorConstraint> constraints = new HashSet<InstructorConstraint>(); 077 for (Lecture lect: variables) { 078 for (InstructorConstraint ic: lect.getInstructorConstraints()) { 079 if (!constraints.add(ic)) continue; 080 if (ic instanceof SoftInstructorConstraint) 081 ret += ((SoftInstructorConstraint)ic).getConflicts(assignment); 082 } 083 } 084 return ret; 085 } 086 087 @Override 088 protected double[] computeBounds(Assignment<Lecture, Placement> assignment) { 089 double[] bounds = new double[] { 0.0, 0.0 }; 090 for (InstructorConstraint ic: ((TimetableModel)getModel()).getInstructorConstraints()) 091 if (ic instanceof SoftInstructorConstraint) 092 bounds[1] += ((SoftInstructorConstraint)ic).getWorstConflicts(); 093 return bounds; 094 } 095 096 @Override 097 public double[] getBounds(Assignment<Lecture, Placement> assignment, Collection<Lecture> variables) { 098 double[] bounds = new double[] { 0.0, 0.0 }; 099 Set<InstructorConstraint> constraints = new HashSet<InstructorConstraint>(); 100 for (Lecture lect: variables) { 101 for (InstructorConstraint ic: lect.getInstructorConstraints()) { 102 if (!constraints.add(ic)) continue; 103 if (ic instanceof SoftInstructorConstraint) 104 bounds[1] += ((SoftInstructorConstraint)ic).getWorstConflicts(); 105 } 106 } 107 return bounds; 108 } 109 110 @Override 111 public void getInfo(Assignment<Lecture, Placement> assignment, Map<String, String> info) { 112 super.getInfo(assignment, info); 113 double conf = getValue(assignment); 114 if (conf > 0.0) 115 info.put("Instructor conflicts", sDoubleFormat.format(conf)); 116 } 117 118 @Override 119 public void getInfo(Assignment<Lecture, Placement> assignment, Map<String, String> info, Collection<Lecture> variables) { 120 super.getInfo(assignment, info, variables); 121 double conf = getValue(assignment, variables); 122 if (conf > 0.0) 123 info.put("Instructor conflicts", sDoubleFormat.format(conf)); 124 } 125}