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    }