QGIS API Documentation 4.0.0-Norrköping (1ddcee3d0e4)
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
72
74{
75 return size;
76}
77
78// O(log size)
80{
81 if ( size <= 0 )
83
84 const int return_value = heap[0];
85
86 size--;
87
88 pos[heap[0]] = -1;
89
90 if ( size > 0 )
91 {
92 pos[heap[size]] = 0;
93
94 heap[0] = heap[size];
95 p[0] = p[size];
96 downheap( 0 );
97 }
98
99 return return_value;
100}
101
102
103bool PriorityQueue::isIn( int key ) const
104{
105 return key <= maxId && pos[key] >= 0;
106}
107
108int PriorityQueue::getId( int key ) const
109{
110 return key <= maxId ? pos[key] : -1;
111}
112
113void PriorityQueue::insert( int key, double p )
114{
115 if ( size == maxsize || key > maxId || key < 0 )
117
118 heap[size] = key;
119 pos[key] = size;
120 this->p[size] = p;
121
122 size++;
123
124
125 upheap( key );
126}
127
128
129// O(size)
130//
132{
133 if ( key < 0 || key > maxId )
134 return;
135 const int i = pos[key];
136
137 if ( i >= 0 )
138 {
139 size--;
140 pos[heap[size]] = i;
141 pos[key] = -1;
142
143 heap[i] = heap[size];
144 p[i] = p[size];
145
146 downheap( i );
147 }
148}
149
150// O (size log size)
152{
153 int i;
154 int pi = 2;
155 while ( size > pi )
156 pi *= 2;
157
158 i = pi / 2 - 2;
159
160 for ( i = size - 1; i >= 0; i-- )
161 downheap( i );
162}
163
164
166{
167 int i;
168 int i2;
169
170 int tmpT;
171 double tmpP;
172
173
174 if ( key < 0 || key > maxId )
175 return;
176
177 i = pos[key];
178
179 if ( i >= -1 )
180 {
181 while ( i > 0 )
182 {
183 if ( greater( p[PARENT( i )], p[i] ) )
184 {
185 i2 = PARENT( i );
186
187 pos[heap[i]] = i2;
188 pos[heap[i2]] = i;
189
190 tmpT = heap[i];
191 tmpP = p[i];
192
193 heap[i] = heap[i2];
194 p[i] = p[i2];
195
196 heap[i2] = tmpT;
197 p[i2] = tmpP;
198
199 i = i2;
200 }
201 else
202 break;
203 }
204 }
205}
206
207// O(log n)
209{
210 int min_child;
211 int tmpT;
212 double tmpP;
213
214 for ( ;; )
215 {
216 if ( LEFT( id ) < size )
217 {
218 if ( RIGHT( id ) < size )
219 {
220 min_child = greater( p[RIGHT( id )], p[LEFT( id )] ) ? LEFT( id ) : RIGHT( id );
221 }
222 else
223 min_child = LEFT( id );
224 }
225 else // leaf
226 break;
227
228 if ( greater( p[id], p[min_child] ) )
229 {
230 pos[heap[id]] = min_child;
231 pos[heap[min_child]] = id;
232
233 tmpT = heap[id];
234 tmpP = p[id];
235
236 heap[id] = heap[min_child];
237 p[id] = p[min_child];
238
239 heap[min_child] = tmpT;
240 p[min_child] = tmpP;
241
242 id = min_child;
243 }
244 else
245 break;
246 }
247}
248
249void PriorityQueue::setPriority( int key, double new_p )
250{
251 if ( key < 0 || key > maxId )
252 return;
253
254 const int i = pos[key];
255
256 if ( i < 0 )
257 {
258 insert( key, new_p );
259 return;
260 }
261
262 p[i] = new_p;
263
264 upheap( key );
265 downheap( pos[key] );
266}
267
268
270{
271 if ( key < 0 || key > maxId )
272 return;
273
274 const int i = pos[key];
275
276 if ( i < 0 )
277 return;
278
279 p[i]--;
280
281 upheap( key );
282 downheap( pos[key] );
283}
284
285
287{
288 int i;
289
290 fprintf( stderr, "Size: %d\nMaxSize: %d\n", size, maxsize );
291
292 for ( i = 0; i < size; i++ )
293 {
294 //printf ("key: %7d -> index: %7d -> key: %7d p: %7d\n", i, pos[i], heap[pos[i]], p[pos[i]]);
295 fprintf( stderr, "id: %7d -> key: %7d -> id: %7d p: %7f\n", i, heap[i], pos[heap[i]], p[i] );
296 }
297 fprintf( stderr, "\n" );
298}
299
300
302{
303 int i;
304 int count = 0;
305 for ( i = 0; i < maxsize; i++ )
306 {
307 if ( pos[i] >= 0 )
308 count++;
309 }
310 return count;
311}
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)