001 package net.sf.cpsolver.coursett.model;
002
003 import java.util.HashMap;
004
005 import net.sf.cpsolver.coursett.Constants;
006
007 /**
008 * Room availability model.
009 *
010 * @version CourseTT 1.2 (University Course Timetabling)<br>
011 * Copyright (C) 2006 - 2010 Tomas Muller<br>
012 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
013 * <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
014 * <br>
015 * This library is free software; you can redistribute it and/or modify
016 * it under the terms of the GNU Lesser General Public License as
017 * published by the Free Software Foundation; either version 3 of the
018 * License, or (at your option) any later version. <br>
019 * <br>
020 * This library is distributed in the hope that it will be useful, but
021 * WITHOUT ANY WARRANTY; without even the implied warranty of
022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
023 * Lesser General Public License for more details. <br>
024 * <br>
025 * You should have received a copy of the GNU Lesser General Public
026 * License along with this library; if not see
027 * <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
028 */
029 public class RoomSharingModel {
030 protected int iStep = 1;
031 protected Long[][] iPreference = null;
032 protected Long[] iDepartmentIds = null;
033 protected HashMap<Long, Integer> iDepartmentIdx = null;
034
035 public static Long sFreeForAllPref = new Long(-1);
036 public static Long sNotAvailablePref = new Long(-2);
037 public static char sFreeForAllPrefChar = '*';
038 public static char sNotAvailablePrefChar = '#';
039
040 public static Long sDefaultPref = sFreeForAllPref;
041 public static char sDefaultPrefChar = sFreeForAllPrefChar;
042
043 public char iFreeForAllPrefChar = sFreeForAllPrefChar;
044 public char iNotAvailablePrefChar = sNotAvailablePrefChar;
045
046 protected RoomSharingModel(int step) {
047 iStep = step;
048 }
049
050 protected RoomSharingModel() {
051 this(6);
052 }
053
054 public RoomSharingModel(int step, Long[] managerIds, String pattern, Character freeForAllPrefChar, Character notAvailablePrefChar) {
055 iStep = step;
056 iPreference = new Long[getNrDays()][getNrTimes()];
057 iDepartmentIds = new Long[managerIds.length];
058 iDepartmentIdx = new HashMap<Long, Integer>();
059 for (int i = 0; i < managerIds.length; i++) {
060 iDepartmentIds[i] = managerIds[i];
061 iDepartmentIdx.put(managerIds[i], i);
062 }
063 if (freeForAllPrefChar != null)
064 iFreeForAllPrefChar = freeForAllPrefChar;
065 if (notAvailablePrefChar != null)
066 iNotAvailablePrefChar = notAvailablePrefChar;
067
068 setPreferences(pattern);
069 }
070
071 public char getFreeForAllPrefChar() { return iFreeForAllPrefChar; }
072 public void setFreeForAllPrefChar(char c) { iFreeForAllPrefChar = c; }
073
074 public char getNotAvailablePrefChar() { return iNotAvailablePrefChar; }
075 public void setNotAvailablePrefChar(char c) { iNotAvailablePrefChar = c; }
076
077 public boolean isFreeForAll(int day, int time) {
078 return sFreeForAllPref.equals(iPreference[day][time]);
079 }
080
081 public boolean isFreeForAll(int slot) {
082 int day = slot / Constants.SLOTS_PER_DAY;
083 int time = (slot % Constants.SLOTS_PER_DAY) / getStep();
084 return sFreeForAllPref.equals(iPreference[day][time]);
085 }
086
087 public boolean isNotAvailable(int day, int time) {
088 return sNotAvailablePref.equals(iPreference[day][time]);
089 }
090
091 public boolean isNotAvailable(int slot) {
092 int day = slot / Constants.SLOTS_PER_DAY;
093 int time = (slot % Constants.SLOTS_PER_DAY) / getStep();
094 return sNotAvailablePref.equals(iPreference[day][time]);
095 }
096
097 public boolean isAvailable(TimeLocation timeLocation, Long departmentId) {
098 for (int d = 0; d < Constants.NR_DAYS; d++) {
099 if ((Constants.DAY_CODES[d] & timeLocation.getDayCode()) == 0)
100 continue;
101 int startTime = timeLocation.getStartSlot() / getStep();
102 int endTime = (timeLocation.getStartSlot() + timeLocation.getLength() - 1) / getStep();
103 for (int t = startTime; t <= endTime; t++) {
104 Long pref = iPreference[d][t];
105 if (pref.equals(sNotAvailablePref))
106 return false;
107 if (pref.equals(sFreeForAllPref))
108 continue;
109 if (departmentId != null && !departmentId.equals(pref))
110 return false;
111 }
112 }
113 return true;
114 }
115
116 public Long getDepartmentId(int day, int time) {
117 Long pref = iPreference[day][time];
118 if (pref.equals(sFreeForAllPref) || pref.equals(sNotAvailablePref))
119 return null;
120 return pref;
121 }
122
123 public Long getDepartmentId(int slot) {
124 int day = slot / Constants.SLOTS_PER_DAY;
125 int time = (slot % Constants.SLOTS_PER_DAY) / getStep();
126 return getDepartmentId(day, time);
127 }
128
129 public Long[] getDepartmentIds() {
130 return iDepartmentIds;
131 }
132
133 public int getNrDepartments() {
134 return (iDepartmentIds == null ? 0 : iDepartmentIds.length);
135 }
136
137 public int getIndex(Long departmentId) {
138 Integer idx = iDepartmentIdx.get(departmentId);
139 if (idx == null)
140 return -1;
141 return idx.intValue();
142 }
143
144 public String getPreferences() {
145 StringBuffer sb = new StringBuffer();
146 for (int d = 0; d < getNrDays(); d++)
147 for (int t = 0; t < getNrTimes(); t++) {
148 if (iPreference[d][t].equals(sFreeForAllPref))
149 sb.append(getFreeForAllPrefChar());
150 else if (iPreference[d][t].equals(sNotAvailablePref))
151 sb.append(getNotAvailablePrefChar());
152 else
153 sb.append((char) ('0' + getIndex(iPreference[d][t])));
154 }
155 return sb.toString();
156 }
157
158 public void setPreferences(String pattern) {
159 try {
160 int idx = 0;
161 for (int d = 0; d < getNrDays(); d++)
162 for (int t = 0; t < getNrTimes(); t++) {
163 char pref = (pattern != null && idx < pattern.length() ? pattern.charAt(idx) : getFreeForAllPrefChar());
164 idx++;
165 if (pref == getNotAvailablePrefChar()) {
166 iPreference[d][t] = sNotAvailablePref;
167 } else if (pref == getFreeForAllPrefChar()) {
168 iPreference[d][t] = sFreeForAllPref;
169 } else {
170 iPreference[d][t] = iDepartmentIds[(pref - '0')];
171 }
172 }
173 } catch (NullPointerException e) {
174 } catch (IndexOutOfBoundsException e) {
175 }
176 }
177
178 public int getNrDays() {
179 return Constants.NR_DAYS;
180 }
181
182 public int getNrTimes() {
183 return Constants.SLOTS_PER_DAY / getStep();
184 }
185
186 public int getStep() {
187 return iStep;
188 }
189 }