lemon/concepts/heap.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 894 bb70ad62c95f
parent 559 c5fd2d996909
child 709 0747f332c478
child 953 b873350e6258
permissions -rw-r--r--
Fix critical bug in preflow (#372)

The wrong transition between the bound decrease and highest active
heuristics caused the bug. The last node chosen in bound decrease mode
is used in the first iteration in highest active mode.
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2009
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 ///\ingroup concept
    20 ///\file
    21 ///\brief The concept of heaps.
    22 
    23 #ifndef LEMON_CONCEPTS_HEAP_H
    24 #define LEMON_CONCEPTS_HEAP_H
    25 
    26 #include <lemon/core.h>
    27 #include <lemon/concept_check.h>
    28 
    29 namespace lemon {
    30 
    31   namespace concepts {
    32 
    33     /// \addtogroup concept
    34     /// @{
    35 
    36     /// \brief The heap concept.
    37     ///
    38     /// Concept class describing the main interface of heaps. A \e heap
    39     /// is a data structure for storing items with specified values called
    40     /// \e priorities in such a way that finding the item with minimum
    41     /// priority is efficient. In a heap one can change the priority of an
    42     /// item, add or erase an item, etc.
    43     ///
    44     /// \tparam PR Type of the priority of the items.
    45     /// \tparam IM A read and writable item map with int values, used
    46     /// internally to handle the cross references.
    47     /// \tparam Comp A functor class for the ordering of the priorities.
    48     /// The default is \c std::less<PR>.
    49 #ifdef DOXYGEN
    50     template <typename PR, typename IM, typename Comp = std::less<PR> >
    51 #else
    52     template <typename PR, typename IM>
    53 #endif
    54     class Heap {
    55     public:
    56 
    57       /// Type of the item-int map.
    58       typedef IM ItemIntMap;
    59       /// Type of the priorities.
    60       typedef PR Prio;
    61       /// Type of the items stored in the heap.
    62       typedef typename ItemIntMap::Key Item;
    63 
    64       /// \brief Type to represent the states of the items.
    65       ///
    66       /// Each item has a state associated to it. It can be "in heap",
    67       /// "pre heap" or "post heap". The later two are indifferent
    68       /// from the point of view of the heap, but may be useful for
    69       /// the user.
    70       ///
    71       /// The item-int map must be initialized in such way that it assigns
    72       /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
    73       enum State {
    74         IN_HEAP = 0,    ///< = 0. The "in heap" state constant.
    75         PRE_HEAP = -1,  ///< = -1. The "pre heap" state constant.
    76         POST_HEAP = -2  ///< = -2. The "post heap" state constant.
    77       };
    78 
    79       /// \brief The constructor.
    80       ///
    81       /// The constructor.
    82       /// \param map A map that assigns \c int values to keys of type
    83       /// \c Item. It is used internally by the heap implementations to
    84       /// handle the cross references. The assigned value must be
    85       /// \c PRE_HEAP (<tt>-1</tt>) for every item.
    86       explicit Heap(ItemIntMap &map) {}
    87 
    88       /// \brief The number of items stored in the heap.
    89       ///
    90       /// Returns the number of items stored in the heap.
    91       int size() const { return 0; }
    92 
    93       /// \brief Checks if the heap is empty.
    94       ///
    95       /// Returns \c true if the heap is empty.
    96       bool empty() const { return false; }
    97 
    98       /// \brief Makes the heap empty.
    99       ///
   100       /// Makes the heap empty.
   101       void clear();
   102 
   103       /// \brief Inserts an item into the heap with the given priority.
   104       ///
   105       /// Inserts the given item into the heap with the given priority.
   106       /// \param i The item to insert.
   107       /// \param p The priority of the item.
   108       void push(const Item &i, const Prio &p) {}
   109 
   110       /// \brief Returns the item having minimum priority.
   111       ///
   112       /// Returns the item having minimum priority.
   113       /// \pre The heap must be non-empty.
   114       Item top() const {}
   115 
   116       /// \brief The minimum priority.
   117       ///
   118       /// Returns the minimum priority.
   119       /// \pre The heap must be non-empty.
   120       Prio prio() const {}
   121 
   122       /// \brief Removes the item having minimum priority.
   123       ///
   124       /// Removes the item having minimum priority.
   125       /// \pre The heap must be non-empty.
   126       void pop() {}
   127 
   128       /// \brief Removes an item from the heap.
   129       ///
   130       /// Removes the given item from the heap if it is already stored.
   131       /// \param i The item to delete.
   132       void erase(const Item &i) {}
   133 
   134       /// \brief The priority of an item.
   135       ///
   136       /// Returns the priority of the given item.
   137       /// \param i The item.
   138       /// \pre \c i must be in the heap.
   139       Prio operator[](const Item &i) const {}
   140 
   141       /// \brief Sets the priority of an item or inserts it, if it is
   142       /// not stored in the heap.
   143       ///
   144       /// This method sets the priority of the given item if it is
   145       /// already stored in the heap.
   146       /// Otherwise it inserts the given item with the given priority.
   147       ///
   148       /// \param i The item.
   149       /// \param p The priority.
   150       void set(const Item &i, const Prio &p) {}
   151 
   152       /// \brief Decreases the priority of an item to the given value.
   153       ///
   154       /// Decreases the priority of an item to the given value.
   155       /// \param i The item.
   156       /// \param p The priority.
   157       /// \pre \c i must be stored in the heap with priority at least \c p.
   158       void decrease(const Item &i, const Prio &p) {}
   159 
   160       /// \brief Increases the priority of an item to the given value.
   161       ///
   162       /// Increases the priority of an item to the given value.
   163       /// \param i The item.
   164       /// \param p The priority.
   165       /// \pre \c i must be stored in the heap with priority at most \c p.
   166       void increase(const Item &i, const Prio &p) {}
   167 
   168       /// \brief Returns if an item is in, has already been in, or has
   169       /// never been in the heap.
   170       ///
   171       /// This method returns \c PRE_HEAP if the given item has never
   172       /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
   173       /// and \c POST_HEAP otherwise.
   174       /// In the latter case it is possible that the item will get back
   175       /// to the heap again.
   176       /// \param i The item.
   177       State state(const Item &i) const {}
   178 
   179       /// \brief Sets the state of an item in the heap.
   180       ///
   181       /// Sets the state of the given item in the heap. It can be used
   182       /// to manually clear the heap when it is important to achive the
   183       /// better time complexity.
   184       /// \param i The item.
   185       /// \param st The state. It should not be \c IN_HEAP.
   186       void state(const Item& i, State st) {}
   187 
   188 
   189       template <typename _Heap>
   190       struct Constraints {
   191       public:
   192         void constraints() {
   193           typedef typename _Heap::Item OwnItem;
   194           typedef typename _Heap::Prio OwnPrio;
   195           typedef typename _Heap::State OwnState;
   196 
   197           Item item;
   198           Prio prio;
   199           item=Item();
   200           prio=Prio();
   201           ignore_unused_variable_warning(item);
   202           ignore_unused_variable_warning(prio);
   203 
   204           OwnItem own_item;
   205           OwnPrio own_prio;
   206           OwnState own_state;
   207           own_item=Item();
   208           own_prio=Prio();
   209           ignore_unused_variable_warning(own_item);
   210           ignore_unused_variable_warning(own_prio);
   211           ignore_unused_variable_warning(own_state);
   212 
   213           _Heap heap1(map);
   214           _Heap heap2 = heap1;
   215           ignore_unused_variable_warning(heap1);
   216           ignore_unused_variable_warning(heap2);
   217 
   218           int s = heap.size();
   219           ignore_unused_variable_warning(s);
   220           bool e = heap.empty();
   221           ignore_unused_variable_warning(e);
   222 
   223           prio = heap.prio();
   224           item = heap.top();
   225           prio = heap[item];
   226           own_prio = heap.prio();
   227           own_item = heap.top();
   228           own_prio = heap[own_item];
   229 
   230           heap.push(item, prio);
   231           heap.push(own_item, own_prio);
   232           heap.pop();
   233 
   234           heap.set(item, prio);
   235           heap.decrease(item, prio);
   236           heap.increase(item, prio);
   237           heap.set(own_item, own_prio);
   238           heap.decrease(own_item, own_prio);
   239           heap.increase(own_item, own_prio);
   240 
   241           heap.erase(item);
   242           heap.erase(own_item);
   243           heap.clear();
   244 
   245           own_state = heap.state(own_item);
   246           heap.state(own_item, own_state);
   247 
   248           own_state = _Heap::PRE_HEAP;
   249           own_state = _Heap::IN_HEAP;
   250           own_state = _Heap::POST_HEAP;
   251         }
   252 
   253         _Heap& heap;
   254         ItemIntMap& map;
   255       };
   256     };
   257 
   258     /// @}
   259   } // namespace lemon
   260 }
   261 #endif