    001package org.cpsolver.ifs.example.tt;
    002
    003import java.util.Set;
    004
    005import org.cpsolver.ifs.assignment.Assignment;
    006import org.cpsolver.ifs.model.BinaryConstraint;
    007
    008
    009/**
    010 * Binary dependence between two activities.
    011 *
    012 * @author  Tomáš Müller
    013 * @version IFS 1.3 (Iterative Forward Search)<br>
    014 *          Copyright (C) 2006 - 2014 Tomáš Müller<br>
    015 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
    016 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
    017 * <br>
    018 *          This library is free software; you can redistribute it and/or modify
    019 *          it under the terms of the GNU Lesser General Public License as
    020 *          published by the Free Software Foundation; either version 3 of the
    021 *          License, or (at your option) any later version. <br>
    022 * <br>
    023 *          This library is distributed in the hope that it will be useful, but
    024 *          WITHOUT ANY WARRANTY; without even the implied warranty of
    025 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    026 *          Lesser General Public License for more details. <br>
    027 * <br>
    028 *          You should have received a copy of the GNU Lesser General Public
    029 *          License along with this library; if not see
    030 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
    031 */
    032public class Dependence extends BinaryConstraint<Activity, Location> {
    033    public static final int TYPE_NO_DEPENDENCE = 0;
    034    public static final int TYPE_BEFORE = 1;
    035    public static final int TYPE_CLOSELY_BEFORE = 2;
    036    public static final int TYPE_AFTER = 3;
    037    public static final int TYPE_CLOSELY_AFTER = 4;
    038    public static final int TYPE_CONCURRENCY = 5;
    039    private int iType = TYPE_NO_DEPENDENCE;
    040    private String iResourceId = null;
    041
    042    public Dependence(String id, int type) {
    043        super();
    044        iType = type;
    045        iResourceId = id;
    046    }
    047
    048    public int getType() {
    049        return iType;
    050    }
    051
    052    public String getResourceId() {
    053        return iResourceId;
    054    }
    055
    056    @Override
    057    public void computeConflicts(Assignment<Activity, Location> assignment, Location location, Set<Location> conflicts) {
    058        Activity activity = location.variable();
    059        Activity another = another(activity);
    060        Location anotherLocation = assignment.getValue(another);
    061        if (anotherLocation == null)
    062            return;
    063        if (isFirst(activity)) {
    064            if (!isConsistent(location.getSlot(), activity.getLength(), anotherLocation.getSlot(), another.getLength()))
    065                conflicts.add(anotherLocation);
    066        } else {
    067            if (!isConsistent(anotherLocation.getSlot(), another.getLength(), location.getSlot(), activity.getLength()))
    068                conflicts.add(anotherLocation);
    069        }
    070    }
    071
    072    public boolean isConsistent(int s1, int l1, int s2, int l2) {
    073        switch (iType) {
    074            case TYPE_BEFORE:
    075                return s1 + l1 <= s2;
    076            case TYPE_CLOSELY_BEFORE:
    077                return s1 + l1 == s2;
    078            case TYPE_AFTER:
    079                return s2 + l2 <= s1;
    080            case TYPE_CLOSELY_AFTER:
    081                return s2 + l2 == s1;
    082            case TYPE_CONCURRENCY:
    083                return (s1 <= s2 && s2 + l2 <= s1 + l1) || (s2 <= s1 && s1 + l1 <= s2 + l2);
    084            default:
    085                return true;
    086        }
    087    }
    088
    089    @Override
    090    public boolean inConflict(Assignment<Activity, Location> assignment, Location location) {
    091        Activity activity = location.variable();
    092        Activity another = another(activity);
    093        Location anotherLocation = assignment.getValue(another);
    094        if (anotherLocation == null)
    095            return false;
    096        if (isFirst(activity)) {
    097            return !isConsistent(location.getSlot(), activity.getLength(), anotherLocation.getSlot(), another
    098                    .getLength());
    099        } else {
    100            return !isConsistent(anotherLocation.getSlot(), another.getLength(), location.getSlot(), activity
    101                    .getLength());
    102        }
    103    }
    104
    105    @Override
    106    public boolean isConsistent(Location l1, Location l2) {
    107        Activity a1 = l1.variable();
    108        Activity a2 = l2.variable();
    109        if (isFirst(a1)) {
    110            return !isConsistent(l1.getSlot(), a1.getLength(), l2.getSlot(), a2.getLength());
    111        } else {
    112            return !isConsistent(l2.getSlot(), a2.getLength(), l1.getSlot(), a1.getLength());
    113        }
    114    }
    115
    116    @Override
    117    public String getName() {
    118        switch (iType) {
    119            case TYPE_BEFORE:
    120                return first().getName() + "<" + second().getName();
    121            case TYPE_CLOSELY_BEFORE:
    122                return first().getName() + "<|" + second().getName();
    123            case TYPE_AFTER:
    124                return first().getName() + ">" + second().getName();
    125            case TYPE_CLOSELY_AFTER:
    126                return first().getName() + "|>" + second().getName();
    127            case TYPE_CONCURRENCY:
    128                return first().getName() + "||" + second().getName();
    129            default:
    130                return first().getName() + "?" + second().getName();
    131        }
    132    }
    133
    134}