lemon/max_cardinality_search.h
author Alpar Juttner <alpar@cs.elte.hu>
Thu, 17 Oct 2013 15:08:41 +0200
changeset 1111 a78e5b779b69
parent 1092 dceba191c00d
permissions -rw-r--r--
Merge bugfix #478
alpar@1092
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
thoneyvazul@916
     2
 *
alpar@1092
     3
 * This file is a part of LEMON, a generic C++ optimization library.
thoneyvazul@916
     4
 *
alpar@1092
     5
 * Copyright (C) 2003-2013
thoneyvazul@916
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
thoneyvazul@916
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
thoneyvazul@916
     8
 *
thoneyvazul@916
     9
 * Permission to use, modify and distribute this software is granted
thoneyvazul@916
    10
 * provided that this copyright notice appears in all copies. For
thoneyvazul@916
    11
 * precise terms see the accompanying LICENSE file.
thoneyvazul@916
    12
 *
thoneyvazul@916
    13
 * This software is provided "AS IS" with no warranty of any kind,
thoneyvazul@916
    14
 * express or implied, and with no claim as to its suitability for any
thoneyvazul@916
    15
 * purpose.
thoneyvazul@916
    16
 *
thoneyvazul@916
    17
 */
thoneyvazul@916
    18
thoneyvazul@916
    19
#ifndef LEMON_MAX_CARDINALITY_SEARCH_H
thoneyvazul@916
    20
#define LEMON_MAX_CARDINALITY_SEARCH_H
thoneyvazul@916
    21
thoneyvazul@916
    22
thoneyvazul@916
    23
/// \ingroup search
alpar@1092
    24
/// \file
thoneyvazul@916
    25
/// \brief Maximum cardinality search in undirected digraphs.
thoneyvazul@916
    26
thoneyvazul@916
    27
#include <lemon/bin_heap.h>
thoneyvazul@916
    28
#include <lemon/bucket_heap.h>
thoneyvazul@916
    29
thoneyvazul@916
    30
#include <lemon/error.h>
thoneyvazul@916
    31
#include <lemon/maps.h>
thoneyvazul@916
    32
thoneyvazul@916
    33
#include <functional>
thoneyvazul@916
    34
thoneyvazul@916
    35
