001    package net.sf.cpsolver.ifs.extension;
002    
003    import java.util.ArrayList;
004    import java.util.Collection;
005    import java.util.List;
006    
007    import net.sf.cpsolver.ifs.model.Constraint;
008    import net.sf.cpsolver.ifs.model.Value;
009    import net.sf.cpsolver.ifs.model.Variable;
010    
011    /**
012     * This class describing a set of assignment (used by CBS).
013     * 
014     * It also contains a counter, name, description and a constraint (for printing
015     * purposes).
016     * 
017     * @version IFS 1.2 (Iterative Forward Search)<br>
018     *          Copyright (C) 2006 - 2010 Tomas Muller<br>
019     *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
020     *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
021     * <br>
022     *          This library is free software; you can redistribute it and/or modify
023     *          it under the terms of the GNU Lesser General Public License as
024     *          published by the Free Software Foundation; either version 3 of the
025     *          License, or (at your option) any later version. <br>
026     * <br>
027     *          This library is distributed in the hope that it will be useful, but
028     *          WITHOUT ANY WARRANTY; without even the implied warranty of
029     *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
030     *          Lesser General Public License for more details. <br>
031     * <br>
032     *          You should have received a copy of the GNU Lesser General Public
033     *          License along with this library; if not see
034     *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
035     */
036    
037    public class AssignmentSet<T extends Value<?, T>> {
038        private List<Assignment<T>> iSet = new ArrayList<Assignment<T>>();
039        private int iCounter = 1;
040        private String iName = null;
041        private String iDescription = null;
042        private Constraint<?, T> iConstraint = null;
043    
044        public AssignmentSet() {
045        }
046    
047        public AssignmentSet(Assignment<T>[] assignments) {
048            for (Assignment<T> a : assignments)
049                iSet.add(a);
050        }
051    
052        public AssignmentSet(Collection<Assignment<T>> assignments) {
053            for (Assignment<T> a : assignments)
054                iSet.add(a);
055        }
056    
057        /**
058         * Create set of assignments from the list of Assignments, Values or
059         * (assigned) Variables
060         */
061        public static <T extends Value<?, T>> AssignmentSet<T> createAssignmentSet(Collection<Assignment<T>> assignments) {
062            AssignmentSet<T> set = new AssignmentSet<T>();
063            for (Assignment<T> a : assignments)
064                set.addAssignment(a);
065            return set;
066        }
067    
068        /**
069         * Create set of assignments from the list of Assignments, Values or
070         * (assigned) Variables
071         */
072        public static <T extends Value<?, T>> AssignmentSet<T> createAssignmentSetForValues(Collection<T> assignments) {
073            AssignmentSet<T> set = new AssignmentSet<T>();
074            for (T a : assignments)
075                set.addAssignment(0l, a, 1.0);
076            return set;
077        }
078    
079        /**
080         * Create set of assignments from the list of Assignments, Values or
081         * (assigned) Variables
082         */
083        public static <T extends Value<?, T>> AssignmentSet<T> createAssignmentSetForVariables(
084                Collection<Variable<?, T>> assignments) {
085            AssignmentSet<T> set = new AssignmentSet<T>();
086            for (Variable<?, T> a : assignments)
087                if (a.getAssignment() != null)
088                    set.addAssignment(0, a.getAssignment(), 1.0);
089            return set;
090        }
091    
092        /** Increment counter */
093        public void incCounter() {
094            iCounter++;
095        }
096    
097        /** Returns counter */
098        public int getCounter() {
099            return iCounter;
100        }
101    
102        /** Returns set of assignments */
103        public List<Assignment<T>> getSet() {
104            return iSet;
105        }
106    
107        /** Returns name */
108        public String getName() {
109            return iName;
110        }
111    
112        /** Sets name */
113        public void setName(String name) {
114            iName = name;
115        }
116    
117        /** Returns description */
118        public String getDescription() {
119            return iDescription;
120        }
121    
122        /** Sets description */
123        public void setDescription(String description) {
124            iDescription = description;
125        }
126    
127        /** Returns constraint */
128        public Constraint<?, T> getConstraint() {
129            return iConstraint;
130        }
131    
132        /** Sets constraint */
133        public void setConstraint(Constraint<?, T> constraint) {
134            iConstraint = constraint;
135        }
136    
137        /** Returns true if it contains the given assignment */
138        public boolean contains(Assignment<T> assignment) {
139            return iSet.contains(assignment);
140        }
141    
142        /** Returns true if it contains all of the given assignments */
143        public boolean contains(AssignmentSet<T> assignmentSet) {
144            return iSet.containsAll(assignmentSet.getSet());
145        }
146    
147        /** Returns true if it contains the given assignment */
148        public boolean contains(T value) {
149            return iSet.contains(new Assignment<T>(0l, value, 1.0));
150        }
151    
152        /** Returns true if it contains the given assignment (assigned variable) */
153        public boolean contains(Variable<?, T> variable) {
154            return (variable.getAssignment() == null ? false : iSet.contains(new Assignment<T>(0l,
155                    variable.getAssignment(), 1.0)));
156        }
157    
158        /** Returns true if it contains all of the given assignments */
159        public boolean contains(Collection<Assignment<T>> assignments) {
160            for (Assignment<T> a : assignments)
161                if (!iSet.contains(a))
162                    return false;
163            return true;
164        }
165    
166        /** Returns true if it contains all of the given assignments */
167        public boolean containsValues(Collection<T> assignments) {
168            for (T a : assignments)
169                if (!iSet.contains(new Assignment<T>(0l, a, 1.0)))
170                    return false;
171            return true;
172        }
173    
174        /** Returns true if it contains all of the given assignments */
175        public boolean containsVariables(Collection<Variable<?, T>> assignments) {
176            for (Variable<?, T> a : assignments)
177                if (a.getAssignment() == null || !iSet.contains(new Assignment<T>(0l, a.getAssignment(), 1.0)))
178                    return false;
179            return true;
180        }
181    
182        /** Adds an assignment */
183        public void addAssignment(Assignment<T> assignment) {
184            if (!contains(assignment))
185                iSet.add(assignment);
186        }
187    
188        /** Adds an assignment */
189        public void addAssignment(long iteration, T value, double ageing) {
190            addAssignment(new Assignment<T>(iteration, value, ageing));
191        }
192    
193        /**
194         * Returns assignment that corresponds to the given value (if it is present
195         * in the set)
196         */
197        public Assignment<T> getAssignment(T value) {
198            for (Assignment<T> a : iSet)
199                if (a.getValue().getId() == value.getId())
200                    return a;
201            return null;
202        }
203    
204        /** Returns number of assignments in the set */
205        public int size() {
206            return getSet().size();
207        }
208    
209        /**
210         * Compares two assignment sets -- name, size and content (assignments) has
211         * to match.
212         */
213        @Override
214        @SuppressWarnings("unchecked")
215        public boolean equals(Object o) {
216            if (o == null)
217                return false;
218            if (o instanceof AssignmentSet<?>) {
219                AssignmentSet<T> as = (AssignmentSet<T>) o;
220                if (getName() == null && as.getName() != null)
221                    return false;
222                if (getName() != null && as.getName() == null)
223                    return false;
224                if (getName() != null && !getName().equals(as.getName()))
225                    return false;
226                if (as.getSet().size() != getSet().size())
227                    return false;
228                return contains(as);
229            }
230            if (o instanceof Collection<?>) {
231                Collection<Assignment<T>> c = (Collection<Assignment<T>>) o;
232                if (c.size() != getSet().size())
233                    return false;
234                return contains(c);
235            }
236            return false;
237        }
238    
239        public static int xor(int a, int b) {
240            return (a | b) & (~a | ~b);
241        }
242    
243        @Override
244        public int hashCode() {
245            int ret = getSet().size();
246            for (Assignment<T> a : iSet)
247                ret = xor(ret, a.hashCode());
248            return ret;
249        }
250    }