    001package net.sf.cpsolver.ifs.example.tt;
    002
    003import 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 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    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}