    001package net.sf.cpsolver.ifs.extension;
    002
    003import java.util.Comparator;
    004
    005import net.sf.cpsolver.ifs.model.Constraint;
    006import net.sf.cpsolver.ifs.model.Value;
    007
    008/**
    009 * This class describing an assignment of a value to a variable together with a
    010 * counter (used by CBS).
    011 *
    012 * Counter also supports ageing: the counter is multiplied by aging factor for
    013 * each iteration.
    014 *
    015 * @version IFS 1.2 (Iterative Forward Search)<br>
    016 *          Copyright (C) 2006 - 2010 Tomáš Müller<br>
    017 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
    018 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
    019 * <br>
    020 *          This library is free software; you can redistribute it and/or modify
    021 *          it under the terms of the GNU Lesser General Public License as
    022 *          published by the Free Software Foundation; either version 3 of the
    023 *          License, or (at your option) any later version. <br>
    024 * <br>
    025 *          This library is distributed in the hope that it will be useful, but
    026 *          WITHOUT ANY WARRANTY; without even the implied warranty of
    027 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    028 *          Lesser General Public License for more details. <br>
    029 * <br>
    030 *          You should have received a copy of the GNU Lesser General Public
    031 *          License along with this library; if not see
    032 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
    033 */
    034public class Assignment<T extends Value<?, T>> {
    035    private T iValue;
    036    private double iCounter = 1.0;
    037    private long iLastRevision;
    038    private double iAgeing = 1.0;
    039    private Constraint<?, T> iConstraint = null;
    040
    041    /**
    042     * Constructor
    043     *
    044     * @param iteration
    045     *            current iteration
    046     * @param value
    047     *            value
    048     * @param ageing
    049     *            ageing factor
    050     */
    051    public Assignment(long iteration, T value, double ageing) {
    052        iValue = value;
    053        iLastRevision = iteration;
    054        iAgeing = ageing;
    055    }
    056
    057    /** Returns value */
    058    public T getValue() {
    059        return iValue;
    060    }
    061
    062    /**
    063     * Increments counter
    064     *
    065     * @param iteration
    066     *            current iteration
    067     */
    068    public void incCounter(long iteration) {
    069        revise(iteration);
    070        iCounter += 1.0;
    071    }
    072
    073    /**
    074     * Set counter
    075     *
    076     * @param cnt
    077     *            new value
    078     */
    079    public void setCounter(double cnt) {
    080        iCounter = cnt;
    081    }
    082
    083    /**
    084     * Get counter
    085     *
    086     * @param iteration
    087     *            current iteration
    088     */
    089    public double getCounter(long iteration) {
    090        if (iteration == 0l)
    091            return iCounter;
    092        if (iAgeing == 1.0)
    093            return iCounter;
    094        return iCounter * Math.pow(iAgeing, iteration - iLastRevision);
    095    }
    096
    097    /** Returns constraint */
    098    public Constraint<?, T> getConstraint() {
    099        return iConstraint;
    100    }
    101
    102    /** Sets constraint */
    103    public void setConstraint(Constraint<?, T> constraint) {
    104        iConstraint = constraint;
    105    }
    106
    107    /**
    108     * Revise counter. If ageing is used, counter is adopted to the current
    109     * iteration: it is multiplited by ageing factor powered by the number of
    110     * iterations since last revision.
    111     */
    112    public synchronized void revise(long iteration) {
    113        if (iAgeing == 1.0)
    114            return;
    115        iCounter *= Math.pow(iAgeing, iteration - iLastRevision);
    116        iLastRevision = iteration;
    117    }
    118
    119    /**
    120     * Combine two integers (for hash code)
    121     */
    122    public static int combine(int a, int b) {
    123        int ret = 0;
    124        for (int i = 0; i < 15; i++)
    125            ret = ret | ((a & (1 << i)) << i) | ((b & (1 << i)) << (i + 1));
    126        return ret;
    127    }
    128
    129    @Override
    130    public int hashCode() {
    131        return iValue.hashCode();
    132    }
    133
    134    @Override
    135    public boolean equals(Object o) {
    136        if (o == null || !(o instanceof Assignment<?>))
    137            return false;
    138        return ((Assignment<?>) o).getValue().equals(getValue());
    139    }
    140
    141    /** String representation */
    142    @Override
    143    public String toString() {
    144        return toString(0l, true);
    145    }
    146
    147    /** String representation (e.g., 10x A := a) */
    148    public String toString(long iteration, boolean assignment) {
    149        return (assignment ? getCounter(iteration) + "x " : "") + getValue().variable().getName()
    150                + (assignment ? " := " : " != ") + getValue().getName();
    151    }
    152
    153    /** Compare two assignments (their counters) */
    154    public int compareTo(long iteration, Assignment<T> a) {
    155        int cmp = getValue().variable().getName().compareTo(a.getValue().variable().getName());
    156        if (cmp != 0)
    157            return cmp;
    158        if (getCounter(iteration) != a.getCounter(iteration))
    159            return (getCounter(iteration) < a.getCounter(iteration) ? 1 : -1);
    160        return getValue().getName().compareTo(a.getValue().getName());
    161    }
    162
    163    /** Assignment comparator */
    164    public static class AssignmentComparator<E extends Value<?, E>> implements Comparator<Assignment<E>> {
    165        private long iIteration;
    166
    167        public AssignmentComparator(long iteration) {
    168            iIteration = iteration;
    169        }
    170
    171        @Override
    172        public int compare(Assignment<E> a1, Assignment<E> a2) {
    173            return a1.compareTo(iIteration, a2);
    174        }
    175    }
    176}