    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}