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