001 package net.sf.cpsolver.coursett.criteria; 002 003 import java.util.Collection; 004 import java.util.HashSet; 005 import java.util.Set; 006 007 import net.sf.cpsolver.coursett.Constants; 008 import net.sf.cpsolver.coursett.constraint.InstructorConstraint; 009 import net.sf.cpsolver.coursett.model.Lecture; 010 import net.sf.cpsolver.coursett.model.Placement; 011 import net.sf.cpsolver.coursett.model.TimetableModel; 012 013 import net.sf.cpsolver.ifs.util.DataProperties; 014 015 /** 016 * Bact-to-back instructor preferences. This criterion counts cases when an instructor 017 * has to teach two classes in two rooms that are too far a part. This objective 018 * is counter by the {@link InstructorConstraint} 019 * (see {@link InstructorConstraint#getDistancePreference(Placement, Placement)}). 020 * <br> 021 * 022 * @version CourseTT 1.2 (University Course Timetabling)<br> 023 * Copyright (C) 2006 - 2011 Tomas Muller<br> 024 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 025 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br> 026 * <br> 027 * This library is free software; you can redistribute it and/or modify 028 * it under the terms of the GNU Lesser General Public License as 029 * published by the Free Software Foundation; either version 3 of the 030 * License, or (at your option) any later version. <br> 031 * <br> 032 * This library is distributed in the hope that it will be useful, but 033 * WITHOUT ANY WARRANTY; without even the implied warranty of 034 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 035 * Lesser General Public License for more details. <br> 036 * <br> 037 * You should have received a copy of the GNU Lesser General Public 038 * License along with this library; if not see 039 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>. 040 */ 041 public class BackToBackInstructorPreferences extends TimetablingCriterion { 042 043 @Override 044 public double getWeightDefault(DataProperties config) { 045 return Constants.sPreferenceLevelDiscouraged * config.getPropertyDouble("Comparator.DistanceInstructorPreferenceWeight", 1.0); 046 } 047 048 @Override 049 public String getPlacementSelectionWeightName() { 050 return "Placement.DistanceInstructorPreferenceWeight"; 051 } 052 053 protected int penalty(Placement value) { 054 int ret = 0; 055 for (InstructorConstraint ic: value.variable().getInstructorConstraints()) { 056 ret += ic.getPreference(value); 057 } 058 return ret; 059 } 060 061 @Override 062 public double getValue(Placement value, Set<Placement> conflicts) { 063 double ret = penalty(value); 064 if (conflicts != null) 065 for (Placement conflict: conflicts) 066 ret -= penalty(conflict); 067 return ret; 068 } 069 070 @Override 071 public double getValue(Collection<Lecture> variables) { 072 double ret = 0; 073 Set<InstructorConstraint> constraints = new HashSet<InstructorConstraint>(); 074 for (Lecture lect: variables) { 075 for (InstructorConstraint ic: lect.getInstructorConstraints()) { 076 if (!constraints.add(ic)) continue; 077 ret += ic.getPreference(); 078 } 079 } 080 return ret; 081 } 082 083 @Override 084 protected void computeBounds() { 085 iBounds = new double[] { 0.0, 0.0 }; 086 for (InstructorConstraint ic: ((TimetableModel)getModel()).getInstructorConstraints()) 087 iBounds[1] += ic.getWorstPreference(); 088 } 089 090 @Override 091 public double[] getBounds(Collection<Lecture> variables) { 092 double[] bounds = new double[] { 0.0, 0.0 }; 093 Set<InstructorConstraint> constraints = new HashSet<InstructorConstraint>(); 094 for (Lecture lect: variables) { 095 for (InstructorConstraint ic: lect.getInstructorConstraints()) { 096 if (!constraints.add(ic)) continue; 097 bounds[1] += ic.getWorstPreference(); 098 } 099 } 100 return bounds; 101 } 102 }