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 Long[][] iPreference = null; 031 protected Long[] iDepartmentIds = null; 032 protected HashMap<Long, Integer> iDepartmentIdx = null; 033 034 public static Long sFreeForAllPref = new Long(-1); 035 public static Long sNotAvailablePref = new Long(-2); 036 public static char sFreeForAllPrefChar = '*'; 037 public static char sNotAvailablePrefChar = '#'; 038 039 public static Long sDefaultPref = sFreeForAllPref; 040 public static char sDefaultPrefChar = sFreeForAllPrefChar; 041 042 public char iFreeForAllPrefChar = sFreeForAllPrefChar; 043 public char iNotAvailablePrefChar = sNotAvailablePrefChar; 044 045 protected RoomSharingModel() { 046 } 047 048 public RoomSharingModel(Long[] managerIds, String pattern, Character freeForAllPrefChar, Character notAvailablePrefChar) { 049 iPreference = new Long[getNrDays()][getNrTimes()]; 050 iDepartmentIds = new Long[managerIds.length]; 051 iDepartmentIdx = new HashMap<Long, Integer>(); 052 for (int i = 0; i < managerIds.length; i++) { 053 iDepartmentIds[i] = managerIds[i]; 054 iDepartmentIdx.put(managerIds[i], i); 055 } 056 if (freeForAllPrefChar != null) 057 iFreeForAllPrefChar = freeForAllPrefChar; 058 if (notAvailablePrefChar != null) 059 iNotAvailablePrefChar = notAvailablePrefChar; 060 061 setPreferences(pattern); 062 } 063 064 public char getFreeForAllPrefChar() { return iFreeForAllPrefChar; } 065 public void setFreeForAllPrefChar(char c) { iFreeForAllPrefChar = c; } 066 067 public char getNotAvailablePrefChar() { return iNotAvailablePrefChar; } 068 public void setNotAvailablePrefChar(char c) { iNotAvailablePrefChar = c; } 069 070 public boolean isFreeForAll(int day, int time) { 071 return iPreference[day][time] == sFreeForAllPref; 072 } 073 074 public boolean isFreeForAll(int slot) { 075 int day = slot / Constants.SLOTS_PER_DAY; 076 int time = (slot % Constants.SLOTS_PER_DAY) / 6; 077 return iPreference[day][time] == sFreeForAllPref; 078 } 079 080 public boolean isNotAvailable(int day, int time) { 081 return iPreference[day][time] == sNotAvailablePref; 082 } 083 084 public boolean isNotAvailable(int slot) { 085 int day = slot / Constants.SLOTS_PER_DAY; 086 int time = (slot % Constants.SLOTS_PER_DAY) / 6; 087 return iPreference[day][time] == sNotAvailablePref; 088 } 089 090 public boolean isAvailable(TimeLocation timeLocation, Long departmentId) { 091 for (int d = 0; d < Constants.NR_DAYS; d++) { 092 if ((Constants.DAY_CODES[d] & timeLocation.getDayCode()) == 0) 093 continue; 094 int startTime = timeLocation.getStartSlot() / 6; 095 int endTime = (timeLocation.getStartSlot() + timeLocation.getLength() - 1) / 6; 096 for (int t = startTime; t <= endTime; t++) { 097 Long pref = iPreference[d][t]; 098 if (pref.equals(sNotAvailablePref)) 099 return false; 100 if (pref.equals(sFreeForAllPref)) 101 continue; 102 if (departmentId != null && !departmentId.equals(pref)) 103 return false; 104 } 105 } 106 return true; 107 } 108 109 public Long getDepartmentId(int day, int time) { 110 Long pref = iPreference[day][time]; 111 if (pref.equals(sFreeForAllPref) || pref.equals(sNotAvailablePref)) 112 return null; 113 return pref; 114 } 115 116 public Long getDepartmentId(int slot) { 117 int day = slot / Constants.SLOTS_PER_DAY; 118 int time = (slot % Constants.SLOTS_PER_DAY) / 6; 119 return getDepartmentId(day, time); 120 } 121 122 public Long[] getDepartmentIds() { 123 return iDepartmentIds; 124 } 125 126 public int getNrDepartments() { 127 return (iDepartmentIds == null ? 0 : iDepartmentIds.length); 128 } 129 130 public int getIndex(Long departmentId) { 131 Integer idx = iDepartmentIdx.get(departmentId); 132 if (idx == null) 133 return -1; 134 return idx.intValue(); 135 } 136 137 public String getPreferences() { 138 StringBuffer sb = new StringBuffer(); 139 for (int d = 0; d < getNrDays(); d++) 140 for (int t = 0; t < getNrTimes(); t++) { 141 if (iPreference[d][t].equals(sFreeForAllPref)) 142 sb.append(getFreeForAllPrefChar()); 143 else if (iPreference[d][t].equals(sNotAvailablePref)) 144 sb.append(getNotAvailablePrefChar()); 145 else 146 sb.append((char) ('0' + getIndex(iPreference[d][t]))); 147 } 148 return sb.toString(); 149 } 150 151 public void setPreferences(String pattern) { 152 try { 153 int idx = 0; 154 for (int d = 0; d < getNrDays(); d++) 155 for (int t = 0; t < getNrTimes(); t++) { 156 char pref = (pattern != null && idx < pattern.length() ? pattern.charAt(idx) : getFreeForAllPrefChar()); 157 idx++; 158 if (pref == getNotAvailablePrefChar()) { 159 iPreference[d][t] = sNotAvailablePref; 160 } else if (pref == getFreeForAllPrefChar()) { 161 iPreference[d][t] = sFreeForAllPref; 162 } else { 163 iPreference[d][t] = iDepartmentIds[(pref - '0')]; 164 } 165 } 166 } catch (NullPointerException e) { 167 } catch (IndexOutOfBoundsException e) { 168 } 169 } 170 171 public int getNrDays() { 172 return Constants.NR_DAYS; 173 } 174 175 public int getNrTimes() { 176 return Constants.SLOTS_PER_DAY / 6; 177 } 178 }