QGIS API Documentation 3.99.0-Master (2fe06baccd8)
Loading...
Searching...
No Matches
priorityqueue.cpp
Go to the documentation of this file.
1/*
2 * libpal - Automated Placement of Labels Library
3 *
4 * Copyright (C) 2008 Maxence Laurent, MIS-TIC, HEIG-VD
5 * University of Applied Sciences, Western Switzerland
6 * http://www.hes-so.ch
7 *
8 * Contact:
9 * maxence.laurent <at> heig-vd <dot> ch
10 * or
11 * eric.taillard <at> heig-vd <dot> ch
12 *
13 * This file is part of libpal.
14 *
15 * libpal is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation, either version 3 of the License, or
18 * (at your option) any later version.
19 *
20 * libpal is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with libpal. If not, see <http://www.gnu.org/licenses/>.
27 *
28 */
29
30#include "priorityqueue.h"
31
32#include <cstdio>
33#include <memory>
34
35#include "internalexception.h"
36
37using namespace pal;
38
39bool smaller( double l, double r )
40{
41 return l > r;
42}
43
44bool bigger( double l, double r )
45{
46 return l < r;
47}
48
49// O (size log size)
50PriorityQueue::PriorityQueue( int n, int maxId, bool min )
51 : maxsize( n )
52 , maxId( maxId )
53{
54 heap = std::make_unique<int[]>( maxsize );
55 p = std::make_unique<double[]>( maxsize );
56 pos = std::make_unique<int[]>( maxId + 1 );
57
58 int i;
59
60 for ( i = 0; i <= maxId; i++ )
61 pos[i] = -1;
62
63
64 if ( min )
65 greater = smaller;
66 else
67 greater = bigger;
68}
69
73
75{
76 return size;
77}
78
79// O(log size)
81{
82 if ( size <= 0 )
84
85 const int return_value = heap[0];
86
87 size--;
88
89 pos[heap[0]] = -1;
90
91 if ( size > 0 )
92 {
93 pos[heap[size]] = 0;
94
95 heap[0] = heap[size];
96 p[0] = p[size];
97 downheap( 0 );
98 }
99
100 return return_value;
101}
102
103
104bool PriorityQueue::isIn( int key ) const
105{
106 return key <= maxId && pos[key] >= 0;
107}
108
109int PriorityQueue::getId( int key ) const
110{
111 return key <= maxId ? pos[key] : -1;
112}
113
114void PriorityQueue::insert( int key, double p )
115{
116 if ( size == maxsize || key > maxId || key < 0 )
118
119 heap[size] = key;
120 pos[key] = size;
121 this->p[size] = p;
122
123 size++;
124
125
126 upheap( key );
127}
128
129
130// O(size)
131//
133{
134 if ( key < 0 || key > maxId )
135 return;
136 const int i = pos[key];
137
138 if ( i >= 0 )
139 {
140 size--;
141 pos[heap[size]] = i;
142 pos[key] = -1;
143
144 heap[i] = heap[size];
145 p[i] = p[size];
146
147 downheap( i );
148 }
149}
150
151// O (size log size)
153{
154 int i;
155 int pi = 2;
156 while ( size > pi ) pi *= 2;
157
158 i = pi / 2 - 2;
159
160 for ( i = size - 1; i >= 0; i-- )
161 downheap( i );
162
163}
164
165
167{
168 int i;
169 int i2;
170
171 int tmpT;
172 double tmpP;
173
174
175 if ( key < 0 || key > maxId )
176 return;
177
178 i = pos[key];
179
180 if ( i >= -1 )
181 {
182 while ( i > 0 )
183 {
184 if ( greater( p[PARENT( i )], p[i] ) )
185 {
186 i2 = PARENT( i );
187
188 pos[heap[i]] = i2;
189 pos[heap[i2]] = i;
190
191 tmpT = heap[i];
192 tmpP = p[i];
193
194 heap[i] = heap[i2];
195 p[i] = p[i2];
196
197 heap[i2] = tmpT;
198 p[i2] = tmpP;
199
200 i = i2;
201 }
202 else
203 break;
204 }
205 }
206}
207
208// O(log n)
210{
211 int min_child;
212 int tmpT;
213 double tmpP;
214
215 for ( ;; )
216 {
217 if ( LEFT( id ) < size )
218 {
219 if ( RIGHT( id ) < size )
220 {
221 min_child = greater( p[RIGHT( id )], p[LEFT( id )] ) ? LEFT( id ) : RIGHT( id );
222 }
223 else
224 min_child = LEFT( id );
225 }
226 else // leaf
227 break;
228
229 if ( greater( p[id], p[min_child] ) )
230 {
231 pos[heap[id]] = min_child;
232 pos[heap[min_child]] = id;
233
234 tmpT = heap[id];
235 tmpP = p[id];
236
237 heap[id] = heap[min_child];
238 p[id] = p[min_child];
239
240 heap[min_child] = tmpT;
241 p[min_child] = tmpP;
242
243 id = min_child;
244 }
245 else
246 break;
247 }
248}
249
250void PriorityQueue::setPriority( int key, double new_p )
251{
252
253 if ( key < 0 || key > maxId )
254 return;
255
256 const int i = pos[key];
257
258 if ( i < 0 )
259 {
260 insert( key, new_p );
261 return;
262 }
263
264 p[i] = new_p;
265
266 upheap( key );
267 downheap( pos[key] );
268}
269
270
272{
273
274 if ( key < 0 || key > maxId )
275 return;
276
277 const int i = pos[key];
278
279 if ( i < 0 )
280 return;
281
282 p[i]--;
283
284 upheap( key );
285 downheap( pos[key] );
286}
287
288
290{
291 int i;
292
293 fprintf( stderr, "Size: %d\nMaxSize: %d\n", size, maxsize );
294
295 for ( i = 0; i < size; i++ )
296 {
297 //printf ("key: %7d -> index: %7d -> key: %7d p: %7d\n", i, pos[i], heap[pos[i]], p[pos[i]]);
298 fprintf( stderr, "id: %7d -> key: %7d -> id: %7d p: %7f\n", i, heap[i], pos[heap[i]], p[i] );
299 }
300 fprintf( stderr, "\n" );
301
302}
303
304
306{
307 int i;
308 int count = 0;
309 for ( i = 0; i < maxsize; i++ )
310 {
311 if ( pos[i] >= 0 )
312 count++;
313 }
314 return count;
315}
Thrown when trying to access an empty data set.
Thrown when something is added in a Full set.
PriorityQueue(int n, int maxId, bool min)
Create a priority queue of max size n \param n max size of the queuet \param p external vector repres...
void decreaseKey(int key)
void setPriority(int key, double new_p)
void insert(int key, double p)
int getId(int key) const
bool isIn(int key) const
bool smaller(double l, double r)
bool bigger(double l, double r)
#define LEFT(x)
#define RIGHT(x)
#define PARENT(x)