    001    package ttsolver.constraint;
    002
    003    import ifs.model.*;
    004    import java.util.Set;
    005    import ttsolver.model.*;
    006
    007    /**
    008     * Room constraint.
    009     * <br>
    010     * Classes with the same room can not overlap in time.
    011     *
    012     * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomáš Müller</a>
    013     * @version 1.0
    014     */
    015
    016    public class RoomConstraint extends Constraint {
    017        private static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(RoomConstraint.class);
    018        private Lecture[] iResource;
    019        private String iResourceId;
    020        private String iName;
    021        private int iSlotsPerDay;
    022        private int iDays;
    023        private long iPreference = 0;
    024        private String iDescription = null;
    025
    026        /** Constructor
    027         * @param id room id
    028         * @param name room name
    029         * @param slotsPerDay number of slots per day
    030         * @param days number of days
    031         * @param description room description
    032         */
    033        public RoomConstraint(String id, String name, int slotsPerDay, int days, String description) {
    034            iSlotsPerDay = slotsPerDay;
    035            iDays = days;
    036            iResourceId = id;
    037            iName = name;
    038            iResource = new Lecture[iSlotsPerDay * iDays];
    039            iDescription = description;
    040            for (int i=0;i<iResource.length;i++)
    041                iResource[i]=null;
    042        }
    043
    044        /** Room id */
    045        public String getResourceId() { return iResourceId; }
    046        /** Room name */
    047        public String getName() { return iName; }
    048        /** Number of slots per day */
    049        public int getSlotsPerDay() { return iSlotsPerDay; }
    050        /** Number of days */
    051        public int getDays() { return iDays; }
    052
    053        public void computeConflicts(Value value, Set conflicts) {
    054            Placement placement = (Placement) value;
    055            if (!placement.getRoomId().equals(getResourceId())) return;
    056            Lecture lecture = (Lecture) value.variable();
    057            for (int i=0; i<placement.getTimeLocation().getSlots().length; i++) {
    058                int slot = placement.getTimeLocation().getSlots()[i];
    059                Lecture conf = iResource[slot];
    060                if (conf!=null && !lecture.equals(conf)) conflicts.add(conf.getAssignment());
    061            }
    062        }
    063
    064        public boolean inConflict(Value value) {
    065            Placement placement = (Placement) value;
    066            if (!placement.getRoomId().equals(getResourceId())) return false;
    067            for (int i=0; i<placement.getTimeLocation().getSlots().length; i++) {
    068                int slot = placement.getTimeLocation().getSlots()[i];
    069                if (iResource[slot]!=null) return true;
    070            }
    071            return false;
    072        }
    073
    074
    075        public boolean isConsistent(Value value1, Value value2) {
    076            Placement p1 = (Placement) value1;
    077            Placement p2 = (Placement) value2;
    078            return !(
    079                p1.getRoomId().equals(getResourceId()) &&
    080                p1.getRoomId().equals(p2.getRoomId()) &&
    081                p1.getTimeLocation().hasIntersection(p2.getTimeLocation())
    082                );
    083        }
    084
    085        public void assigned(long iteration, Value value) {
    086            super.assigned(iteration, value);
    087            Placement placement = (Placement) value;
    088            if (placement.getRoomId()==null || !placement.getRoomId().equals(getResourceId())) return;
    089            iPreference += placement.getRoomLocation().getPreference();
    090            Lecture lecture = (Lecture) value.variable();
    091            for (int i=0; i<placement.getTimeLocation().getSlots().length; i++) {
    092                int slot = placement.getTimeLocation().getSlots()[i];
    093                iResource[slot] = lecture;
    094            }
    095        }
    096
    097        public void unassigned(long iteration, Value value) {
    098            super.unassigned(iteration, value);
    099            Placement placement = (Placement) value;
    100            if (placement.getRoomId()==null || !placement.getRoomId().equals(getResourceId())) return;
    101            iPreference -= placement.getRoomLocation().getPreference();
    102            Lecture lecture = (Lecture) value.variable();
    103            for (int i=0; i<placement.getTimeLocation().getSlots().length; i++) {
    104                int slot = placement.getTimeLocation().getSlots()[i];
    105                iResource[slot] = null;
    106            }
    107        }
    108
    109        /** Lookup table getResource()[slot] -> lecture using this room placed in the given time slot (null if empty) */
    110        public Lecture[] getResource() { return iResource; }
    111
    112        /** Number of useless slots for this room */
    113        public int countUselessSlots() {
    114            int ret = 0;
    115            for (int d=0;d<iDays;d++) {
    116                for (int s=1;s<iSlotsPerDay-1;s++) {
    117                    int slot = d*iSlotsPerDay+s;
    118                    if (iResource[slot-1]!=null && iResource[slot]==null && iResource[slot+1]!=null)
    119                        ret++;
    120                }
    121            }
    122            return ret;
    123        }
    124
    125        /** Room usage */
    126        protected void printUsage(StringBuffer sb) {
    127            for (int slot=0;slot<getResource().length;slot++) {
    128                if (getResource()[slot]!=null) {
    129                    int day = slot / edu.purdue.smas.timetable.util.Constants.SLOTS_PER_DAY;
    130                    int time = (7*60)+30 + (30 * (slot % edu.purdue.smas.timetable.util.Constants.SLOTS_PER_DAY));
    131                    int h = time / 60;
    132                    int m = time % 60;
    133                    String d = edu.purdue.smas.timetable.util.Constants.DAY_NAMES_SHORT[day];
    134                    int slots = ((Placement)((Lecture)getResource()[slot]).getAssignment()).getTimeLocation().getLength();
    135                    time += (30*slots);
    136                    int h2 = time / 60;
    137                    int m2 = time % 60;
    138                    sb.append(sb.length()==0?"":",\n        ").append("["+d+(h>12?h-12:h)+":"+(m<10?"0":"")+m+(h>=12?"pm":"am")+"-"+(h2>12?h2-12:h2)+":"+(m2<10?"0":"")+m2+(h2>=12?"pm":"am")+"]=").append(((Lecture)iResource[slot]).getName());
    139                    slot+=slots-1;
    140                    //sb.append(sb.length()==0?"":", ").append("s"+(slot+1)+"=").append(((Lecture)getResource()[slot]).getName());
    141                }
    142            }
    143        }
    144
    145        public String toString() {
    146            StringBuffer sb = new StringBuffer("Room{name="+getName()+" preference="+iPreference);
    147            printUsage(sb);
    148            sb.append("\n      }");
    149            return sb.toString();
    150        }
    151        /** Room description */
    152        public String getDescription() { return iDescription; }
    153    }