namespace lemon {
thoneyvazul@916
    36
thoneyvazul@916
    37
  /// \brief Default traits class of MaxCardinalitySearch class.
thoneyvazul@916
    38
  ///
thoneyvazul@916
    39
  /// Default traits class of MaxCardinalitySearch class.
thoneyvazul@916
    40
  /// \param Digraph Digraph type.
thoneyvazul@916
    41
  /// \param CapacityMap Type of capacity map.
thoneyvazul@916
    42
  template <typename GR, typename CAP>
thoneyvazul@916
    43
  struct MaxCardinalitySearchDefaultTraits {
alpar@1092
    44
    /// The digraph type the algorithm runs on.
thoneyvazul@916
    45
    typedef GR Digraph;
thoneyvazul@916
    46
thoneyvazul@916
    47
    template <typename CM>
thoneyvazul@916
    48
    struct CapMapSelector {
thoneyvazul@916
    49
thoneyvazul@916
    50
      typedef CM CapacityMap;
thoneyvazul@916
    51
thoneyvazul@916
    52
      static CapacityMap *createCapacityMap(const Digraph& g) {
alpar@1092
    53
        return new CapacityMap(g);
thoneyvazul@916
    54
      }
thoneyvazul@916
    55
    };
thoneyvazul@916
    56
thoneyvazul@916
    57
    template <typename CM>
thoneyvazul@916
    58
    struct CapMapSelector<ConstMap<CM, Const<int, 1> > > {
thoneyvazul@916
    59
thoneyvazul@916
    60
      typedef ConstMap<CM, Const<int, 1> > CapacityMap;
thoneyvazul@916
    61
thoneyvazul@916
    62
      static CapacityMap *createCapacityMap(const Digraph&) {
alpar@1092
    63
        return new CapacityMap;
thoneyvazul@916
    64
      }
thoneyvazul@916
    65
    };
thoneyvazul@916
    66
thoneyvazul@916
    67
    /// \brief The type of the map that stores the arc capacities.
thoneyvazul@916
    68
    ///
thoneyvazul@916
    69
    /// The type of the map that stores the arc capacities.
thoneyvazul@916
    70
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
thoneyvazul@916
    71
    typedef typename CapMapSelector<CAP>::CapacityMap CapacityMap;
thoneyvazul@916
    72
thoneyvazul@916
    73
    /// \brief The type of the capacity of the arcs.
thoneyvazul@916
    74
    typedef typename CapacityMap::Value Value;
thoneyvazul@916
    75
thoneyvazul@916
    76
    /// \brief Instantiates a CapacityMap.
thoneyvazul@916
    77
    ///
thoneyvazul@916
    78
    /// This function instantiates a \ref CapacityMap.
thoneyvazul@916
    79
    /// \param digraph is the digraph, to which we would like to define
thoneyvazul@916
    80
    /// the CapacityMap.
thoneyvazul@916
    81
    static CapacityMap *createCapacityMap(const Digraph& digraph) {
thoneyvazul@916
    82
      return CapMapSelector<CapacityMap>::createCapacityMap(digraph);
thoneyvazul@916
    83
    }
thoneyvazul@916
    84
thoneyvazul@916
    85
    /// \brief The cross reference type used by heap.
thoneyvazul@916
    86
    ///
thoneyvazul@916
    87
    /// The cross reference type used by heap.
thoneyvazul@916
    88
    /// Usually it is \c Digraph::NodeMap<int>.
thoneyvazul@916
    89
    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
thoneyvazul@916
    90
thoneyvazul@916
    91
    /// \brief Instantiates a HeapCrossRef.
thoneyvazul@916
    92
    ///
alpar@1092
    93
    /// This function instantiates a \ref HeapCrossRef.
alpar@1092
    94
    /// \param digraph is the digraph, to which we would like to define the
thoneyvazul@916
    95
    /// HeapCrossRef.
thoneyvazul@916
    96
    static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) {
thoneyvazul@916
    97
      return new HeapCrossRef(digraph);
thoneyvazul@916
    98
    }
alpar@1092
    99
thoneyvazul@916
   100
    template <typename CapacityMap>
thoneyvazul@916
   101
    struct HeapSelector {
thoneyvazul@916
   102
      template <typename Value, typename Ref>
alpar@1092
   103
      struct Selector {
thoneyvazul@916
   104
        typedef BinHeap<Value, Ref, std::greater<Value> > Heap;
thoneyvazul@916
   105
      };
thoneyvazul@916
   106
    };
thoneyvazul@916
   107
thoneyvazul@916
   108
    template <typename CapacityKey>
thoneyvazul@916
   109
    struct HeapSelector<ConstMap<CapacityKey, Const<int, 1> > > {
thoneyvazul@916
   110
      template <typename Value, typename Ref>
thoneyvazul@916
   111
      struct Selector {
thoneyvazul@916
   112
        typedef BucketHeap<Ref, false > Heap;
thoneyvazul@916
   113
      };
thoneyvazul@916
   114
    };
thoneyvazul@916
   115
thoneyvazul@916
   116
    /// \brief The heap type used by MaxCardinalitySearch algorithm.
thoneyvazul@916
   117
    ///
thoneyvazul@916
   118
    /// The heap type used by MaxCardinalitySearch algorithm. It should
thoneyvazul@916
   119
    /// maximalize the priorities. The default heap type is
thoneyvazul@916
   120
    /// the \ref BinHeap, but it is specialized when the
thoneyvazul@916
   121
    /// CapacityMap is ConstMap<Digraph::Node, Const<int, 1> >
thoneyvazul@916
   122
    /// to BucketHeap.
thoneyvazul@916
   123
    ///
thoneyvazul@916
   124
    /// \sa MaxCardinalitySearch
thoneyvazul@916
   125
    typedef typename HeapSelector<CapacityMap>
thoneyvazul@916
   126
    ::template Selector<Value, HeapCrossRef>
thoneyvazul@916
   127
    ::Heap Heap;
thoneyvazul@916
   128
thoneyvazul@916
   129
    /// \brief Instantiates a Heap.
thoneyvazul@916
   130
    ///
alpar@1092
   131
    /// This function instantiates a \ref Heap.
thoneyvazul@916
   132
    /// \param crossref The cross reference of the heap.
thoneyvazul@916
   133
    static Heap *createHeap(HeapCrossRef& crossref) {
thoneyvazul@916
   134
      return new Heap(crossref);
thoneyvazul@916
   135
    }
thoneyvazul@916
   136
thoneyvazul@916
   137
    /// \brief The type of the map that stores whether a node is processed.
thoneyvazul@916
   138
    ///
thoneyvazul@916
   139
    /// The type of the map that stores whether a node is processed.
thoneyvazul@916
   140
    /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
thoneyvazul@916
   141
    /// By default it is a NullMap.
thoneyvazul@916
   142
    typedef NullMap<typename Digraph::Node, bool> ProcessedMap;
thoneyvazul@916
   143
thoneyvazul@916
   144
    /// \brief Instantiates a ProcessedMap.
thoneyvazul@916
   145
    ///
alpar@1092
   146
    /// This function instantiates a \ref ProcessedMap.
thoneyvazul@916
   147
    /// \param digraph is the digraph, to which
thoneyvazul@916
   148
    /// we would like to define the \ref ProcessedMap
thoneyvazul@916
   149
#ifdef DOXYGEN
thoneyvazul@916
   150
    static ProcessedMap *createProcessedMap(const Digraph &digraph)
thoneyvazul@916
   151
#else
thoneyvazul@916
   152
    static ProcessedMap *createProcessedMap(const Digraph &)
thoneyvazul@916
   153
#endif
thoneyvazul@916
   154
    {
thoneyvazul@916
   155
      return new ProcessedMap();
thoneyvazul@916
   156
    }
thoneyvazul@916
   157
thoneyvazul@916
   158
    /// \brief The type of the map that stores the cardinalities of the nodes.
alpar@1092
   159
    ///
thoneyvazul@916
   160
    /// The type of the map that stores the cardinalities of the nodes.
thoneyvazul@916
   161
    /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
thoneyvazul@916
   162
    typedef typename Digraph::template NodeMap<Value> CardinalityMap;
thoneyvazul@916
   163
thoneyvazul@916
   164
    /// \brief Instantiates a CardinalityMap.
thoneyvazul@916
   165
    ///
alpar@1092
   166
    /// This function instantiates a \ref CardinalityMap.
alpar@1093
   167
    /// \param digraph is the digraph, to which we would like to
alpar@1093
   168
    /// define the \ref CardinalityMap
thoneyvazul@916
   169
    static CardinalityMap *createCardinalityMap(const Digraph &digraph) {
thoneyvazul@916
   170
      return new CardinalityMap(digraph);
thoneyvazul@916
   171
    }
thoneyvazul@916
   172
thoneyvazul@916
   173
thoneyvazul@916
   174
  };
alpar@1092
   175
thoneyvazul@916
   176
  /// \ingroup search
thoneyvazul@916
   177
  ///
thoneyvazul@916
   178
  /// \brief Maximum Cardinality Search algorithm class.
thoneyvazul@916
   179
  ///
alpar@1092
   180
  /// This class provides an efficient implementation of Maximum Cardinality
alpar@1092
   181
  /// Search algorithm. The maximum cardinality search first chooses any
thoneyvazul@916
   182
  /// node of the digraph. Then every time it chooses one unprocessed node
alpar@1093
   183
  /// with maximum cardinality, i.e the sum of capacities on out arcs
alpar@1093
   184
  /// to the nodes
thoneyvazul@916
   185
  /// which were previusly processed.
thoneyvazul@916
   186
  /// If there is a cut in the digraph the algorithm should choose
thoneyvazul@916
   187
  /// again any unprocessed node of the digraph.
thoneyvazul@916
   188
thoneyvazul@916
   189
  /// The arc capacities are passed to the algorithm using a
alpar@1092
   190
  /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
thoneyvazul@916
   191
  /// kind of capacity.
thoneyvazul@916
   192
  ///
alpar@1092
   193
  /// The type of the capacity is determined by the \ref
thoneyvazul@916
   194
  /// concepts::ReadMap::Value "Value" of the capacity map.
thoneyvazul@916
   195
  ///
thoneyvazul@916
   196
  /// It is also possible to change the underlying priority heap.
thoneyvazul@916
   197
  ///
thoneyvazul@916
   198
  ///
