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