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