thoneyvazul@916
   199
  /// \param GR The digraph type the algorithm runs on. The value of
alpar@1092
   200
  /// Digraph is not used directly by the search algorithm, it
thoneyvazul@916
   201
  /// is only passed to \ref MaxCardinalitySearchDefaultTraits.
alpar@1092
   202
  /// \param CAP This read-only ArcMap determines the capacities of
thoneyvazul@916
   203
  /// the arcs. It is read once for each arc, so the map may involve in
thoneyvazul@916
   204
  /// relatively time consuming process to compute the arc capacity if
thoneyvazul@916
   205
  /// it is necessary. The default map type is \ref
thoneyvazul@916
   206
  /// ConstMap "ConstMap<concepts::Digraph::Arc, Const<int,1> >". The value
alpar@1092
   207
  /// of CapacityMap is not used directly by search algorithm, it is only
alpar@1092
   208
  /// passed to \ref MaxCardinalitySearchDefaultTraits.
alpar@1092
   209
  /// \param TR Traits class to set various data types used by the
alpar@1092
   210
  /// algorithm.  The default traits class is
alpar@1092
   211
  /// \ref MaxCardinalitySearchDefaultTraits
alpar@1092
   212
  /// "MaxCardinalitySearchDefaultTraits<GR, CAP>".
alpar@1092
   213
  /// See \ref MaxCardinalitySearchDefaultTraits
thoneyvazul@916
   214
  /// for the documentation of a MaxCardinalitySearch traits class.
thoneyvazul@916
   215
thoneyvazul@916
   216
#ifdef DOXYGEN
thoneyvazul@916
   217
  template <typename GR, typename CAP, typename TR>
thoneyvazul@916
   218
#else
alpar@1092
   219
  template <typename GR, typename CAP =
alpar@1092
   220
            ConstMap<typename GR::Arc, Const<int,1> >,
alpar@1092
   221
            typename TR =
thoneyvazul@916
   222
            MaxCardinalitySearchDefaultTraits<GR, CAP> >
thoneyvazul@916
   223
#endif
thoneyvazul@916
   224
  class MaxCardinalitySearch {
thoneyvazul@916
   225
  public:
thoneyvazul@916
   226
thoneyvazul@916
   227
    typedef TR Traits;
thoneyvazul@916
   228
    ///The type of the underlying digraph.
thoneyvazul@916
   229
    typedef typename Traits::Digraph Digraph;
alpar@1092
   230
thoneyvazul@916
   231
    ///The type of the capacity of the arcs.
thoneyvazul@916
   232
    typedef typename Traits::CapacityMap::Value Value;
thoneyvazul@916
   233
    ///The type of the map that stores the arc capacities.
thoneyvazul@916
   234
    typedef typename Traits::CapacityMap CapacityMap;
thoneyvazul@916
   235
    ///The type of the map indicating if a node is processed.
thoneyvazul@916
   236
    typedef typename Traits::ProcessedMap ProcessedMap;
thoneyvazul@916
   237
    ///The type of the map that stores the cardinalities of the nodes.
thoneyvazul@916
   238
    typedef typename Traits::CardinalityMap CardinalityMap;
thoneyvazul@916
   239
    ///The cross reference type used for the current heap.
thoneyvazul@916
   240
    typedef typename Traits::HeapCrossRef HeapCrossRef;
thoneyvazul@916
   241
    ///The heap type used by the algorithm. It maximizes the priorities.
thoneyvazul@916
   242
    typedef typename Traits::Heap Heap;
thoneyvazul@916
   243
  private:
thoneyvazul@916
   244
    // Pointer to the underlying digraph.
thoneyvazul@916
   245
    const Digraph *_graph;
thoneyvazul@916
   246
    // Pointer to the capacity map
thoneyvazul@916
   247
    const CapacityMap *_capacity;
thoneyvazul@916
   248
    // Indicates if \ref _capacity is locally allocated (\c true) or not.
thoneyvazul@916
   249
    bool local_capacity;
thoneyvazul@916
   250
    // Pointer to the map of cardinality.
thoneyvazul@916
   251
    CardinalityMap *_cardinality;
thoneyvazul@916
   252
    // Indicates if \ref _cardinality is locally allocated (\c true) or not.
thoneyvazul@916
   253
    bool local_cardinality;
thoneyvazul@916
   254
    // Pointer to the map of processed status of the nodes.
thoneyvazul@916
   255
    ProcessedMap *_processed;
thoneyvazul@916
   256
    // Indicates if \ref _processed is locally allocated (\c true) or not.
thoneyvazul@916
   257
    bool local_processed;
thoneyvazul@916
   258
    // Pointer to the heap cross references.
thoneyvazul@916
   259
    HeapCrossRef *_heap_cross_ref;
thoneyvazul@916
   260
    // Indicates if \ref _heap_cross_ref is locally allocated (\c true) or not.
thoneyvazul@916
   261
    bool local_heap_cross_ref;
thoneyvazul@916
   262
    // Pointer to the heap.
thoneyvazul@916
   263
    Heap *_heap;
thoneyvazul@916
   264
    // Indicates if \ref _heap is locally allocated (\c true) or not.
thoneyvazul@916
   265
    bool local_heap;
thoneyvazul@916
   266
thoneyvazul@916
   267
  public :
thoneyvazul@916
   268
thoneyvazul@916
   269
    typedef MaxCardinalitySearch Create;
alpar@1092
   270
thoneyvazul@916
   271
    ///\name Named template parameters
thoneyvazul@916
   272
thoneyvazul@916
   273
    ///@{
thoneyvazul@916
   274
thoneyvazul@916
   275
    template <class T>
thoneyvazul@916
   276
    struct DefCapacityMapTraits : public Traits {
thoneyvazul@916
   277
      typedef T CapacityMap;
thoneyvazul@916
   278
      static CapacityMap *createCapacityMap(const Digraph &) {
alpar@1092
   279
               LEMON_ASSERT(false,"Uninitialized parameter.");
alpar@1092
   280
        return 0;
thoneyvazul@916
   281
      }
thoneyvazul@916
   282
    };
alpar@1092
   283
    /// \brief \ref named-templ-param "Named parameter" for setting
thoneyvazul@916
   284
    /// CapacityMap type
thoneyvazul@916
   285
    ///
thoneyvazul@916
   286
    /// \ref named-templ-param "Named parameter" for setting CapacityMap type
thoneyvazul@916
   287
    /// for the algorithm.
thoneyvazul@916
   288
    template <class T>
alpar@1092
   289
    struct SetCapacityMap
alpar@1092
   290
      : public MaxCardinalitySearch<Digraph, CapacityMap,
alpar@1092
   291
                                    DefCapacityMapTraits<T> > {
alpar@1092
   292
      typedef MaxCardinalitySearch<Digraph, CapacityMap,
thoneyvazul@916
   293
                                   DefCapacityMapTraits<T> > Create;
thoneyvazul@916
   294
    };
thoneyvazul@916
   295
thoneyvazul@916
   296
    template <class T>
thoneyvazul@916
   297
    struct DefCardinalityMapTraits : public Traits {
thoneyvazul@916
   298
      typedef T CardinalityMap;
alpar@1092
   299
      static CardinalityMap *createCardinalityMap(const Digraph &)
thoneyvazul@916
   300
      {
alpar@1092
   301
        LEMON_ASSERT(false,"Uninitialized parameter.");
alpar@1092
   302
        return 0;
thoneyvazul@916
   303
      }
thoneyvazul@916
   304
    };
alpar@1092
   305
    /// \brief \ref named-templ-param "Named parameter" for setting
thoneyvazul@916
   306
    /// CardinalityMap type
thoneyvazul@916
   307
    ///
alpar@1092
   308
    /// \ref named-templ-param "Named parameter" for setting CardinalityMap
thoneyvazul@916
   309
    /// type for the algorithm.
thoneyvazul@916
   310
    template <class T>
alpar@1092
   311
    struct SetCardinalityMap
alpar@1092
   312
      : public MaxCardinalitySearch<Digraph, CapacityMap,
alpar@1092
   313
                                    DefCardinalityMapTraits<T> > {
alpar@1092
   314
      typedef MaxCardinalitySearch<Digraph, CapacityMap,
thoneyvazul@916
   315
                                   DefCardinalityMapTraits<T> > Create;
thoneyvazul@916
   316
    };
alpar@1092
   317
thoneyvazul@916
   318
    template <class T>
thoneyvazul@916
   319
    struct DefProcessedMapTraits : public Traits {
thoneyvazul@916
   320
      typedef T ProcessedMap;
thoneyvazul@916
   321
      static ProcessedMap *createProcessedMap(const Digraph &) {
alpar@1092
   322
               LEMON_ASSERT(false,"Uninitialized parameter.");
alpar@1092
   323
        return 0;
thoneyvazul@916
   324
      }
thoneyvazul@916
   325
    };
alpar@1092
   326
    /// \brief \ref named-templ-param "Named parameter" for setting
thoneyvazul@916
   327
    /// ProcessedMap type
thoneyvazul@916
   328
    ///
thoneyvazul@916
   329
    /// \ref named-templ-param "Named parameter" for setting ProcessedMap type
thoneyvazul@916
   330
    /// for the algorithm.
thoneyvazul@916
   331
    template <class T>
alpar@1092
   332
    struct SetProcessedMap
alpar@1092
   333
      : public MaxCardinalitySearch<Digraph, CapacityMap,
alpar@1092
   334
                                    DefProcessedMapTraits<T> > {
alpar@1092
   335
      typedef MaxCardinalitySearch<Digraph, CapacityMap,
thoneyvazul@916
   336
                                   DefProcessedMapTraits<T> > Create;
thoneyvazul@916
   337
    };
alpar@1092
   338
thoneyvazul@916
   339
    template <class H, class CR>
thoneyvazul@916
   340
    struct DefHeapTraits : public Traits {
thoneyvazul@916
   341
      typedef CR HeapCrossRef;
thoneyvazul@916
   342
      typedef H Heap;
thoneyvazul@916
   343
      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
alpar@1092
   344
             LEMON_ASSERT(false,"Uninitialized parameter.");
alpar@1092
   345
        return 0;
thoneyvazul@916
   346
      }
thoneyvazul@916
   347
      static Heap *createHeap(HeapCrossRef &) {
alpar@1092
   348
               LEMON_ASSERT(false,"Uninitialized parameter.");
alpar@1092
   349
        return 0;
thoneyvazul@916
   350
      }
thoneyvazul@916
   351
    };
