    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}