001package net.sf.cpsolver.coursett.model; 002 003import java.util.HashMap; 004 005import 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 Tomáš Müller<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 */ 029public 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}