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