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