alpar@1092
   352
    /// \brief \ref named-templ-param "Named parameter" for setting heap
thoneyvazul@916
   353
    /// and cross reference type
thoneyvazul@916
   354
    ///
alpar@1092
   355
    /// \ref named-templ-param "Named parameter" for setting heap and cross
thoneyvazul@916
   356
    /// reference type for the algorithm.
thoneyvazul@916
   357
    template <class H, class CR = typename Digraph::template NodeMap<int> >
thoneyvazul@916
   358
    struct SetHeap
alpar@1092
   359
      : public MaxCardinalitySearch<Digraph, CapacityMap,
alpar@1092
   360
                                    DefHeapTraits<H, CR> > {
alpar@1092
   361
      typedef MaxCardinalitySearch< Digraph, CapacityMap,
thoneyvazul@916
   362
                                    DefHeapTraits<H, CR> > Create;
thoneyvazul@916
   363
    };
thoneyvazul@916
   364
thoneyvazul@916
   365
    template <class H, class CR>
thoneyvazul@916
   366
    struct DefStandardHeapTraits : public Traits {
thoneyvazul@916
   367
      typedef CR HeapCrossRef;
thoneyvazul@916
   368
      typedef H Heap;
thoneyvazul@916
   369
      static HeapCrossRef *createHeapCrossRef(const Digraph &digraph) {
alpar@1092
   370
        return new HeapCrossRef(digraph);
thoneyvazul@916
   371
      }
thoneyvazul@916
   372
      static Heap *createHeap(HeapCrossRef &crossref) {
alpar@1092
   373
        return new Heap(crossref);
thoneyvazul@916
   374
      }
thoneyvazul@916
   375
    };
thoneyvazul@916
   376
alpar@1092
   377
    /// \brief \ref named-templ-param "Named parameter" for setting heap and
thoneyvazul@916
   378
    /// cross reference type with automatic allocation
thoneyvazul@916
   379
    ///
alpar@1092
   380
    /// \ref named-templ-param "Named parameter" for setting heap and cross
alpar@1092
   381
    /// reference type. It can allocate the heap and the cross reference
