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