001 package net.sf.cpsolver.ifs.example.tt;
002
003 import java.util.Set;
004
005 import net.sf.cpsolver.ifs.model.BinaryConstraint;
006
007 /**
008 * Binary dependence between two activities.
009 *
010 * @version IFS 1.2 (Iterative Forward Search)<br>
011 * Copyright (C) 2006 - 2010 Tomas Muller<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 */
029 public class Dependence extends BinaryConstraint<Activity, Location> {
030 public static final int TYPE_NO_DEPENDENCE = 0;
031 public static final int TYPE_BEFORE = 1;
032 public static final int TYPE_CLOSELY_BEFORE = 2;
033 public static final int TYPE_AFTER = 3;
034 public static final int TYPE_CLOSELY_AFTER = 4;
035 public static final int TYPE_CONCURRENCY = 5;
036 private int iType = TYPE_NO_DEPENDENCE;
037 private String iResourceId = null;
038
039 public Dependence(String id, int type) {
040 super();
041 iType = type;
042 iResourceId = id;
043 }
044
045 public int getType() {
046 return iType;
047 }
048
049 public String getResourceId() {
050 return iResourceId;
051 }
052
053 @Override
054 public void computeConflicts(Location location, Set<Location> conflicts) {
055 Activity activity = location.variable();
056 Activity another = another(activity);
057 Location anotherLocation = another.getAssignment();
058 if (anotherLocation == null)
059 return;
060 if (isFirst(activity)) {
061 if (!isConsistent(location.getSlot(), activity.getLength(), anotherLocation.getSlot(), another.getLength()))
062 conflicts.add(anotherLocation);
063 } else {
064 if (!isConsistent(anotherLocation.getSlot(), another.getLength(), location.getSlot(), activity.getLength()))
065 conflicts.add(anotherLocation);
066 }
067 }
068
069 public boolean isConsistent(int s1, int l1, int s2, int l2) {
070 switch (iType) {
071 case TYPE_BEFORE:
072 return s1 + l1 <= s2;
073 case TYPE_CLOSELY_BEFORE:
074 return s1 + l1 == s2;
075 case TYPE_AFTER:
076 return s2 + l2 <= s1;
077 case TYPE_CLOSELY_AFTER:
078 return s2 + l2 == s1;
079 case TYPE_CONCURRENCY:
080 return (s1 <= s2 && s2 + l2 <= s1 + l1) || (s2 <= s1 && s1 + l1 <= s2 + l2);
081 default:
082 return true;
083 }
084 }
085
086 @Override
087 public boolean inConflict(Location location) {
088 Activity activity = location.variable();
089 Activity another = another(activity);
090 Location anotherLocation = another.getAssignment();
091 if (anotherLocation == null)
092 return false;
093 if (isFirst(activity)) {
094 return !isConsistent(location.getSlot(), activity.getLength(), anotherLocation.getSlot(), another
095 .getLength());
096 } else {
097 return !isConsistent(anotherLocation.getSlot(), another.getLength(), location.getSlot(), activity
098 .getLength());
099 }
100 }
101
102 @Override
103 public boolean isConsistent(Location l1, Location l2) {
104 Activity a1 = l1.variable();
105 Activity a2 = l2.variable();
106 if (isFirst(a1)) {
107 return !isConsistent(l1.getSlot(), a1.getLength(), l2.getSlot(), a2.getLength());
108 } else {
109 return !isConsistent(l2.getSlot(), a2.getLength(), l1.getSlot(), a1.getLength());
110 }
111 }
112
113 @Override
114 public String getName() {
115 switch (iType) {
116 case TYPE_BEFORE:
117 return first().getName() + "<" + second().getName();
118 case TYPE_CLOSELY_BEFORE:
119 return first().getName() + "<|" + second().getName();
120 case TYPE_AFTER:
121 return first().getName() + ">" + second().getName();
122 case TYPE_CLOSELY_AFTER:
123 return first().getName() + "|>" + second().getName();
124 case TYPE_CONCURRENCY:
125 return first().getName() + "||" + second().getName();
126 default:
127 return first().getName() + "?" + second().getName();
128 }
129 }
130
131 }