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