alpar@1092
   382
    /// object if the cross reference's constructor waits for the digraph as
thoneyvazul@916
   383
    /// parameter and the heap's constructor waits for the cross reference.
thoneyvazul@916
   384
    template <class H, class CR = typename Digraph::template NodeMap<int> >
thoneyvazul@916
   385
    struct SetStandardHeap
alpar@1092
   386
      : public MaxCardinalitySearch<Digraph, CapacityMap,
alpar@1092
   387
                                    DefStandardHeapTraits<H, CR> > {
alpar@1092
   388
      typedef MaxCardinalitySearch<Digraph, CapacityMap,
alpar@1092
   389
                                   DefStandardHeapTraits<H, CR> >
thoneyvazul@916
   390
      Create;
thoneyvazul@916
   391
    };
alpar@1092
   392
thoneyvazul@916
   393
    ///@}
thoneyvazul@916
   394
thoneyvazul@916
   395
thoneyvazul@916
   396
  protected:
thoneyvazul@916
   397
thoneyvazul@916
   398
    MaxCardinalitySearch() {}
thoneyvazul@916
   399
alpar@1092
   400
  public:
alpar@1092
   401
thoneyvazul@916
   402
    /// \brief Constructor.
thoneyvazul@916
   403
    ///
thoneyvazul@916
   404
    ///\param digraph the digraph the algorithm will run on.
thoneyvazul@916
   405
    ///\param capacity the capacity map used by the algorithm.
thoneyvazul@916
   406
    MaxCardinalitySearch(const Digraph& digraph,
alpar@1092
   407
                         const CapacityMap& capacity) :
thoneyvazul@916
   408
      _graph(&digraph),
thoneyvazul@916
   409
      _capacity(&capacity), local_capacity(false),
thoneyvazul@916
   410
      _cardinality(0), local_cardinality(false),
thoneyvazul@916
   411
      _processed(0), local_processed(false),
thoneyvazul@916
   412
      _heap_cross_ref(0), local_heap_cross_ref(false),
thoneyvazul@916
   413
      _heap(0), local_heap(false)
thoneyvazul@916
   414
    { }
thoneyvazul@916
   415
alpar@977
   416
    /// \brief Constructor.
alpar@977
   417
    ///
alpar@977
   418
    ///\param digraph the digraph the algorithm will run on.
alpar@977
   419
    ///
alpar@977
   420
    ///A constant 1 capacity map will be allocated.
alpar@977
   421
    MaxCardinalitySearch(const Digraph& digraph) :
alpar@977
   422
      _graph(&digraph),
alpar@977
   423
      _capacity(0), local_capacity(false),
alpar@977
   424
      _cardinality(0), local_cardinality(false),
alpar@977
   425
      _processed(0), local_processed(false),
alpar@977
   426
      _heap_cross_ref(0), local_heap_cross_ref(false),
alpar@977
   427
      _heap(0), local_heap(false)
alpar@977
   428
    { }
alpar@977
   429
thoneyvazul@916
   430
    /// \brief Destructor.
thoneyvazul@916
   431
    ~MaxCardinalitySearch() {
thoneyvazul@916
   432
      if(local_capacity) delete _capacity;
thoneyvazul@916
   433
      if(local_cardinality) delete _cardinality;
thoneyvazul@916
   434
      if(local_processed) delete _processed;
thoneyvazul@916
   435
      if(local_heap_cross_ref) delete _heap_cross_ref;
thoneyvazul@916
   436
      if(local_heap) delete _heap;
thoneyvazul@916
   437
    }
thoneyvazul@916
   438
thoneyvazul@916
   439
    /// \brief Sets the capacity map.
thoneyvazul@916
   440
    ///
thoneyvazul@916
   441
    /// Sets the capacity map.
thoneyvazul@916
   442
    /// \return <tt> (*this) </tt>
thoneyvazul@916
   443
    MaxCardinalitySearch &capacityMap(const CapacityMap &m) {
thoneyvazul@916
   444
      if (local_capacity) {
alpar@1092
   445
        delete _capacity;
alpar@1092
   446
        local_capacity=false;
thoneyvazul@916
   447
      }
thoneyvazul@916
   448
      _capacity=&m;
thoneyvazul@916
   449
      return *this;
thoneyvazul@916
   450
    }
thoneyvazul@916
   451
thoneyvazul@916
   452
    /// \brief Returns a const reference to the capacity map.
thoneyvazul@916
   453
    ///
thoneyvazul@916
   454
    /// Returns a const reference to the capacity map used by
thoneyvazul@916
   455
    /// the algorithm.
thoneyvazul@916
   456
    const CapacityMap &capacityMap() const {
thoneyvazul@916
   457
      return *_capacity;
thoneyvazul@916
   458
    }
thoneyvazul@916
   459
alpar@1092
   460
    /// \brief Sets the map storing the cardinalities calculated by the
thoneyvazul@916
   461
    /// algorithm.
thoneyvazul@916
   462
    ///
thoneyvazul@916
   463
    /// Sets the map storing the cardinalities calculated by the algorithm.
thoneyvazul@916
   464
    /// If you don't use this function before calling \ref run(),
thoneyvazul@916
   465
    /// it will allocate one. The destuctor deallocates this
thoneyvazul@916
   466
    /// automatically allocated map, of course.
thoneyvazul@916
   467
    /// \return <tt> (*this) </tt>
thoneyvazul@916
   468
    MaxCardinalitySearch &cardinalityMap(CardinalityMap &m) {
thoneyvazul@916
   469
      if(local_cardinality) {
alpar@1092
   470
        delete _cardinality;
alpar@1092
   471
        local_cardinality=false;
thoneyvazul@916
   472
      }
thoneyvazul@916
   473
      _cardinality = &m;
thoneyvazul@916
   474
      return *this;
thoneyvazul@916
   475
    }
thoneyvazul@916
   476
thoneyvazul@916
   477
    /// \brief Sets the map storing the processed nodes.
thoneyvazul@916
   478
    ///
thoneyvazul@916
   479
    /// Sets the map storing the processed nodes.
thoneyvazul@916
   480
    /// If you don't use this function before calling \ref run(),
thoneyvazul@916
   481
    /// it will allocate one. The destuctor deallocates this
thoneyvazul@916
   482
    /// automatically allocated map, of course.
