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 }