001    package net.sf.cpsolver.ifs.example.tt;
002    
003    import net.sf.cpsolver.ifs.model.Value;
004    
005    /**
006     * Location (value, i.e., a single placement of the activity). Location encodes
007     * a slot and a selection of resources.
008     * 
009     * @version IFS 1.2 (Iterative Forward Search)<br>
010     *          Copyright (C) 2006 - 2010 Tomas Muller<br>
011     *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
012     *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
013     * <br>
014     *          This library is free software; you can redistribute it and/or modify
015     *          it under the terms of the GNU Lesser General Public License as
016     *          published by the Free Software Foundation; either version 3 of the
017     *          License, or (at your option) any later version. <br>
018     * <br>
019     *          This library is distributed in the hope that it will be useful, but
020     *          WITHOUT ANY WARRANTY; without even the implied warranty of
021     *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
022     *          Lesser General Public License for more details. <br>
023     * <br>
024     *          You should have received a copy of the GNU Lesser General Public
025     *          License along with this library; if not see
026     *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
027     */
028    public class Location extends Value<Activity, Location> {
029        private int iSlot;
030        private Resource[] iResources;
031        private int iNrOfDiscouragedSlots = -1;
032    
033        /**
034         * Constructor.
035         * 
036         * @param activity
037         *            parent activity
038         * @param slot
039         *            starting time
040         * @param resources
041         *            selection of resources
042         */
043        public Location(Activity activity, int slot, Resource[] resources) {
044            super(activity);
045            iSlot = slot;
046            iResources = resources;
047            iNrOfDiscouragedSlots = computeNrOfDiscouragedSlots();
048        }
049    
050        /**
051         * Constructor. slot = nrHours * day + hour
052         * 
053         * @param activity
054         *            parent activity
055         * @param day
056         *            day
057         * @param hour
058         *            starting hour
059         * @param resources
060         *            required resources
061         */
062        public Location(Activity activity, int day, int hour, Resource[] resources) {
063            super(activity);
064            iSlot = ((TimetableModel) activity.getModel()).getNrHours() * day + hour;
065            iResources = resources;
066            iNrOfDiscouragedSlots = computeNrOfDiscouragedSlots();
067        }
068    
069        /** Gets slot */
070        public int getSlot() {
071            return iSlot;
072        }
073    
074        /** Gets selection of resources */
075        public Resource[] getResources() {
076            return iResources;
077        }
078    
079        /** Gets given resource */
080        public Resource getResource(int idx) {
081            return iResources[idx];
082        }
083    
084        /** Returns true if the given resource is used by this location */
085        public boolean containResource(Resource resource) {
086            for (int i = 0; i < iResources.length; i++)
087                if (iResources[i].equals(resource))
088                    return true;
089            return false;
090        }
091    
092        /** Number of slots (over all resources) which are discouraged */
093        public int getNrOfDiscouragedSlots() {
094            return iNrOfDiscouragedSlots;
095        }
096    
097        /** Int value (for optimization) -- getNrOfDiscouragedSlots() is returned */
098        @Override
099        public double toDouble() {
100            return iNrOfDiscouragedSlots;
101        }
102    
103        /**
104         * Computes number of discouraged slots (over all resources and the
105         * activity)
106         */
107        public int computeNrOfDiscouragedSlots() {
108            Activity a = variable();
109            int ret = 0;
110            for (int i = getSlot(); i < getSlot() + a.getLength(); i++) {
111                if (a.isDiscouragedSlot(i))
112                    ret++;
113                for (int j = 0; j < getResources().length; j++)
114                    if (getResource(j).isDiscouragedSlot(i))
115                        ret++;
116            }
117            return ret;
118        }
119    
120        /**
121         * Returns true if the location intersects with another location. This means
122         * the same resource is used in the same time.
123         */
124        public boolean hasIntersection(Location location) {
125            int s1 = getSlot();
126            int l1 = variable().getLength();
127            int s2 = location.getSlot();
128            int l2 = location.variable().getLength();
129            return !(s1 + l1 <= s2 || s2 + l2 <= s1);
130        }
131    
132        /**
133         * Returns true if the location is prohibited. This means that the activity
134         * or a required resource has a time slot which is used by this location
135         * prohibited.
136         */
137        public boolean isProhibited() {
138            Activity a = variable();
139            for (int i = getSlot(); i < getSlot() + a.getLength(); i++) {
140                if (a.isProhibitedSlot(i))
141                    return true;
142                for (int j = 0; j < getResources().length; j++)
143                    if (getResource(j).isProhibitedSlot(i))
144                        return true;
145            }
146            return false;
147        }
148    
149        @Override
150        public String getName() {
151            StringBuffer sb = new StringBuffer(getSlot() + "/");
152            for (int i = 0; i < iResources.length; i++) {
153                if (i > 0)
154                    sb.append(",");
155                sb.append(iResources[i].getName());
156            }
157            return sb.toString();
158        }
159    }