thoneyvazul@916
   483
    /// \return <tt> (*this) </tt>
alpar@1092
   484
    MaxCardinalitySearch &processedMap(ProcessedMap &m)
thoneyvazul@916
   485
    {
thoneyvazul@916
   486
      if(local_processed) {
alpar@1092
   487
        delete _processed;
alpar@1092
   488
        local_processed=false;
thoneyvazul@916
   489
      }
thoneyvazul@916
   490
      _processed = &m;
thoneyvazul@916
   491
      return *this;
thoneyvazul@916
   492
    }
thoneyvazul@916
   493
thoneyvazul@916
   494
    /// \brief Returns a const reference to the cardinality map.
thoneyvazul@916
   495
    ///
thoneyvazul@916
   496
    /// Returns a const reference to the cardinality map used by
thoneyvazul@916
   497
    /// the algorithm.
thoneyvazul@916
   498
    const ProcessedMap &processedMap() const {
thoneyvazul@916
   499
      return *_processed;
thoneyvazul@916
   500
    }
thoneyvazul@916
   501
thoneyvazul@916
   502
    /// \brief Sets the heap and the cross reference used by algorithm.
thoneyvazul@916
   503
    ///
thoneyvazul@916
   504
    /// Sets the heap and the cross reference used by algorithm.
thoneyvazul@916
   505
    /// If you don't use this function before calling \ref run(),
thoneyvazul@916
   506
    /// it will allocate one. The destuctor deallocates this
thoneyvazul@916
   507
    /// automatically allocated map, of course.
thoneyvazul@916
   508
    /// \return <tt> (*this) </tt>
thoneyvazul@916
   509
    MaxCardinalitySearch &heap(Heap& hp, HeapCrossRef &cr) {
thoneyvazul@916
   510
      if(local_heap_cross_ref) {
alpar@1092
   511
        delete _heap_cross_ref;
alpar@1092
   512
        local_heap_cross_ref = false;
thoneyvazul@916
   513
      }
thoneyvazul@916
   514
      _heap_cross_ref = &cr;
thoneyvazul@916
   515
      if(local_heap) {
alpar@1092
   516
        delete _heap;
alpar@1092
   517
        local_heap = false;
thoneyvazul@916
   518
      }
thoneyvazul@916
   519
      _heap = &hp;
thoneyvazul@916
   520
      return *this;
thoneyvazul@916
   521
    }
thoneyvazul@916
   522
thoneyvazul@916
   523
    /// \brief Returns a const reference to the heap.
thoneyvazul@916
   524
    ///
thoneyvazul@916
   525
    /// Returns a const reference to the heap used by
thoneyvazul@916
   526
    /// the algorithm.
thoneyvazul@916
   527
    const Heap &heap() const {
thoneyvazul@916
   528
      return *_heap;
thoneyvazul@916
   529
    }
thoneyvazul@916
   530
thoneyvazul@916
   531
    /// \brief Returns a const reference to the cross reference.
thoneyvazul@916
   532
    ///
thoneyvazul@916
   533
    /// Returns a const reference to the cross reference
thoneyvazul@916
   534
    /// of the heap.
thoneyvazul@916
   535
    const HeapCrossRef &heapCrossRef() const {
thoneyvazul@916
   536
      return *_heap_cross_ref;
thoneyvazul@916
   537
    }
thoneyvazul@916
   538
thoneyvazul@916
   539
  private:
thoneyvazul@916
   540
thoneyvazul@916
   541
    typedef typename Digraph::Node Node;
thoneyvazul@916
   542
    typedef typename Digraph::NodeIt NodeIt;
thoneyvazul@916
   543
    typedef typename Digraph::Arc Arc;
thoneyvazul@916
   544
    typedef typename Digraph::InArcIt InArcIt;
thoneyvazul@916
   545
thoneyvazul@916
   546
    void create_maps() {
thoneyvazul@916
   547
      if(!_capacity) {
alpar@1092
   548
        local_capacity = true;
alpar@1092
   549
        _capacity = Traits::createCapacityMap(*_graph);
thoneyvazul@916
   550
      }
thoneyvazul@916
   551
      if(!_cardinality) {
alpar@1092
   552
        local_cardinality = true;
alpar@1092
   553
        _cardinality = Traits::createCardinalityMap(*_graph);
thoneyvazul@916
   554
      }
thoneyvazul@916
   555
      if(!_processed) {
alpar@1092
   556
        local_processed = true;
alpar@1092
   557
        _processed = Traits::createProcessedMap(*_graph);
thoneyvazul@916
   558
      }
thoneyvazul@916
   559
      if (!_heap_cross_ref) {
alpar@1092
   560
        local_heap_cross_ref = true;
alpar@1092
   561
        _heap_cross_ref = Traits::createHeapCrossRef(*_graph);
thoneyvazul@916
   562
      }
thoneyvazul@916
   563
      if (!_heap) {
alpar@1092
   564
        local_heap = true;
alpar@1092
   565
        _heap = Traits::createHeap(*_heap_cross_ref);
thoneyvazul@916
   566
      }
thoneyvazul@916
   567
    }
alpar@1092
   568
thoneyvazul@916
   569
    void finalizeNodeData(Node node, Value capacity) {
thoneyvazul@916
   570
      _processed->set(node, true);
thoneyvazul@916
   571
      _cardinality->set(node, capacity);
thoneyvazul@916
   572
    }
thoneyvazul@916
   573
thoneyvazul@916
   574
  public:
thoneyvazul@916
   575
    /// \name Execution control
thoneyvazul@916
   576
    /// The simplest way to execute the algorithm is to use
thoneyvazul@916
   577
    /// one of the member functions called \ref run().
thoneyvazul@916
   578
    /// \n
thoneyvazul@916
   579
    /// If you need more control on the execution,
thoneyvazul@916
   580
    /// first you must call \ref init(), then you can add several source nodes
thoneyvazul@916
   581
    /// with \ref addSource().
thoneyvazul@916
   582
    /// Finally \ref start() will perform the computation.
thoneyvazul@916
   583
thoneyvazul@916
   584
    ///@{
thoneyvazul@916
   585
thoneyvazul@916
   586
    /// \brief Initializes the internal data structures.
thoneyvazul@916
   587
    ///
thoneyvazul@916
   588
    /// Initializes the internal data structures, and clears the heap.
