001package net.sf.cpsolver.ifs.extension;
002
003import java.util.ArrayList;
004import java.util.Collection;
005import java.util.List;
006
007import net.sf.cpsolver.ifs.model.Constraint;
008import net.sf.cpsolver.ifs.model.Value;
009import 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 Tomáš Müller<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
037public 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}