    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}