thoneyvazul@916
   589
    void init() {
thoneyvazul@916
   590
      create_maps();
thoneyvazul@916
   591
      _heap->clear();
thoneyvazul@916
   592
      for (NodeIt it(*_graph) ; it != INVALID ; ++it) {
alpar@1092
   593
        _processed->set(it, false);
alpar@1092
   594
        _heap_cross_ref->set(it, Heap::PRE_HEAP);
thoneyvazul@916
   595
      }
thoneyvazul@916
   596
    }
alpar@1092
   597
thoneyvazul@916
   598
    /// \brief Adds a new source node.
alpar@1092
   599
    ///
thoneyvazul@916
   600
    /// Adds a new source node to the priority heap.
thoneyvazul@916
   601
    ///
thoneyvazul@916
   602
    /// It checks if the node has not yet been added to the heap.
thoneyvazul@916
   603
    void addSource(Node source, Value capacity = 0) {
thoneyvazul@916
   604
      if(_heap->state(source) == Heap::PRE_HEAP) {
alpar@1092
   605
        _heap->push(source, capacity);
alpar@1092
   606
      }
thoneyvazul@916
   607
    }
alpar@1092
   608
thoneyvazul@916
   609
    /// \brief Processes the next node in the priority heap
thoneyvazul@916
   610
    ///
thoneyvazul@916
   611
    /// Processes the next node in the priority heap.
thoneyvazul@916
   612
    ///
thoneyvazul@916
   613
    /// \return The processed node.
thoneyvazul@916
   614
    ///
thoneyvazul@916
   615
    /// \warning The priority heap must not be empty!
thoneyvazul@916
   616
    Node processNextNode() {
alpar@1092
   617
      Node node = _heap->top();
thoneyvazul@916
   618
      finalizeNodeData(node, _heap->prio());
thoneyvazul@916
   619
      _heap->pop();
alpar@1092
   620
thoneyvazul@916
   621
      for (InArcIt it(*_graph, node); it != INVALID; ++it) {
alpar@1092
   622
        Node source = _graph->source(it);
alpar@1092
   623
        switch (_heap->state(source)) {
alpar@1092
   624
        case Heap::PRE_HEAP:
alpar@1092
   625
          _heap->push(source, (*_capacity)[it]);
alpar@1092
   626
          break;
alpar@1092
   627
        case Heap::IN_HEAP:
alpar@1092
   628
          _heap->decrease(source, (*_heap)[source] + (*_capacity)[it]);
alpar@1092
   629
          break;
alpar@1092
   630
        case Heap::POST_HEAP:
alpar@1092
   631
          break;
alpar@1092
   632
        }
thoneyvazul@916
   633
      }
thoneyvazul@916
   634
      return node;
thoneyvazul@916
   635
    }
thoneyvazul@916
   636
thoneyvazul@916
   637
    /// \brief Next node to be processed.
thoneyvazul@916
   638
    ///
thoneyvazul@916
   639
    /// Next node to be processed.
thoneyvazul@916
   640
    ///
alpar@1092
   641
    /// \return The next node to be processed or INVALID if the
thoneyvazul@916
   642
    /// priority heap is empty.
alpar@1092
   643
    Node nextNode() {
thoneyvazul@916
   644
      return !_heap->empty() ? _heap->top() : INVALID;
thoneyvazul@916
   645
    }
alpar@1092
   646
thoneyvazul@916
   647
    /// \brief Returns \c false if there are nodes
thoneyvazul@916
   648
    /// to be processed in the priority heap
thoneyvazul@916
   649
    ///
thoneyvazul@916
   650
    /// Returns \c false if there are nodes
thoneyvazul@916
   651
    /// to be processed in the priority heap
thoneyvazul@916
   652
    bool emptyQueue() { return _heap->empty(); }
alpar@1092
   653
    /// \brief Returns the number of the nodes to be processed
thoneyvazul@916
   654
    /// in the priority heap
thoneyvazul@916
   655
    ///
thoneyvazul@916
   656
    /// Returns the number of the nodes to be processed in the priority heap
thoneyvazul@916
   657
    int emptySize() { return _heap->size(); }
alpar@1092
   658
thoneyvazul@916
   659
    /// \brief Executes the algorithm.
thoneyvazul@916
   660
    ///
thoneyvazul@916
   661
    /// Executes the algorithm.
thoneyvazul@916
   662
    ///
thoneyvazul@916
   663
    ///\pre init() must be called and at least one node should be added
thoneyvazul@916
   664
    /// with addSource() before using this function.
thoneyvazul@916
   665
    ///
alpar@1092
   666
    /// This method runs the Maximum Cardinality Search algorithm from the
thoneyvazul@916
   667
    /// source node(s).
thoneyvazul@916
   668
    void start() {
thoneyvazul@916
   669
      while ( !_heap->empty() ) processNextNode();
thoneyvazul@916
   670
    }
alpar@1092
   671
thoneyvazul@916
   672
    /// \brief Executes the algorithm until \c dest is reached.
thoneyvazul@916
   673
    ///
thoneyvazul@916
   674
    /// Executes the algorithm until \c dest is reached.
thoneyvazul@916
   675
    ///
thoneyvazul@916
   676
    /// \pre init() must be called and at least one node should be added
thoneyvazul@916
   677
    /// with addSource() before using this function.
thoneyvazul@916
   678
    ///
alpar@1092
   679
    /// This method runs the %MaxCardinalitySearch algorithm from the source
thoneyvazul@916
   680
    /// nodes.
thoneyvazul@916
   681
    void start(Node dest) {
thoneyvazul@916
   682
      while ( !_heap->empty() && _heap->top()!=dest ) processNextNode();
thoneyvazul@916
   683
      if ( !_heap->empty() ) finalizeNodeData(_heap->top(), _heap->prio());
thoneyvazul@916
   684
    }
alpar@1092
   685
thoneyvazul@916
   686
    /// \brief Executes the algorithm until a condition is met.
thoneyvazul@916
   687
    ///
thoneyvazul@916
   688
    /// Executes the algorithm until a condition is met.
thoneyvazul@916
   689
    ///
thoneyvazul@916
   690
    /// \pre init() must be called and at least one node should be added
thoneyvazul@916
   691
    /// with addSource() before using this function.
thoneyvazul@916
   692
    ///
thoneyvazul@916
   693
    /// \param nm must be a bool (or convertible) node map. The algorithm
