001 package net.sf.cpsolver.ifs.extension;
002
003 import java.util.Comparator;
004
005 import net.sf.cpsolver.ifs.model.Constraint;
006 import 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 Tomas Muller<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 */
034 public 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 }