001package net.sf.cpsolver.coursett.criteria;
002
003import java.util.Collection;
004import java.util.Set;
005
006import net.sf.cpsolver.coursett.Constants;
007import net.sf.cpsolver.coursett.model.Lecture;
008import net.sf.cpsolver.coursett.model.Placement;
009import net.sf.cpsolver.coursett.model.RoomLocation;
010import net.sf.cpsolver.coursett.preference.PreferenceCombination;
011import 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 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 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}