lemon/concepts/heap.h
author Peter Kovacs <kpeter@inf.elte.hu>
Thu, 12 Nov 2009 23:26:13 +0100
changeset 806 fa6f37d7a25b
parent 709 0747f332c478
child 817 b87f0504cdbe
permissions -rw-r--r--
Entirely rework CapacityScaling (#180)

- Use the new interface similarly to NetworkSimplex.
- Rework the implementation using an efficient internal structure
for handling the residual network. This improvement made the
code much faster (up to 2-5 times faster on large graphs).
- Handle GEQ supply type (LEQ is not supported).
- Handle negative costs for arcs of finite capacity.
(Note that this algorithm cannot handle arcs of negative cost
and infinite upper bound, thus it returns UNBOUNDED if such
an arc exists.)
- Extend the documentation.
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
kpeter@709
    19
#ifndef LEMON_CONCEPTS_HEAP_H
kpeter@709
    20
#define LEMON_CONCEPTS_HEAP_H
kpeter@709
    21
alpar@100
    22
///\ingroup concept
alpar@100
    23
///\file
kpeter@113
    24
///\brief The concept of heaps.
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@709
    38
    /// This concept class describes the main interface of heaps.
kpeter@710
    39
    /// The various \ref heaps "heap structures" are efficient
kpeter@709
    40
    /// implementations of the abstract data type \e priority \e queue.
kpeter@709
    41
    /// They store items with specified values called \e priorities
kpeter@709
    42
    /// in such a way that finding and removing the item with minimum
kpeter@709
    43
    /// priority are efficient. The basic operations are adding and
kpeter@709
    44
    /// erasing items, changing the priority of an item, etc.
kpeter@559
    45
    ///
kpeter@709
    46
    /// Heaps are crucial in several algorithms, such as Dijkstra and Prim.
kpeter@709
    47
    /// Any class that conforms to this concept can be used easily in such
kpeter@709
    48
    /// algorithms.
kpeter@709
    49
    ///
kpeter@709
    50
    /// \tparam PR Type of the priorities of the items.
kpeter@709
    51
    /// \tparam IM A read-writable item map with \c int values, used
kpeter@559
    52
    /// internally to handle the cross references.
kpeter@709
    53
    /// \tparam CMP A functor class for comparing the priorities.
kpeter@559
    54
    /// The default is \c std::less<PR>.
kpeter@559
    55
#ifdef DOXYGEN
kpeter@709
    56
    template <typename PR, typename IM, typename CMP>
kpeter@559
    57
#else
kpeter@709
    58
    template <typename PR, typename IM, typename CMP = std::less<PR> >
kpeter@559
    59
#endif
alpar@100
    60
    class Heap {
alpar@100
    61
    public:
alpar@100
    62
kpeter@559
    63
      /// Type of the item-int map.
kpeter@559
    64
      typedef IM ItemIntMap;
kpeter@559
    65
      /// Type of the priorities.
kpeter@559
    66
      typedef PR Prio;
kpeter@113
    67
      /// Type of the items stored in the heap.
kpeter@113
    68
      typedef typename ItemIntMap::Key Item;
alpar@100
    69
kpeter@113
    70
      /// \brief Type to represent the states of the items.
alpar@100
    71
      ///
kpeter@113
    72
      /// Each item has a state associated to it. It can be "in heap",
kpeter@709
    73
      /// "pre-heap" or "post-heap". The latter two are indifferent from the
kpeter@709
    74
      /// heap's point of view, but may be useful to the user.
alpar@100
    75
      ///
kpeter@559
    76
      /// The item-int map must be initialized in such way that it assigns
kpeter@559
    77
      /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
alpar@100
    78
      enum State {
kpeter@584
    79
        IN_HEAP = 0,    ///< = 0. The "in heap" state constant.
kpeter@709
    80
        PRE_HEAP = -1,  ///< = -1. The "pre-heap" state constant.
kpeter@709
    81
        POST_HEAP = -2  ///< = -2. The "post-heap" state constant.
alpar@100
    82
      };
alpar@209
    83
kpeter@709
    84
      /// \brief Constructor.
alpar@100
    85
      ///
kpeter@709
    86
      /// Constructor.
kpeter@113
    87
      /// \param map A map that assigns \c int values to keys of type
kpeter@113
    88
      /// \c Item. It is used internally by the heap implementations to
kpeter@113
    89
      /// handle the cross references. The assigned value must be
kpeter@709
    90
      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
kpeter@113
    91
      explicit Heap(ItemIntMap &map) {}
alpar@100
    92
kpeter@709
    93
      /// \brief Constructor.
kpeter@709
    94
      ///
kpeter@709
    95
      /// Constructor.
kpeter@709
    96
      /// \param map A map that assigns \c int values to keys of type
kpeter@709
    97
      /// \c Item. It is used internally by the heap implementations to
kpeter@709
    98
      /// handle the cross references. The assigned value must be
kpeter@709
    99
      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
kpeter@709
   100
      /// \param comp The function object used for comparing the priorities.
kpeter@709
   101
      explicit Heap(ItemIntMap &map, const CMP &comp) {}
kpeter@709
   102
alpar@100
   103
      /// \brief The number of items stored in the heap.
alpar@100
   104
      ///
kpeter@709
   105
      /// This function returns the number of items stored in the heap.
alpar@100
   106
      int size() const { return 0; }
alpar@100
   107
kpeter@709
   108
      /// \brief Check if the heap is empty.
alpar@100
   109
      ///
kpeter@709
   110
      /// This function returns \c true if the heap is empty.
alpar@100
   111
      bool empty() const { return false; }
alpar@100
   112
kpeter@709
   113
      /// \brief Make the heap empty.
alpar@100
   114
      ///
kpeter@709
   115
      /// This functon makes the heap empty.
kpeter@709
   116
      /// It does not change the cross reference map. If you want to reuse
kpeter@709
   117
      /// a heap that is not surely empty, you should first clear it and
kpeter@709
   118
      /// then you should set the cross reference map to \c PRE_HEAP
kpeter@709
   119
      /// for each item.
kpeter@709
   120
      void clear() {}
alpar@100
   121
kpeter@709
   122
      /// \brief Insert an item into the heap with the given priority.
alpar@209
   123
      ///
kpeter@709
   124
      /// This function inserts the given item into the heap with the
kpeter@709
   125
      /// given priority.
alpar@100
   126
      /// \param i The item to insert.
alpar@100
   127
      /// \param p The priority of the item.
kpeter@709
   128
      /// \pre \e i must not be stored in the heap.
alpar@100
   129
      void push(const Item &i, const Prio &p) {}
alpar@100
   130
kpeter@709
   131
      /// \brief Return the item having minimum priority.
alpar@100
   132
      ///
kpeter@709
   133
      /// This function returns the item having minimum priority.
kpeter@113
   134
      /// \pre The heap must be non-empty.
alpar@100
   135
      Item top() const {}
alpar@100
   136
kpeter@113
   137
      /// \brief The minimum priority.
alpar@100
   138
      ///
kpeter@709
   139
      /// This function returns the minimum priority.
kpeter@113
   140
      /// \pre The heap must be non-empty.
alpar@100
   141
      Prio prio() const {}
alpar@100
   142
kpeter@709
   143
      /// \brief Remove the item having minimum priority.
alpar@100
   144
      ///
kpeter@709
   145
      /// This function removes the item having minimum priority.
kpeter@113
   146
      /// \pre The heap must be non-empty.
alpar@100
   147
      void pop() {}
alpar@100
   148
kpeter@709
   149
      /// \brief Remove the given item from the heap.
alpar@100
   150
      ///
kpeter@709
   151
      /// This function removes the given item from the heap if it is
kpeter@709
   152
      /// already stored.
alpar@209
   153
      /// \param i The item to delete.
kpeter@709
   154
      /// \pre \e i must be in the heap.
alpar@100
   155
      void erase(const Item &i) {}
alpar@100
   156
kpeter@709
   157
      /// \brief The priority of the given item.
alpar@100
   158
      ///
kpeter@709
   159
      /// This function returns the priority of the given item.
kpeter@559
   160
      /// \param i The item.
kpeter@709
   161
      /// \pre \e i must be in the heap.
alpar@100
   162
      Prio operator[](const Item &i) const {}
alpar@100
   163
kpeter@709
   164
      /// \brief Set the priority of an item or insert it, if it is
kpeter@113
   165
      /// not stored in the heap.
alpar@100
   166
      ///
kpeter@113
   167
      /// This method sets the priority of the given item if it is
kpeter@709
   168
      /// already stored in the heap. Otherwise it inserts the given
kpeter@709
   169
      /// item into the heap with the given priority.
kpeter@113
   170
      ///
alpar@100
   171
      /// \param i The item.
alpar@100
   172
      /// \param p The priority.
alpar@100
   173
      void set(const Item &i, const Prio &p) {}
alpar@209
   174
kpeter@709
   175
      /// \brief Decrease the priority of an item to the given value.
alpar@100
   176
      ///
kpeter@709
   177
      /// This function decreases the priority of an item to the given value.
alpar@100
   178
      /// \param i The item.
alpar@100
   179
      /// \param p The priority.
kpeter@709
   180
      /// \pre \e i must be stored in the heap with priority at least \e p.
alpar@100
   181
      void decrease(const Item &i, const Prio &p) {}
alpar@100
   182
kpeter@709
   183
      /// \brief Increase the priority of an item to the given value.
alpar@100
   184
      ///
kpeter@709
   185
      /// This function increases the priority of an item to the given value.
alpar@100
   186
      /// \param i The item.
alpar@100
   187
      /// \param p The priority.
kpeter@709
   188
      /// \pre \e i must be stored in the heap with priority at most \e p.
alpar@100
   189
      void increase(const Item &i, const Prio &p) {}
alpar@100
   190
kpeter@709
   191
      /// \brief Return the state of an item.
alpar@100
   192
      ///
kpeter@113
   193
      /// This method returns \c PRE_HEAP if the given item has never
kpeter@113
   194
      /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
kpeter@113
   195
      /// and \c POST_HEAP otherwise.
kpeter@113
   196
      /// In the latter case it is possible that the item will get back
kpeter@113
   197
      /// to the heap again.
alpar@100
   198
      /// \param i The item.
alpar@100
   199
      State state(const Item &i) const {}
alpar@100
   200
kpeter@709
   201
      /// \brief Set the state of an item in the heap.
alpar@100
   202
      ///
kpeter@709
   203
      /// This function sets the state of the given item in the heap.
kpeter@709
   204
      /// It can be used to manually clear the heap when it is important
kpeter@709
   205
      /// to achive better time complexity.
alpar@100
   206
      /// \param i The item.
kpeter@113
   207
      /// \param st The state. It should not be \c IN_HEAP.
alpar@100
   208
      void state(const Item& i, State st) {}
alpar@100
   209
alpar@100
   210
alpar@100
   211
      template <typename _Heap>
alpar@100
   212
      struct Constraints {
alpar@100
   213
      public:
alpar@209
   214
        void constraints() {
alpar@209
   215
          typedef typename _Heap::Item OwnItem;
alpar@209
   216
          typedef typename _Heap::Prio OwnPrio;
alpar@209
   217
          typedef typename _Heap::State OwnState;
kpeter@113
   218
alpar@209
   219
          Item item;
alpar@209
   220
          Prio prio;
alpar@209
   221
          item=Item();
alpar@209
   222
          prio=Prio();
alpar@209
   223
          ignore_unused_variable_warning(item);
alpar@209
   224
          ignore_unused_variable_warning(prio);
alpar@100
   225
alpar@209
   226
          OwnItem own_item;
alpar@209
   227
          OwnPrio own_prio;
alpar@209
   228
          OwnState own_state;
alpar@209
   229
          own_item=Item();
alpar@209
   230
          own_prio=Prio();
alpar@209
   231
          ignore_unused_variable_warning(own_item);
alpar@209
   232
          ignore_unused_variable_warning(own_prio);
alpar@209
   233
          ignore_unused_variable_warning(own_state);
alpar@100
   234
alpar@209
   235
          _Heap heap1(map);
alpar@209
   236
          _Heap heap2 = heap1;
alpar@209
   237
          ignore_unused_variable_warning(heap1);
alpar@209
   238
          ignore_unused_variable_warning(heap2);
alpar@100
   239
alpar@209
   240
          int s = heap.size();
alpar@209
   241
          ignore_unused_variable_warning(s);
alpar@209
   242
          bool e = heap.empty();
alpar@209
   243
          ignore_unused_variable_warning(e);
alpar@100
   244
alpar@209
   245
          prio = heap.prio();
alpar@209
   246
          item = heap.top();
alpar@209
   247
          prio = heap[item];
alpar@209
   248
          own_prio = heap.prio();
alpar@209
   249
          own_item = heap.top();
alpar@209
   250
          own_prio = heap[own_item];
alpar@100
   251
alpar@209
   252
          heap.push(item, prio);
alpar@209
   253
          heap.push(own_item, own_prio);
alpar@209
   254
          heap.pop();
alpar@100
   255
alpar@209
   256
          heap.set(item, prio);
alpar@209
   257
          heap.decrease(item, prio);
alpar@209
   258
          heap.increase(item, prio);
alpar@209
   259
          heap.set(own_item, own_prio);
alpar@209
   260
          heap.decrease(own_item, own_prio);
alpar@209
   261
          heap.increase(own_item, own_prio);
alpar@100
   262
alpar@209
   263
          heap.erase(item);
alpar@209
   264
          heap.erase(own_item);
alpar@209
   265
          heap.clear();
alpar@100
   266
alpar@209
   267
          own_state = heap.state(own_item);
alpar@209
   268
          heap.state(own_item, own_state);
alpar@100
   269
alpar@209
   270
          own_state = _Heap::PRE_HEAP;
alpar@209
   271
          own_state = _Heap::IN_HEAP;
alpar@209
   272
          own_state = _Heap::POST_HEAP;
alpar@209
   273
        }
alpar@209
   274
alpar@209
   275
        _Heap& heap;
alpar@209
   276
        ItemIntMap& map;
alpar@100
   277
      };
alpar@100
   278
    };
alpar@100
   279
alpar@100
   280
    /// @}
alpar@100
   281
  } // namespace lemon
alpar@100
   282
}
deba@529
   283
#endif