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    }