001    package net.sf.cpsolver.coursett.model;
002    
003    import java.util.Hashtable;
004    
005    import net.sf.cpsolver.coursett.Constants;
006    
007    /**
008     * Room availability model.
009     * 
010     * @version
011     * CourseTT 1.1 (University Course Timetabling)<br>
012     * Copyright (C) 2006 Tomáš Müller<br>
013     * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
014     * Lazenska 391, 76314 Zlin, Czech Republic<br>
015     * <br>
016     * This library is free software; you can redistribute it and/or
017     * modify it under the terms of the GNU Lesser General Public
018     * License as published by the Free Software Foundation; either
019     * version 2.1 of the License, or (at your option) any later version.
020     * <br><br>
021     * This library is distributed in the hope that it will be useful,
022     * but 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.
025     * <br><br>
026     * You should have received a copy of the GNU Lesser General Public
027     * License along with this library; if not, write to the Free Software
028     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
029     */
030    public class RoomSharingModel {
031        protected Long[][] iPreference = null;
032        protected Long[] iDepartmentIds = null;
033        protected Hashtable iDepartmentIdx = null;
034    
035        public static Long sFreeForAllPref = new Long(-1);
036        public static Long sNotAvailablePref = new Long(-2);
037        public static char sFreeForAllPrefChar = 'F';
038        public static char sNotAvailablePrefChar = 'X';
039    
040        public static Long sDefaultPref = sFreeForAllPref;
041        public static char sDefaultPrefChar = sFreeForAllPrefChar;
042        
043        protected RoomSharingModel() {}
044        
045        public RoomSharingModel(Long[] managerIds, String pattern) {
046            iPreference = new Long[getNrDays()][getNrTimes()];
047            iDepartmentIds = new Long[managerIds.length];
048            iDepartmentIdx = new Hashtable();
049            for (int i=0;i<managerIds.length;i++) {
050                iDepartmentIds[i] = managerIds[i];
051                iDepartmentIdx.put(managerIds[i],new Integer(i));
052            }
053            
054            setPreferences(pattern);
055        }
056    
057        public boolean isFreeForAll(int day, int time) {
058            return iPreference[day][time]==sFreeForAllPref;
059        }
060        public boolean isFreeForAll(int slot) {
061            int day = slot / Constants.SLOTS_PER_DAY;
062            int time = (slot % Constants.SLOTS_PER_DAY) / 6;
063            return iPreference[day][time]==sFreeForAllPref;
064        }
065        public boolean isNotAvailable(int day, int time) {
066            return iPreference[day][time]==sNotAvailablePref;
067        }
068        public boolean isNotAvailable(int slot) {
069            int day = slot / Constants.SLOTS_PER_DAY;
070            int time = (slot % Constants.SLOTS_PER_DAY) / 6;
071            return iPreference[day][time]==sNotAvailablePref;
072        }
073        public boolean isAvailable(TimeLocation timeLocation, Long departmentId) {
074            for (int d = 0; d<Constants.NR_DAYS; d++) {
075                if ((Constants.DAY_CODES[d] & timeLocation.getDayCode())==0) continue;
076                int startTime = timeLocation.getStartSlot() / 6;
077                int endTime = (timeLocation.getStartSlot()+timeLocation.getLength()-1) / 6;
078                for (int t = startTime; t<=endTime; t++) {
079                    Long pref = iPreference[d][t];
080                    if (pref.equals(sNotAvailablePref)) return false;
081                    if (pref.equals(sFreeForAllPref)) continue;
082                    if (departmentId!=null && !departmentId.equals(pref)) return false;
083                }
084            }
085            return true;
086        }
087    
088        public Long getDepartmentId(int day, int time) {
089            Long pref = iPreference[day][time];
090            if (pref.equals(sFreeForAllPref) || pref.equals(sNotAvailablePref)) return null;
091            return pref;
092        }
093        public Long getDepartmentId(int slot) {
094            int day = slot / Constants.SLOTS_PER_DAY;
095            int time = (slot % Constants.SLOTS_PER_DAY) / 6;
096            return getDepartmentId(day, time);
097        }
098    
099        public Long[] getDepartmentIds() { return iDepartmentIds; }
100        public int getNrDepartments() {
101            return (iDepartmentIds==null?0:iDepartmentIds.length);
102        }
103        public int getIndex(Long departmentId) {
104            Integer idx = (Integer)iDepartmentIdx.get(departmentId);
105            if (idx==null) return -1;
106            return idx.intValue();
107        }
108        public String getPreferences() {
109            StringBuffer sb = new StringBuffer();
110            for (int d=0;d<getNrDays();d++)
111                for (int t=0;t<getNrTimes();t++) {
112                    if (iPreference[d][t].equals(sFreeForAllPref))
113                        sb.append(sFreeForAllPrefChar);
114                    else if (iPreference[d][t].equals(sNotAvailablePref))
115                        sb.append(sNotAvailablePrefChar);
116                    else
117                        sb.append((char)('0'+getIndex(iPreference[d][t])));
118                }
119            return sb.toString();
120        }
121        public void setPreferences(String pattern) {
122            try {
123                int idx = 0;
124                for (int d=0;d<getNrDays();d++)
125                    for (int t=0;t<getNrTimes();t++) {
126                        char pref = (pattern!=null && idx<pattern.length()?pattern.charAt(idx):sDefaultPrefChar);
127                        idx++;
128                        if (pref==sNotAvailablePrefChar) {
129                            iPreference[d][t]=sNotAvailablePref;
130                        } else if (pref==sFreeForAllPrefChar) {
131                            iPreference[d][t]=sFreeForAllPref;
132                        } else {
133                            iPreference[d][t]=iDepartmentIds[(int)(pref-'0')];
134                        }
135                    }
136            } catch (NullPointerException e) {
137            } catch (IndexOutOfBoundsException e) {
138            }
139        }
140        
141        public int getNrDays() { return Constants.NR_DAYS; }
142        public int getNrTimes() { return Constants.SLOTS_PER_DAY/6; }
143    }