source: src/main/java/weka/clusterers/forOPTICSAndDBScan/Utils/UpdateQueue.java @ 15

Last change on this file since 15 was 4, checked in by gnappo, 14 years ago

Import di weka.

File size: 6.3 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 *    Copyright (C) 2004
19 *    & Matthias Schubert (schubert@dbs.ifi.lmu.de)
20 *    & Zhanna Melnikova-Albrecht (melnikov@cip.ifi.lmu.de)
21 *    & Rainer Holzmann (holzmann@cip.ifi.lmu.de)
22 */
23
24package weka.clusterers.forOPTICSAndDBScan.Utils;
25
26import weka.core.RevisionHandler;
27import weka.core.RevisionUtils;
28
29import java.util.ArrayList;
30import java.util.TreeMap;
31
32/**
33 * <p>
34 * UpdateQueue.java <br/>
35 * Authors: Rainer Holzmann, Zhanna Melnikova-Albrecht, Matthias Schubert <br/>
36 * Date: Aug 27, 2004 <br/>
37 * Time: 5:36:35 PM <br/>
38 * $ Revision 1.4 $ <br/>
39 * </p>
40 *
41 * @author Matthias Schubert (schubert@dbs.ifi.lmu.de)
42 * @author Zhanna Melnikova-Albrecht (melnikov@cip.ifi.lmu.de)
43 * @author Rainer Holzmann (holzmann@cip.ifi.lmu.de)
44 * @version $Revision: 1.3 $
45 */
46public class UpdateQueue
47    implements RevisionHandler {
48
49    /**
50     * Used to store the binary heap
51     */
52    private ArrayList queue;
53
54    /**
55     * Used to get efficient access to the stored Objects
56     */
57    private TreeMap objectPositionsInHeap;
58
59    // *****************************************************************************************************************
60    // constructors
61    // *****************************************************************************************************************
62
63    /**
64     * Creates a new PriorityQueue (backed on a binary heap) with the ability to efficiently
65     * update the priority of the stored objects in the heap. The ascending (!) queue is
66     * dynamically growing and shrinking.
67     */
68    public UpdateQueue() {
69        queue = new ArrayList();
70        objectPositionsInHeap = new TreeMap();
71    }
72
73    // *****************************************************************************************************************
74    // methods
75    // *****************************************************************************************************************
76
77    /**
78     * Adds a new Object to the queue
79     * @param priority The priority associated with the object (in this case: the reachability-distance)
80     * @param objectKey The key for this object
81     * @param o
82     */
83    public void add(double priority, Object o, String objectKey) {
84        int objectPosition = 0;
85
86        if (objectPositionsInHeap.containsKey(objectKey)) {
87            objectPosition = ((Integer) objectPositionsInHeap.get(objectKey)).intValue();
88            if (((UpdateQueueElement) queue.get(objectPosition)).getPriority() <= priority) return;
89            queue.set(objectPosition++, new UpdateQueueElement(priority, o, objectKey));
90        } else {
91            queue.add(new UpdateQueueElement(priority, o, objectKey));
92            objectPosition = size();
93        }
94        heapValueUpwards(objectPosition);
95    }
96
97    /**
98     * Returns the priority for the object at the specified index
99     * @param index the index of the object
100     * @return priority
101     */
102    public double getPriority(int index) {
103        return ((UpdateQueueElement) queue.get(index)).getPriority();
104    }
105
106    /**
107     * Restores the heap after inserting a new object
108     */
109    private void heapValueUpwards(int pos) {
110        int a = pos;
111        int c = a / 2;
112
113        UpdateQueueElement recentlyInsertedElement = (UpdateQueueElement) queue.get(a - 1);
114
115        /** ascending order! */
116        while (c > 0 && getPriority(c - 1) > recentlyInsertedElement.getPriority()) {
117            queue.set(a - 1, queue.get(c - 1));       //shift parent-node down
118            objectPositionsInHeap.put(((UpdateQueueElement) queue.get(a - 1)).getObjectKey(), new Integer(a - 1));
119            a = c;                                    //(c <= 0) => no parent-node remains
120            c = a / 2;
121        }
122        queue.set(a - 1, recentlyInsertedElement);
123        objectPositionsInHeap.put(((UpdateQueueElement) queue.get(a - 1)).getObjectKey(), new Integer(a - 1));
124    }
125
126    /**
127     * Restores the heap after removing the next element
128     */
129    private void heapValueDownwards() {
130        int a = 1;
131        int c = 2 * a;           //descendant
132
133        UpdateQueueElement updateQueueElement = (UpdateQueueElement) queue.get(a - 1);
134
135        if (c < size() && (getPriority(c) < getPriority(c - 1))) c++;
136
137        while (c <= size() && getPriority(c - 1) < updateQueueElement.getPriority()) {
138            queue.set(a - 1, queue.get(c - 1));
139            objectPositionsInHeap.put(((UpdateQueueElement) queue.get(a - 1)).getObjectKey(), new Integer(a - 1));
140            a = c;
141            c = 2 * a;
142            if (c < size() && (getPriority(c) < getPriority(c - 1))) c++;
143        }
144        queue.set(a - 1, updateQueueElement);
145        objectPositionsInHeap.put(((UpdateQueueElement) queue.get(a - 1)).getObjectKey(), new Integer(a - 1));
146    }
147
148    /**
149     * Returns the queue's size
150     * @return size
151     */
152    public int size() {
153        return queue.size();
154    }
155
156    /**
157     * Tests, if the queue has some more elements left
158     * @return true, if there are any elements left, else false
159     */
160    public boolean hasNext() {
161        return !(queue.size() == 0);
162    }
163
164    /**
165     * Returns the element with the lowest priority
166     * @return next element
167     */
168    public UpdateQueueElement next() {
169        UpdateQueueElement next = (UpdateQueueElement) queue.get(0);
170        queue.set(0, queue.get(size() - 1));
171        queue.remove(size() - 1);
172        objectPositionsInHeap.remove(next.getObjectKey());
173        if (hasNext()) {
174            heapValueDownwards();
175        }
176        return next;
177    }
178   
179    /**
180     * Returns the revision string.
181     *
182     * @return          the revision
183     */
184    public String getRevision() {
185      return RevisionUtils.extract("$Revision: 1.3 $");
186    }
187}
Note: See TracBrowser for help on using the repository browser.