001 package net.sf.cpsolver.coursett.criteria;
002
003 import java.util.Collection;
004 import java.util.Set;
005
006 import net.sf.cpsolver.coursett.Constants;
007 import net.sf.cpsolver.coursett.model.Lecture;
008 import net.sf.cpsolver.coursett.model.Placement;
009 import net.sf.cpsolver.coursett.model.RoomLocation;
010 import net.sf.cpsolver.coursett.preference.PreferenceCombination;
011 import net.sf.cpsolver.ifs.util.DataProperties;
012
013 /**
014 * Too big rooms. This criterion counts cases where a class is placed in a room
015 * that is too big for the class. In general, a room is discouraged (in this
016 * criterion) if it has 25% more space than needed, strongly discouraged
017 * if it has more than 50% space than needed. Needed space is counted as the space
018 * of the smallest room in which a class can take place.
019 * <br>
020 *
021 * @version CourseTT 1.2 (University Course Timetabling)<br>
022 * Copyright (C) 2006 - 2011 Tomas Muller<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 */
040 public class TooBigRooms extends TimetablingCriterion {
041
042 @Override
043 public double getWeightDefault(DataProperties config) {
044 return config.getPropertyDouble("Comparator.TooBigRoomWeight", 0.1);
045 }
046
047 @Override
048 public String getPlacementSelectionWeightName() {
049 return "Placement.TooBigRoomWeight";
050 }
051
052 @Override
053 public double getValue(Placement value, Set<Placement> conflicts) {
054 double ret = getTooBigRoomPreference(value);
055 if (conflicts != null)
056 for (Placement conflict: conflicts)
057 ret -= getTooBigRoomPreference(conflict);
058 return ret;
059 }
060
061 @Override
062 public double[] getBounds(Collection<Lecture> variables) {
063 double[] bounds = new double[] { 0.0, 0.0 };
064 for (Lecture lect: variables) {
065 if (lect.getNrRooms() > 0)
066 bounds[0] += Constants.sPreferenceLevelStronglyDiscouraged;
067 }
068 return bounds;
069 }
070
071 public static long getDiscouragedRoomSize(Placement value) {
072 return Math.round(1.25 * value.variable().minRoomSize());
073 }
074
075 public static long getStronglyDiscouragedRoomSize(Placement value) {
076 return Math.round(1.5 * value.variable().minRoomSize());
077 }
078
079 public static int getTooBigRoomPreference(Placement value) {
080 if (value.isMultiRoom()) {
081 PreferenceCombination pref = PreferenceCombination.getDefault();
082 for (RoomLocation r : value.getRoomLocations()) {
083 if (r.getRoomSize() > getStronglyDiscouragedRoomSize(value))
084 pref.addPreferenceInt(Constants.sPreferenceLevelStronglyDiscouraged);
085 else if (r.getRoomSize() > getDiscouragedRoomSize(value))
086 pref.addPreferenceInt(Constants.sPreferenceLevelDiscouraged);
087 }
088 return pref.getPreferenceInt();
089 } else {
090 if (value.getRoomLocation().getRoomSize() > getStronglyDiscouragedRoomSize(value))
091 return Constants.sPreferenceLevelStronglyDiscouraged;
092 else if (value.getRoomLocation().getRoomSize() > getDiscouragedRoomSize(value))
093 return Constants.sPreferenceLevelDiscouraged;
094 else
095 return Constants.sPreferenceLevelNeutral;
096 }
097 }
098
099 }