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