Scippy

SCIP

Solving Constraint Integer Programs

pqueue.h
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2025 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file pqueue.h
26 * @brief class for priority queues
27 * @author Andreas Bley
28 * @author Marc Pfetsch
29 */
30
31#ifndef _PQUEUE_H
32#define _PQUEUE_H
33
34#include <algorithm>
35#include <functional>
36
37namespace std
38{
39 ///
40 template<typename Key,
41 typename Data,
42 typename Compare = less<Key> >
43
44 class pqueue /*lint --e{3713}*/
45 {
46 private:
47
48 //--------------------
49 // item node class
50 //--------------------
51 class node /*lint --e{3713}*/
52 {
53 friend class pqueue;
54
55 public:
56 //
57 node(
58 const Key& k,
59 const Data& d ):
60 key (k),
61 data (d),
62 sleft (0),
63 sright(0),
64 left (NULL),
65 right (NULL),
66 father(NULL)
67 {}
68
69 //
70 ~node()
71 {
72 left = nullptr;
73 right = nullptr;
74 father = nullptr;
75 }
76
77 private:
78 //
79 void delete_children_recursive()
80 {
81 if ( left != NULL )
82 {
83 left->delete_children_recursive();
84 delete left;
85 left = NULL;
86 }
87 if ( right != NULL )
88 {
89 right->delete_children_recursive();
90 delete right;
91 right = NULL;
92 }
93 }
94
95 Key key;
96 Data data;
97 int sleft;
98 int sright;
99 node* left;
100 node* right;
101 node* father;
102 };
103
104 public:
105
106 typedef node* pqueue_item;
107
108 private:
109
110 node* root;
111 Compare compare;
112
113 public:
114
115 /** Default constructor, creates empty priority queue. */
117 root( NULL )
118 {} /*lint !e1401*/
119
120 /** Destructs queue */
122 {
123 clear(); /*lint !e1551*/
124 } /*lint !e1579*/
125
126 /** Empties queue */
127 void clear()
128 {
129 if ( root != NULL )
130 {
131 root->delete_children_recursive();
132 delete root;
133 root = NULL;
134 }
135 }
136
137 /** Returns true if the pqueue is empty. */
138 bool empty() const
139 {
140 return ( root == NULL );
141 }
142
143 /** Returns size of queue. */
144 int size() const
145 {
146 return ( root == NULL ? 0 : root->sleft + root->sright + 1 );
147 }
148
149 /** Returns key of queue item. */
150 const Key& get_key(
151 pqueue_item it
152 ) const
153 {
154 assert( it != NULL );
155 return it->key;
156 }
157
158 /** Returns data of queue item. */
159 const Data& get_data(
160 pqueue_item it
161 ) const
162 {
163 assert( it != NULL );
164 return it->data;
165 }
166
167 /** Returns queue item at top (with lowers key). */
169 {
170 return root; /*lint !e1535*//*lint !e1806*/
171 }
172
173 /** Inserts a new entry into the queue, returns new item */
175 const Key& key,
176 const Data& data
177 )
178 {
179 node* nn = NULL;
180 if ( root == NULL )
181 {
182 nn = new node(key,data);
183 if ( nn == NULL ) /*lint !e774*/
184 throw std::bad_alloc();
185 root = nn;
186 }
187 else
188 nn = create_new_node(key, data, root);
189
190 rotate_backward(nn);
191 return nn;
192 }
193
194 /** Reduces the key a queue item. */
196 pqueue_item item,
197 const Key& new_key
198 )
199 {
200 assert( item );
201 assert( compare(new_key, item->key) );
202
203 item->key = new_key;
204 rotate_backward(item);
205 }
206
207 /** Removes the topmost item from the queue. */
208 void pop()
209 {
210 assert ( root != NULL );
211 remove( root );
212 }
213
214 /** Removes the item from the queue */
215 void remove(
216 node* item
217 )
218 {
219 assert ( item != NULL );
220 assert ( root != NULL );
221
222 bool goto_left = ( item->left != NULL );
223 bool goto_right = ( item->right != NULL );
224 if ( goto_left && goto_right )
225 {
226 goto_right = ( compare( item->right->key, item->left->key ) );
227 goto_left = ! goto_right;
228 }
229 if ( goto_right )
230 {
231 swap_with_father( item->right );
232 remove( item );
233 return;
234 }
235 if ( goto_left )
236 {
237 swap_with_father( item->left );
238 remove( item );
239 return;
240 }
241 // at leave: remove and update all sizes
242 for (node* n = item, *f = n->father; f != NULL; n = f, f = n->father) /*lint !e440*/ /*lint !e2840*/
243 {
244 if ( f->left == n )
245 {
246 f->sleft -= 1;
247 }
248 else
249 {
250 assert( f->right == n );
251 f->sright -= 1;
252 }
253 }
254 if ( item->father )
255 {
256 if ( item->father->left == item )
257 {
258 assert( item->father->sleft == 0 );
259 item->father->left = NULL;
260 }
261 else
262 {
263 assert( item->father->right == item );
264 assert( item->father->sright == 0 );
265 item->father->right = NULL;
266 }
267 }
268 else
269 {
270 assert( item == root );
271 root = NULL;
272 }
273 delete item;
274 }
275
276
277 private:
278
279 /** creates new element in the tree such that tree remains balanced */
280 node* create_new_node(
281 const Key& key,
282 const Data& data,
283 node* subproblem
284 )
285 {
286 assert( subproblem != NULL );
287
288 if ( subproblem->sleft == 0 )
289 {
290 assert( subproblem->left == NULL );
291
292 node* nn = new node(key,data);
293 subproblem->left = nn;
294 subproblem->sleft = 1;
295 nn->father = subproblem;
296 return nn;
297 }
298 if ( subproblem->sright == 0 )
299 {
300 assert( subproblem->right == NULL );
301
302 node* nn = new node(key,data);
303 subproblem->right = nn;
304 subproblem->sright = 1;
305 nn->father = subproblem;
306 return nn;
307 }
308 assert( subproblem->left != NULL );
309 assert( subproblem->right != NULL );
310
311 if ( subproblem->sleft <= subproblem->sright )
312 {
313 subproblem->sleft += 1;
314 return create_new_node(key, data, subproblem->left);
315 }
316
317 subproblem->sright += 1;
318 return create_new_node(key, data, subproblem->right);
319 }
320
321
322 void swap_with_father(
323 node* n1
324 )
325 {
326 int n1_sleft = n1->sleft;
327 int n1_sright = n1->sright;
328 node* n1_left = n1->left;
329 node* n1_right = n1->right;
330 node* n1_father = n1->father;
331 assert( n1_father != NULL );
332 assert( n1_father->left == n1 || n1_father->right == n1 );
333
334 if ( root == n1_father )
335 root = n1;
336
337 if ( n1_father->left == n1 )
338 {
339 n1->left = n1_father;
340 n1->right = n1_father->right;
341 }
342 else
343 {
344 assert( n1_father->right == n1 );
345
346 n1->left = n1_father->left;
347 n1->right = n1_father;
348 }
349 n1_father->left = n1_left;
350 n1_father->right = n1_right;
351
352 n1->sleft = n1_father->sleft;
353 n1->sright = n1_father->sright;
354 n1_father->sleft = n1_sleft;
355 n1_father->sright = n1_sright;
356
357 n1->father = n1_father->father;
358 n1_father->father = n1;
359
360 if ( n1->left )
361 n1->left-> father = n1;
362 if ( n1->right )
363 n1->right->father = n1;
364 if ( n1_father->left )
365 n1_father->left->father = n1_father;
366 if ( n1_father->right )
367 n1_father->right->father = n1_father;
368 if ( n1->father )
369 {
370 if ( n1->father->left == n1_father )
371 n1->father->left = n1;
372 if ( n1->father->right == n1_father )
373 n1->father->right = n1;
374 }
375 }
376
377 void rotate_backward(
378 node* item
379 )
380 {
381 assert( item != NULL );
382
383 if ( item->father )
384 {
385 if ( ! compare( item->father->key, item->key ) )
386 {
387 swap_with_father( item );
388 rotate_backward( item );
389 }
390 }
391 }
392 }; /*lint !e1712*/
393
394} // namespace std
395
396#endif /* _PQUEUE_H */
void clear()
Definition: pqueue.h:127
void pop()
Definition: pqueue.h:208
node * pqueue_item
Definition: pqueue.h:106
void remove(node *item)
Definition: pqueue.h:215
bool empty() const
Definition: pqueue.h:138
int size() const
Definition: pqueue.h:144
void decrease_key(pqueue_item item, const Key &new_key)
Definition: pqueue.h:195
const Data & get_data(pqueue_item it) const
Definition: pqueue.h:159
pqueue_item insert(const Key &key, const Data &data)
Definition: pqueue.h:174
pqueue_item top()
Definition: pqueue.h:168
const Key & get_key(pqueue_item it) const
Definition: pqueue.h:150
#define NULL
Definition: def.h:248
Definition: pqueue.h:38