source: branches/MetisMQI/src/main/java/weka/classifiers/lazy/kstar/KStarCache.java

Last change on this file was 29, checked in by gnappo, 14 years ago

Taggata versione per la demo e aggiunto branch.

File size: 8.8 KB
Line 
1/*
2 *    This program is free software; you can redistribute it and/or modify
3 *    it under the terms of the GNU General Public License as published by
4 *    the Free Software Foundation; either version 2 of the License, or
5 *    (at your option) any later version.
6 *
7 *    This program is distributed in the hope that it will be useful,
8 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
9 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 *    GNU General Public License for more details.
11 *
12 *    You should have received a copy of the GNU General Public License
13 *    along with this program; if not, write to the Free Software
14 *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17/**
18 *    KStarCache.java
19 *    Copyright (C) 1995 University of Waikato
20 *    Java port to Weka by Abdelaziz Mahoui (am14@cs.waikato.ac.nz).
21 *
22 */
23
24
25package weka.classifiers.lazy.kstar;
26
27import weka.core.RevisionHandler;
28import weka.core.RevisionUtils;
29
30import java.io.Serializable;
31
32/**
33 * A class representing the caching system used to keep track of each attribute
34 * value and its corresponding scale factor or stop parameter.
35 *
36 * @author Len Trigg (len@reeltwo.com)
37 * @author Abdelaziz Mahoui (am14@cs.waikato.ac.nz)
38 * @version $Revision: 1.11 $
39 */
40public class KStarCache
41  implements Serializable, RevisionHandler {
42
43  /** for serialization */
44  private static final long serialVersionUID = -7693632394267140678L;
45 
46  /**
47   * cache table
48   */
49  CacheTable m_Cache = new CacheTable();
50 
51  /**
52   * Stores the specified values in the cahce table for easy retrieval.
53   *
54   * @param key attribute value used key to lookup the cache table.
55   * @param value cache parameter: attribute scale/stop parameter.
56   * @param pmiss cache parameter: transformation probability to
57   * attribute with missing value.
58   */
59  public void store(double key, double value, double pmiss) {
60    if ( !m_Cache.containsKey(key) ) {
61      m_Cache.insert(key, value, pmiss);
62    }
63  }
64 
65  /**
66   * Checks if the specified key maps with an entry in the cache table
67   *
68   * @param key the key to map with an entry in the hashtable.
69   */
70  public boolean containsKey(double key) {
71    if ( m_Cache.containsKey(key) ) {
72      return true;
73    }
74    return false;
75  }
76 
77  /**
78   * Returns the values in the cache mapped by the specified key
79   *
80   * @param key the key used to retrieve the table entry.
81   */
82  public TableEntry getCacheValues( double key ) {
83    if ( m_Cache.containsKey(key) ) {
84      return m_Cache.getEntry(key);
85    }
86    return null;
87  }
88
89  /**
90   * A custom hashtable class to support the caching system.
91   *
92   */
93  public class CacheTable
94    implements Serializable, RevisionHandler {
95
96    /** for serialization */
97    private static final long serialVersionUID = -8086106452588253423L;
98
99    /** The hash table data. */
100    private TableEntry [] m_Table;
101
102    /** The total number of entries in the hash table. */
103    private int m_Count;
104
105    /** Rehashes the table when count exceeds this threshold. */
106    private int m_Threshold;
107
108    /** The load factor for the hashtable. */
109    private float m_LoadFactor;
110
111    /** The default size of the hashtable */
112    private final int DEFAULT_TABLE_SIZE = 101;
113
114    /** The default load factor for the hashtable */
115    private final float DEFAULT_LOAD_FACTOR = 0.75f;
116
117    //    private final float DEFAULT_LOAD_FACTOR = 0.5f;
118    /** Accuracy value for equality */
119    private final double EPSILON = 1.0E-5;
120   
121    /**
122     * Constructs a new hashtable with a default capacity and load factor.
123     */
124    public CacheTable(int size, float loadFactor) {
125      m_Table = new TableEntry[size];
126      m_LoadFactor = loadFactor;
127      m_Threshold = (int)(size * loadFactor);
128      m_Count = 0;
129    }
130   
131    /**
132     * Constructs a new hashtable with a default capacity and load factor.
133     */
134    public CacheTable() {
135      this(101, 0.75f);
136    }
137   
138    /**
139     * Tests if the specified double is a key in this hashtable.
140     */
141    public boolean containsKey(double key) {
142      TableEntry [] table = m_Table;
143      int hash = hashCode(key);
144      int index = (hash & 0x7FFFFFFF) % table.length;
145      for (TableEntry e = table[index] ; e != null ; e = e.next) {
146        if ((e.hash == hash) && (Math.abs(e.key - key) < EPSILON)) {
147          return true;
148        }
149      }
150      return false;
151    }
152   
153    /**
154     * Inserts a new entry in the hashtable using the specified key.
155     * If the key already exist in the hashtable, do nothing.
156     */
157    public void insert(double key, double value, double pmiss) {
158      // Makes sure the key is not already in the hashtable.
159      TableEntry e, ne;
160      TableEntry [] table = m_Table;
161      int hash = hashCode(key);
162      int index = (hash & 0x7FFFFFFF) % table.length;
163      // start looking along the chain
164      for (e = table[index] ; e != null ; e = e.next) {
165        if ((e.hash == hash) && (Math.abs(e.key - key) < EPSILON)) {
166          return;
167        }
168      }
169      // At this point, key is not in table.
170      // Creates a new entry.
171      ne = new TableEntry( hash, key, value, pmiss, table[index] );
172      // Put entry at the head of the chain.
173      table[index] = ne;
174      m_Count++;
175      // Rehash the table if the threshold is exceeded
176      if (m_Count >= m_Threshold) {
177        rehash();
178      }
179    }
180   
181    /**
182     * Returns the table entry to which the specified key is mapped in
183     * this hashtable.
184     * @return a table entry.
185     */
186    public TableEntry getEntry(double key) {
187      TableEntry [] table = m_Table;
188      int hash = hashCode(key);
189      int index = (hash & 0x7FFFFFFF) % table.length;
190      for (TableEntry e = table[index] ; e != null ; e = e.next) {
191        if ((e.hash == hash) && (Math.abs(e.key - key) < EPSILON)) {
192          return e;
193        }
194      }
195      return null;
196    }
197   
198    /**
199     * Returns the number of keys in this hashtable.
200     * @return the number of keys in this hashtable.
201     */
202    public int size() {
203      return m_Count;
204    }
205   
206    /**
207     * Tests if this hashtable maps no keys to values.
208     * @return true if this hastable maps no keys to values.
209     */
210    public boolean isEmpty() {
211      return m_Count == 0;
212    }
213   
214    /**
215     * Clears this hashtable so that it contains no keys.
216     */
217    public void clear() {
218      TableEntry table[] = m_Table;
219      for (int index = table.length; --index >= 0; ) {
220        table[index] = null;
221      }
222      m_Count = 0;
223    }
224   
225    /**
226     * Rehashes the contents of the hashtable into a hashtable with a
227     * larger capacity. This method is called automatically when the
228     * number of keys in the hashtable exceeds this hashtable's capacity
229     * and load factor.
230     */
231    private void rehash() {
232      int oldCapacity = m_Table.length;
233      TableEntry [] oldTable = m_Table;   
234      int newCapacity = oldCapacity * 2 + 1;
235      TableEntry [] newTable = new TableEntry[newCapacity];
236      m_Threshold = (int)(newCapacity * m_LoadFactor);
237      m_Table = newTable;
238      TableEntry e, old;
239      for (int i = oldCapacity ; i-- > 0 ;) {
240        for (old = oldTable[i] ; old != null ; ) {
241          e = old;
242          old = old.next;
243          int index = (e.hash & 0x7FFFFFFF) % newCapacity;
244          e.next = newTable[index];
245          newTable[index] = e;
246        }
247      }
248    }
249   
250    /**
251     * Returns the hash code of the specified double.
252     * @return the hash code of the specified double.
253     */
254    private int hashCode(double key) {
255      long bits = Double.doubleToLongBits(key);
256      return (int)(bits ^ (bits >> 32));
257    }
258   
259    /**
260     * Returns the revision string.
261     *
262     * @return          the revision
263     */
264    public String getRevision() {
265      return RevisionUtils.extract("$Revision: 1.11 $");
266    }
267  } // CacheTable
268 
269  /**
270   * Hashtable collision list.
271   */
272  public class TableEntry
273    implements Serializable, RevisionHandler {
274
275    /** for serialization */
276    private static final long serialVersionUID = 4057602386766259138L;
277
278    /** attribute value hash code */
279    public int hash;
280
281    /** attribute value */
282    public double key;
283
284    /** scale factor or stop parameter */
285    public double value;
286
287    /** transformation probability to missing value */
288    public double pmiss;
289
290    /** next table entry (separate chaining) */
291    public TableEntry next = null;
292
293    /** Constructor */
294    public TableEntry(int hash, double key, double value, 
295                      double pmiss, TableEntry next) {
296      this.hash  = hash;
297      this.key   = key;
298      this.value = value;
299      this.pmiss = pmiss;
300      this.next  = next;
301    }
302   
303    /**
304     * Returns the revision string.
305     *
306     * @return          the revision
307     */
308    public String getRevision() {
309      return RevisionUtils.extract("$Revision: 1.11 $");
310    }
311  }  // TableEntry
312 
313  /**
314   * Returns the revision string.
315   *
316   * @return            the revision
317   */
318  public String getRevision() {
319    return RevisionUtils.extract("$Revision: 1.11 $");
320  }
321 
322} // Cache
Note: See TracBrowser for help on using the repository browser.