001package org.cpsolver.ifs.extension;
002
003import java.util.ArrayList;
004import java.util.Collection;
005import java.util.List;
006
007import org.cpsolver.ifs.model.Constraint;
008import org.cpsolver.ifs.model.Value;
009
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.3 (Iterative Forward Search)<br>
018 *          Copyright (C) 2006 - 2014 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 * @param <T> Value
036 */
037public class AssignedValueSet<T extends Value<?, T>> {
038    private List<AssignedValue<T>> iSet = new ArrayList<AssignedValue<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 AssignedValueSet() {
045    }
046
047    public AssignedValueSet(AssignedValue<T>[] assignments) {
048        for (AssignedValue<T> a : assignments)
049            iSet.add(a);
050    }
051
052    public AssignedValueSet(Collection<AssignedValue<T>> assignments) {
053        for (AssignedValue<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     * @param assignments list of assignments
061     * @param <T> Value
062     * @return a set of assignments
063     */
064    public static <T extends Value<?, T>> AssignedValueSet<T> createAssignmentSet(Collection<AssignedValue<T>> assignments) {
065        AssignedValueSet<T> set = new AssignedValueSet<T>();
066        for (AssignedValue<T> a : assignments)
067            set.addAssignment(a);
068        return set;
069    }
070
071    /**
072     * Create set of assignments from the list of Assignments, Values or
073     * (assigned) Variables
074     * @param assignments list of assignments
075     * @param <T> Value
076     * @return a set of assignments
077     */
078    public static <T extends Value<?, T>> AssignedValueSet<T> createAssignmentSetForValues(Collection<T> assignments) {
079        AssignedValueSet<T> set = new AssignedValueSet<T>();
080        for (T a : assignments)
081            set.addAssignment(0l, a, 1.0);
082        return set;
083    }
084
085    /** Increment counter */
086    public void incCounter() {
087        iCounter++;
088    }
089
090    /** Returns counter 
091     * @return counter
092     **/
093    public int getCounter() {
094        return iCounter;
095    }
096
097    /** Returns set of assignments 
098     * @return assignments in the set
099     **/
100    public List<AssignedValue<T>> getSet() {
101        return iSet;
102    }
103
104    /** Returns name
105     * @return a name
106     **/
107    public String getName() {
108        return iName;
109    }
110
111    /** Sets name
112     * @param name a name
113     **/
114    public void setName(String name) {
115        iName = name;
116    }
117
118    /** Returns description
119     * @return a description
120     **/
121    public String getDescription() {
122        return iDescription;
123    }
124
125    /** Sets description
126     * @param description a description
127     **/
128    public void setDescription(String description) {
129        iDescription = description;
130    }
131
132    /** Returns constraint
133     * @return a constraint 
134     **/
135    public Constraint<?, T> getConstraint() {
136        return iConstraint;
137    }
138
139    /** Sets constraint
140     * @param constraint a constraint 
141     **/
142    public void setConstraint(Constraint<?, T> constraint) {
143        iConstraint = constraint;
144    }
145
146    /** Returns true if it contains the given assignment
147     * @param assignment an assignment
148     * @return true if in the set
149     **/
150    public boolean contains(AssignedValue<T> assignment) {
151        return iSet.contains(assignment);
152    }
153
154    /** Returns true if it contains all of the given assignments
155     * @param assignmentSet a set of assignments
156     * @return true if all in the set
157     **/
158    public boolean contains(AssignedValueSet<T> assignmentSet) {
159        return iSet.containsAll(assignmentSet.getSet());
160    }
161
162    /** Returns true if it contains the given assignment
163     * @param value an assignment (of the value to its variable)
164     * @return true if in the set
165     **/
166    public boolean contains(T value) {
167        return iSet.contains(new AssignedValue<T>(0l, value, 1.0));
168    }
169
170    /** Returns true if it contains all of the given assignments
171     * @param assignments a set of assignments
172     * @return true if all in the set
173     **/
174    public boolean contains(Collection<AssignedValue<T>> assignments) {
175        for (AssignedValue<T> a : assignments)
176            if (!iSet.contains(a))
177                return false;
178        return true;
179    }
180
181    /** Returns true if it contains all of the given assignments
182     * @param assignments a set of assignments (values to their variables)
183     * @return true if all in the set
184     **/
185    public boolean containsValues(Collection<T> assignments) {
186        for (T a : assignments)
187            if (!iSet.contains(new AssignedValue<T>(0l, a, 1.0)))
188                return false;
189        return true;
190    }
191
192    /** Adds an assignment
193     * @param assignment an assignment
194     **/
195    public void addAssignment(AssignedValue<T> assignment) {
196        if (!contains(assignment))
197            iSet.add(assignment);
198    }
199
200    /** Adds an assignment
201     * @param iteration current iteration
202     * @param value an assignment
203     * @param aging aging factor
204     **/
205    public void addAssignment(long iteration, T value, double aging) {
206        addAssignment(new AssignedValue<T>(iteration, value, aging));
207    }
208
209    /**
210     * Returns assignment that corresponds to the given value (if it is present
211     * in the set)
212     * @param value an assignment
213     * @return a corresponding assignment of the set, null if not present
214     */
215    public AssignedValue<T> getAssignment(T value) {
216        for (AssignedValue<T> a : iSet)
217            if (a.getValue().getId() == value.getId())
218                return a;
219        return null;
220    }
221
222    /** Returns number of assignments in the set 
223     * @return number of assignments in the set
224     **/
225    public int size() {
226        return getSet().size();
227    }
228
229    /**
230     * Compares two assignment sets -- name, size and content (assignments) has
231     * to match.
232     */
233    @Override
234    @SuppressWarnings("unchecked")
235    public boolean equals(Object o) {
236        if (o == null)
237            return false;
238        if (o instanceof AssignedValueSet<?>) {
239            AssignedValueSet<T> as = (AssignedValueSet<T>) o;
240            if (getName() == null && as.getName() != null)
241                return false;
242            if (getName() != null && as.getName() == null)
243                return false;
244            if (getName() != null && !getName().equals(as.getName()))
245                return false;
246            if (as.getSet().size() != getSet().size())
247                return false;
248            return contains(as);
249        }
250        if (o instanceof Collection<?>) {
251            Collection<AssignedValue<T>> c = (Collection<AssignedValue<T>>) o;
252            if (c.size() != getSet().size())
253                return false;
254            return contains(c);
255        }
256        return false;
257    }
258
259    public static int xor(int a, int b) {
260        return (a | b) & (~a | ~b);
261    }
262
263    @Override
264    public int hashCode() {
265        int ret = getSet().size();
266        for (AssignedValue<T> a : iSet)
267            ret = xor(ret, a.hashCode());
268        return ret;
269    }
270}