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}