    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}