001 package net.sf.cpsolver.coursett.constraint;
002
003 import java.util.Set;
004
005 import net.sf.cpsolver.coursett.model.Lecture;
006 import net.sf.cpsolver.coursett.model.Placement;
007 import net.sf.cpsolver.coursett.model.RoomSharingModel;
008 import net.sf.cpsolver.ifs.model.Value;
009 import net.sf.cpsolver.ifs.util.DataProperties;
010
011 /**
012 * Discouraged room constraint.
013 * This constraint is based on {@link RoomConstraint}, however, it tries to minimize the usage of the room as much as possible.
014 *
015 * @version
016 * CourseTT 1.1 (University Course Timetabling)<br>
017 * Copyright (C) 2006 Tomáš Müller<br>
018 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
019 * Lazenska 391, 76314 Zlin, Czech Republic<br>
020 * <br>
021 * This library is free software; you can redistribute it and/or
022 * modify it under the terms of the GNU Lesser General Public
023 * License as published by the Free Software Foundation; either
024 * version 2.1 of the License, or (at your option) any later version.
025 * <br><br>
026 * This library is distributed in the hope that it will be useful,
027 * but WITHOUT ANY WARRANTY; without even the implied warranty of
028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
029 * Lesser General Public License for more details.
030 * <br><br>
031 * You should have received a copy of the GNU Lesser General Public
032 * License along with this library; if not, write to the Free Software
033 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
034 */
035 public class DiscouragedRoomConstraint extends RoomConstraint {
036 int iUsage = 0;
037 int iLimit = 0;
038 boolean iEnabled = false;
039
040 private int iUnassignmentsToWeaken = 1000;
041 private long iUnassignment = 0;
042
043 public DiscouragedRoomConstraint(DataProperties config, Long id, String name, Long buildingId, int capacity, RoomSharingModel roomSharingModel, int x, int y, boolean ignoreTooFar, boolean constraint) {
044 super(id, name, buildingId, capacity, roomSharingModel, x, y, ignoreTooFar, constraint);
045 iUnassignmentsToWeaken = config.getPropertyInt("DiscouragedRoom.Unassignments2Weaken", iUnassignmentsToWeaken);
046 }
047
048 public int getLimit() {
049 return iLimit;
050 }
051 public int getUsage() {
052 return iUsage;
053 }
054
055 public boolean isOverLimit(Value value) {
056 if (!iEnabled) return false; //not enabled
057 if (iUnassignmentsToWeaken==0) return false; //not working
058 Placement placement = (Placement) value;
059 if (!placement.hasRoomLocation(getResourceId())) return false; //different room
060 Lecture lecture = (Lecture)placement.variable();
061 if (lecture.roomLocations().size()==lecture.getNrRooms()) return false; //required room
062 if (lecture.isCommitted()) return false; //commited class
063 if (lecture.getAssignment()!=null && ((Placement)lecture.getAssignment()).hasRoomLocation(getResourceId())) return false; //already assigned in this room
064 if (iUsage+1<=iLimit) return false; //under the limit
065 return true;
066 }
067
068 public void computeConflicts(Value value, Set conflicts) {
069 if (!getConstraint()) return;
070 super.computeConflicts(value, conflicts);
071 if (isOverLimit(value)) conflicts.add(value);
072 }
073
074 public boolean inConflict(Value value) {
075 if (!getConstraint()) return false;
076 if (isOverLimit(value)) return true;
077 return super.inConflict(value);
078 }
079
080 public boolean isConsistent(Value value1, Value value2) {
081 if (!getConstraint()) return true;
082 if (isOverLimit(value1) || isOverLimit(value2)) return false;
083 return super.isConsistent(value1, value2);
084 }
085
086 public void assigned(long iteration, Value value) {
087 super.assigned(iteration, value);
088 Placement placement = (Placement) value;
089 if (!placement.hasRoomLocation(getResourceId())) return;
090 Lecture lecture = (Lecture)placement.variable();
091 if (lecture.isCommitted()) return;
092 iUsage++;
093 }
094
095 public void unassigned(long iteration, Value value) {
096 super.unassigned(iteration, value);
097 Placement placement = (Placement) value;
098 if (!placement.hasRoomLocation(getResourceId())) {
099 iUnassignment++;
100 if (iUnassignmentsToWeaken>0 && iUnassignment%iUnassignmentsToWeaken==0) iLimit++;
101 } else {
102 iUsage--;
103 }
104 }
105
106 public String getName() { return "discouraged "+super.getName(); }
107 public String toString() { return "Discouraged "+super.toString(); }
108
109 public void setEnabled(boolean enabled) {
110 iEnabled = enabled;
111 iLimit = Math.max(iUsage, iLimit);
112 }
113 public boolean isEnabled() { return iEnabled; }
114 }