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