001package org.cpsolver.ifs.example.tt;
002
003import org.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.3 (Iterative Forward Search)<br>
010 *          Copyright (C) 2006 - 2014 Tomáš Müller<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 */
028public 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     * @return slot
071     **/
072    public int getSlot() {
073        return iSlot;
074    }
075
076    /** Gets selection of resources
077     * @return selection of resources
078     **/
079    public Resource[] getResources() {
080        return iResources;
081    }
082
083    /** Gets given resource
084     * @param idx index
085     * @return given resource
086     **/
087    public Resource getResource(int idx) {
088        return iResources[idx];
089    }
090
091    /** Returns true if the given resource is used by this location 
092     * @param resource given resource
093     * @return true if the given resource is used by this location
094     **/
095    public boolean containResource(Resource resource) {
096        for (int i = 0; i < iResources.length; i++)
097            if (iResources[i].equals(resource))
098                return true;
099        return false;
100    }
101
102    /** Number of slots (over all resources) which are discouraged
103     * @return number of slots (over all resources) which are discouraged
104     **/
105    public int getNrOfDiscouragedSlots() {
106        return iNrOfDiscouragedSlots;
107    }
108
109    /** Placement value (for optimization) -- getNrOfDiscouragedSlots() is returned */
110    @Override
111    public double toDouble() {
112        return iNrOfDiscouragedSlots;
113    }
114
115    /**
116     * Computes number of discouraged slots (over all resources and the
117     * activity)
118     * @return number of discouraged slots
119     */
120    public int computeNrOfDiscouragedSlots() {
121        Activity a = variable();
122        int ret = 0;
123        for (int i = getSlot(); i < getSlot() + a.getLength(); i++) {
124            if (a.isDiscouragedSlot(i))
125                ret++;
126            for (int j = 0; j < getResources().length; j++)
127                if (getResource(j).isDiscouragedSlot(i))
128                    ret++;
129        }
130        return ret;
131    }
132
133    /**
134     * Returns true if the location intersects with another location. This means
135     * the same resource is used in the same time.
136     * @param location another location
137     * @return true if this location intersects with the other location
138     */
139    public boolean hasIntersection(Location location) {
140        int s1 = getSlot();
141        int l1 = variable().getLength();
142        int s2 = location.getSlot();
143        int l2 = location.variable().getLength();
144        return !(s1 + l1 <= s2 || s2 + l2 <= s1);
145    }
146
147    /**
148     * Returns true if the location is prohibited. This means that the activity
149     * or a required resource has a time slot which is used by this location
150     * prohibited.
151     * @return true if the location is prohibited
152     */
153    public boolean isProhibited() {
154        Activity a = variable();
155        for (int i = getSlot(); i < getSlot() + a.getLength(); i++) {
156            if (a.isProhibitedSlot(i))
157                return true;
158            for (int j = 0; j < getResources().length; j++)
159                if (getResource(j).isProhibitedSlot(i))
160                    return true;
161        }
162        return false;
163    }
164
165    @Override
166    public String getName() {
167        StringBuffer sb = new StringBuffer(getSlot() + "/");
168        for (int i = 0; i < iResources.length; i++) {
169            if (i > 0)
170                sb.append(",");
171            sb.append(iResources[i].getName());
172        }
173        return sb.toString();
174    }
175}