    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}