source: GTP/trunk/Lib/Vis/Preprocessing/src/FlexibleHeap.h @ 2559

Revision 2559, 5.6 KB checked in by mattausch, 17 years ago (diff)
Line 
1#ifndef FLEXIBLEHEAP_H
2#define FLEXIBLEHEAP_H
3
4#include <vector>
5
6
7namespace GtpVisibilityPreprocessor {
8
9const static int NOT_IN_HEAP = -100;
10
11/** This class implements an element for a heap.
12        Classes using the heap should be inherited from this class.
13*/
14class Heapable
15{
16public:
17       
18        Heapable(): mPriority(0) { NotInHeap(); SetPriority(0.0f); }
19
20        inline bool IsInHeap() { return mPosition != NOT_IN_HEAP; }
21        inline void NotInHeap() { mPosition = NOT_IN_HEAP; }
22        inline int GetHeapPos() { return mPosition; }
23        inline void SetHeapPos(const int t) { mPosition = t; }
24
25        inline void  SetPriority(const float k) { mPriority = k; }
26        //inline float GetPriority() const  { return mPriority; }
27        virtual float GetPriority() const = 0;
28
29protected:
30
31        float mPriority;
32        int mPosition;
33};
34
35
36/** This class implements a flexible heap for use as a priority queue.
37        Unlike the stl priority_queue, the class allows access to all
38        elements. It implements efficient insertion routines and remove routines
39        of arbitrary elements.
40*/
41template<typename T>
42class FlexibleHeap
43{
44public:
45        FlexibleHeap() { }
46        FlexibleHeap(const unsigned int n): mBuffer(n) { }
47
48        void Push(T t);
49        void Push(T t, const float priority);
50        bool Update(T t);
51        bool Update(T t, const float priority);
52
53        inline unsigned int Size() const;
54        inline bool Empty() const;
55        inline T Item(const unsigned int i);
56        inline const T Item(const unsigned int i) const;
57        T Pop();
58        inline T Top() const;
59        /** Erases the element from the heap.
60        */
61        T Erase(T);
62
63        void Reserve(const size_t n);
64
65protected:
66
67        inline void Place(T x, const unsigned int i);
68        inline void Swap(const unsigned int i, const unsigned int j);
69
70        inline unsigned int Parent(const unsigned int i) const { return (i - 1) / 2; }
71        inline unsigned int Left(const unsigned int i) const { return 2 * i + 1; }
72        inline unsigned int Right(const unsigned int i) const { return 2 * i + 2; }
73
74        void UpHeap(const unsigned int i);
75        void DownHeap(const unsigned int i);
76
77
78        ///////
79       
80        std::vector<T> mBuffer;
81};
82
83
84
85
86/******************************************************************/
87/*                 FexibleHeap implementation                     */
88/******************************************************************/
89
90
91template <typename T>
92void FlexibleHeap<T>::Push(T t)
93{
94        Push(t, t->GetPriority());
95}
96
97
98template <typename T>
99bool FlexibleHeap<T>::Update(T t)
100{
101        return Update(t, t->GetPriority());
102}
103
104
105template <typename T>
106inline unsigned int FlexibleHeap<T>::Size() const
107{
108        return (unsigned int)mBuffer.size();
109}
110
111template <typename T>
112void FlexibleHeap<T>::Reserve(const size_t n)
113{
114        mBuffer.reserve(n);
115}
116
117template <typename T>
118inline bool FlexibleHeap<T>::Empty() const
119{
120        return mBuffer.empty();
121}
122
123
124template <typename T>
125inline T FlexibleHeap<T>::Item(const unsigned int i)
126{
127        return mBuffer[i];
128}
129
130
131template <typename T>
132inline const T FlexibleHeap<T>::Item(const unsigned int i) const
133{
134        return mBuffer[i];
135}
136
137
138template <typename T>
139inline T FlexibleHeap<T>::Top() const
140{
141        return (mBuffer.empty() ? (T)NULL : mBuffer.front());
142}
143
144
145template <typename T>
146inline void FlexibleHeap<T>::Place(T x, const unsigned int i)
147{
148        mBuffer[i] = x;
149        x->SetHeapPos(i);
150}
151
152
153template <typename T>
154void FlexibleHeap<T>::Swap(const unsigned int i, const unsigned int j)
155{
156        T tmp = mBuffer[i];
157
158        Place(mBuffer[j], i);
159        Place(tmp, j);
160}
161
162
163template <typename T>
164void FlexibleHeap<T>::UpHeap(const unsigned int i)
165{
166        T moving = mBuffer[i];
167        unsigned int index = i;
168        unsigned int p = Parent(i);
169
170        while ((index > 0) && (moving->GetPriority() > mBuffer[p]->GetPriority()))
171        {
172                Place(mBuffer[p], index);
173                index = p;
174                p = Parent(p);
175        }
176
177        if (index != i)
178        {
179                Place(moving, index);
180        }
181}
182
183
184template <typename T>
185void FlexibleHeap<T>::DownHeap(const unsigned int i)
186{
187        T moving = mBuffer[i];
188
189        unsigned int index = i;
190        unsigned int l = Left(i);
191        unsigned int r = Right(i);
192        unsigned int largest;
193
194        while (l < (int)mBuffer.size())
195        {
196                if ((r < (unsigned int)mBuffer.size()) && (mBuffer[l]->GetPriority() < mBuffer[r]->GetPriority()))
197                        largest = r;
198                else
199                        largest = l;
200
201                if (moving->GetPriority() < mBuffer[largest]->GetPriority())
202                {
203                        Place(mBuffer[largest], index);
204                        index = largest;
205                        l = Left(index);
206                        r = Right(index);
207                }
208                else
209                {
210                        break;
211                }
212        }
213
214        if (index != i)
215        {
216                Place(moving, index);
217        }
218}
219
220
221template <typename T>
222void FlexibleHeap<T>::Push(T t, const float v)
223{
224        t->SetPriority(v);
225
226        unsigned int i = (unsigned int)mBuffer.size();
227
228        t->SetHeapPos(i);
229        mBuffer.push_back(t);
230
231        UpHeap(i);
232}
233
234template <typename T>
235bool FlexibleHeap<T>::Update(T t, const float v)
236{
237        if (t->IsInHeap())
238                return false;
239
240        t->SetPriority(v);
241
242        const unsigned int i = t->GetHeapPos();
243
244        if ((i > 0) && (v > mBuffer[Parent(i)]->GetPriority()))
245                UpHeap(i);
246        else
247                DownHeap(i);
248
249        return true;
250}
251
252template <typename T>
253T FlexibleHeap<T>::Pop()
254{
255        if (mBuffer.empty())
256                return NULL;
257
258        Swap(0, (int)mBuffer.size() - 1);
259
260        T dead = mBuffer.back();
261        mBuffer.pop_back();
262
263        if (!mBuffer.empty())
264                DownHeap(0);
265
266        dead->NotInHeap();
267
268        return dead;
269}
270
271
272template <typename T>
273T FlexibleHeap<T>::Erase(T t)
274{
275        if (!t->IsInHeap())
276                return (T)NULL;
277
278        const int i = t->GetHeapPos();
279
280        Swap(i, (int)mBuffer.size() - 1);
281       
282        mBuffer.pop_back();
283        t->NotInHeap();
284
285        if (i < (int)mBuffer.size())
286        {
287        if (mBuffer[i]->GetPriority() < t->GetPriority())
288                DownHeap(i);
289        else
290                UpHeap(i);
291        }
292
293        return t;
294}
295
296}
297
298// FLEXIBLEHEAP_H
299#endif
Note: See TracBrowser for help on using the repository browser.