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    }