thoneyvazul@916
   694
    /// will stop when it reaches a node \c v with <tt>nm[v]==true</tt>.
thoneyvazul@916
   695
    template <typename NodeBoolMap>
thoneyvazul@916
   696
    void start(const NodeBoolMap &nm) {
thoneyvazul@916
   697
      while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
thoneyvazul@916
   698
      if ( !_heap->empty() ) finalizeNodeData(_heap->top(),_heap->prio());
thoneyvazul@916
   699
    }
alpar@1092
   700
thoneyvazul@916
   701
    /// \brief Runs the maximum cardinality search algorithm from node \c s.
thoneyvazul@916
   702
    ///
alpar@1092
   703
    /// This method runs the %MaxCardinalitySearch algorithm from a root
thoneyvazul@916
   704
    /// node \c s.
thoneyvazul@916
   705
    ///
thoneyvazul@916
   706
    ///\note d.run(s) is just a shortcut of the following code.
thoneyvazul@916
   707
    ///\code
thoneyvazul@916
   708
    ///  d.init();
thoneyvazul@916
   709
    ///  d.addSource(s);
thoneyvazul@916
   710
    ///  d.start();
thoneyvazul@916
   711
    ///\endcode
thoneyvazul@916
   712
    void run(Node s) {
thoneyvazul@916
   713
      init();
thoneyvazul@916
   714
      addSource(s);
thoneyvazul@916
   715
      start();
thoneyvazul@916
   716
    }
thoneyvazul@916
   717
alpar@1092
   718
    /// \brief Runs the maximum cardinality search algorithm for the
thoneyvazul@916
   719
    /// whole digraph.
thoneyvazul@916
   720
    ///
alpar@1092
   721
    /// This method runs the %MaxCardinalitySearch algorithm from all
thoneyvazul@916
   722
    /// unprocessed node of the digraph.
thoneyvazul@916
   723
    ///
thoneyvazul@916
   724
    ///\note d.run(s) is just a shortcut of the following code.
thoneyvazul@916
   725
    ///\code
thoneyvazul@916
   726
    ///  d.init();
thoneyvazul@916
   727
    ///  for (NodeIt it(digraph); it != INVALID; ++it) {
thoneyvazul@916
   728
    ///    if (!d.reached(it)) {
thoneyvazul@916
   729
    ///      d.addSource(s);
thoneyvazul@916
   730
    ///      d.start();
thoneyvazul@916
   731
    ///    }
thoneyvazul@916
   732
    ///  }
thoneyvazul@916
   733
    ///\endcode
thoneyvazul@916
   734
    void run() {
thoneyvazul@916
   735
      init();
thoneyvazul@916
   736
      for (NodeIt it(*_graph); it != INVALID; ++it) {
thoneyvazul@916
   737
        if (!reached(it)) {
thoneyvazul@916
   738
          addSource(it);
thoneyvazul@916
   739
          start();
thoneyvazul@916
   740
        }
thoneyvazul@916
   741
      }
thoneyvazul@916
   742
    }
alpar@1092
   743
thoneyvazul@916
   744
    ///@}
thoneyvazul@916
   745
thoneyvazul@916
   746
    /// \name Query Functions
alpar@1092
   747
    /// The results of the maximum cardinality search algorithm can be
thoneyvazul@916
   748
    /// obtained using these functions.
thoneyvazul@916
   749
    /// \n
alpar@1092
   750
    /// Before the use of these functions, either run() or start() must be
thoneyvazul@916
   751
    /// called.
alpar@1092
   752
thoneyvazul@916
   753
    ///@{
thoneyvazul@916
   754
thoneyvazul@916
   755
    /// \brief The cardinality of a node.
thoneyvazul@916
   756
    ///
thoneyvazul@916
   757
    /// Returns the cardinality of a node.
thoneyvazul@916
   758
    /// \pre \ref run() must be called before using this function.
thoneyvazul@916
   759
    /// \warning If node \c v in unreachable from the root the return value
thoneyvazul@916
   760
    /// of this funcion is undefined.
thoneyvazul@916
   761
    Value cardinality(Node node) const { return (*_cardinality)[node]; }
thoneyvazul@916
   762
thoneyvazul@916
   763
    /// \brief The current cardinality of a node.
thoneyvazul@916
   764
    ///
thoneyvazul@916
   765
    /// Returns the current cardinality of a node.
thoneyvazul@916
   766
    /// \pre the given node should be reached but not processed
thoneyvazul@916
   767
    Value currentCardinality(Node node) const { return (*_heap)[node]; }
thoneyvazul@916
   768
thoneyvazul@916
   769
    /// \brief Returns a reference to the NodeMap of cardinalities.
thoneyvazul@916
   770
    ///
alpar@1092
   771
    /// Returns a reference to the NodeMap of cardinalities. \pre \ref run()
thoneyvazul@916
   772
    /// must be called before using this function.
thoneyvazul@916
   773
    const CardinalityMap &cardinalityMap() const { return *_cardinality;}
alpar@1092
   774
thoneyvazul@916
   775
    /// \brief Checks if a node is reachable from the root.
thoneyvazul@916
   776
    ///
thoneyvazul@916
   777
    /// Returns \c true if \c v is reachable from the root.
thoneyvazul@916
   778
    /// \warning The source nodes are initated as unreached.
thoneyvazul@916
   779
    /// \pre \ref run() must be called before using this function.
thoneyvazul@916
   780
    bool reached(Node v) { return (*_heap_cross_ref)[v] != Heap::PRE_HEAP; }
thoneyvazul@916
   781
thoneyvazul@916
   782
    /// \brief Checks if a node is processed.
thoneyvazul@916
   783
    ///
thoneyvazul@916
   784
    /// Returns \c true if \c v is processed, i.e. the shortest
thoneyvazul@916
   785
    /// path to \c v has already found.
thoneyvazul@916
   786
    /// \pre \ref run() must be called before using this function.
thoneyvazul@916
   787
    bool processed(Node v) { return (*_heap_cross_ref)[v] == Heap::POST_HEAP; }
alpar@1092
   788
thoneyvazul@916
   789
    ///@}
thoneyvazul@916
   790
  };
thoneyvazul@916
   791
thoneyvazul@916
   792
}
thoneyvazul@916
   793
thoneyvazul@916
   794
#endif