1.1 --- a/doc/groups.dox Sun Aug 02 12:40:20 2009 +0200
1.2 +++ b/doc/groups.dox Fri Sep 25 09:13:03 2009 +0200
1.3 @@ -226,14 +226,6 @@
1.4 */
1.5
1.6 /**
1.7 -@defgroup matrices Matrices
1.8 -@ingroup datas
1.9 -\brief Two dimensional data storages implemented in LEMON.
1.10 -
1.11 -This group contains two dimensional data storages implemented in LEMON.
1.12 -*/
1.13 -
1.14 -/**
1.15 @defgroup paths Path Structures
1.16 @ingroup datas
1.17 \brief %Path structures implemented in LEMON.
1.18 @@ -246,7 +238,36 @@
1.19 efficient to have e.g. the Dijkstra algorithm to store its result in
1.20 any kind of path structure.
1.21
1.22 -\sa lemon::concepts::Path
1.23 +\sa \ref concepts::Path "Path concept"
1.24 +*/
1.25 +
1.26 +/**
1.27 +@defgroup heaps Heap Structures
1.28 +@ingroup datas
1.29 +\brief %Heap structures implemented in LEMON.
1.30 +
1.31 +This group contains the heap structures implemented in LEMON.
1.32 +
1.33 +LEMON provides several heap classes. They are efficient implementations
1.34 +of the abstract data type \e priority \e queue. They store items with
1.35 +specified values called \e priorities in such a way that finding and
1.36 +removing the item with minimum priority are efficient.
1.37 +The basic operations are adding and erasing items, changing the priority
1.38 +of an item, etc.
1.39 +
1.40 +Heaps are crucial in several algorithms, such as Dijkstra and Prim.
1.41 +The heap implementations have the same interface, thus any of them can be
1.42 +used easily in such algorithms.
1.43 +
1.44 +\sa \ref concepts::Heap "Heap concept"
1.45 +*/
1.46 +
1.47 +/**
1.48 +@defgroup matrices Matrices
1.49 +@ingroup datas
1.50 +\brief Two dimensional data storages implemented in LEMON.
1.51 +
1.52 +This group contains two dimensional data storages implemented in LEMON.
1.53 */
1.54
1.55 /**
1.56 @@ -259,6 +280,28 @@
1.57 */
1.58
1.59 /**
1.60 +@defgroup geomdat Geometric Data Structures
1.61 +@ingroup auxdat
1.62 +\brief Geometric data structures implemented in LEMON.
1.63 +
1.64 +This group contains geometric data structures implemented in LEMON.
1.65 +
1.66 + - \ref lemon::dim2::Point "dim2::Point" implements a two dimensional
1.67 + vector with the usual operations.
1.68 + - \ref lemon::dim2::Box "dim2::Box" can be used to determine the
1.69 + rectangular bounding box of a set of \ref lemon::dim2::Point
1.70 + "dim2::Point"'s.
1.71 +*/
1.72 +
1.73 +/**
1.74 +@defgroup matrices Matrices
1.75 +@ingroup auxdat
1.76 +\brief Two dimensional data storages implemented in LEMON.
1.77 +
1.78 +This group contains two dimensional data storages implemented in LEMON.
1.79 +*/
1.80 +
1.81 +/**
1.82 @defgroup algs Algorithms
1.83 \brief This group contains the several algorithms
1.84 implemented in LEMON.
1.85 @@ -298,6 +341,15 @@
1.86 */
1.87
1.88 /**
1.89 +@defgroup spantree Minimum Spanning Tree Algorithms
1.90 +@ingroup algs
1.91 +\brief Algorithms for finding minimum cost spanning trees and arborescences.
1.92 +
1.93 +This group contains the algorithms for finding minimum cost spanning
1.94 +trees and arborescences.
1.95 +*/
1.96 +
1.97 +/**
1.98 @defgroup max_flow Maximum Flow Algorithms
1.99 @ingroup algs
1.100 \brief Algorithms for finding maximum flows.
1.101 @@ -375,7 +427,7 @@
1.102 cut is the \f$X\f$ solution of the next optimization problem:
1.103
1.104 \f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
1.105 - \sum_{uv\in A, u\in X, v\not\in X}cap(uv) \f]
1.106 + \sum_{uv\in A: u\in X, v\not\in X}cap(uv) \f]
1.107
1.108 LEMON contains several algorithms related to minimum cut problems:
1.109
1.110 @@ -391,30 +443,6 @@
1.111 */
1.112
1.113 /**
1.114 -@defgroup graph_properties Connectivity and Other Graph Properties
1.115 -@ingroup algs
1.116 -\brief Algorithms for discovering the graph properties
1.117 -
1.118 -This group contains the algorithms for discovering the graph properties
1.119 -like connectivity, bipartiteness, euler property, simplicity etc.
1.120 -
1.121 -\image html edge_biconnected_components.png
1.122 -\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
1.123 -*/
1.124 -
1.125 -/**
1.126 -@defgroup planar Planarity Embedding and Drawing
1.127 -@ingroup algs
1.128 -\brief Algorithms for planarity checking, embedding and drawing
1.129 -
1.130 -This group contains the algorithms for planarity checking,
1.131 -embedding and drawing.
1.132 -
1.133 -\image html planar.png
1.134 -\image latex planar.eps "Plane graph" width=\textwidth
1.135 -*/
1.136 -
1.137 -/**
1.138 @defgroup matching Matching Algorithms
1.139 @ingroup algs
1.140 \brief Algorithms for finding matchings in graphs and bipartite graphs.
1.141 @@ -455,12 +483,36 @@
1.142 */
1.143
1.144 /**
1.145 -@defgroup spantree Minimum Spanning Tree Algorithms
1.146 +@defgroup graph_properties Connectivity and Other Graph Properties
1.147 @ingroup algs
1.148 -\brief Algorithms for finding minimum cost spanning trees and arborescences.
1.149 +\brief Algorithms for discovering the graph properties
1.150
1.151 -This group contains the algorithms for finding minimum cost spanning
1.152 -trees and arborescences.
1.153 +This group contains the algorithms for discovering the graph properties
1.154 +like connectivity, bipartiteness, euler property, simplicity etc.
1.155 +
1.156 +\image html connected_components.png
1.157 +\image latex connected_components.eps "Connected components" width=\textwidth
1.158 +*/
1.159 +
1.160 +/**
1.161 +@defgroup planar Planarity Embedding and Drawing
1.162 +@ingroup algs
1.163 +\brief Algorithms for planarity checking, embedding and drawing
1.164 +
1.165 +This group contains the algorithms for planarity checking,
1.166 +embedding and drawing.
1.167 +
1.168 +\image html planar.png
1.169 +\image latex planar.eps "Plane graph" width=\textwidth
1.170 +*/
1.171 +
1.172 +/**
1.173 +@defgroup approx Approximation Algorithms
1.174 +@ingroup algs
1.175 +\brief Approximation algorithms.
1.176 +
1.177 +This group contains the approximation and heuristic algorithms
1.178 +implemented in LEMON.
1.179 */
1.180
1.181 /**
1.182 @@ -473,15 +525,6 @@
1.183 */
1.184
1.185 /**
1.186 -@defgroup approx Approximation Algorithms
1.187 -@ingroup algs
1.188 -\brief Approximation algorithms.
1.189 -
1.190 -This group contains the approximation and heuristic algorithms
1.191 -implemented in LEMON.
1.192 -*/
1.193 -
1.194 -/**
1.195 @defgroup gen_opt_group General Optimization Tools
1.196 \brief This group contains some general optimization frameworks
1.197 implemented in LEMON.
1.198 @@ -587,7 +630,7 @@
1.199 */
1.200
1.201 /**
1.202 -@defgroup dimacs_group DIMACS format
1.203 +@defgroup dimacs_group DIMACS Format
1.204 @ingroup io_group
1.205 \brief Read and write files in DIMACS format
1.206
1.207 @@ -649,6 +692,15 @@
1.208 */
1.209
1.210 /**
1.211 +@defgroup tools Standalone Utility Applications
1.212 +
1.213 +Some utility applications are listed here.
1.214 +
1.215 +The standard compilation procedure (<tt>./configure;make</tt>) will compile
1.216 +them, as well.
1.217 +*/
1.218 +
1.219 +/**
1.220 \anchor demoprograms
1.221
1.222 @defgroup demos Demo Programs
1.223 @@ -660,13 +712,4 @@
1.224 <tt>make check</tt> commands.
1.225 */
1.226
1.227 -/**
1.228 -@defgroup tools Standalone Utility Applications
1.229 -
1.230 -Some utility applications are listed here.
1.231 -
1.232 -The standard compilation procedure (<tt>./configure;make</tt>) will compile
1.233 -them, as well.
1.234 -*/
1.235 -
1.236 }
2.1 --- a/lemon/Makefile.am Sun Aug 02 12:40:20 2009 +0200
2.2 +++ b/lemon/Makefile.am Fri Sep 25 09:13:03 2009 +0200
2.3 @@ -57,8 +57,11 @@
2.4 lemon/adaptors.h \
2.5 lemon/arg_parser.h \
2.6 lemon/assert.h \
2.7 + lemon/bellman_ford.h \
2.8 lemon/bfs.h \
2.9 lemon/bin_heap.h \
2.10 + lemon/binom_heap.h \
2.11 + lemon/bucket_heap.h \
2.12 lemon/cbc.h \
2.13 lemon/circulation.h \
2.14 lemon/clp.h \
2.15 @@ -76,12 +79,15 @@
2.16 lemon/elevator.h \
2.17 lemon/error.h \
2.18 lemon/euler.h \
2.19 + lemon/fib_heap.h \
2.20 + lemon/fourary_heap.h \
2.21 lemon/full_graph.h \
2.22 lemon/glpk.h \
2.23 lemon/gomory_hu.h \
2.24 lemon/graph_to_eps.h \
2.25 lemon/grid_graph.h \
2.26 lemon/hypercube_graph.h \
2.27 + lemon/kary_heap.h \
2.28 lemon/kruskal.h \
2.29 lemon/hao_orlin.h \
2.30 lemon/lgf_reader.h \
2.31 @@ -90,15 +96,16 @@
2.32 lemon/lp.h \
2.33 lemon/lp_base.h \
2.34 lemon/lp_skeleton.h \
2.35 - lemon/list_graph.h \
2.36 lemon/maps.h \
2.37 lemon/matching.h \
2.38 lemon/math.h \
2.39 lemon/min_cost_arborescence.h \
2.40 lemon/nauty_reader.h \
2.41 lemon/network_simplex.h \
2.42 + lemon/pairing_heap.h \
2.43 lemon/path.h \
2.44 lemon/preflow.h \
2.45 + lemon/radix_heap.h \
2.46 lemon/radix_sort.h \
2.47 lemon/random.h \
2.48 lemon/smart_graph.h \
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/lemon/bellman_ford.h Fri Sep 25 09:13:03 2009 +0200
3.3 @@ -0,0 +1,1100 @@
3.4 +/* -*- C++ -*-
3.5 + *
3.6 + * This file is a part of LEMON, a generic C++ optimization library
3.7 + *
3.8 + * Copyright (C) 2003-2008
3.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
3.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
3.11 + *
3.12 + * Permission to use, modify and distribute this software is granted
3.13 + * provided that this copyright notice appears in all copies. For
3.14 + * precise terms see the accompanying LICENSE file.
3.15 + *
3.16 + * This software is provided "AS IS" with no warranty of any kind,
3.17 + * express or implied, and with no claim as to its suitability for any
3.18 + * purpose.
3.19 + *
3.20 + */
3.21 +
3.22 +#ifndef LEMON_BELLMAN_FORD_H
3.23 +#define LEMON_BELLMAN_FORD_H
3.24 +
3.25 +/// \ingroup shortest_path
3.26 +/// \file
3.27 +/// \brief Bellman-Ford algorithm.
3.28 +
3.29 +#include <lemon/bits/path_dump.h>
3.30 +#include <lemon/core.h>
3.31 +#include <lemon/error.h>
3.32 +#include <lemon/maps.h>
3.33 +#include <lemon/path.h>
3.34 +
3.35 +#include <limits>
3.36 +
3.37 +namespace lemon {
3.38 +
3.39 + /// \brief Default OperationTraits for the BellmanFord algorithm class.
3.40 + ///
3.41 + /// This operation traits class defines all computational operations
3.42 + /// and constants that are used in the Bellman-Ford algorithm.
3.43 + /// The default implementation is based on the \c numeric_limits class.
3.44 + /// If the numeric type does not have infinity value, then the maximum
3.45 + /// value is used as extremal infinity value.
3.46 + template <
3.47 + typename V,
3.48 + bool has_inf = std::numeric_limits<V>::has_infinity>
3.49 + struct BellmanFordDefaultOperationTraits {
3.50 + /// \e
3.51 + typedef V Value;
3.52 + /// \brief Gives back the zero value of the type.
3.53 + static Value zero() {
3.54 + return static_cast<Value>(0);
3.55 + }
3.56 + /// \brief Gives back the positive infinity value of the type.
3.57 + static Value infinity() {
3.58 + return std::numeric_limits<Value>::infinity();
3.59 + }
3.60 + /// \brief Gives back the sum of the given two elements.
3.61 + static Value plus(const Value& left, const Value& right) {
3.62 + return left + right;
3.63 + }
3.64 + /// \brief Gives back \c true only if the first value is less than
3.65 + /// the second.
3.66 + static bool less(const Value& left, const Value& right) {
3.67 + return left < right;
3.68 + }
3.69 + };
3.70 +
3.71 + template <typename V>
3.72 + struct BellmanFordDefaultOperationTraits<V, false> {
3.73 + typedef V Value;
3.74 + static Value zero() {
3.75 + return static_cast<Value>(0);
3.76 + }
3.77 + static Value infinity() {
3.78 + return std::numeric_limits<Value>::max();
3.79 + }
3.80 + static Value plus(const Value& left, const Value& right) {
3.81 + if (left == infinity() || right == infinity()) return infinity();
3.82 + return left + right;
3.83 + }
3.84 + static bool less(const Value& left, const Value& right) {
3.85 + return left < right;
3.86 + }
3.87 + };
3.88 +
3.89 + /// \brief Default traits class of BellmanFord class.
3.90 + ///
3.91 + /// Default traits class of BellmanFord class.
3.92 + /// \param GR The type of the digraph.
3.93 + /// \param LEN The type of the length map.
3.94 + template<typename GR, typename LEN>
3.95 + struct BellmanFordDefaultTraits {
3.96 + /// The type of the digraph the algorithm runs on.
3.97 + typedef GR Digraph;
3.98 +
3.99 + /// \brief The type of the map that stores the arc lengths.
3.100 + ///
3.101 + /// The type of the map that stores the arc lengths.
3.102 + /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
3.103 + typedef LEN LengthMap;
3.104 +
3.105 + /// The type of the arc lengths.
3.106 + typedef typename LEN::Value Value;
3.107 +
3.108 + /// \brief Operation traits for Bellman-Ford algorithm.
3.109 + ///
3.110 + /// It defines the used operations and the infinity value for the
3.111 + /// given \c Value type.
3.112 + /// \see BellmanFordDefaultOperationTraits
3.113 + typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
3.114 +
3.115 + /// \brief The type of the map that stores the last arcs of the
3.116 + /// shortest paths.
3.117 + ///
3.118 + /// The type of the map that stores the last
3.119 + /// arcs of the shortest paths.
3.120 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
3.121 + typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
3.122 +
3.123 + /// \brief Instantiates a \c PredMap.
3.124 + ///
3.125 + /// This function instantiates a \ref PredMap.
3.126 + /// \param g is the digraph to which we would like to define the
3.127 + /// \ref PredMap.
3.128 + static PredMap *createPredMap(const GR& g) {
3.129 + return new PredMap(g);
3.130 + }
3.131 +
3.132 + /// \brief The type of the map that stores the distances of the nodes.
3.133 + ///
3.134 + /// The type of the map that stores the distances of the nodes.
3.135 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
3.136 + typedef typename GR::template NodeMap<typename LEN::Value> DistMap;
3.137 +
3.138 + /// \brief Instantiates a \c DistMap.
3.139 + ///
3.140 + /// This function instantiates a \ref DistMap.
3.141 + /// \param g is the digraph to which we would like to define the
3.142 + /// \ref DistMap.
3.143 + static DistMap *createDistMap(const GR& g) {
3.144 + return new DistMap(g);
3.145 + }
3.146 +
3.147 + };
3.148 +
3.149 + /// \brief %BellmanFord algorithm class.
3.150 + ///
3.151 + /// \ingroup shortest_path
3.152 + /// This class provides an efficient implementation of the Bellman-Ford
3.153 + /// algorithm. The maximum time complexity of the algorithm is
3.154 + /// <tt>O(ne)</tt>.
3.155 + ///
3.156 + /// The Bellman-Ford algorithm solves the single-source shortest path
3.157 + /// problem when the arcs can have negative lengths, but the digraph
3.158 + /// should not contain directed cycles with negative total length.
3.159 + /// If all arc costs are non-negative, consider to use the Dijkstra
3.160 + /// algorithm instead, since it is more efficient.
3.161 + ///
3.162 + /// The arc lengths are passed to the algorithm using a
3.163 + /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
3.164 + /// kind of length. The type of the length values is determined by the
3.165 + /// \ref concepts::ReadMap::Value "Value" type of the length map.
3.166 + ///
3.167 + /// There is also a \ref bellmanFord() "function-type interface" for the
3.168 + /// Bellman-Ford algorithm, which is convenient in the simplier cases and
3.169 + /// it can be used easier.
3.170 + ///
3.171 + /// \tparam GR The type of the digraph the algorithm runs on.
3.172 + /// The default type is \ref ListDigraph.
3.173 + /// \tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
3.174 + /// the lengths of the arcs. The default map type is
3.175 + /// \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
3.176 +#ifdef DOXYGEN
3.177 + template <typename GR, typename LEN, typename TR>
3.178 +#else
3.179 + template <typename GR=ListDigraph,
3.180 + typename LEN=typename GR::template ArcMap<int>,
3.181 + typename TR=BellmanFordDefaultTraits<GR,LEN> >
3.182 +#endif
3.183 + class BellmanFord {
3.184 + public:
3.185 +
3.186 + ///The type of the underlying digraph.
3.187 + typedef typename TR::Digraph Digraph;
3.188 +
3.189 + /// \brief The type of the arc lengths.
3.190 + typedef typename TR::LengthMap::Value Value;
3.191 + /// \brief The type of the map that stores the arc lengths.
3.192 + typedef typename TR::LengthMap LengthMap;
3.193 + /// \brief The type of the map that stores the last
3.194 + /// arcs of the shortest paths.
3.195 + typedef typename TR::PredMap PredMap;
3.196 + /// \brief The type of the map that stores the distances of the nodes.
3.197 + typedef typename TR::DistMap DistMap;
3.198 + /// The type of the paths.
3.199 + typedef PredMapPath<Digraph, PredMap> Path;
3.200 + ///\brief The \ref BellmanFordDefaultOperationTraits
3.201 + /// "operation traits class" of the algorithm.
3.202 + typedef typename TR::OperationTraits OperationTraits;
3.203 +
3.204 + ///The \ref BellmanFordDefaultTraits "traits class" of the algorithm.
3.205 + typedef TR Traits;
3.206 +
3.207 + private:
3.208 +
3.209 + typedef typename Digraph::Node Node;
3.210 + typedef typename Digraph::NodeIt NodeIt;
3.211 + typedef typename Digraph::Arc Arc;
3.212 + typedef typename Digraph::OutArcIt OutArcIt;
3.213 +
3.214 + // Pointer to the underlying digraph.
3.215 + const Digraph *_gr;
3.216 + // Pointer to the length map
3.217 + const LengthMap *_length;
3.218 + // Pointer to the map of predecessors arcs.
3.219 + PredMap *_pred;
3.220 + // Indicates if _pred is locally allocated (true) or not.
3.221 + bool _local_pred;
3.222 + // Pointer to the map of distances.
3.223 + DistMap *_dist;
3.224 + // Indicates if _dist is locally allocated (true) or not.
3.225 + bool _local_dist;
3.226 +
3.227 + typedef typename Digraph::template NodeMap<bool> MaskMap;
3.228 + MaskMap *_mask;
3.229 +
3.230 + std::vector<Node> _process;
3.231 +
3.232 + // Creates the maps if necessary.
3.233 + void create_maps() {
3.234 + if(!_pred) {
3.235 + _local_pred = true;
3.236 + _pred = Traits::createPredMap(*_gr);
3.237 + }
3.238 + if(!_dist) {
3.239 + _local_dist = true;
3.240 + _dist = Traits::createDistMap(*_gr);
3.241 + }
3.242 + _mask = new MaskMap(*_gr, false);
3.243 + }
3.244 +
3.245 + public :
3.246 +
3.247 + typedef BellmanFord Create;
3.248 +
3.249 + /// \name Named Template Parameters
3.250 +
3.251 + ///@{
3.252 +
3.253 + template <class T>
3.254 + struct SetPredMapTraits : public Traits {
3.255 + typedef T PredMap;
3.256 + static PredMap *createPredMap(const Digraph&) {
3.257 + LEMON_ASSERT(false, "PredMap is not initialized");
3.258 + return 0; // ignore warnings
3.259 + }
3.260 + };
3.261 +
3.262 + /// \brief \ref named-templ-param "Named parameter" for setting
3.263 + /// \c PredMap type.
3.264 + ///
3.265 + /// \ref named-templ-param "Named parameter" for setting
3.266 + /// \c PredMap type.
3.267 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
3.268 + template <class T>
3.269 + struct SetPredMap
3.270 + : public BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > {
3.271 + typedef BellmanFord< Digraph, LengthMap, SetPredMapTraits<T> > Create;
3.272 + };
3.273 +
3.274 + template <class T>
3.275 + struct SetDistMapTraits : public Traits {
3.276 + typedef T DistMap;
3.277 + static DistMap *createDistMap(const Digraph&) {
3.278 + LEMON_ASSERT(false, "DistMap is not initialized");
3.279 + return 0; // ignore warnings
3.280 + }
3.281 + };
3.282 +
3.283 + /// \brief \ref named-templ-param "Named parameter" for setting
3.284 + /// \c DistMap type.
3.285 + ///
3.286 + /// \ref named-templ-param "Named parameter" for setting
3.287 + /// \c DistMap type.
3.288 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
3.289 + template <class T>
3.290 + struct SetDistMap
3.291 + : public BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > {
3.292 + typedef BellmanFord< Digraph, LengthMap, SetDistMapTraits<T> > Create;
3.293 + };
3.294 +
3.295 + template <class T>
3.296 + struct SetOperationTraitsTraits : public Traits {
3.297 + typedef T OperationTraits;
3.298 + };
3.299 +
3.300 + /// \brief \ref named-templ-param "Named parameter" for setting
3.301 + /// \c OperationTraits type.
3.302 + ///
3.303 + /// \ref named-templ-param "Named parameter" for setting
3.304 + /// \c OperationTraits type.
3.305 + /// For more information see \ref BellmanFordDefaultOperationTraits.
3.306 + template <class T>
3.307 + struct SetOperationTraits
3.308 + : public BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> > {
3.309 + typedef BellmanFord< Digraph, LengthMap, SetOperationTraitsTraits<T> >
3.310 + Create;
3.311 + };
3.312 +
3.313 + ///@}
3.314 +
3.315 + protected:
3.316 +
3.317 + BellmanFord() {}
3.318 +
3.319 + public:
3.320 +
3.321 + /// \brief Constructor.
3.322 + ///
3.323 + /// Constructor.
3.324 + /// \param g The digraph the algorithm runs on.
3.325 + /// \param length The length map used by the algorithm.
3.326 + BellmanFord(const Digraph& g, const LengthMap& length) :
3.327 + _gr(&g), _length(&length),
3.328 + _pred(0), _local_pred(false),
3.329 + _dist(0), _local_dist(false), _mask(0) {}
3.330 +
3.331 + ///Destructor.
3.332 + ~BellmanFord() {
3.333 + if(_local_pred) delete _pred;
3.334 + if(_local_dist) delete _dist;
3.335 + if(_mask) delete _mask;
3.336 + }
3.337 +
3.338 + /// \brief Sets the length map.
3.339 + ///
3.340 + /// Sets the length map.
3.341 + /// \return <tt>(*this)</tt>
3.342 + BellmanFord &lengthMap(const LengthMap &map) {
3.343 + _length = ↦
3.344 + return *this;
3.345 + }
3.346 +
3.347 + /// \brief Sets the map that stores the predecessor arcs.
3.348 + ///
3.349 + /// Sets the map that stores the predecessor arcs.
3.350 + /// If you don't use this function before calling \ref run()
3.351 + /// or \ref init(), an instance will be allocated automatically.
3.352 + /// The destructor deallocates this automatically allocated map,
3.353 + /// of course.
3.354 + /// \return <tt>(*this)</tt>
3.355 + BellmanFord &predMap(PredMap &map) {
3.356 + if(_local_pred) {
3.357 + delete _pred;
3.358 + _local_pred=false;
3.359 + }
3.360 + _pred = ↦
3.361 + return *this;
3.362 + }
3.363 +
3.364 + /// \brief Sets the map that stores the distances of the nodes.
3.365 + ///
3.366 + /// Sets the map that stores the distances of the nodes calculated
3.367 + /// by the algorithm.
3.368 + /// If you don't use this function before calling \ref run()
3.369 + /// or \ref init(), an instance will be allocated automatically.
3.370 + /// The destructor deallocates this automatically allocated map,
3.371 + /// of course.
3.372 + /// \return <tt>(*this)</tt>
3.373 + BellmanFord &distMap(DistMap &map) {
3.374 + if(_local_dist) {
3.375 + delete _dist;
3.376 + _local_dist=false;
3.377 + }
3.378 + _dist = ↦
3.379 + return *this;
3.380 + }
3.381 +
3.382 + /// \name Execution Control
3.383 + /// The simplest way to execute the Bellman-Ford algorithm is to use
3.384 + /// one of the member functions called \ref run().\n
3.385 + /// If you need better control on the execution, you have to call
3.386 + /// \ref init() first, then you can add several source nodes
3.387 + /// with \ref addSource(). Finally the actual path computation can be
3.388 + /// performed with \ref start(), \ref checkedStart() or
3.389 + /// \ref limitedStart().
3.390 +
3.391 + ///@{
3.392 +
3.393 + /// \brief Initializes the internal data structures.
3.394 + ///
3.395 + /// Initializes the internal data structures. The optional parameter
3.396 + /// is the initial distance of each node.
3.397 + void init(const Value value = OperationTraits::infinity()) {
3.398 + create_maps();
3.399 + for (NodeIt it(*_gr); it != INVALID; ++it) {
3.400 + _pred->set(it, INVALID);
3.401 + _dist->set(it, value);
3.402 + }
3.403 + _process.clear();
3.404 + if (OperationTraits::less(value, OperationTraits::infinity())) {
3.405 + for (NodeIt it(*_gr); it != INVALID; ++it) {
3.406 + _process.push_back(it);
3.407 + _mask->set(it, true);
3.408 + }
3.409 + }
3.410 + }
3.411 +
3.412 + /// \brief Adds a new source node.
3.413 + ///
3.414 + /// This function adds a new source node. The optional second parameter
3.415 + /// is the initial distance of the node.
3.416 + void addSource(Node source, Value dst = OperationTraits::zero()) {
3.417 + _dist->set(source, dst);
3.418 + if (!(*_mask)[source]) {
3.419 + _process.push_back(source);
3.420 + _mask->set(source, true);
3.421 + }
3.422 + }
3.423 +
3.424 + /// \brief Executes one round from the Bellman-Ford algorithm.
3.425 + ///
3.426 + /// If the algoritm calculated the distances in the previous round
3.427 + /// exactly for the paths of at most \c k arcs, then this function
3.428 + /// will calculate the distances exactly for the paths of at most
3.429 + /// <tt>k+1</tt> arcs. Performing \c k iterations using this function
3.430 + /// calculates the shortest path distances exactly for the paths
3.431 + /// consisting of at most \c k arcs.
3.432 + ///
3.433 + /// \warning The paths with limited arc number cannot be retrieved
3.434 + /// easily with \ref path() or \ref predArc() functions. If you also
3.435 + /// need the shortest paths and not only the distances, you should
3.436 + /// store the \ref predMap() "predecessor map" after each iteration
3.437 + /// and build the path manually.
3.438 + ///
3.439 + /// \return \c true when the algorithm have not found more shorter
3.440 + /// paths.
3.441 + ///
3.442 + /// \see ActiveIt
3.443 + bool processNextRound() {
3.444 + for (int i = 0; i < int(_process.size()); ++i) {
3.445 + _mask->set(_process[i], false);
3.446 + }
3.447 + std::vector<Node> nextProcess;
3.448 + std::vector<Value> values(_process.size());
3.449 + for (int i = 0; i < int(_process.size()); ++i) {
3.450 + values[i] = (*_dist)[_process[i]];
3.451 + }
3.452 + for (int i = 0; i < int(_process.size()); ++i) {
3.453 + for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
3.454 + Node target = _gr->target(it);
3.455 + Value relaxed = OperationTraits::plus(values[i], (*_length)[it]);
3.456 + if (OperationTraits::less(relaxed, (*_dist)[target])) {
3.457 + _pred->set(target, it);
3.458 + _dist->set(target, relaxed);
3.459 + if (!(*_mask)[target]) {
3.460 + _mask->set(target, true);
3.461 + nextProcess.push_back(target);
3.462 + }
3.463 + }
3.464 + }
3.465 + }
3.466 + _process.swap(nextProcess);
3.467 + return _process.empty();
3.468 + }
3.469 +
3.470 + /// \brief Executes one weak round from the Bellman-Ford algorithm.
3.471 + ///
3.472 + /// If the algorithm calculated the distances in the previous round
3.473 + /// at least for the paths of at most \c k arcs, then this function
3.474 + /// will calculate the distances at least for the paths of at most
3.475 + /// <tt>k+1</tt> arcs.
3.476 + /// This function does not make it possible to calculate the shortest
3.477 + /// path distances exactly for paths consisting of at most \c k arcs,
3.478 + /// this is why it is called weak round.
3.479 + ///
3.480 + /// \return \c true when the algorithm have not found more shorter
3.481 + /// paths.
3.482 + ///
3.483 + /// \see ActiveIt
3.484 + bool processNextWeakRound() {
3.485 + for (int i = 0; i < int(_process.size()); ++i) {
3.486 + _mask->set(_process[i], false);
3.487 + }
3.488 + std::vector<Node> nextProcess;
3.489 + for (int i = 0; i < int(_process.size()); ++i) {
3.490 + for (OutArcIt it(*_gr, _process[i]); it != INVALID; ++it) {
3.491 + Node target = _gr->target(it);
3.492 + Value relaxed =
3.493 + OperationTraits::plus((*_dist)[_process[i]], (*_length)[it]);
3.494 + if (OperationTraits::less(relaxed, (*_dist)[target])) {
3.495 + _pred->set(target, it);
3.496 + _dist->set(target, relaxed);
3.497 + if (!(*_mask)[target]) {
3.498 + _mask->set(target, true);
3.499 + nextProcess.push_back(target);
3.500 + }
3.501 + }
3.502 + }
3.503 + }
3.504 + _process.swap(nextProcess);
3.505 + return _process.empty();
3.506 + }
3.507 +
3.508 + /// \brief Executes the algorithm.
3.509 + ///
3.510 + /// Executes the algorithm.
3.511 + ///
3.512 + /// This method runs the Bellman-Ford algorithm from the root node(s)
3.513 + /// in order to compute the shortest path to each node.
3.514 + ///
3.515 + /// The algorithm computes
3.516 + /// - the shortest path tree (forest),
3.517 + /// - the distance of each node from the root(s).
3.518 + ///
3.519 + /// \pre init() must be called and at least one root node should be
3.520 + /// added with addSource() before using this function.
3.521 + void start() {
3.522 + int num = countNodes(*_gr) - 1;
3.523 + for (int i = 0; i < num; ++i) {
3.524 + if (processNextWeakRound()) break;
3.525 + }
3.526 + }
3.527 +
3.528 + /// \brief Executes the algorithm and checks the negative cycles.
3.529 + ///
3.530 + /// Executes the algorithm and checks the negative cycles.
3.531 + ///
3.532 + /// This method runs the Bellman-Ford algorithm from the root node(s)
3.533 + /// in order to compute the shortest path to each node and also checks
3.534 + /// if the digraph contains cycles with negative total length.
3.535 + ///
3.536 + /// The algorithm computes
3.537 + /// - the shortest path tree (forest),
3.538 + /// - the distance of each node from the root(s).
3.539 + ///
3.540 + /// \return \c false if there is a negative cycle in the digraph.
3.541 + ///
3.542 + /// \pre init() must be called and at least one root node should be
3.543 + /// added with addSource() before using this function.
3.544 + bool checkedStart() {
3.545 + int num = countNodes(*_gr);
3.546 + for (int i = 0; i < num; ++i) {
3.547 + if (processNextWeakRound()) return true;
3.548 + }
3.549 + return _process.empty();
3.550 + }
3.551 +
3.552 + /// \brief Executes the algorithm with arc number limit.
3.553 + ///
3.554 + /// Executes the algorithm with arc number limit.
3.555 + ///
3.556 + /// This method runs the Bellman-Ford algorithm from the root node(s)
3.557 + /// in order to compute the shortest path distance for each node
3.558 + /// using only the paths consisting of at most \c num arcs.
3.559 + ///
3.560 + /// The algorithm computes
3.561 + /// - the limited distance of each node from the root(s),
3.562 + /// - the predecessor arc for each node.
3.563 + ///
3.564 + /// \warning The paths with limited arc number cannot be retrieved
3.565 + /// easily with \ref path() or \ref predArc() functions. If you also
3.566 + /// need the shortest paths and not only the distances, you should
3.567 + /// store the \ref predMap() "predecessor map" after each iteration
3.568 + /// and build the path manually.
3.569 + ///
3.570 + /// \pre init() must be called and at least one root node should be
3.571 + /// added with addSource() before using this function.
3.572 + void limitedStart(int num) {
3.573 + for (int i = 0; i < num; ++i) {
3.574 + if (processNextRound()) break;
3.575 + }
3.576 + }
3.577 +
3.578 + /// \brief Runs the algorithm from the given root node.
3.579 + ///
3.580 + /// This method runs the Bellman-Ford algorithm from the given root
3.581 + /// node \c s in order to compute the shortest path to each node.
3.582 + ///
3.583 + /// The algorithm computes
3.584 + /// - the shortest path tree (forest),
3.585 + /// - the distance of each node from the root(s).
3.586 + ///
3.587 + /// \note bf.run(s) is just a shortcut of the following code.
3.588 + /// \code
3.589 + /// bf.init();
3.590 + /// bf.addSource(s);
3.591 + /// bf.start();
3.592 + /// \endcode
3.593 + void run(Node s) {
3.594 + init();
3.595 + addSource(s);
3.596 + start();
3.597 + }
3.598 +
3.599 + /// \brief Runs the algorithm from the given root node with arc
3.600 + /// number limit.
3.601 + ///
3.602 + /// This method runs the Bellman-Ford algorithm from the given root
3.603 + /// node \c s in order to compute the shortest path distance for each
3.604 + /// node using only the paths consisting of at most \c num arcs.
3.605 + ///
3.606 + /// The algorithm computes
3.607 + /// - the limited distance of each node from the root(s),
3.608 + /// - the predecessor arc for each node.
3.609 + ///
3.610 + /// \warning The paths with limited arc number cannot be retrieved
3.611 + /// easily with \ref path() or \ref predArc() functions. If you also
3.612 + /// need the shortest paths and not only the distances, you should
3.613 + /// store the \ref predMap() "predecessor map" after each iteration
3.614 + /// and build the path manually.
3.615 + ///
3.616 + /// \note bf.run(s, num) is just a shortcut of the following code.
3.617 + /// \code
3.618 + /// bf.init();
3.619 + /// bf.addSource(s);
3.620 + /// bf.limitedStart(num);
3.621 + /// \endcode
3.622 + void run(Node s, int num) {
3.623 + init();
3.624 + addSource(s);
3.625 + limitedStart(num);
3.626 + }
3.627 +
3.628 + ///@}
3.629 +
3.630 + /// \brief LEMON iterator for getting the active nodes.
3.631 + ///
3.632 + /// This class provides a common style LEMON iterator that traverses
3.633 + /// the active nodes of the Bellman-Ford algorithm after the last
3.634 + /// phase. These nodes should be checked in the next phase to
3.635 + /// find augmenting arcs outgoing from them.
3.636 + class ActiveIt {
3.637 + public:
3.638 +
3.639 + /// \brief Constructor.
3.640 + ///
3.641 + /// Constructor for getting the active nodes of the given BellmanFord
3.642 + /// instance.
3.643 + ActiveIt(const BellmanFord& algorithm) : _algorithm(&algorithm)
3.644 + {
3.645 + _index = _algorithm->_process.size() - 1;
3.646 + }
3.647 +
3.648 + /// \brief Invalid constructor.
3.649 + ///
3.650 + /// Invalid constructor.
3.651 + ActiveIt(Invalid) : _algorithm(0), _index(-1) {}
3.652 +
3.653 + /// \brief Conversion to \c Node.
3.654 + ///
3.655 + /// Conversion to \c Node.
3.656 + operator Node() const {
3.657 + return _index >= 0 ? _algorithm->_process[_index] : INVALID;
3.658 + }
3.659 +
3.660 + /// \brief Increment operator.
3.661 + ///
3.662 + /// Increment operator.
3.663 + ActiveIt& operator++() {
3.664 + --_index;
3.665 + return *this;
3.666 + }
3.667 +
3.668 + bool operator==(const ActiveIt& it) const {
3.669 + return static_cast<Node>(*this) == static_cast<Node>(it);
3.670 + }
3.671 + bool operator!=(const ActiveIt& it) const {
3.672 + return static_cast<Node>(*this) != static_cast<Node>(it);
3.673 + }
3.674 + bool operator<(const ActiveIt& it) const {
3.675 + return static_cast<Node>(*this) < static_cast<Node>(it);
3.676 + }
3.677 +
3.678 + private:
3.679 + const BellmanFord* _algorithm;
3.680 + int _index;
3.681 + };
3.682 +
3.683 + /// \name Query Functions
3.684 + /// The result of the Bellman-Ford algorithm can be obtained using these
3.685 + /// functions.\n
3.686 + /// Either \ref run() or \ref init() should be called before using them.
3.687 +
3.688 + ///@{
3.689 +
3.690 + /// \brief The shortest path to the given node.
3.691 + ///
3.692 + /// Gives back the shortest path to the given node from the root(s).
3.693 + ///
3.694 + /// \warning \c t should be reached from the root(s).
3.695 + ///
3.696 + /// \pre Either \ref run() or \ref init() must be called before
3.697 + /// using this function.
3.698 + Path path(Node t) const
3.699 + {
3.700 + return Path(*_gr, *_pred, t);
3.701 + }
3.702 +
3.703 + /// \brief The distance of the given node from the root(s).
3.704 + ///
3.705 + /// Returns the distance of the given node from the root(s).
3.706 + ///
3.707 + /// \warning If node \c v is not reached from the root(s), then
3.708 + /// the return value of this function is undefined.
3.709 + ///
3.710 + /// \pre Either \ref run() or \ref init() must be called before
3.711 + /// using this function.
3.712 + Value dist(Node v) const { return (*_dist)[v]; }
3.713 +
3.714 + /// \brief Returns the 'previous arc' of the shortest path tree for
3.715 + /// the given node.
3.716 + ///
3.717 + /// This function returns the 'previous arc' of the shortest path
3.718 + /// tree for node \c v, i.e. it returns the last arc of a
3.719 + /// shortest path from a root to \c v. It is \c INVALID if \c v
3.720 + /// is not reached from the root(s) or if \c v is a root.
3.721 + ///
3.722 + /// The shortest path tree used here is equal to the shortest path
3.723 + /// tree used in \ref predNode() and \predMap().
3.724 + ///
3.725 + /// \pre Either \ref run() or \ref init() must be called before
3.726 + /// using this function.
3.727 + Arc predArc(Node v) const { return (*_pred)[v]; }
3.728 +
3.729 + /// \brief Returns the 'previous node' of the shortest path tree for
3.730 + /// the given node.
3.731 + ///
3.732 + /// This function returns the 'previous node' of the shortest path
3.733 + /// tree for node \c v, i.e. it returns the last but one node of
3.734 + /// a shortest path from a root to \c v. It is \c INVALID if \c v
3.735 + /// is not reached from the root(s) or if \c v is a root.
3.736 + ///
3.737 + /// The shortest path tree used here is equal to the shortest path
3.738 + /// tree used in \ref predArc() and \predMap().
3.739 + ///
3.740 + /// \pre Either \ref run() or \ref init() must be called before
3.741 + /// using this function.
3.742 + Node predNode(Node v) const {
3.743 + return (*_pred)[v] == INVALID ? INVALID : _gr->source((*_pred)[v]);
3.744 + }
3.745 +
3.746 + /// \brief Returns a const reference to the node map that stores the
3.747 + /// distances of the nodes.
3.748 + ///
3.749 + /// Returns a const reference to the node map that stores the distances
3.750 + /// of the nodes calculated by the algorithm.
3.751 + ///
3.752 + /// \pre Either \ref run() or \ref init() must be called before
3.753 + /// using this function.
3.754 + const DistMap &distMap() const { return *_dist;}
3.755 +
3.756 + /// \brief Returns a const reference to the node map that stores the
3.757 + /// predecessor arcs.
3.758 + ///
3.759 + /// Returns a const reference to the node map that stores the predecessor
3.760 + /// arcs, which form the shortest path tree (forest).
3.761 + ///
3.762 + /// \pre Either \ref run() or \ref init() must be called before
3.763 + /// using this function.
3.764 + const PredMap &predMap() const { return *_pred; }
3.765 +
3.766 + /// \brief Checks if a node is reached from the root(s).
3.767 + ///
3.768 + /// Returns \c true if \c v is reached from the root(s).
3.769 + ///
3.770 + /// \pre Either \ref run() or \ref init() must be called before
3.771 + /// using this function.
3.772 + bool reached(Node v) const {
3.773 + return (*_dist)[v] != OperationTraits::infinity();
3.774 + }
3.775 +
3.776 + /// \brief Gives back a negative cycle.
3.777 + ///
3.778 + /// This function gives back a directed cycle with negative total
3.779 + /// length if the algorithm has already found one.
3.780 + /// Otherwise it gives back an empty path.
3.781 + lemon::Path<Digraph> negativeCycle() {
3.782 + typename Digraph::template NodeMap<int> state(*_gr, -1);
3.783 + lemon::Path<Digraph> cycle;
3.784 + for (int i = 0; i < int(_process.size()); ++i) {
3.785 + if (state[_process[i]] != -1) continue;
3.786 + for (Node v = _process[i]; (*_pred)[v] != INVALID;
3.787 + v = _gr->source((*_pred)[v])) {
3.788 + if (state[v] == i) {
3.789 + cycle.addFront((*_pred)[v]);
3.790 + for (Node u = _gr->source((*_pred)[v]); u != v;
3.791 + u = _gr->source((*_pred)[u])) {
3.792 + cycle.addFront((*_pred)[u]);
3.793 + }
3.794 + return cycle;
3.795 + }
3.796 + else if (state[v] >= 0) {
3.797 + break;
3.798 + }
3.799 + state[v] = i;
3.800 + }
3.801 + }
3.802 + return cycle;
3.803 + }
3.804 +
3.805 + ///@}
3.806 + };
3.807 +
3.808 + /// \brief Default traits class of bellmanFord() function.
3.809 + ///
3.810 + /// Default traits class of bellmanFord() function.
3.811 + /// \tparam GR The type of the digraph.
3.812 + /// \tparam LEN The type of the length map.
3.813 + template <typename GR, typename LEN>
3.814 + struct BellmanFordWizardDefaultTraits {
3.815 + /// The type of the digraph the algorithm runs on.
3.816 + typedef GR Digraph;
3.817 +
3.818 + /// \brief The type of the map that stores the arc lengths.
3.819 + ///
3.820 + /// The type of the map that stores the arc lengths.
3.821 + /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
3.822 + typedef LEN LengthMap;
3.823 +
3.824 + /// The type of the arc lengths.
3.825 + typedef typename LEN::Value Value;
3.826 +
3.827 + /// \brief Operation traits for Bellman-Ford algorithm.
3.828 + ///
3.829 + /// It defines the used operations and the infinity value for the
3.830 + /// given \c Value type.
3.831 + /// \see BellmanFordDefaultOperationTraits
3.832 + typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
3.833 +
3.834 + /// \brief The type of the map that stores the last
3.835 + /// arcs of the shortest paths.
3.836 + ///
3.837 + /// The type of the map that stores the last arcs of the shortest paths.
3.838 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
3.839 + typedef typename GR::template NodeMap<typename GR::Arc> PredMap;
3.840 +
3.841 + /// \brief Instantiates a \c PredMap.
3.842 + ///
3.843 + /// This function instantiates a \ref PredMap.
3.844 + /// \param g is the digraph to which we would like to define the
3.845 + /// \ref PredMap.
3.846 + static PredMap *createPredMap(const GR &g) {
3.847 + return new PredMap(g);
3.848 + }
3.849 +
3.850 + /// \brief The type of the map that stores the distances of the nodes.
3.851 + ///
3.852 + /// The type of the map that stores the distances of the nodes.
3.853 + /// It must conform to the \ref concepts::WriteMap "WriteMap" concept.
3.854 + typedef typename GR::template NodeMap<Value> DistMap;
3.855 +
3.856 + /// \brief Instantiates a \c DistMap.
3.857 + ///
3.858 + /// This function instantiates a \ref DistMap.
3.859 + /// \param g is the digraph to which we would like to define the
3.860 + /// \ref DistMap.
3.861 + static DistMap *createDistMap(const GR &g) {
3.862 + return new DistMap(g);
3.863 + }
3.864 +
3.865 + ///The type of the shortest paths.
3.866 +
3.867 + ///The type of the shortest paths.
3.868 + ///It must meet the \ref concepts::Path "Path" concept.
3.869 + typedef lemon::Path<Digraph> Path;
3.870 + };
3.871 +
3.872 + /// \brief Default traits class used by BellmanFordWizard.
3.873 + ///
3.874 + /// Default traits class used by BellmanFordWizard.
3.875 + /// \tparam GR The type of the digraph.
3.876 + /// \tparam LEN The type of the length map.
3.877 + template <typename GR, typename LEN>
3.878 + class BellmanFordWizardBase
3.879 + : public BellmanFordWizardDefaultTraits<GR, LEN> {
3.880 +
3.881 + typedef BellmanFordWizardDefaultTraits<GR, LEN> Base;
3.882 + protected:
3.883 + // Type of the nodes in the digraph.
3.884 + typedef typename Base::Digraph::Node Node;
3.885 +
3.886 + // Pointer to the underlying digraph.
3.887 + void *_graph;
3.888 + // Pointer to the length map
3.889 + void *_length;
3.890 + // Pointer to the map of predecessors arcs.
3.891 + void *_pred;
3.892 + // Pointer to the map of distances.
3.893 + void *_dist;
3.894 + //Pointer to the shortest path to the target node.
3.895 + void *_path;
3.896 + //Pointer to the distance of the target node.
3.897 + void *_di;
3.898 +
3.899 + public:
3.900 + /// Constructor.
3.901 +
3.902 + /// This constructor does not require parameters, it initiates
3.903 + /// all of the attributes to default values \c 0.
3.904 + BellmanFordWizardBase() :
3.905 + _graph(0), _length(0), _pred(0), _dist(0), _path(0), _di(0) {}
3.906 +
3.907 + /// Constructor.
3.908 +
3.909 + /// This constructor requires two parameters,
3.910 + /// others are initiated to \c 0.
3.911 + /// \param gr The digraph the algorithm runs on.
3.912 + /// \param len The length map.
3.913 + BellmanFordWizardBase(const GR& gr,
3.914 + const LEN& len) :
3.915 + _graph(reinterpret_cast<void*>(const_cast<GR*>(&gr))),
3.916 + _length(reinterpret_cast<void*>(const_cast<LEN*>(&len))),
3.917 + _pred(0), _dist(0), _path(0), _di(0) {}
3.918 +
3.919 + };
3.920 +
3.921 + /// \brief Auxiliary class for the function-type interface of the
3.922 + /// \ref BellmanFord "Bellman-Ford" algorithm.
3.923 + ///
3.924 + /// This auxiliary class is created to implement the
3.925 + /// \ref bellmanFord() "function-type interface" of the
3.926 + /// \ref BellmanFord "Bellman-Ford" algorithm.
3.927 + /// It does not have own \ref run() method, it uses the
3.928 + /// functions and features of the plain \ref BellmanFord.
3.929 + ///
3.930 + /// This class should only be used through the \ref bellmanFord()
3.931 + /// function, which makes it easier to use the algorithm.
3.932 + template<class TR>
3.933 + class BellmanFordWizard : public TR {
3.934 + typedef TR Base;
3.935 +
3.936 + typedef typename TR::Digraph Digraph;
3.937 +
3.938 + typedef typename Digraph::Node Node;
3.939 + typedef typename Digraph::NodeIt NodeIt;
3.940 + typedef typename Digraph::Arc Arc;
3.941 + typedef typename Digraph::OutArcIt ArcIt;
3.942 +
3.943 + typedef typename TR::LengthMap LengthMap;
3.944 + typedef typename LengthMap::Value Value;
3.945 + typedef typename TR::PredMap PredMap;
3.946 + typedef typename TR::DistMap DistMap;
3.947 + typedef typename TR::Path Path;
3.948 +
3.949 + public:
3.950 + /// Constructor.
3.951 + BellmanFordWizard() : TR() {}
3.952 +
3.953 + /// \brief Constructor that requires parameters.
3.954 + ///
3.955 + /// Constructor that requires parameters.
3.956 + /// These parameters will be the default values for the traits class.
3.957 + /// \param gr The digraph the algorithm runs on.
3.958 + /// \param len The length map.
3.959 + BellmanFordWizard(const Digraph& gr, const LengthMap& len)
3.960 + : TR(gr, len) {}
3.961 +
3.962 + /// \brief Copy constructor
3.963 + BellmanFordWizard(const TR &b) : TR(b) {}
3.964 +
3.965 + ~BellmanFordWizard() {}
3.966 +
3.967 + /// \brief Runs the Bellman-Ford algorithm from the given source node.
3.968 + ///
3.969 + /// This method runs the Bellman-Ford algorithm from the given source
3.970 + /// node in order to compute the shortest path to each node.
3.971 + void run(Node s) {
3.972 + BellmanFord<Digraph,LengthMap,TR>
3.973 + bf(*reinterpret_cast<const Digraph*>(Base::_graph),
3.974 + *reinterpret_cast<const LengthMap*>(Base::_length));
3.975 + if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
3.976 + if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
3.977 + bf.run(s);
3.978 + }
3.979 +
3.980 + /// \brief Runs the Bellman-Ford algorithm to find the shortest path
3.981 + /// between \c s and \c t.
3.982 + ///
3.983 + /// This method runs the Bellman-Ford algorithm from node \c s
3.984 + /// in order to compute the shortest path to node \c t.
3.985 + /// Actually, it computes the shortest path to each node, but using
3.986 + /// this function you can retrieve the distance and the shortest path
3.987 + /// for a single target node easier.
3.988 + ///
3.989 + /// \return \c true if \c t is reachable form \c s.
3.990 + bool run(Node s, Node t) {
3.991 + BellmanFord<Digraph,LengthMap,TR>
3.992 + bf(*reinterpret_cast<const Digraph*>(Base::_graph),
3.993 + *reinterpret_cast<const LengthMap*>(Base::_length));
3.994 + if (Base::_pred) bf.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
3.995 + if (Base::_dist) bf.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
3.996 + bf.run(s);
3.997 + if (Base::_path) *reinterpret_cast<Path*>(Base::_path) = bf.path(t);
3.998 + if (Base::_di) *reinterpret_cast<Value*>(Base::_di) = bf.dist(t);
3.999 + return bf.reached(t);
3.1000 + }
3.1001 +
3.1002 + template<class T>
3.1003 + struct SetPredMapBase : public Base {
3.1004 + typedef T PredMap;
3.1005 + static PredMap *createPredMap(const Digraph &) { return 0; };
3.1006 + SetPredMapBase(const TR &b) : TR(b) {}
3.1007 + };
3.1008 +
3.1009 + /// \brief \ref named-templ-param "Named parameter" for setting
3.1010 + /// the predecessor map.
3.1011 + ///
3.1012 + /// \ref named-templ-param "Named parameter" for setting
3.1013 + /// the map that stores the predecessor arcs of the nodes.
3.1014 + template<class T>
3.1015 + BellmanFordWizard<SetPredMapBase<T> > predMap(const T &t) {
3.1016 + Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
3.1017 + return BellmanFordWizard<SetPredMapBase<T> >(*this);
3.1018 + }
3.1019 +
3.1020 + template<class T>
3.1021 + struct SetDistMapBase : public Base {
3.1022 + typedef T DistMap;
3.1023 + static DistMap *createDistMap(const Digraph &) { return 0; };
3.1024 + SetDistMapBase(const TR &b) : TR(b) {}
3.1025 + };
3.1026 +
3.1027 + /// \brief \ref named-templ-param "Named parameter" for setting
3.1028 + /// the distance map.
3.1029 + ///
3.1030 + /// \ref named-templ-param "Named parameter" for setting
3.1031 + /// the map that stores the distances of the nodes calculated
3.1032 + /// by the algorithm.
3.1033 + template<class T>
3.1034 + BellmanFordWizard<SetDistMapBase<T> > distMap(const T &t) {
3.1035 + Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
3.1036 + return BellmanFordWizard<SetDistMapBase<T> >(*this);
3.1037 + }
3.1038 +
3.1039 + template<class T>
3.1040 + struct SetPathBase : public Base {
3.1041 + typedef T Path;
3.1042 + SetPathBase(const TR &b) : TR(b) {}
3.1043 + };
3.1044 +
3.1045 + /// \brief \ref named-func-param "Named parameter" for getting
3.1046 + /// the shortest path to the target node.
3.1047 + ///
3.1048 + /// \ref named-func-param "Named parameter" for getting
3.1049 + /// the shortest path to the target node.
3.1050 + template<class T>
3.1051 + BellmanFordWizard<SetPathBase<T> > path(const T &t)
3.1052 + {
3.1053 + Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
3.1054 + return BellmanFordWizard<SetPathBase<T> >(*this);
3.1055 + }
3.1056 +
3.1057 + /// \brief \ref named-func-param "Named parameter" for getting
3.1058 + /// the distance of the target node.
3.1059 + ///
3.1060 + /// \ref named-func-param "Named parameter" for getting
3.1061 + /// the distance of the target node.
3.1062 + BellmanFordWizard dist(const Value &d)
3.1063 + {
3.1064 + Base::_di=reinterpret_cast<void*>(const_cast<Value*>(&d));
3.1065 + return *this;
3.1066 + }
3.1067 +
3.1068 + };
3.1069 +
3.1070 + /// \brief Function type interface for the \ref BellmanFord "Bellman-Ford"
3.1071 + /// algorithm.
3.1072 + ///
3.1073 + /// \ingroup shortest_path
3.1074 + /// Function type interface for the \ref BellmanFord "Bellman-Ford"
3.1075 + /// algorithm.
3.1076 + ///
3.1077 + /// This function also has several \ref named-templ-func-param
3.1078 + /// "named parameters", they are declared as the members of class
3.1079 + /// \ref BellmanFordWizard.
3.1080 + /// The following examples show how to use these parameters.
3.1081 + /// \code
3.1082 + /// // Compute shortest path from node s to each node
3.1083 + /// bellmanFord(g,length).predMap(preds).distMap(dists).run(s);
3.1084 + ///
3.1085 + /// // Compute shortest path from s to t
3.1086 + /// bool reached = bellmanFord(g,length).path(p).dist(d).run(s,t);
3.1087 + /// \endcode
3.1088 + /// \warning Don't forget to put the \ref BellmanFordWizard::run() "run()"
3.1089 + /// to the end of the parameter list.
3.1090 + /// \sa BellmanFordWizard
3.1091 + /// \sa BellmanFord
3.1092 + template<typename GR, typename LEN>
3.1093 + BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >
3.1094 + bellmanFord(const GR& digraph,
3.1095 + const LEN& length)
3.1096 + {
3.1097 + return BellmanFordWizard<BellmanFordWizardBase<GR,LEN> >(digraph, length);
3.1098 + }
3.1099 +
3.1100 +} //END OF NAMESPACE LEMON
3.1101 +
3.1102 +#endif
3.1103 +
4.1 --- a/lemon/bfs.h Sun Aug 02 12:40:20 2009 +0200
4.2 +++ b/lemon/bfs.h Fri Sep 25 09:13:03 2009 +0200
4.3 @@ -414,8 +414,8 @@
4.4 ///\name Execution Control
4.5 ///The simplest way to execute the BFS algorithm is to use one of the
4.6 ///member functions called \ref run(Node) "run()".\n
4.7 - ///If you need more control on the execution, first you have to call
4.8 - ///\ref init(), then you can add several source nodes with
4.9 + ///If you need better control on the execution, you have to call
4.10 + ///\ref init() first, then you can add several source nodes with
4.11 ///\ref addSource(). Finally the actual path computation can be
4.12 ///performed with one of the \ref start() functions.
4.13
4.14 @@ -1422,8 +1422,8 @@
4.15 /// \name Execution Control
4.16 /// The simplest way to execute the BFS algorithm is to use one of the
4.17 /// member functions called \ref run(Node) "run()".\n
4.18 - /// If you need more control on the execution, first you have to call
4.19 - /// \ref init(), then you can add several source nodes with
4.20 + /// If you need better control on the execution, you have to call
4.21 + /// \ref init() first, then you can add several source nodes with
4.22 /// \ref addSource(). Finally the actual path computation can be
4.23 /// performed with one of the \ref start() functions.
4.24
5.1 --- a/lemon/bin_heap.h Sun Aug 02 12:40:20 2009 +0200
5.2 +++ b/lemon/bin_heap.h Fri Sep 25 09:13:03 2009 +0200
5.3 @@ -19,9 +19,9 @@
5.4 #ifndef LEMON_BIN_HEAP_H
5.5 #define LEMON_BIN_HEAP_H
5.6
5.7 -///\ingroup auxdat
5.8 +///\ingroup heaps
5.9 ///\file
5.10 -///\brief Binary Heap implementation.
5.11 +///\brief Binary heap implementation.
5.12
5.13 #include <vector>
5.14 #include <utility>
5.15 @@ -29,45 +29,41 @@
5.16
5.17 namespace lemon {
5.18
5.19 - ///\ingroup auxdat
5.20 + /// \ingroup heaps
5.21 ///
5.22 - ///\brief A Binary Heap implementation.
5.23 + /// \brief Binary heap data structure.
5.24 ///
5.25 - ///This class implements the \e binary \e heap data structure.
5.26 - ///
5.27 - ///A \e heap is a data structure for storing items with specified values
5.28 - ///called \e priorities in such a way that finding the item with minimum
5.29 - ///priority is efficient. \c Comp specifies the ordering of the priorities.
5.30 - ///In a heap one can change the priority of an item, add or erase an
5.31 - ///item, etc.
5.32 + /// This class implements the \e binary \e heap data structure.
5.33 + /// It fully conforms to the \ref concepts::Heap "heap concept".
5.34 ///
5.35 - ///\tparam PR Type of the priority of the items.
5.36 - ///\tparam IM A read and writable item map with int values, used internally
5.37 - ///to handle the cross references.
5.38 - ///\tparam Comp A functor class for the ordering of the priorities.
5.39 - ///The default is \c std::less<PR>.
5.40 - ///
5.41 - ///\sa FibHeap
5.42 - ///\sa Dijkstra
5.43 - template <typename PR, typename IM, typename Comp = std::less<PR> >
5.44 + /// \tparam PR Type of the priorities of the items.
5.45 + /// \tparam IM A read-writable item map with \c int values, used
5.46 + /// internally to handle the cross references.
5.47 + /// \tparam CMP A functor class for comparing the priorities.
5.48 + /// The default is \c std::less<PR>.
5.49 +#ifdef DOXYGEN
5.50 + template <typename PR, typename IM, typename CMP>
5.51 +#else
5.52 + template <typename PR, typename IM, typename CMP = std::less<PR> >
5.53 +#endif
5.54 class BinHeap {
5.55 + public:
5.56
5.57 - public:
5.58 - ///\e
5.59 + /// Type of the item-int map.
5.60 typedef IM ItemIntMap;
5.61 - ///\e
5.62 + /// Type of the priorities.
5.63 typedef PR Prio;
5.64 - ///\e
5.65 + /// Type of the items stored in the heap.
5.66 typedef typename ItemIntMap::Key Item;
5.67 - ///\e
5.68 + /// Type of the item-priority pairs.
5.69 typedef std::pair<Item,Prio> Pair;
5.70 - ///\e
5.71 - typedef Comp Compare;
5.72 + /// Functor type for comparing the priorities.
5.73 + typedef CMP Compare;
5.74
5.75 - /// \brief Type to represent the items states.
5.76 + /// \brief Type to represent the states of the items.
5.77 ///
5.78 - /// Each Item element have a state associated to it. It may be "in heap",
5.79 - /// "pre heap" or "post heap". The latter two are indifferent from the
5.80 + /// Each item has a state associated to it. It can be "in heap",
5.81 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
5.82 /// heap's point of view, but may be useful to the user.
5.83 ///
5.84 /// The item-int map must be initialized in such way that it assigns
5.85 @@ -84,42 +80,43 @@
5.86 ItemIntMap &_iim;
5.87
5.88 public:
5.89 - /// \brief The constructor.
5.90 +
5.91 + /// \brief Constructor.
5.92 ///
5.93 - /// The constructor.
5.94 - /// \param map should be given to the constructor, since it is used
5.95 - /// internally to handle the cross references. The value of the map
5.96 - /// must be \c PRE_HEAP (<tt>-1</tt>) for every item.
5.97 + /// Constructor.
5.98 + /// \param map A map that assigns \c int values to the items.
5.99 + /// It is used internally to handle the cross references.
5.100 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
5.101 explicit BinHeap(ItemIntMap &map) : _iim(map) {}
5.102
5.103 - /// \brief The constructor.
5.104 + /// \brief Constructor.
5.105 ///
5.106 - /// The constructor.
5.107 - /// \param map should be given to the constructor, since it is used
5.108 - /// internally to handle the cross references. The value of the map
5.109 - /// should be PRE_HEAP (-1) for each element.
5.110 - ///
5.111 - /// \param comp The comparator function object.
5.112 + /// Constructor.
5.113 + /// \param map A map that assigns \c int values to the items.
5.114 + /// It is used internally to handle the cross references.
5.115 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
5.116 + /// \param comp The function object used for comparing the priorities.
5.117 BinHeap(ItemIntMap &map, const Compare &comp)
5.118 : _iim(map), _comp(comp) {}
5.119
5.120
5.121 - /// The number of items stored in the heap.
5.122 + /// \brief The number of items stored in the heap.
5.123 ///
5.124 - /// \brief Returns the number of items stored in the heap.
5.125 + /// This function returns the number of items stored in the heap.
5.126 int size() const { return _data.size(); }
5.127
5.128 - /// \brief Checks if the heap stores no items.
5.129 + /// \brief Check if the heap is empty.
5.130 ///
5.131 - /// Returns \c true if and only if the heap stores no items.
5.132 + /// This function returns \c true if the heap is empty.
5.133 bool empty() const { return _data.empty(); }
5.134
5.135 - /// \brief Make empty this heap.
5.136 + /// \brief Make the heap empty.
5.137 ///
5.138 - /// Make empty this heap. It does not change the cross reference map.
5.139 - /// If you want to reuse what is not surely empty you should first clear
5.140 - /// the heap and after that you should set the cross reference map for
5.141 - /// each item to \c PRE_HEAP.
5.142 + /// This functon makes the heap empty.
5.143 + /// It does not change the cross reference map. If you want to reuse
5.144 + /// a heap that is not surely empty, you should first clear it and
5.145 + /// then you should set the cross reference map to \c PRE_HEAP
5.146 + /// for each item.
5.147 void clear() {
5.148 _data.clear();
5.149 }
5.150 @@ -127,12 +124,12 @@
5.151 private:
5.152 static int parent(int i) { return (i-1)/2; }
5.153
5.154 - static int second_child(int i) { return 2*i+2; }
5.155 + static int secondChild(int i) { return 2*i+2; }
5.156 bool less(const Pair &p1, const Pair &p2) const {
5.157 return _comp(p1.second, p2.second);
5.158 }
5.159
5.160 - int bubble_up(int hole, Pair p) {
5.161 + int bubbleUp(int hole, Pair p) {
5.162 int par = parent(hole);
5.163 while( hole>0 && less(p,_data[par]) ) {
5.164 move(_data[par],hole);
5.165 @@ -143,8 +140,8 @@
5.166 return hole;
5.167 }
5.168
5.169 - int bubble_down(int hole, Pair p, int length) {
5.170 - int child = second_child(hole);
5.171 + int bubbleDown(int hole, Pair p, int length) {
5.172 + int child = secondChild(hole);
5.173 while(child < length) {
5.174 if( less(_data[child-1], _data[child]) ) {
5.175 --child;
5.176 @@ -153,7 +150,7 @@
5.177 goto ok;
5.178 move(_data[child], hole);
5.179 hole = child;
5.180 - child = second_child(hole);
5.181 + child = secondChild(hole);
5.182 }
5.183 child--;
5.184 if( child<length && less(_data[child], p) ) {
5.185 @@ -171,87 +168,91 @@
5.186 }
5.187
5.188 public:
5.189 +
5.190 /// \brief Insert a pair of item and priority into the heap.
5.191 ///
5.192 - /// Adds \c p.first to the heap with priority \c p.second.
5.193 + /// This function inserts \c p.first to the heap with priority
5.194 + /// \c p.second.
5.195 /// \param p The pair to insert.
5.196 + /// \pre \c p.first must not be stored in the heap.
5.197 void push(const Pair &p) {
5.198 int n = _data.size();
5.199 _data.resize(n+1);
5.200 - bubble_up(n, p);
5.201 + bubbleUp(n, p);
5.202 }
5.203
5.204 - /// \brief Insert an item into the heap with the given heap.
5.205 + /// \brief Insert an item into the heap with the given priority.
5.206 ///
5.207 - /// Adds \c i to the heap with priority \c p.
5.208 + /// This function inserts the given item into the heap with the
5.209 + /// given priority.
5.210 /// \param i The item to insert.
5.211 /// \param p The priority of the item.
5.212 + /// \pre \e i must not be stored in the heap.
5.213 void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
5.214
5.215 - /// \brief Returns the item with minimum priority relative to \c Compare.
5.216 + /// \brief Return the item having minimum priority.
5.217 ///
5.218 - /// This method returns the item with minimum priority relative to \c
5.219 - /// Compare.
5.220 - /// \pre The heap must be nonempty.
5.221 + /// This function returns the item having minimum priority.
5.222 + /// \pre The heap must be non-empty.
5.223 Item top() const {
5.224 return _data[0].first;
5.225 }
5.226
5.227 - /// \brief Returns the minimum priority relative to \c Compare.
5.228 + /// \brief The minimum priority.
5.229 ///
5.230 - /// It returns the minimum priority relative to \c Compare.
5.231 - /// \pre The heap must be nonempty.
5.232 + /// This function returns the minimum priority.
5.233 + /// \pre The heap must be non-empty.
5.234 Prio prio() const {
5.235 return _data[0].second;
5.236 }
5.237
5.238 - /// \brief Deletes the item with minimum priority relative to \c Compare.
5.239 + /// \brief Remove the item having minimum priority.
5.240 ///
5.241 - /// This method deletes the item with minimum priority relative to \c
5.242 - /// Compare from the heap.
5.243 + /// This function removes the item having minimum priority.
5.244 /// \pre The heap must be non-empty.
5.245 void pop() {
5.246 int n = _data.size()-1;
5.247 _iim.set(_data[0].first, POST_HEAP);
5.248 if (n > 0) {
5.249 - bubble_down(0, _data[n], n);
5.250 + bubbleDown(0, _data[n], n);
5.251 }
5.252 _data.pop_back();
5.253 }
5.254
5.255 - /// \brief Deletes \c i from the heap.
5.256 + /// \brief Remove the given item from the heap.
5.257 ///
5.258 - /// This method deletes item \c i from the heap.
5.259 - /// \param i The item to erase.
5.260 - /// \pre The item should be in the heap.
5.261 + /// This function removes the given item from the heap if it is
5.262 + /// already stored.
5.263 + /// \param i The item to delete.
5.264 + /// \pre \e i must be in the heap.
5.265 void erase(const Item &i) {
5.266 int h = _iim[i];
5.267 int n = _data.size()-1;
5.268 _iim.set(_data[h].first, POST_HEAP);
5.269 if( h < n ) {
5.270 - if ( bubble_up(h, _data[n]) == h) {
5.271 - bubble_down(h, _data[n], n);
5.272 + if ( bubbleUp(h, _data[n]) == h) {
5.273 + bubbleDown(h, _data[n], n);
5.274 }
5.275 }
5.276 _data.pop_back();
5.277 }
5.278
5.279 -
5.280 - /// \brief Returns the priority of \c i.
5.281 + /// \brief The priority of the given item.
5.282 ///
5.283 - /// This function returns the priority of item \c i.
5.284 + /// This function returns the priority of the given item.
5.285 /// \param i The item.
5.286 - /// \pre \c i must be in the heap.
5.287 + /// \pre \e i must be in the heap.
5.288 Prio operator[](const Item &i) const {
5.289 int idx = _iim[i];
5.290 return _data[idx].second;
5.291 }
5.292
5.293 - /// \brief \c i gets to the heap with priority \c p independently
5.294 - /// if \c i was already there.
5.295 + /// \brief Set the priority of an item or insert it, if it is
5.296 + /// not stored in the heap.
5.297 ///
5.298 - /// This method calls \ref push(\c i, \c p) if \c i is not stored
5.299 - /// in the heap and sets the priority of \c i to \c p otherwise.
5.300 + /// This method sets the priority of the given item if it is
5.301 + /// already stored in the heap. Otherwise it inserts the given
5.302 + /// item into the heap with the given priority.
5.303 /// \param i The item.
5.304 /// \param p The priority.
5.305 void set(const Item &i, const Prio &p) {
5.306 @@ -260,44 +261,42 @@
5.307 push(i,p);
5.308 }
5.309 else if( _comp(p, _data[idx].second) ) {
5.310 - bubble_up(idx, Pair(i,p));
5.311 + bubbleUp(idx, Pair(i,p));
5.312 }
5.313 else {
5.314 - bubble_down(idx, Pair(i,p), _data.size());
5.315 + bubbleDown(idx, Pair(i,p), _data.size());
5.316 }
5.317 }
5.318
5.319 - /// \brief Decreases the priority of \c i to \c p.
5.320 + /// \brief Decrease the priority of an item to the given value.
5.321 ///
5.322 - /// This method decreases the priority of item \c i to \c p.
5.323 + /// This function decreases the priority of an item to the given value.
5.324 /// \param i The item.
5.325 /// \param p The priority.
5.326 - /// \pre \c i must be stored in the heap with priority at least \c
5.327 - /// p relative to \c Compare.
5.328 + /// \pre \e i must be stored in the heap with priority at least \e p.
5.329 void decrease(const Item &i, const Prio &p) {
5.330 int idx = _iim[i];
5.331 - bubble_up(idx, Pair(i,p));
5.332 + bubbleUp(idx, Pair(i,p));
5.333 }
5.334
5.335 - /// \brief Increases the priority of \c i to \c p.
5.336 + /// \brief Increase the priority of an item to the given value.
5.337 ///
5.338 - /// This method sets the priority of item \c i to \c p.
5.339 + /// This function increases the priority of an item to the given value.
5.340 /// \param i The item.
5.341 /// \param p The priority.
5.342 - /// \pre \c i must be stored in the heap with priority at most \c
5.343 - /// p relative to \c Compare.
5.344 + /// \pre \e i must be stored in the heap with priority at most \e p.
5.345 void increase(const Item &i, const Prio &p) {
5.346 int idx = _iim[i];
5.347 - bubble_down(idx, Pair(i,p), _data.size());
5.348 + bubbleDown(idx, Pair(i,p), _data.size());
5.349 }
5.350
5.351 - /// \brief Returns if \c item is in, has already been in, or has
5.352 - /// never been in the heap.
5.353 + /// \brief Return the state of an item.
5.354 ///
5.355 - /// This method returns PRE_HEAP if \c item has never been in the
5.356 - /// heap, IN_HEAP if it is in the heap at the moment, and POST_HEAP
5.357 - /// otherwise. In the latter case it is possible that \c item will
5.358 - /// get back to the heap again.
5.359 + /// This method returns \c PRE_HEAP if the given item has never
5.360 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
5.361 + /// and \c POST_HEAP otherwise.
5.362 + /// In the latter case it is possible that the item will get back
5.363 + /// to the heap again.
5.364 /// \param i The item.
5.365 State state(const Item &i) const {
5.366 int s = _iim[i];
5.367 @@ -306,11 +305,11 @@
5.368 return State(s);
5.369 }
5.370
5.371 - /// \brief Sets the state of the \c item in the heap.
5.372 + /// \brief Set the state of an item in the heap.
5.373 ///
5.374 - /// Sets the state of the \c item in the heap. It can be used to
5.375 - /// manually clear the heap when it is important to achive the
5.376 - /// better time complexity.
5.377 + /// This function sets the state of the given item in the heap.
5.378 + /// It can be used to manually clear the heap when it is important
5.379 + /// to achive better time complexity.
5.380 /// \param i The item.
5.381 /// \param st The state. It should not be \c IN_HEAP.
5.382 void state(const Item& i, State st) {
5.383 @@ -327,12 +326,13 @@
5.384 }
5.385 }
5.386
5.387 - /// \brief Replaces an item in the heap.
5.388 + /// \brief Replace an item in the heap.
5.389 ///
5.390 - /// The \c i item is replaced with \c j item. The \c i item should
5.391 - /// be in the heap, while the \c j should be out of the heap. The
5.392 - /// \c i item will out of the heap and \c j will be in the heap
5.393 - /// with the same prioriority as prevoiusly the \c i item.
5.394 + /// This function replaces item \c i with item \c j.
5.395 + /// Item \c i must be in the heap, while \c j must be out of the heap.
5.396 + /// After calling this method, item \c i will be out of the
5.397 + /// heap and \c j will be in the heap with the same prioriority
5.398 + /// as item \c i had before.
5.399 void replace(const Item& i, const Item& j) {
5.400 int idx = _iim[i];
5.401 _iim.set(i, _iim[j]);
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/lemon/binom_heap.h Fri Sep 25 09:13:03 2009 +0200
6.3 @@ -0,0 +1,445 @@
6.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
6.5 + *
6.6 + * This file is a part of LEMON, a generic C++ optimization library.
6.7 + *
6.8 + * Copyright (C) 2003-2009
6.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
6.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
6.11 + *
6.12 + * Permission to use, modify and distribute this software is granted
6.13 + * provided that this copyright notice appears in all copies. For
6.14 + * precise terms see the accompanying LICENSE file.
6.15 + *
6.16 + * This software is provided "AS IS" with no warranty of any kind,
6.17 + * express or implied, and with no claim as to its suitability for any
6.18 + * purpose.
6.19 + *
6.20 + */
6.21 +
6.22 +#ifndef LEMON_BINOM_HEAP_H
6.23 +#define LEMON_BINOM_HEAP_H
6.24 +
6.25 +///\file
6.26 +///\ingroup heaps
6.27 +///\brief Binomial Heap implementation.
6.28 +
6.29 +#include <vector>
6.30 +#include <utility>
6.31 +#include <functional>
6.32 +#include <lemon/math.h>
6.33 +#include <lemon/counter.h>
6.34 +
6.35 +namespace lemon {
6.36 +
6.37 + /// \ingroup heaps
6.38 + ///
6.39 + ///\brief Binomial heap data structure.
6.40 + ///
6.41 + /// This class implements the \e binomial \e heap data structure.
6.42 + /// It fully conforms to the \ref concepts::Heap "heap concept".
6.43 + ///
6.44 + /// The methods \ref increase() and \ref erase() are not efficient
6.45 + /// in a binomial heap. In case of many calls of these operations,
6.46 + /// it is better to use other heap structure, e.g. \ref BinHeap
6.47 + /// "binary heap".
6.48 + ///
6.49 + /// \tparam PR Type of the priorities of the items.
6.50 + /// \tparam IM A read-writable item map with \c int values, used
6.51 + /// internally to handle the cross references.
6.52 + /// \tparam CMP A functor class for comparing the priorities.
6.53 + /// The default is \c std::less<PR>.
6.54 +#ifdef DOXYGEN
6.55 + template <typename PR, typename IM, typename CMP>
6.56 +#else
6.57 + template <typename PR, typename IM, typename CMP = std::less<PR> >
6.58 +#endif
6.59 + class BinomHeap {
6.60 + public:
6.61 + /// Type of the item-int map.
6.62 + typedef IM ItemIntMap;
6.63 + /// Type of the priorities.
6.64 + typedef PR Prio;
6.65 + /// Type of the items stored in the heap.
6.66 + typedef typename ItemIntMap::Key Item;
6.67 + /// Functor type for comparing the priorities.
6.68 + typedef CMP Compare;
6.69 +
6.70 + /// \brief Type to represent the states of the items.
6.71 + ///
6.72 + /// Each item has a state associated to it. It can be "in heap",
6.73 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
6.74 + /// heap's point of view, but may be useful to the user.
6.75 + ///
6.76 + /// The item-int map must be initialized in such way that it assigns
6.77 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
6.78 + enum State {
6.79 + IN_HEAP = 0, ///< = 0.
6.80 + PRE_HEAP = -1, ///< = -1.
6.81 + POST_HEAP = -2 ///< = -2.
6.82 + };
6.83 +
6.84 + private:
6.85 + class Store;
6.86 +
6.87 + std::vector<Store> _data;
6.88 + int _min, _head;
6.89 + ItemIntMap &_iim;
6.90 + Compare _comp;
6.91 + int _num_items;
6.92 +
6.93 + public:
6.94 + /// \brief Constructor.
6.95 + ///
6.96 + /// Constructor.
6.97 + /// \param map A map that assigns \c int values to the items.
6.98 + /// It is used internally to handle the cross references.
6.99 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
6.100 + explicit BinomHeap(ItemIntMap &map)
6.101 + : _min(0), _head(-1), _iim(map), _num_items(0) {}
6.102 +
6.103 + /// \brief Constructor.
6.104 + ///
6.105 + /// Constructor.
6.106 + /// \param map A map that assigns \c int values to the items.
6.107 + /// It is used internally to handle the cross references.
6.108 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
6.109 + /// \param comp The function object used for comparing the priorities.
6.110 + BinomHeap(ItemIntMap &map, const Compare &comp)
6.111 + : _min(0), _head(-1), _iim(map), _comp(comp), _num_items(0) {}
6.112 +
6.113 + /// \brief The number of items stored in the heap.
6.114 + ///
6.115 + /// This function returns the number of items stored in the heap.
6.116 + int size() const { return _num_items; }
6.117 +
6.118 + /// \brief Check if the heap is empty.
6.119 + ///
6.120 + /// This function returns \c true if the heap is empty.
6.121 + bool empty() const { return _num_items==0; }
6.122 +
6.123 + /// \brief Make the heap empty.
6.124 + ///
6.125 + /// This functon makes the heap empty.
6.126 + /// It does not change the cross reference map. If you want to reuse
6.127 + /// a heap that is not surely empty, you should first clear it and
6.128 + /// then you should set the cross reference map to \c PRE_HEAP
6.129 + /// for each item.
6.130 + void clear() {
6.131 + _data.clear(); _min=0; _num_items=0; _head=-1;
6.132 + }
6.133 +
6.134 + /// \brief Set the priority of an item or insert it, if it is
6.135 + /// not stored in the heap.
6.136 + ///
6.137 + /// This method sets the priority of the given item if it is
6.138 + /// already stored in the heap. Otherwise it inserts the given
6.139 + /// item into the heap with the given priority.
6.140 + /// \param item The item.
6.141 + /// \param value The priority.
6.142 + void set (const Item& item, const Prio& value) {
6.143 + int i=_iim[item];
6.144 + if ( i >= 0 && _data[i].in ) {
6.145 + if ( _comp(value, _data[i].prio) ) decrease(item, value);
6.146 + if ( _comp(_data[i].prio, value) ) increase(item, value);
6.147 + } else push(item, value);
6.148 + }
6.149 +
6.150 + /// \brief Insert an item into the heap with the given priority.
6.151 + ///
6.152 + /// This function inserts the given item into the heap with the
6.153 + /// given priority.
6.154 + /// \param item The item to insert.
6.155 + /// \param value The priority of the item.
6.156 + /// \pre \e item must not be stored in the heap.
6.157 + void push (const Item& item, const Prio& value) {
6.158 + int i=_iim[item];
6.159 + if ( i<0 ) {
6.160 + int s=_data.size();
6.161 + _iim.set( item,s );
6.162 + Store st;
6.163 + st.name=item;
6.164 + st.prio=value;
6.165 + _data.push_back(st);
6.166 + i=s;
6.167 + }
6.168 + else {
6.169 + _data[i].parent=_data[i].right_neighbor=_data[i].child=-1;
6.170 + _data[i].degree=0;
6.171 + _data[i].in=true;
6.172 + _data[i].prio=value;
6.173 + }
6.174 +
6.175 + if( 0==_num_items ) {
6.176 + _head=i;
6.177 + _min=i;
6.178 + } else {
6.179 + merge(i);
6.180 + if( _comp(_data[i].prio, _data[_min].prio) ) _min=i;
6.181 + }
6.182 + ++_num_items;
6.183 + }
6.184 +
6.185 + /// \brief Return the item having minimum priority.
6.186 + ///
6.187 + /// This function returns the item having minimum priority.
6.188 + /// \pre The heap must be non-empty.
6.189 + Item top() const { return _data[_min].name; }
6.190 +
6.191 + /// \brief The minimum priority.
6.192 + ///
6.193 + /// This function returns the minimum priority.
6.194 + /// \pre The heap must be non-empty.
6.195 + Prio prio() const { return _data[_min].prio; }
6.196 +
6.197 + /// \brief The priority of the given item.
6.198 + ///
6.199 + /// This function returns the priority of the given item.
6.200 + /// \param item The item.
6.201 + /// \pre \e item must be in the heap.
6.202 + const Prio& operator[](const Item& item) const {
6.203 + return _data[_iim[item]].prio;
6.204 + }
6.205 +
6.206 + /// \brief Remove the item having minimum priority.
6.207 + ///
6.208 + /// This function removes the item having minimum priority.
6.209 + /// \pre The heap must be non-empty.
6.210 + void pop() {
6.211 + _data[_min].in=false;
6.212 +
6.213 + int head_child=-1;
6.214 + if ( _data[_min].child!=-1 ) {
6.215 + int child=_data[_min].child;
6.216 + int neighb;
6.217 + while( child!=-1 ) {
6.218 + neighb=_data[child].right_neighbor;
6.219 + _data[child].parent=-1;
6.220 + _data[child].right_neighbor=head_child;
6.221 + head_child=child;
6.222 + child=neighb;
6.223 + }
6.224 + }
6.225 +
6.226 + if ( _data[_head].right_neighbor==-1 ) {
6.227 + // there was only one root
6.228 + _head=head_child;
6.229 + }
6.230 + else {
6.231 + // there were more roots
6.232 + if( _head!=_min ) { unlace(_min); }
6.233 + else { _head=_data[_head].right_neighbor; }
6.234 + merge(head_child);
6.235 + }
6.236 + _min=findMin();
6.237 + --_num_items;
6.238 + }
6.239 +
6.240 + /// \brief Remove the given item from the heap.
6.241 + ///
6.242 + /// This function removes the given item from the heap if it is
6.243 + /// already stored.
6.244 + /// \param item The item to delete.
6.245 + /// \pre \e item must be in the heap.
6.246 + void erase (const Item& item) {
6.247 + int i=_iim[item];
6.248 + if ( i >= 0 && _data[i].in ) {
6.249 + decrease( item, _data[_min].prio-1 );
6.250 + pop();
6.251 + }
6.252 + }
6.253 +
6.254 + /// \brief Decrease the priority of an item to the given value.
6.255 + ///
6.256 + /// This function decreases the priority of an item to the given value.
6.257 + /// \param item The item.
6.258 + /// \param value The priority.
6.259 + /// \pre \e item must be stored in the heap with priority at least \e value.
6.260 + void decrease (Item item, const Prio& value) {
6.261 + int i=_iim[item];
6.262 + int p=_data[i].parent;
6.263 + _data[i].prio=value;
6.264 +
6.265 + while( p!=-1 && _comp(value, _data[p].prio) ) {
6.266 + _data[i].name=_data[p].name;
6.267 + _data[i].prio=_data[p].prio;
6.268 + _data[p].name=item;
6.269 + _data[p].prio=value;
6.270 + _iim[_data[i].name]=i;
6.271 + i=p;
6.272 + p=_data[p].parent;
6.273 + }
6.274 + _iim[item]=i;
6.275 + if ( _comp(value, _data[_min].prio) ) _min=i;
6.276 + }
6.277 +
6.278 + /// \brief Increase the priority of an item to the given value.
6.279 + ///
6.280 + /// This function increases the priority of an item to the given value.
6.281 + /// \param item The item.
6.282 + /// \param value The priority.
6.283 + /// \pre \e item must be stored in the heap with priority at most \e value.
6.284 + void increase (Item item, const Prio& value) {
6.285 + erase(item);
6.286 + push(item, value);
6.287 + }
6.288 +
6.289 + /// \brief Return the state of an item.
6.290 + ///
6.291 + /// This method returns \c PRE_HEAP if the given item has never
6.292 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
6.293 + /// and \c POST_HEAP otherwise.
6.294 + /// In the latter case it is possible that the item will get back
6.295 + /// to the heap again.
6.296 + /// \param item The item.
6.297 + State state(const Item &item) const {
6.298 + int i=_iim[item];
6.299 + if( i>=0 ) {
6.300 + if ( _data[i].in ) i=0;
6.301 + else i=-2;
6.302 + }
6.303 + return State(i);
6.304 + }
6.305 +
6.306 + /// \brief Set the state of an item in the heap.
6.307 + ///
6.308 + /// This function sets the state of the given item in the heap.
6.309 + /// It can be used to manually clear the heap when it is important
6.310 + /// to achive better time complexity.
6.311 + /// \param i The item.
6.312 + /// \param st The state. It should not be \c IN_HEAP.
6.313 + void state(const Item& i, State st) {
6.314 + switch (st) {
6.315 + case POST_HEAP:
6.316 + case PRE_HEAP:
6.317 + if (state(i) == IN_HEAP) {
6.318 + erase(i);
6.319 + }
6.320 + _iim[i] = st;
6.321 + break;
6.322 + case IN_HEAP:
6.323 + break;
6.324 + }
6.325 + }
6.326 +
6.327 + private:
6.328 +
6.329 + // Find the minimum of the roots
6.330 + int findMin() {
6.331 + if( _head!=-1 ) {
6.332 + int min_loc=_head, min_val=_data[_head].prio;
6.333 + for( int x=_data[_head].right_neighbor; x!=-1;
6.334 + x=_data[x].right_neighbor ) {
6.335 + if( _comp( _data[x].prio,min_val ) ) {
6.336 + min_val=_data[x].prio;
6.337 + min_loc=x;
6.338 + }
6.339 + }
6.340 + return min_loc;
6.341 + }
6.342 + else return -1;
6.343 + }
6.344 +
6.345 + // Merge the heap with another heap starting at the given position
6.346 + void merge(int a) {
6.347 + if( _head==-1 || a==-1 ) return;
6.348 + if( _data[a].right_neighbor==-1 &&
6.349 + _data[a].degree<=_data[_head].degree ) {
6.350 + _data[a].right_neighbor=_head;
6.351 + _head=a;
6.352 + } else {
6.353 + interleave(a);
6.354 + }
6.355 + if( _data[_head].right_neighbor==-1 ) return;
6.356 +
6.357 + int x=_head;
6.358 + int x_prev=-1, x_next=_data[x].right_neighbor;
6.359 + while( x_next!=-1 ) {
6.360 + if( _data[x].degree!=_data[x_next].degree ||
6.361 + ( _data[x_next].right_neighbor!=-1 &&
6.362 + _data[_data[x_next].right_neighbor].degree==_data[x].degree ) ) {
6.363 + x_prev=x;
6.364 + x=x_next;
6.365 + }
6.366 + else {
6.367 + if( _comp(_data[x_next].prio,_data[x].prio) ) {
6.368 + if( x_prev==-1 ) {
6.369 + _head=x_next;
6.370 + } else {
6.371 + _data[x_prev].right_neighbor=x_next;
6.372 + }
6.373 + fuse(x,x_next);
6.374 + x=x_next;
6.375 + }
6.376 + else {
6.377 + _data[x].right_neighbor=_data[x_next].right_neighbor;
6.378 + fuse(x_next,x);
6.379 + }
6.380 + }
6.381 + x_next=_data[x].right_neighbor;
6.382 + }
6.383 + }
6.384 +
6.385 + // Interleave the elements of the given list into the list of the roots
6.386 + void interleave(int a) {
6.387 + int p=_head, q=a;
6.388 + int curr=_data.size();
6.389 + _data.push_back(Store());
6.390 +
6.391 + while( p!=-1 || q!=-1 ) {
6.392 + if( q==-1 || ( p!=-1 && _data[p].degree<_data[q].degree ) ) {
6.393 + _data[curr].right_neighbor=p;
6.394 + curr=p;
6.395 + p=_data[p].right_neighbor;
6.396 + }
6.397 + else {
6.398 + _data[curr].right_neighbor=q;
6.399 + curr=q;
6.400 + q=_data[q].right_neighbor;
6.401 + }
6.402 + }
6.403 +
6.404 + _head=_data.back().right_neighbor;
6.405 + _data.pop_back();
6.406 + }
6.407 +
6.408 + // Lace node a under node b
6.409 + void fuse(int a, int b) {
6.410 + _data[a].parent=b;
6.411 + _data[a].right_neighbor=_data[b].child;
6.412 + _data[b].child=a;
6.413 +
6.414 + ++_data[b].degree;
6.415 + }
6.416 +
6.417 + // Unlace node a (if it has siblings)
6.418 + void unlace(int a) {
6.419 + int neighb=_data[a].right_neighbor;
6.420 + int other=_head;
6.421 +
6.422 + while( _data[other].right_neighbor!=a )
6.423 + other=_data[other].right_neighbor;
6.424 + _data[other].right_neighbor=neighb;
6.425 + }
6.426 +
6.427 + private:
6.428 +
6.429 + class Store {
6.430 + friend class BinomHeap;
6.431 +
6.432 + Item name;
6.433 + int parent;
6.434 + int right_neighbor;
6.435 + int child;
6.436 + int degree;
6.437 + bool in;
6.438 + Prio prio;
6.439 +
6.440 + Store() : parent(-1), right_neighbor(-1), child(-1), degree(0),
6.441 + in(true) {}
6.442 + };
6.443 + };
6.444 +
6.445 +} //namespace lemon
6.446 +
6.447 +#endif //LEMON_BINOM_HEAP_H
6.448 +
7.1 --- a/lemon/bits/edge_set_extender.h Sun Aug 02 12:40:20 2009 +0200
7.2 +++ b/lemon/bits/edge_set_extender.h Fri Sep 25 09:13:03 2009 +0200
7.3 @@ -537,7 +537,7 @@
7.4 typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
7.5
7.6 public:
7.7 - ArcMap(const Graph& _g)
7.8 + explicit ArcMap(const Graph& _g)
7.9 : Parent(_g) {}
7.10 ArcMap(const Graph& _g, const _Value& _v)
7.11 : Parent(_g, _v) {}
7.12 @@ -561,7 +561,7 @@
7.13 typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
7.14
7.15 public:
7.16 - EdgeMap(const Graph& _g)
7.17 + explicit EdgeMap(const Graph& _g)
7.18 : Parent(_g) {}
7.19
7.20 EdgeMap(const Graph& _g, const _Value& _v)
8.1 --- a/lemon/bits/graph_extender.h Sun Aug 02 12:40:20 2009 +0200
8.2 +++ b/lemon/bits/graph_extender.h Fri Sep 25 09:13:03 2009 +0200
8.3 @@ -604,7 +604,7 @@
8.4 typedef MapExtender<DefaultMap<Graph, Node, _Value> > Parent;
8.5
8.6 public:
8.7 - NodeMap(const Graph& graph)
8.8 + explicit NodeMap(const Graph& graph)
8.9 : Parent(graph) {}
8.10 NodeMap(const Graph& graph, const _Value& value)
8.11 : Parent(graph, value) {}
8.12 @@ -628,7 +628,7 @@
8.13 typedef MapExtender<DefaultMap<Graph, Arc, _Value> > Parent;
8.14
8.15 public:
8.16 - ArcMap(const Graph& graph)
8.17 + explicit ArcMap(const Graph& graph)
8.18 : Parent(graph) {}
8.19 ArcMap(const Graph& graph, const _Value& value)
8.20 : Parent(graph, value) {}
8.21 @@ -652,7 +652,7 @@
8.22 typedef MapExtender<DefaultMap<Graph, Edge, _Value> > Parent;
8.23
8.24 public:
8.25 - EdgeMap(const Graph& graph)
8.26 + explicit EdgeMap(const Graph& graph)
8.27 : Parent(graph) {}
8.28
8.29 EdgeMap(const Graph& graph, const _Value& value)
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/lemon/bucket_heap.h Fri Sep 25 09:13:03 2009 +0200
9.3 @@ -0,0 +1,594 @@
9.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
9.5 + *
9.6 + * This file is a part of LEMON, a generic C++ optimization library.
9.7 + *
9.8 + * Copyright (C) 2003-2009
9.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
9.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
9.11 + *
9.12 + * Permission to use, modify and distribute this software is granted
9.13 + * provided that this copyright notice appears in all copies. For
9.14 + * precise terms see the accompanying LICENSE file.
9.15 + *
9.16 + * This software is provided "AS IS" with no warranty of any kind,
9.17 + * express or implied, and with no claim as to its suitability for any
9.18 + * purpose.
9.19 + *
9.20 + */
9.21 +
9.22 +#ifndef LEMON_BUCKET_HEAP_H
9.23 +#define LEMON_BUCKET_HEAP_H
9.24 +
9.25 +///\ingroup heaps
9.26 +///\file
9.27 +///\brief Bucket heap implementation.
9.28 +
9.29 +#include <vector>
9.30 +#include <utility>
9.31 +#include <functional>
9.32 +
9.33 +namespace lemon {
9.34 +
9.35 + namespace _bucket_heap_bits {
9.36 +
9.37 + template <bool MIN>
9.38 + struct DirectionTraits {
9.39 + static bool less(int left, int right) {
9.40 + return left < right;
9.41 + }
9.42 + static void increase(int& value) {
9.43 + ++value;
9.44 + }
9.45 + };
9.46 +
9.47 + template <>
9.48 + struct DirectionTraits<false> {
9.49 + static bool less(int left, int right) {
9.50 + return left > right;
9.51 + }
9.52 + static void increase(int& value) {
9.53 + --value;
9.54 + }
9.55 + };
9.56 +
9.57 + }
9.58 +
9.59 + /// \ingroup heaps
9.60 + ///
9.61 + /// \brief Bucket heap data structure.
9.62 + ///
9.63 + /// This class implements the \e bucket \e heap data structure.
9.64 + /// It practically conforms to the \ref concepts::Heap "heap concept",
9.65 + /// but it has some limitations.
9.66 + ///
9.67 + /// The bucket heap is a very simple structure. It can store only
9.68 + /// \c int priorities and it maintains a list of items for each priority
9.69 + /// in the range <tt>[0..C)</tt>. So it should only be used when the
9.70 + /// priorities are small. It is not intended to use as a Dijkstra heap.
9.71 + ///
9.72 + /// \tparam IM A read-writable item map with \c int values, used
9.73 + /// internally to handle the cross references.
9.74 + /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
9.75 + /// The default is \e min-heap. If this parameter is set to \c false,
9.76 + /// then the comparison is reversed, so the top(), prio() and pop()
9.77 + /// functions deal with the item having maximum priority instead of the
9.78 + /// minimum.
9.79 + ///
9.80 + /// \sa SimpleBucketHeap
9.81 + template <typename IM, bool MIN = true>
9.82 + class BucketHeap {
9.83 +
9.84 + public:
9.85 +
9.86 + /// Type of the item-int map.
9.87 + typedef IM ItemIntMap;
9.88 + /// Type of the priorities.
9.89 + typedef int Prio;
9.90 + /// Type of the items stored in the heap.
9.91 + typedef typename ItemIntMap::Key Item;
9.92 + /// Type of the item-priority pairs.
9.93 + typedef std::pair<Item,Prio> Pair;
9.94 +
9.95 + private:
9.96 +
9.97 + typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
9.98 +
9.99 + public:
9.100 +
9.101 + /// \brief Type to represent the states of the items.
9.102 + ///
9.103 + /// Each item has a state associated to it. It can be "in heap",
9.104 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
9.105 + /// heap's point of view, but may be useful to the user.
9.106 + ///
9.107 + /// The item-int map must be initialized in such way that it assigns
9.108 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
9.109 + enum State {
9.110 + IN_HEAP = 0, ///< = 0.
9.111 + PRE_HEAP = -1, ///< = -1.
9.112 + POST_HEAP = -2 ///< = -2.
9.113 + };
9.114 +
9.115 + public:
9.116 +
9.117 + /// \brief Constructor.
9.118 + ///
9.119 + /// Constructor.
9.120 + /// \param map A map that assigns \c int values to the items.
9.121 + /// It is used internally to handle the cross references.
9.122 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
9.123 + explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
9.124 +
9.125 + /// \brief The number of items stored in the heap.
9.126 + ///
9.127 + /// This function returns the number of items stored in the heap.
9.128 + int size() const { return _data.size(); }
9.129 +
9.130 + /// \brief Check if the heap is empty.
9.131 + ///
9.132 + /// This function returns \c true if the heap is empty.
9.133 + bool empty() const { return _data.empty(); }
9.134 +
9.135 + /// \brief Make the heap empty.
9.136 + ///
9.137 + /// This functon makes the heap empty.
9.138 + /// It does not change the cross reference map. If you want to reuse
9.139 + /// a heap that is not surely empty, you should first clear it and
9.140 + /// then you should set the cross reference map to \c PRE_HEAP
9.141 + /// for each item.
9.142 + void clear() {
9.143 + _data.clear(); _first.clear(); _minimum = 0;
9.144 + }
9.145 +
9.146 + private:
9.147 +
9.148 + void relocateLast(int idx) {
9.149 + if (idx + 1 < int(_data.size())) {
9.150 + _data[idx] = _data.back();
9.151 + if (_data[idx].prev != -1) {
9.152 + _data[_data[idx].prev].next = idx;
9.153 + } else {
9.154 + _first[_data[idx].value] = idx;
9.155 + }
9.156 + if (_data[idx].next != -1) {
9.157 + _data[_data[idx].next].prev = idx;
9.158 + }
9.159 + _iim[_data[idx].item] = idx;
9.160 + }
9.161 + _data.pop_back();
9.162 + }
9.163 +
9.164 + void unlace(int idx) {
9.165 + if (_data[idx].prev != -1) {
9.166 + _data[_data[idx].prev].next = _data[idx].next;
9.167 + } else {
9.168 + _first[_data[idx].value] = _data[idx].next;
9.169 + }
9.170 + if (_data[idx].next != -1) {
9.171 + _data[_data[idx].next].prev = _data[idx].prev;
9.172 + }
9.173 + }
9.174 +
9.175 + void lace(int idx) {
9.176 + if (int(_first.size()) <= _data[idx].value) {
9.177 + _first.resize(_data[idx].value + 1, -1);
9.178 + }
9.179 + _data[idx].next = _first[_data[idx].value];
9.180 + if (_data[idx].next != -1) {
9.181 + _data[_data[idx].next].prev = idx;
9.182 + }
9.183 + _first[_data[idx].value] = idx;
9.184 + _data[idx].prev = -1;
9.185 + }
9.186 +
9.187 + public:
9.188 +
9.189 + /// \brief Insert a pair of item and priority into the heap.
9.190 + ///
9.191 + /// This function inserts \c p.first to the heap with priority
9.192 + /// \c p.second.
9.193 + /// \param p The pair to insert.
9.194 + /// \pre \c p.first must not be stored in the heap.
9.195 + void push(const Pair& p) {
9.196 + push(p.first, p.second);
9.197 + }
9.198 +
9.199 + /// \brief Insert an item into the heap with the given priority.
9.200 + ///
9.201 + /// This function inserts the given item into the heap with the
9.202 + /// given priority.
9.203 + /// \param i The item to insert.
9.204 + /// \param p The priority of the item.
9.205 + /// \pre \e i must not be stored in the heap.
9.206 + void push(const Item &i, const Prio &p) {
9.207 + int idx = _data.size();
9.208 + _iim[i] = idx;
9.209 + _data.push_back(BucketItem(i, p));
9.210 + lace(idx);
9.211 + if (Direction::less(p, _minimum)) {
9.212 + _minimum = p;
9.213 + }
9.214 + }
9.215 +
9.216 + /// \brief Return the item having minimum priority.
9.217 + ///
9.218 + /// This function returns the item having minimum priority.
9.219 + /// \pre The heap must be non-empty.
9.220 + Item top() const {
9.221 + while (_first[_minimum] == -1) {
9.222 + Direction::increase(_minimum);
9.223 + }
9.224 + return _data[_first[_minimum]].item;
9.225 + }
9.226 +
9.227 + /// \brief The minimum priority.
9.228 + ///
9.229 + /// This function returns the minimum priority.
9.230 + /// \pre The heap must be non-empty.
9.231 + Prio prio() const {
9.232 + while (_first[_minimum] == -1) {
9.233 + Direction::increase(_minimum);
9.234 + }
9.235 + return _minimum;
9.236 + }
9.237 +
9.238 + /// \brief Remove the item having minimum priority.
9.239 + ///
9.240 + /// This function removes the item having minimum priority.
9.241 + /// \pre The heap must be non-empty.
9.242 + void pop() {
9.243 + while (_first[_minimum] == -1) {
9.244 + Direction::increase(_minimum);
9.245 + }
9.246 + int idx = _first[_minimum];
9.247 + _iim[_data[idx].item] = -2;
9.248 + unlace(idx);
9.249 + relocateLast(idx);
9.250 + }
9.251 +
9.252 + /// \brief Remove the given item from the heap.
9.253 + ///
9.254 + /// This function removes the given item from the heap if it is
9.255 + /// already stored.
9.256 + /// \param i The item to delete.
9.257 + /// \pre \e i must be in the heap.
9.258 + void erase(const Item &i) {
9.259 + int idx = _iim[i];
9.260 + _iim[_data[idx].item] = -2;
9.261 + unlace(idx);
9.262 + relocateLast(idx);
9.263 + }
9.264 +
9.265 + /// \brief The priority of the given item.
9.266 + ///
9.267 + /// This function returns the priority of the given item.
9.268 + /// \param i The item.
9.269 + /// \pre \e i must be in the heap.
9.270 + Prio operator[](const Item &i) const {
9.271 + int idx = _iim[i];
9.272 + return _data[idx].value;
9.273 + }
9.274 +
9.275 + /// \brief Set the priority of an item or insert it, if it is
9.276 + /// not stored in the heap.
9.277 + ///
9.278 + /// This method sets the priority of the given item if it is
9.279 + /// already stored in the heap. Otherwise it inserts the given
9.280 + /// item into the heap with the given priority.
9.281 + /// \param i The item.
9.282 + /// \param p The priority.
9.283 + void set(const Item &i, const Prio &p) {
9.284 + int idx = _iim[i];
9.285 + if (idx < 0) {
9.286 + push(i, p);
9.287 + } else if (Direction::less(p, _data[idx].value)) {
9.288 + decrease(i, p);
9.289 + } else {
9.290 + increase(i, p);
9.291 + }
9.292 + }
9.293 +
9.294 + /// \brief Decrease the priority of an item to the given value.
9.295 + ///
9.296 + /// This function decreases the priority of an item to the given value.
9.297 + /// \param i The item.
9.298 + /// \param p The priority.
9.299 + /// \pre \e i must be stored in the heap with priority at least \e p.
9.300 + void decrease(const Item &i, const Prio &p) {
9.301 + int idx = _iim[i];
9.302 + unlace(idx);
9.303 + _data[idx].value = p;
9.304 + if (Direction::less(p, _minimum)) {
9.305 + _minimum = p;
9.306 + }
9.307 + lace(idx);
9.308 + }
9.309 +
9.310 + /// \brief Increase the priority of an item to the given value.
9.311 + ///
9.312 + /// This function increases the priority of an item to the given value.
9.313 + /// \param i The item.
9.314 + /// \param p The priority.
9.315 + /// \pre \e i must be stored in the heap with priority at most \e p.
9.316 + void increase(const Item &i, const Prio &p) {
9.317 + int idx = _iim[i];
9.318 + unlace(idx);
9.319 + _data[idx].value = p;
9.320 + lace(idx);
9.321 + }
9.322 +
9.323 + /// \brief Return the state of an item.
9.324 + ///
9.325 + /// This method returns \c PRE_HEAP if the given item has never
9.326 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
9.327 + /// and \c POST_HEAP otherwise.
9.328 + /// In the latter case it is possible that the item will get back
9.329 + /// to the heap again.
9.330 + /// \param i The item.
9.331 + State state(const Item &i) const {
9.332 + int idx = _iim[i];
9.333 + if (idx >= 0) idx = 0;
9.334 + return State(idx);
9.335 + }
9.336 +
9.337 + /// \brief Set the state of an item in the heap.
9.338 + ///
9.339 + /// This function sets the state of the given item in the heap.
9.340 + /// It can be used to manually clear the heap when it is important
9.341 + /// to achive better time complexity.
9.342 + /// \param i The item.
9.343 + /// \param st The state. It should not be \c IN_HEAP.
9.344 + void state(const Item& i, State st) {
9.345 + switch (st) {
9.346 + case POST_HEAP:
9.347 + case PRE_HEAP:
9.348 + if (state(i) == IN_HEAP) {
9.349 + erase(i);
9.350 + }
9.351 + _iim[i] = st;
9.352 + break;
9.353 + case IN_HEAP:
9.354 + break;
9.355 + }
9.356 + }
9.357 +
9.358 + private:
9.359 +
9.360 + struct BucketItem {
9.361 + BucketItem(const Item& _item, int _value)
9.362 + : item(_item), value(_value) {}
9.363 +
9.364 + Item item;
9.365 + int value;
9.366 +
9.367 + int prev, next;
9.368 + };
9.369 +
9.370 + ItemIntMap& _iim;
9.371 + std::vector<int> _first;
9.372 + std::vector<BucketItem> _data;
9.373 + mutable int _minimum;
9.374 +
9.375 + }; // class BucketHeap
9.376 +
9.377 + /// \ingroup heaps
9.378 + ///
9.379 + /// \brief Simplified bucket heap data structure.
9.380 + ///
9.381 + /// This class implements a simplified \e bucket \e heap data
9.382 + /// structure. It does not provide some functionality, but it is
9.383 + /// faster and simpler than BucketHeap. The main difference is
9.384 + /// that BucketHeap stores a doubly-linked list for each key while
9.385 + /// this class stores only simply-linked lists. It supports erasing
9.386 + /// only for the item having minimum priority and it does not support
9.387 + /// key increasing and decreasing.
9.388 + ///
9.389 + /// Note that this implementation does not conform to the
9.390 + /// \ref concepts::Heap "heap concept" due to the lack of some
9.391 + /// functionality.
9.392 + ///
9.393 + /// \tparam IM A read-writable item map with \c int values, used
9.394 + /// internally to handle the cross references.
9.395 + /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
9.396 + /// The default is \e min-heap. If this parameter is set to \c false,
9.397 + /// then the comparison is reversed, so the top(), prio() and pop()
9.398 + /// functions deal with the item having maximum priority instead of the
9.399 + /// minimum.
9.400 + ///
9.401 + /// \sa BucketHeap
9.402 + template <typename IM, bool MIN = true >
9.403 + class SimpleBucketHeap {
9.404 +
9.405 + public:
9.406 +
9.407 + /// Type of the item-int map.
9.408 + typedef IM ItemIntMap;
9.409 + /// Type of the priorities.
9.410 + typedef int Prio;
9.411 + /// Type of the items stored in the heap.
9.412 + typedef typename ItemIntMap::Key Item;
9.413 + /// Type of the item-priority pairs.
9.414 + typedef std::pair<Item,Prio> Pair;
9.415 +
9.416 + private:
9.417 +
9.418 + typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
9.419 +
9.420 + public:
9.421 +
9.422 + /// \brief Type to represent the states of the items.
9.423 + ///
9.424 + /// Each item has a state associated to it. It can be "in heap",
9.425 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
9.426 + /// heap's point of view, but may be useful to the user.
9.427 + ///
9.428 + /// The item-int map must be initialized in such way that it assigns
9.429 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
9.430 + enum State {
9.431 + IN_HEAP = 0, ///< = 0.
9.432 + PRE_HEAP = -1, ///< = -1.
9.433 + POST_HEAP = -2 ///< = -2.
9.434 + };
9.435 +
9.436 + public:
9.437 +
9.438 + /// \brief Constructor.
9.439 + ///
9.440 + /// Constructor.
9.441 + /// \param map A map that assigns \c int values to the items.
9.442 + /// It is used internally to handle the cross references.
9.443 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
9.444 + explicit SimpleBucketHeap(ItemIntMap &map)
9.445 + : _iim(map), _free(-1), _num(0), _minimum(0) {}
9.446 +
9.447 + /// \brief The number of items stored in the heap.
9.448 + ///
9.449 + /// This function returns the number of items stored in the heap.
9.450 + int size() const { return _num; }
9.451 +
9.452 + /// \brief Check if the heap is empty.
9.453 + ///
9.454 + /// This function returns \c true if the heap is empty.
9.455 + bool empty() const { return _num == 0; }
9.456 +
9.457 + /// \brief Make the heap empty.
9.458 + ///
9.459 + /// This functon makes the heap empty.
9.460 + /// It does not change the cross reference map. If you want to reuse
9.461 + /// a heap that is not surely empty, you should first clear it and
9.462 + /// then you should set the cross reference map to \c PRE_HEAP
9.463 + /// for each item.
9.464 + void clear() {
9.465 + _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
9.466 + }
9.467 +
9.468 + /// \brief Insert a pair of item and priority into the heap.
9.469 + ///
9.470 + /// This function inserts \c p.first to the heap with priority
9.471 + /// \c p.second.
9.472 + /// \param p The pair to insert.
9.473 + /// \pre \c p.first must not be stored in the heap.
9.474 + void push(const Pair& p) {
9.475 + push(p.first, p.second);
9.476 + }
9.477 +
9.478 + /// \brief Insert an item into the heap with the given priority.
9.479 + ///
9.480 + /// This function inserts the given item into the heap with the
9.481 + /// given priority.
9.482 + /// \param i The item to insert.
9.483 + /// \param p The priority of the item.
9.484 + /// \pre \e i must not be stored in the heap.
9.485 + void push(const Item &i, const Prio &p) {
9.486 + int idx;
9.487 + if (_free == -1) {
9.488 + idx = _data.size();
9.489 + _data.push_back(BucketItem(i));
9.490 + } else {
9.491 + idx = _free;
9.492 + _free = _data[idx].next;
9.493 + _data[idx].item = i;
9.494 + }
9.495 + _iim[i] = idx;
9.496 + if (p >= int(_first.size())) _first.resize(p + 1, -1);
9.497 + _data[idx].next = _first[p];
9.498 + _first[p] = idx;
9.499 + if (Direction::less(p, _minimum)) {
9.500 + _minimum = p;
9.501 + }
9.502 + ++_num;
9.503 + }
9.504 +
9.505 + /// \brief Return the item having minimum priority.
9.506 + ///
9.507 + /// This function returns the item having minimum priority.
9.508 + /// \pre The heap must be non-empty.
9.509 + Item top() const {
9.510 + while (_first[_minimum] == -1) {
9.511 + Direction::increase(_minimum);
9.512 + }
9.513 + return _data[_first[_minimum]].item;
9.514 + }
9.515 +
9.516 + /// \brief The minimum priority.
9.517 + ///
9.518 + /// This function returns the minimum priority.
9.519 + /// \pre The heap must be non-empty.
9.520 + Prio prio() const {
9.521 + while (_first[_minimum] == -1) {
9.522 + Direction::increase(_minimum);
9.523 + }
9.524 + return _minimum;
9.525 + }
9.526 +
9.527 + /// \brief Remove the item having minimum priority.
9.528 + ///
9.529 + /// This function removes the item having minimum priority.
9.530 + /// \pre The heap must be non-empty.
9.531 + void pop() {
9.532 + while (_first[_minimum] == -1) {
9.533 + Direction::increase(_minimum);
9.534 + }
9.535 + int idx = _first[_minimum];
9.536 + _iim[_data[idx].item] = -2;
9.537 + _first[_minimum] = _data[idx].next;
9.538 + _data[idx].next = _free;
9.539 + _free = idx;
9.540 + --_num;
9.541 + }
9.542 +
9.543 + /// \brief The priority of the given item.
9.544 + ///
9.545 + /// This function returns the priority of the given item.
9.546 + /// \param i The item.
9.547 + /// \pre \e i must be in the heap.
9.548 + /// \warning This operator is not a constant time function because
9.549 + /// it scans the whole data structure to find the proper value.
9.550 + Prio operator[](const Item &i) const {
9.551 + for (int k = 0; k < int(_first.size()); ++k) {
9.552 + int idx = _first[k];
9.553 + while (idx != -1) {
9.554 + if (_data[idx].item == i) {
9.555 + return k;
9.556 + }
9.557 + idx = _data[idx].next;
9.558 + }
9.559 + }
9.560 + return -1;
9.561 + }
9.562 +
9.563 + /// \brief Return the state of an item.
9.564 + ///
9.565 + /// This method returns \c PRE_HEAP if the given item has never
9.566 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
9.567 + /// and \c POST_HEAP otherwise.
9.568 + /// In the latter case it is possible that the item will get back
9.569 + /// to the heap again.
9.570 + /// \param i The item.
9.571 + State state(const Item &i) const {
9.572 + int idx = _iim[i];
9.573 + if (idx >= 0) idx = 0;
9.574 + return State(idx);
9.575 + }
9.576 +
9.577 + private:
9.578 +
9.579 + struct BucketItem {
9.580 + BucketItem(const Item& _item)
9.581 + : item(_item) {}
9.582 +
9.583 + Item item;
9.584 + int next;
9.585 + };
9.586 +
9.587 + ItemIntMap& _iim;
9.588 + std::vector<int> _first;
9.589 + std::vector<BucketItem> _data;
9.590 + int _free, _num;
9.591 + mutable int _minimum;
9.592 +
9.593 + }; // class SimpleBucketHeap
9.594 +
9.595 +}
9.596 +
9.597 +#endif
10.1 --- a/lemon/circulation.h Sun Aug 02 12:40:20 2009 +0200
10.2 +++ b/lemon/circulation.h Fri Sep 25 09:13:03 2009 +0200
10.3 @@ -72,7 +72,11 @@
10.4 /// The type of the map that stores the flow values.
10.5 /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
10.6 /// concept.
10.7 +#ifdef DOXYGEN
10.8 + typedef GR::ArcMap<Value> FlowMap;
10.9 +#else
10.10 typedef typename Digraph::template ArcMap<Value> FlowMap;
10.11 +#endif
10.12
10.13 /// \brief Instantiates a FlowMap.
10.14 ///
10.15 @@ -87,9 +91,12 @@
10.16 ///
10.17 /// The elevator type used by the algorithm.
10.18 ///
10.19 - /// \sa Elevator
10.20 - /// \sa LinkedElevator
10.21 + /// \sa Elevator, LinkedElevator
10.22 +#ifdef DOXYGEN
10.23 + typedef lemon::Elevator<GR, GR::Node> Elevator;
10.24 +#else
10.25 typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
10.26 +#endif
10.27
10.28 /// \brief Instantiates an Elevator.
10.29 ///
10.30 @@ -450,25 +457,27 @@
10.31 return *_level;
10.32 }
10.33
10.34 - /// \brief Sets the tolerance used by algorithm.
10.35 + /// \brief Sets the tolerance used by the algorithm.
10.36 ///
10.37 - /// Sets the tolerance used by algorithm.
10.38 - Circulation& tolerance(const Tolerance& tolerance) const {
10.39 + /// Sets the tolerance object used by the algorithm.
10.40 + /// \return <tt>(*this)</tt>
10.41 + Circulation& tolerance(const Tolerance& tolerance) {
10.42 _tol = tolerance;
10.43 return *this;
10.44 }
10.45
10.46 /// \brief Returns a const reference to the tolerance.
10.47 ///
10.48 - /// Returns a const reference to the tolerance.
10.49 + /// Returns a const reference to the tolerance object used by
10.50 + /// the algorithm.
10.51 const Tolerance& tolerance() const {
10.52 - return tolerance;
10.53 + return _tol;
10.54 }
10.55
10.56 /// \name Execution Control
10.57 /// The simplest way to execute the algorithm is to call \ref run().\n
10.58 - /// If you need more control on the initial solution or the execution,
10.59 - /// first you have to call one of the \ref init() functions, then
10.60 + /// If you need better control on the initial solution or the execution,
10.61 + /// you have to call one of the \ref init() functions first, then
10.62 /// the \ref start() function.
10.63
10.64 ///@{
11.1 --- a/lemon/concepts/heap.h Sun Aug 02 12:40:20 2009 +0200
11.2 +++ b/lemon/concepts/heap.h Fri Sep 25 09:13:03 2009 +0200
11.3 @@ -16,13 +16,13 @@
11.4 *
11.5 */
11.6
11.7 +#ifndef LEMON_CONCEPTS_HEAP_H
11.8 +#define LEMON_CONCEPTS_HEAP_H
11.9 +
11.10 ///\ingroup concept
11.11 ///\file
11.12 ///\brief The concept of heaps.
11.13
11.14 -#ifndef LEMON_CONCEPTS_HEAP_H
11.15 -#define LEMON_CONCEPTS_HEAP_H
11.16 -
11.17 #include <lemon/core.h>
11.18 #include <lemon/concept_check.h>
11.19
11.20 @@ -35,21 +35,27 @@
11.21
11.22 /// \brief The heap concept.
11.23 ///
11.24 - /// Concept class describing the main interface of heaps. A \e heap
11.25 - /// is a data structure for storing items with specified values called
11.26 - /// \e priorities in such a way that finding the item with minimum
11.27 - /// priority is efficient. In a heap one can change the priority of an
11.28 - /// item, add or erase an item, etc.
11.29 + /// This concept class describes the main interface of heaps.
11.30 + /// The various \ref heaps "heap structures" are efficient
11.31 + /// implementations of the abstract data type \e priority \e queue.
11.32 + /// They store items with specified values called \e priorities
11.33 + /// in such a way that finding and removing the item with minimum
11.34 + /// priority are efficient. The basic operations are adding and
11.35 + /// erasing items, changing the priority of an item, etc.
11.36 ///
11.37 - /// \tparam PR Type of the priority of the items.
11.38 - /// \tparam IM A read and writable item map with int values, used
11.39 + /// Heaps are crucial in several algorithms, such as Dijkstra and Prim.
11.40 + /// Any class that conforms to this concept can be used easily in such
11.41 + /// algorithms.
11.42 + ///
11.43 + /// \tparam PR Type of the priorities of the items.
11.44 + /// \tparam IM A read-writable item map with \c int values, used
11.45 /// internally to handle the cross references.
11.46 - /// \tparam Comp A functor class for the ordering of the priorities.
11.47 + /// \tparam CMP A functor class for comparing the priorities.
11.48 /// The default is \c std::less<PR>.
11.49 #ifdef DOXYGEN
11.50 - template <typename PR, typename IM, typename Comp = std::less<PR> >
11.51 + template <typename PR, typename IM, typename CMP>
11.52 #else
11.53 - template <typename PR, typename IM>
11.54 + template <typename PR, typename IM, typename CMP = std::less<PR> >
11.55 #endif
11.56 class Heap {
11.57 public:
11.58 @@ -64,109 +70,125 @@
11.59 /// \brief Type to represent the states of the items.
11.60 ///
11.61 /// Each item has a state associated to it. It can be "in heap",
11.62 - /// "pre heap" or "post heap". The later two are indifferent
11.63 - /// from the point of view of the heap, but may be useful for
11.64 - /// the user.
11.65 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
11.66 + /// heap's point of view, but may be useful to the user.
11.67 ///
11.68 /// The item-int map must be initialized in such way that it assigns
11.69 /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
11.70 enum State {
11.71 IN_HEAP = 0, ///< = 0. The "in heap" state constant.
11.72 - PRE_HEAP = -1, ///< = -1. The "pre heap" state constant.
11.73 - POST_HEAP = -2 ///< = -2. The "post heap" state constant.
11.74 + PRE_HEAP = -1, ///< = -1. The "pre-heap" state constant.
11.75 + POST_HEAP = -2 ///< = -2. The "post-heap" state constant.
11.76 };
11.77
11.78 - /// \brief The constructor.
11.79 + /// \brief Constructor.
11.80 ///
11.81 - /// The constructor.
11.82 + /// Constructor.
11.83 /// \param map A map that assigns \c int values to keys of type
11.84 /// \c Item. It is used internally by the heap implementations to
11.85 /// handle the cross references. The assigned value must be
11.86 - /// \c PRE_HEAP (<tt>-1</tt>) for every item.
11.87 + /// \c PRE_HEAP (<tt>-1</tt>) for each item.
11.88 explicit Heap(ItemIntMap &map) {}
11.89
11.90 + /// \brief Constructor.
11.91 + ///
11.92 + /// Constructor.
11.93 + /// \param map A map that assigns \c int values to keys of type
11.94 + /// \c Item. It is used internally by the heap implementations to
11.95 + /// handle the cross references. The assigned value must be
11.96 + /// \c PRE_HEAP (<tt>-1</tt>) for each item.
11.97 + /// \param comp The function object used for comparing the priorities.
11.98 + explicit Heap(ItemIntMap &map, const CMP &comp) {}
11.99 +
11.100 /// \brief The number of items stored in the heap.
11.101 ///
11.102 - /// Returns the number of items stored in the heap.
11.103 + /// This function returns the number of items stored in the heap.
11.104 int size() const { return 0; }
11.105
11.106 - /// \brief Checks if the heap is empty.
11.107 + /// \brief Check if the heap is empty.
11.108 ///
11.109 - /// Returns \c true if the heap is empty.
11.110 + /// This function returns \c true if the heap is empty.
11.111 bool empty() const { return false; }
11.112
11.113 - /// \brief Makes the heap empty.
11.114 + /// \brief Make the heap empty.
11.115 ///
11.116 - /// Makes the heap empty.
11.117 - void clear();
11.118 + /// This functon makes the heap empty.
11.119 + /// It does not change the cross reference map. If you want to reuse
11.120 + /// a heap that is not surely empty, you should first clear it and
11.121 + /// then you should set the cross reference map to \c PRE_HEAP
11.122 + /// for each item.
11.123 + void clear() {}
11.124
11.125 - /// \brief Inserts an item into the heap with the given priority.
11.126 + /// \brief Insert an item into the heap with the given priority.
11.127 ///
11.128 - /// Inserts the given item into the heap with the given priority.
11.129 + /// This function inserts the given item into the heap with the
11.130 + /// given priority.
11.131 /// \param i The item to insert.
11.132 /// \param p The priority of the item.
11.133 + /// \pre \e i must not be stored in the heap.
11.134 void push(const Item &i, const Prio &p) {}
11.135
11.136 - /// \brief Returns the item having minimum priority.
11.137 + /// \brief Return the item having minimum priority.
11.138 ///
11.139 - /// Returns the item having minimum priority.
11.140 + /// This function returns the item having minimum priority.
11.141 /// \pre The heap must be non-empty.
11.142 Item top() const {}
11.143
11.144 /// \brief The minimum priority.
11.145 ///
11.146 - /// Returns the minimum priority.
11.147 + /// This function returns the minimum priority.
11.148 /// \pre The heap must be non-empty.
11.149 Prio prio() const {}
11.150
11.151 - /// \brief Removes the item having minimum priority.
11.152 + /// \brief Remove the item having minimum priority.
11.153 ///
11.154 - /// Removes the item having minimum priority.
11.155 + /// This function removes the item having minimum priority.
11.156 /// \pre The heap must be non-empty.
11.157 void pop() {}
11.158
11.159 - /// \brief Removes an item from the heap.
11.160 + /// \brief Remove the given item from the heap.
11.161 ///
11.162 - /// Removes the given item from the heap if it is already stored.
11.163 + /// This function removes the given item from the heap if it is
11.164 + /// already stored.
11.165 /// \param i The item to delete.
11.166 + /// \pre \e i must be in the heap.
11.167 void erase(const Item &i) {}
11.168
11.169 - /// \brief The priority of an item.
11.170 + /// \brief The priority of the given item.
11.171 ///
11.172 - /// Returns the priority of the given item.
11.173 + /// This function returns the priority of the given item.
11.174 /// \param i The item.
11.175 - /// \pre \c i must be in the heap.
11.176 + /// \pre \e i must be in the heap.
11.177 Prio operator[](const Item &i) const {}
11.178
11.179 - /// \brief Sets the priority of an item or inserts it, if it is
11.180 + /// \brief Set the priority of an item or insert it, if it is
11.181 /// not stored in the heap.
11.182 ///
11.183 /// This method sets the priority of the given item if it is
11.184 - /// already stored in the heap.
11.185 - /// Otherwise it inserts the given item with the given priority.
11.186 + /// already stored in the heap. Otherwise it inserts the given
11.187 + /// item into the heap with the given priority.
11.188 ///
11.189 /// \param i The item.
11.190 /// \param p The priority.
11.191 void set(const Item &i, const Prio &p) {}
11.192
11.193 - /// \brief Decreases the priority of an item to the given value.
11.194 + /// \brief Decrease the priority of an item to the given value.
11.195 ///
11.196 - /// Decreases the priority of an item to the given value.
11.197 + /// This function decreases the priority of an item to the given value.
11.198 /// \param i The item.
11.199 /// \param p The priority.
11.200 - /// \pre \c i must be stored in the heap with priority at least \c p.
11.201 + /// \pre \e i must be stored in the heap with priority at least \e p.
11.202 void decrease(const Item &i, const Prio &p) {}
11.203
11.204 - /// \brief Increases the priority of an item to the given value.
11.205 + /// \brief Increase the priority of an item to the given value.
11.206 ///
11.207 - /// Increases the priority of an item to the given value.
11.208 + /// This function increases the priority of an item to the given value.
11.209 /// \param i The item.
11.210 /// \param p The priority.
11.211 - /// \pre \c i must be stored in the heap with priority at most \c p.
11.212 + /// \pre \e i must be stored in the heap with priority at most \e p.
11.213 void increase(const Item &i, const Prio &p) {}
11.214
11.215 - /// \brief Returns if an item is in, has already been in, or has
11.216 - /// never been in the heap.
11.217 + /// \brief Return the state of an item.
11.218 ///
11.219 /// This method returns \c PRE_HEAP if the given item has never
11.220 /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
11.221 @@ -176,11 +198,11 @@
11.222 /// \param i The item.
11.223 State state(const Item &i) const {}
11.224
11.225 - /// \brief Sets the state of an item in the heap.
11.226 + /// \brief Set the state of an item in the heap.
11.227 ///
11.228 - /// Sets the state of the given item in the heap. It can be used
11.229 - /// to manually clear the heap when it is important to achive the
11.230 - /// better time complexity.
11.231 + /// This function sets the state of the given item in the heap.
11.232 + /// It can be used to manually clear the heap when it is important
11.233 + /// to achive better time complexity.
11.234 /// \param i The item.
11.235 /// \param st The state. It should not be \c IN_HEAP.
11.236 void state(const Item& i, State st) {}
12.1 --- a/lemon/dfs.h Sun Aug 02 12:40:20 2009 +0200
12.2 +++ b/lemon/dfs.h Fri Sep 25 09:13:03 2009 +0200
12.3 @@ -412,8 +412,8 @@
12.4 ///\name Execution Control
12.5 ///The simplest way to execute the DFS algorithm is to use one of the
12.6 ///member functions called \ref run(Node) "run()".\n
12.7 - ///If you need more control on the execution, first you have to call
12.8 - ///\ref init(), then you can add a source node with \ref addSource()
12.9 + ///If you need better control on the execution, you have to call
12.10 + ///\ref init() first, then you can add a source node with \ref addSource()
12.11 ///and perform the actual computation with \ref start().
12.12 ///This procedure can be repeated if there are nodes that have not
12.13 ///been reached.
12.14 @@ -1364,8 +1364,8 @@
12.15 /// \name Execution Control
12.16 /// The simplest way to execute the DFS algorithm is to use one of the
12.17 /// member functions called \ref run(Node) "run()".\n
12.18 - /// If you need more control on the execution, first you have to call
12.19 - /// \ref init(), then you can add a source node with \ref addSource()
12.20 + /// If you need better control on the execution, you have to call
12.21 + /// \ref init() first, then you can add a source node with \ref addSource()
12.22 /// and perform the actual computation with \ref start().
12.23 /// This procedure can be repeated if there are nodes that have not
12.24 /// been reached.
13.1 --- a/lemon/dijkstra.h Sun Aug 02 12:40:20 2009 +0200
13.2 +++ b/lemon/dijkstra.h Fri Sep 25 09:13:03 2009 +0200
13.3 @@ -589,8 +589,8 @@
13.4 ///\name Execution Control
13.5 ///The simplest way to execute the %Dijkstra algorithm is to use
13.6 ///one of the member functions called \ref run(Node) "run()".\n
13.7 - ///If you need more control on the execution, first you have to call
13.8 - ///\ref init(), then you can add several source nodes with
13.9 + ///If you need better control on the execution, you have to call
13.10 + ///\ref init() first, then you can add several source nodes with
13.11 ///\ref addSource(). Finally the actual path computation can be
13.12 ///performed with one of the \ref start() functions.
13.13
14.1 --- a/lemon/dim2.h Sun Aug 02 12:40:20 2009 +0200
14.2 +++ b/lemon/dim2.h Fri Sep 25 09:13:03 2009 +0200
14.3 @@ -21,16 +21,9 @@
14.4
14.5 #include <iostream>
14.6
14.7 -///\ingroup misc
14.8 +///\ingroup geomdat
14.9 ///\file
14.10 ///\brief A simple two dimensional vector and a bounding box implementation
14.11 -///
14.12 -/// The class \ref lemon::dim2::Point "dim2::Point" implements
14.13 -/// a two dimensional vector with the usual operations.
14.14 -///
14.15 -/// The class \ref lemon::dim2::Box "dim2::Box" can be used to determine
14.16 -/// the rectangular bounding box of a set of
14.17 -/// \ref lemon::dim2::Point "dim2::Point"'s.
14.18
14.19 namespace lemon {
14.20
14.21 @@ -40,7 +33,7 @@
14.22 ///tools for handling two dimensional coordinates
14.23 namespace dim2 {
14.24
14.25 - /// \addtogroup misc
14.26 + /// \addtogroup geomdat
14.27 /// @{
14.28
14.29 /// Two dimensional vector (plain vector)
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/lemon/fib_heap.h Fri Sep 25 09:13:03 2009 +0200
15.3 @@ -0,0 +1,475 @@
15.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
15.5 + *
15.6 + * This file is a part of LEMON, a generic C++ optimization library.
15.7 + *
15.8 + * Copyright (C) 2003-2009
15.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
15.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
15.11 + *
15.12 + * Permission to use, modify and distribute this software is granted
15.13 + * provided that this copyright notice appears in all copies. For
15.14 + * precise terms see the accompanying LICENSE file.
15.15 + *
15.16 + * This software is provided "AS IS" with no warranty of any kind,
15.17 + * express or implied, and with no claim as to its suitability for any
15.18 + * purpose.
15.19 + *
15.20 + */
15.21 +
15.22 +#ifndef LEMON_FIB_HEAP_H
15.23 +#define LEMON_FIB_HEAP_H
15.24 +
15.25 +///\file
15.26 +///\ingroup heaps
15.27 +///\brief Fibonacci heap implementation.
15.28 +
15.29 +#include <vector>
15.30 +#include <utility>
15.31 +#include <functional>
15.32 +#include <lemon/math.h>
15.33 +
15.34 +namespace lemon {
15.35 +
15.36 + /// \ingroup heaps
15.37 + ///
15.38 + /// \brief Fibonacci heap data structure.
15.39 + ///
15.40 + /// This class implements the \e Fibonacci \e heap data structure.
15.41 + /// It fully conforms to the \ref concepts::Heap "heap concept".
15.42 + ///
15.43 + /// The methods \ref increase() and \ref erase() are not efficient in a
15.44 + /// Fibonacci heap. In case of many calls of these operations, it is
15.45 + /// better to use other heap structure, e.g. \ref BinHeap "binary heap".
15.46 + ///
15.47 + /// \tparam PR Type of the priorities of the items.
15.48 + /// \tparam IM A read-writable item map with \c int values, used
15.49 + /// internally to handle the cross references.
15.50 + /// \tparam CMP A functor class for comparing the priorities.
15.51 + /// The default is \c std::less<PR>.
15.52 +#ifdef DOXYGEN
15.53 + template <typename PR, typename IM, typename CMP>
15.54 +#else
15.55 + template <typename PR, typename IM, typename CMP = std::less<PR> >
15.56 +#endif
15.57 + class FibHeap {
15.58 + public:
15.59 +
15.60 + /// Type of the item-int map.
15.61 + typedef IM ItemIntMap;
15.62 + /// Type of the priorities.
15.63 + typedef PR Prio;
15.64 + /// Type of the items stored in the heap.
15.65 + typedef typename ItemIntMap::Key Item;
15.66 + /// Type of the item-priority pairs.
15.67 + typedef std::pair<Item,Prio> Pair;
15.68 + /// Functor type for comparing the priorities.
15.69 + typedef CMP Compare;
15.70 +
15.71 + private:
15.72 + class Store;
15.73 +
15.74 + std::vector<Store> _data;
15.75 + int _minimum;
15.76 + ItemIntMap &_iim;
15.77 + Compare _comp;
15.78 + int _num;
15.79 +
15.80 + public:
15.81 +
15.82 + /// \brief Type to represent the states of the items.
15.83 + ///
15.84 + /// Each item has a state associated to it. It can be "in heap",
15.85 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
15.86 + /// heap's point of view, but may be useful to the user.
15.87 + ///
15.88 + /// The item-int map must be initialized in such way that it assigns
15.89 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
15.90 + enum State {
15.91 + IN_HEAP = 0, ///< = 0.
15.92 + PRE_HEAP = -1, ///< = -1.
15.93 + POST_HEAP = -2 ///< = -2.
15.94 + };
15.95 +
15.96 + /// \brief Constructor.
15.97 + ///
15.98 + /// Constructor.
15.99 + /// \param map A map that assigns \c int values to the items.
15.100 + /// It is used internally to handle the cross references.
15.101 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
15.102 + explicit FibHeap(ItemIntMap &map)
15.103 + : _minimum(0), _iim(map), _num() {}
15.104 +
15.105 + /// \brief Constructor.
15.106 + ///
15.107 + /// Constructor.
15.108 + /// \param map A map that assigns \c int values to the items.
15.109 + /// It is used internally to handle the cross references.
15.110 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
15.111 + /// \param comp The function object used for comparing the priorities.
15.112 + FibHeap(ItemIntMap &map, const Compare &comp)
15.113 + : _minimum(0), _iim(map), _comp(comp), _num() {}
15.114 +
15.115 + /// \brief The number of items stored in the heap.
15.116 + ///
15.117 + /// This function returns the number of items stored in the heap.
15.118 + int size() const { return _num; }
15.119 +
15.120 + /// \brief Check if the heap is empty.
15.121 + ///
15.122 + /// This function returns \c true if the heap is empty.
15.123 + bool empty() const { return _num==0; }
15.124 +
15.125 + /// \brief Make the heap empty.
15.126 + ///
15.127 + /// This functon makes the heap empty.
15.128 + /// It does not change the cross reference map. If you want to reuse
15.129 + /// a heap that is not surely empty, you should first clear it and
15.130 + /// then you should set the cross reference map to \c PRE_HEAP
15.131 + /// for each item.
15.132 + void clear() {
15.133 + _data.clear(); _minimum = 0; _num = 0;
15.134 + }
15.135 +
15.136 + /// \brief Insert an item into the heap with the given priority.
15.137 + ///
15.138 + /// This function inserts the given item into the heap with the
15.139 + /// given priority.
15.140 + /// \param item The item to insert.
15.141 + /// \param prio The priority of the item.
15.142 + /// \pre \e item must not be stored in the heap.
15.143 + void push (const Item& item, const Prio& prio) {
15.144 + int i=_iim[item];
15.145 + if ( i < 0 ) {
15.146 + int s=_data.size();
15.147 + _iim.set( item, s );
15.148 + Store st;
15.149 + st.name=item;
15.150 + _data.push_back(st);
15.151 + i=s;
15.152 + } else {
15.153 + _data[i].parent=_data[i].child=-1;
15.154 + _data[i].degree=0;
15.155 + _data[i].in=true;
15.156 + _data[i].marked=false;
15.157 + }
15.158 +
15.159 + if ( _num ) {
15.160 + _data[_data[_minimum].right_neighbor].left_neighbor=i;
15.161 + _data[i].right_neighbor=_data[_minimum].right_neighbor;
15.162 + _data[_minimum].right_neighbor=i;
15.163 + _data[i].left_neighbor=_minimum;
15.164 + if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
15.165 + } else {
15.166 + _data[i].right_neighbor=_data[i].left_neighbor=i;
15.167 + _minimum=i;
15.168 + }
15.169 + _data[i].prio=prio;
15.170 + ++_num;
15.171 + }
15.172 +
15.173 + /// \brief Return the item having minimum priority.
15.174 + ///
15.175 + /// This function returns the item having minimum priority.
15.176 + /// \pre The heap must be non-empty.
15.177 + Item top() const { return _data[_minimum].name; }
15.178 +
15.179 + /// \brief The minimum priority.
15.180 + ///
15.181 + /// This function returns the minimum priority.
15.182 + /// \pre The heap must be non-empty.
15.183 + Prio prio() const { return _data[_minimum].prio; }
15.184 +
15.185 + /// \brief Remove the item having minimum priority.
15.186 + ///
15.187 + /// This function removes the item having minimum priority.
15.188 + /// \pre The heap must be non-empty.
15.189 + void pop() {
15.190 + /*The first case is that there are only one root.*/
15.191 + if ( _data[_minimum].left_neighbor==_minimum ) {
15.192 + _data[_minimum].in=false;
15.193 + if ( _data[_minimum].degree!=0 ) {
15.194 + makeRoot(_data[_minimum].child);
15.195 + _minimum=_data[_minimum].child;
15.196 + balance();
15.197 + }
15.198 + } else {
15.199 + int right=_data[_minimum].right_neighbor;
15.200 + unlace(_minimum);
15.201 + _data[_minimum].in=false;
15.202 + if ( _data[_minimum].degree > 0 ) {
15.203 + int left=_data[_minimum].left_neighbor;
15.204 + int child=_data[_minimum].child;
15.205 + int last_child=_data[child].left_neighbor;
15.206 +
15.207 + makeRoot(child);
15.208 +
15.209 + _data[left].right_neighbor=child;
15.210 + _data[child].left_neighbor=left;
15.211 + _data[right].left_neighbor=last_child;
15.212 + _data[last_child].right_neighbor=right;
15.213 + }
15.214 + _minimum=right;
15.215 + balance();
15.216 + } // the case where there are more roots
15.217 + --_num;
15.218 + }
15.219 +
15.220 + /// \brief Remove the given item from the heap.
15.221 + ///
15.222 + /// This function removes the given item from the heap if it is
15.223 + /// already stored.
15.224 + /// \param item The item to delete.
15.225 + /// \pre \e item must be in the heap.
15.226 + void erase (const Item& item) {
15.227 + int i=_iim[item];
15.228 +
15.229 + if ( i >= 0 && _data[i].in ) {
15.230 + if ( _data[i].parent!=-1 ) {
15.231 + int p=_data[i].parent;
15.232 + cut(i,p);
15.233 + cascade(p);
15.234 + }
15.235 + _minimum=i; //As if its prio would be -infinity
15.236 + pop();
15.237 + }
15.238 + }
15.239 +
15.240 + /// \brief The priority of the given item.
15.241 + ///
15.242 + /// This function returns the priority of the given item.
15.243 + /// \param item The item.
15.244 + /// \pre \e item must be in the heap.
15.245 + Prio operator[](const Item& item) const {
15.246 + return _data[_iim[item]].prio;
15.247 + }
15.248 +
15.249 + /// \brief Set the priority of an item or insert it, if it is
15.250 + /// not stored in the heap.
15.251 + ///
15.252 + /// This method sets the priority of the given item if it is
15.253 + /// already stored in the heap. Otherwise it inserts the given
15.254 + /// item into the heap with the given priority.
15.255 + /// \param item The item.
15.256 + /// \param prio The priority.
15.257 + void set (const Item& item, const Prio& prio) {
15.258 + int i=_iim[item];
15.259 + if ( i >= 0 && _data[i].in ) {
15.260 + if ( _comp(prio, _data[i].prio) ) decrease(item, prio);
15.261 + if ( _comp(_data[i].prio, prio) ) increase(item, prio);
15.262 + } else push(item, prio);
15.263 + }
15.264 +
15.265 + /// \brief Decrease the priority of an item to the given value.
15.266 + ///
15.267 + /// This function decreases the priority of an item to the given value.
15.268 + /// \param item The item.
15.269 + /// \param prio The priority.
15.270 + /// \pre \e item must be stored in the heap with priority at least \e prio.
15.271 + void decrease (const Item& item, const Prio& prio) {
15.272 + int i=_iim[item];
15.273 + _data[i].prio=prio;
15.274 + int p=_data[i].parent;
15.275 +
15.276 + if ( p!=-1 && _comp(prio, _data[p].prio) ) {
15.277 + cut(i,p);
15.278 + cascade(p);
15.279 + }
15.280 + if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
15.281 + }
15.282 +
15.283 + /// \brief Increase the priority of an item to the given value.
15.284 + ///
15.285 + /// This function increases the priority of an item to the given value.
15.286 + /// \param item The item.
15.287 + /// \param prio The priority.
15.288 + /// \pre \e item must be stored in the heap with priority at most \e prio.
15.289 + void increase (const Item& item, const Prio& prio) {
15.290 + erase(item);
15.291 + push(item, prio);
15.292 + }
15.293 +
15.294 + /// \brief Return the state of an item.
15.295 + ///
15.296 + /// This method returns \c PRE_HEAP if the given item has never
15.297 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
15.298 + /// and \c POST_HEAP otherwise.
15.299 + /// In the latter case it is possible that the item will get back
15.300 + /// to the heap again.
15.301 + /// \param item The item.
15.302 + State state(const Item &item) const {
15.303 + int i=_iim[item];
15.304 + if( i>=0 ) {
15.305 + if ( _data[i].in ) i=0;
15.306 + else i=-2;
15.307 + }
15.308 + return State(i);
15.309 + }
15.310 +
15.311 + /// \brief Set the state of an item in the heap.
15.312 + ///
15.313 + /// This function sets the state of the given item in the heap.
15.314 + /// It can be used to manually clear the heap when it is important
15.315 + /// to achive better time complexity.
15.316 + /// \param i The item.
15.317 + /// \param st The state. It should not be \c IN_HEAP.
15.318 + void state(const Item& i, State st) {
15.319 + switch (st) {
15.320 + case POST_HEAP:
15.321 + case PRE_HEAP:
15.322 + if (state(i) == IN_HEAP) {
15.323 + erase(i);
15.324 + }
15.325 + _iim[i] = st;
15.326 + break;
15.327 + case IN_HEAP:
15.328 + break;
15.329 + }
15.330 + }
15.331 +
15.332 + private:
15.333 +
15.334 + void balance() {
15.335 +
15.336 + int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
15.337 +
15.338 + std::vector<int> A(maxdeg,-1);
15.339 +
15.340 + /*
15.341 + *Recall that now minimum does not point to the minimum prio element.
15.342 + *We set minimum to this during balance().
15.343 + */
15.344 + int anchor=_data[_minimum].left_neighbor;
15.345 + int next=_minimum;
15.346 + bool end=false;
15.347 +
15.348 + do {
15.349 + int active=next;
15.350 + if ( anchor==active ) end=true;
15.351 + int d=_data[active].degree;
15.352 + next=_data[active].right_neighbor;
15.353 +
15.354 + while (A[d]!=-1) {
15.355 + if( _comp(_data[active].prio, _data[A[d]].prio) ) {
15.356 + fuse(active,A[d]);
15.357 + } else {
15.358 + fuse(A[d],active);
15.359 + active=A[d];
15.360 + }
15.361 + A[d]=-1;
15.362 + ++d;
15.363 + }
15.364 + A[d]=active;
15.365 + } while ( !end );
15.366 +
15.367 +
15.368 + while ( _data[_minimum].parent >=0 )
15.369 + _minimum=_data[_minimum].parent;
15.370 + int s=_minimum;
15.371 + int m=_minimum;
15.372 + do {
15.373 + if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
15.374 + s=_data[s].right_neighbor;
15.375 + } while ( s != m );
15.376 + }
15.377 +
15.378 + void makeRoot(int c) {
15.379 + int s=c;
15.380 + do {
15.381 + _data[s].parent=-1;
15.382 + s=_data[s].right_neighbor;
15.383 + } while ( s != c );
15.384 + }
15.385 +
15.386 + void cut(int a, int b) {
15.387 + /*
15.388 + *Replacing a from the children of b.
15.389 + */
15.390 + --_data[b].degree;
15.391 +
15.392 + if ( _data[b].degree !=0 ) {
15.393 + int child=_data[b].child;
15.394 + if ( child==a )
15.395 + _data[b].child=_data[child].right_neighbor;
15.396 + unlace(a);
15.397 + }
15.398 +
15.399 +
15.400 + /*Lacing a to the roots.*/
15.401 + int right=_data[_minimum].right_neighbor;
15.402 + _data[_minimum].right_neighbor=a;
15.403 + _data[a].left_neighbor=_minimum;
15.404 + _data[a].right_neighbor=right;
15.405 + _data[right].left_neighbor=a;
15.406 +
15.407 + _data[a].parent=-1;
15.408 + _data[a].marked=false;
15.409 + }
15.410 +
15.411 + void cascade(int a) {
15.412 + if ( _data[a].parent!=-1 ) {
15.413 + int p=_data[a].parent;
15.414 +
15.415 + if ( _data[a].marked==false ) _data[a].marked=true;
15.416 + else {
15.417 + cut(a,p);
15.418 + cascade(p);
15.419 + }
15.420 + }
15.421 + }
15.422 +
15.423 + void fuse(int a, int b) {
15.424 + unlace(b);
15.425 +
15.426 + /*Lacing b under a.*/
15.427 + _data[b].parent=a;
15.428 +
15.429 + if (_data[a].degree==0) {
15.430 + _data[b].left_neighbor=b;
15.431 + _data[b].right_neighbor=b;
15.432 + _data[a].child=b;
15.433 + } else {
15.434 + int child=_data[a].child;
15.435 + int last_child=_data[child].left_neighbor;
15.436 + _data[child].left_neighbor=b;
15.437 + _data[b].right_neighbor=child;
15.438 + _data[last_child].right_neighbor=b;
15.439 + _data[b].left_neighbor=last_child;
15.440 + }
15.441 +
15.442 + ++_data[a].degree;
15.443 +
15.444 + _data[b].marked=false;
15.445 + }
15.446 +
15.447 + /*
15.448 + *It is invoked only if a has siblings.
15.449 + */
15.450 + void unlace(int a) {
15.451 + int leftn=_data[a].left_neighbor;
15.452 + int rightn=_data[a].right_neighbor;
15.453 + _data[leftn].right_neighbor=rightn;
15.454 + _data[rightn].left_neighbor=leftn;
15.455 + }
15.456 +
15.457 +
15.458 + class Store {
15.459 + friend class FibHeap;
15.460 +
15.461 + Item name;
15.462 + int parent;
15.463 + int left_neighbor;
15.464 + int right_neighbor;
15.465 + int child;
15.466 + int degree;
15.467 + bool marked;
15.468 + bool in;
15.469 + Prio prio;
15.470 +
15.471 + Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
15.472 + };
15.473 + };
15.474 +
15.475 +} //namespace lemon
15.476 +
15.477 +#endif //LEMON_FIB_HEAP_H
15.478 +
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/lemon/fourary_heap.h Fri Sep 25 09:13:03 2009 +0200
16.3 @@ -0,0 +1,342 @@
16.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
16.5 + *
16.6 + * This file is a part of LEMON, a generic C++ optimization library.
16.7 + *
16.8 + * Copyright (C) 2003-2009
16.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
16.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
16.11 + *
16.12 + * Permission to use, modify and distribute this software is granted
16.13 + * provided that this copyright notice appears in all copies. For
16.14 + * precise terms see the accompanying LICENSE file.
16.15 + *
16.16 + * This software is provided "AS IS" with no warranty of any kind,
16.17 + * express or implied, and with no claim as to its suitability for any
16.18 + * purpose.
16.19 + *
16.20 + */
16.21 +
16.22 +#ifndef LEMON_FOURARY_HEAP_H
16.23 +#define LEMON_FOURARY_HEAP_H
16.24 +
16.25 +///\ingroup heaps
16.26 +///\file
16.27 +///\brief Fourary heap implementation.
16.28 +
16.29 +#include <vector>
16.30 +#include <utility>
16.31 +#include <functional>
16.32 +
16.33 +namespace lemon {
16.34 +
16.35 + /// \ingroup heaps
16.36 + ///
16.37 + ///\brief Fourary heap data structure.
16.38 + ///
16.39 + /// This class implements the \e fourary \e heap data structure.
16.40 + /// It fully conforms to the \ref concepts::Heap "heap concept".
16.41 + ///
16.42 + /// The fourary heap is a specialization of the \ref KaryHeap "K-ary heap"
16.43 + /// for <tt>K=4</tt>. It is similar to the \ref BinHeap "binary heap",
16.44 + /// but its nodes have at most four children, instead of two.
16.45 + ///
16.46 + /// \tparam PR Type of the priorities of the items.
16.47 + /// \tparam IM A read-writable item map with \c int values, used
16.48 + /// internally to handle the cross references.
16.49 + /// \tparam CMP A functor class for comparing the priorities.
16.50 + /// The default is \c std::less<PR>.
16.51 + ///
16.52 + ///\sa BinHeap
16.53 + ///\sa KaryHeap
16.54 +#ifdef DOXYGEN
16.55 + template <typename PR, typename IM, typename CMP>
16.56 +#else
16.57 + template <typename PR, typename IM, typename CMP = std::less<PR> >
16.58 +#endif
16.59 + class FouraryHeap {
16.60 + public:
16.61 + /// Type of the item-int map.
16.62 + typedef IM ItemIntMap;
16.63 + /// Type of the priorities.
16.64 + typedef PR Prio;
16.65 + /// Type of the items stored in the heap.
16.66 + typedef typename ItemIntMap::Key Item;
16.67 + /// Type of the item-priority pairs.
16.68 + typedef std::pair<Item,Prio> Pair;
16.69 + /// Functor type for comparing the priorities.
16.70 + typedef CMP Compare;
16.71 +
16.72 + /// \brief Type to represent the states of the items.
16.73 + ///
16.74 + /// Each item has a state associated to it. It can be "in heap",
16.75 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
16.76 + /// heap's point of view, but may be useful to the user.
16.77 + ///
16.78 + /// The item-int map must be initialized in such way that it assigns
16.79 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
16.80 + enum State {
16.81 + IN_HEAP = 0, ///< = 0.
16.82 + PRE_HEAP = -1, ///< = -1.
16.83 + POST_HEAP = -2 ///< = -2.
16.84 + };
16.85 +
16.86 + private:
16.87 + std::vector<Pair> _data;
16.88 + Compare _comp;
16.89 + ItemIntMap &_iim;
16.90 +
16.91 + public:
16.92 + /// \brief Constructor.
16.93 + ///
16.94 + /// Constructor.
16.95 + /// \param map A map that assigns \c int values to the items.
16.96 + /// It is used internally to handle the cross references.
16.97 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
16.98 + explicit FouraryHeap(ItemIntMap &map) : _iim(map) {}
16.99 +
16.100 + /// \brief Constructor.
16.101 + ///
16.102 + /// Constructor.
16.103 + /// \param map A map that assigns \c int values to the items.
16.104 + /// It is used internally to handle the cross references.
16.105 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
16.106 + /// \param comp The function object used for comparing the priorities.
16.107 + FouraryHeap(ItemIntMap &map, const Compare &comp)
16.108 + : _iim(map), _comp(comp) {}
16.109 +
16.110 + /// \brief The number of items stored in the heap.
16.111 + ///
16.112 + /// This function returns the number of items stored in the heap.
16.113 + int size() const { return _data.size(); }
16.114 +
16.115 + /// \brief Check if the heap is empty.
16.116 + ///
16.117 + /// This function returns \c true if the heap is empty.
16.118 + bool empty() const { return _data.empty(); }
16.119 +
16.120 + /// \brief Make the heap empty.
16.121 + ///
16.122 + /// This functon makes the heap empty.
16.123 + /// It does not change the cross reference map. If you want to reuse
16.124 + /// a heap that is not surely empty, you should first clear it and
16.125 + /// then you should set the cross reference map to \c PRE_HEAP
16.126 + /// for each item.
16.127 + void clear() { _data.clear(); }
16.128 +
16.129 + private:
16.130 + static int parent(int i) { return (i-1)/4; }
16.131 + static int firstChild(int i) { return 4*i+1; }
16.132 +
16.133 + bool less(const Pair &p1, const Pair &p2) const {
16.134 + return _comp(p1.second, p2.second);
16.135 + }
16.136 +
16.137 + void bubbleUp(int hole, Pair p) {
16.138 + int par = parent(hole);
16.139 + while( hole>0 && less(p,_data[par]) ) {
16.140 + move(_data[par],hole);
16.141 + hole = par;
16.142 + par = parent(hole);
16.143 + }
16.144 + move(p, hole);
16.145 + }
16.146 +
16.147 + void bubbleDown(int hole, Pair p, int length) {
16.148 + if( length>1 ) {
16.149 + int child = firstChild(hole);
16.150 + while( child+3<length ) {
16.151 + int min=child;
16.152 + if( less(_data[++child], _data[min]) ) min=child;
16.153 + if( less(_data[++child], _data[min]) ) min=child;
16.154 + if( less(_data[++child], _data[min]) ) min=child;
16.155 + if( !less(_data[min], p) )
16.156 + goto ok;
16.157 + move(_data[min], hole);
16.158 + hole = min;
16.159 + child = firstChild(hole);
16.160 + }
16.161 + if ( child<length ) {
16.162 + int min = child;
16.163 + if( ++child<length && less(_data[child], _data[min]) ) min=child;
16.164 + if( ++child<length && less(_data[child], _data[min]) ) min=child;
16.165 + if( less(_data[min], p) ) {
16.166 + move(_data[min], hole);
16.167 + hole = min;
16.168 + }
16.169 + }
16.170 + }
16.171 + ok:
16.172 + move(p, hole);
16.173 + }
16.174 +
16.175 + void move(const Pair &p, int i) {
16.176 + _data[i] = p;
16.177 + _iim.set(p.first, i);
16.178 + }
16.179 +
16.180 + public:
16.181 + /// \brief Insert a pair of item and priority into the heap.
16.182 + ///
16.183 + /// This function inserts \c p.first to the heap with priority
16.184 + /// \c p.second.
16.185 + /// \param p The pair to insert.
16.186 + /// \pre \c p.first must not be stored in the heap.
16.187 + void push(const Pair &p) {
16.188 + int n = _data.size();
16.189 + _data.resize(n+1);
16.190 + bubbleUp(n, p);
16.191 + }
16.192 +
16.193 + /// \brief Insert an item into the heap with the given priority.
16.194 + ///
16.195 + /// This function inserts the given item into the heap with the
16.196 + /// given priority.
16.197 + /// \param i The item to insert.
16.198 + /// \param p The priority of the item.
16.199 + /// \pre \e i must not be stored in the heap.
16.200 + void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
16.201 +
16.202 + /// \brief Return the item having minimum priority.
16.203 + ///
16.204 + /// This function returns the item having minimum priority.
16.205 + /// \pre The heap must be non-empty.
16.206 + Item top() const { return _data[0].first; }
16.207 +
16.208 + /// \brief The minimum priority.
16.209 + ///
16.210 + /// This function returns the minimum priority.
16.211 + /// \pre The heap must be non-empty.
16.212 + Prio prio() const { return _data[0].second; }
16.213 +
16.214 + /// \brief Remove the item having minimum priority.
16.215 + ///
16.216 + /// This function removes the item having minimum priority.
16.217 + /// \pre The heap must be non-empty.
16.218 + void pop() {
16.219 + int n = _data.size()-1;
16.220 + _iim.set(_data[0].first, POST_HEAP);
16.221 + if (n>0) bubbleDown(0, _data[n], n);
16.222 + _data.pop_back();
16.223 + }
16.224 +
16.225 + /// \brief Remove the given item from the heap.
16.226 + ///
16.227 + /// This function removes the given item from the heap if it is
16.228 + /// already stored.
16.229 + /// \param i The item to delete.
16.230 + /// \pre \e i must be in the heap.
16.231 + void erase(const Item &i) {
16.232 + int h = _iim[i];
16.233 + int n = _data.size()-1;
16.234 + _iim.set(_data[h].first, POST_HEAP);
16.235 + if( h<n ) {
16.236 + if( less(_data[parent(h)], _data[n]) )
16.237 + bubbleDown(h, _data[n], n);
16.238 + else
16.239 + bubbleUp(h, _data[n]);
16.240 + }
16.241 + _data.pop_back();
16.242 + }
16.243 +
16.244 + /// \brief The priority of the given item.
16.245 + ///
16.246 + /// This function returns the priority of the given item.
16.247 + /// \param i The item.
16.248 + /// \pre \e i must be in the heap.
16.249 + Prio operator[](const Item &i) const {
16.250 + int idx = _iim[i];
16.251 + return _data[idx].second;
16.252 + }
16.253 +
16.254 + /// \brief Set the priority of an item or insert it, if it is
16.255 + /// not stored in the heap.
16.256 + ///
16.257 + /// This method sets the priority of the given item if it is
16.258 + /// already stored in the heap. Otherwise it inserts the given
16.259 + /// item into the heap with the given priority.
16.260 + /// \param i The item.
16.261 + /// \param p The priority.
16.262 + void set(const Item &i, const Prio &p) {
16.263 + int idx = _iim[i];
16.264 + if( idx < 0 )
16.265 + push(i,p);
16.266 + else if( _comp(p, _data[idx].second) )
16.267 + bubbleUp(idx, Pair(i,p));
16.268 + else
16.269 + bubbleDown(idx, Pair(i,p), _data.size());
16.270 + }
16.271 +
16.272 + /// \brief Decrease the priority of an item to the given value.
16.273 + ///
16.274 + /// This function decreases the priority of an item to the given value.
16.275 + /// \param i The item.
16.276 + /// \param p The priority.
16.277 + /// \pre \e i must be stored in the heap with priority at least \e p.
16.278 + void decrease(const Item &i, const Prio &p) {
16.279 + int idx = _iim[i];
16.280 + bubbleUp(idx, Pair(i,p));
16.281 + }
16.282 +
16.283 + /// \brief Increase the priority of an item to the given value.
16.284 + ///
16.285 + /// This function increases the priority of an item to the given value.
16.286 + /// \param i The item.
16.287 + /// \param p The priority.
16.288 + /// \pre \e i must be stored in the heap with priority at most \e p.
16.289 + void increase(const Item &i, const Prio &p) {
16.290 + int idx = _iim[i];
16.291 + bubbleDown(idx, Pair(i,p), _data.size());
16.292 + }
16.293 +
16.294 + /// \brief Return the state of an item.
16.295 + ///
16.296 + /// This method returns \c PRE_HEAP if the given item has never
16.297 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
16.298 + /// and \c POST_HEAP otherwise.
16.299 + /// In the latter case it is possible that the item will get back
16.300 + /// to the heap again.
16.301 + /// \param i The item.
16.302 + State state(const Item &i) const {
16.303 + int s = _iim[i];
16.304 + if (s>=0) s=0;
16.305 + return State(s);
16.306 + }
16.307 +
16.308 + /// \brief Set the state of an item in the heap.
16.309 + ///
16.310 + /// This function sets the state of the given item in the heap.
16.311 + /// It can be used to manually clear the heap when it is important
16.312 + /// to achive better time complexity.
16.313 + /// \param i The item.
16.314 + /// \param st The state. It should not be \c IN_HEAP.
16.315 + void state(const Item& i, State st) {
16.316 + switch (st) {
16.317 + case POST_HEAP:
16.318 + case PRE_HEAP:
16.319 + if (state(i) == IN_HEAP) erase(i);
16.320 + _iim[i] = st;
16.321 + break;
16.322 + case IN_HEAP:
16.323 + break;
16.324 + }
16.325 + }
16.326 +
16.327 + /// \brief Replace an item in the heap.
16.328 + ///
16.329 + /// This function replaces item \c i with item \c j.
16.330 + /// Item \c i must be in the heap, while \c j must be out of the heap.
16.331 + /// After calling this method, item \c i will be out of the
16.332 + /// heap and \c j will be in the heap with the same prioriority
16.333 + /// as item \c i had before.
16.334 + void replace(const Item& i, const Item& j) {
16.335 + int idx = _iim[i];
16.336 + _iim.set(i, _iim[j]);
16.337 + _iim.set(j, idx);
16.338 + _data[idx].first = j;
16.339 + }
16.340 +
16.341 + }; // class FouraryHeap
16.342 +
16.343 +} // namespace lemon
16.344 +
16.345 +#endif // LEMON_FOURARY_HEAP_H
17.1 --- a/lemon/gomory_hu.h Sun Aug 02 12:40:20 2009 +0200
17.2 +++ b/lemon/gomory_hu.h Fri Sep 25 09:13:03 2009 +0200
17.3 @@ -359,10 +359,10 @@
17.4 /// This example counts the nodes in the minimum cut separating \c s from
17.5 /// \c t.
17.6 /// \code
17.7 - /// GomoruHu<Graph> gom(g, capacities);
17.8 + /// GomoryHu<Graph> gom(g, capacities);
17.9 /// gom.run();
17.10 /// int cnt=0;
17.11 - /// for(GomoruHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
17.12 + /// for(GomoryHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
17.13 /// \endcode
17.14 class MinCutNodeIt
17.15 {
17.16 @@ -456,10 +456,10 @@
17.17 /// This example computes the value of the minimum cut separating \c s from
17.18 /// \c t.
17.19 /// \code
17.20 - /// GomoruHu<Graph> gom(g, capacities);
17.21 + /// GomoryHu<Graph> gom(g, capacities);
17.22 /// gom.run();
17.23 /// int value=0;
17.24 - /// for(GomoruHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
17.25 + /// for(GomoryHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
17.26 /// value+=capacities[e];
17.27 /// \endcode
17.28 /// The result will be the same as the value returned by
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/lemon/kary_heap.h Fri Sep 25 09:13:03 2009 +0200
18.3 @@ -0,0 +1,352 @@
18.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
18.5 + *
18.6 + * This file is a part of LEMON, a generic C++ optimization library.
18.7 + *
18.8 + * Copyright (C) 2003-2009
18.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
18.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
18.11 + *
18.12 + * Permission to use, modify and distribute this software is granted
18.13 + * provided that this copyright notice appears in all copies. For
18.14 + * precise terms see the accompanying LICENSE file.
18.15 + *
18.16 + * This software is provided "AS IS" with no warranty of any kind,
18.17 + * express or implied, and with no claim as to its suitability for any
18.18 + * purpose.
18.19 + *
18.20 + */
18.21 +
18.22 +#ifndef LEMON_KARY_HEAP_H
18.23 +#define LEMON_KARY_HEAP_H
18.24 +
18.25 +///\ingroup heaps
18.26 +///\file
18.27 +///\brief Fourary heap implementation.
18.28 +
18.29 +#include <vector>
18.30 +#include <utility>
18.31 +#include <functional>
18.32 +
18.33 +namespace lemon {
18.34 +
18.35 + /// \ingroup heaps
18.36 + ///
18.37 + ///\brief K-ary heap data structure.
18.38 + ///
18.39 + /// This class implements the \e K-ary \e heap data structure.
18.40 + /// It fully conforms to the \ref concepts::Heap "heap concept".
18.41 + ///
18.42 + /// The \ref KaryHeap "K-ary heap" is a generalization of the
18.43 + /// \ref BinHeap "binary heap" structure, its nodes have at most
18.44 + /// \c K children, instead of two.
18.45 + /// \ref BinHeap and \ref FouraryHeap are specialized implementations
18.46 + /// of this structure for <tt>K=2</tt> and <tt>K=4</tt>, respectively.
18.47 + ///
18.48 + /// \tparam PR Type of the priorities of the items.
18.49 + /// \tparam IM A read-writable item map with \c int values, used
18.50 + /// internally to handle the cross references.
18.51 + /// \tparam K The degree of the heap, each node have at most \e K
18.52 + /// children. The default is 16. Powers of two are suggested to use
18.53 + /// so that the multiplications and divisions needed to traverse the
18.54 + /// nodes of the heap could be performed faster.
18.55 + /// \tparam CMP A functor class for comparing the priorities.
18.56 + /// The default is \c std::less<PR>.
18.57 + ///
18.58 + ///\sa BinHeap
18.59 + ///\sa FouraryHeap
18.60 +#ifdef DOXYGEN
18.61 + template <typename PR, typename IM, int K, typename CMP>
18.62 +#else
18.63 + template <typename PR, typename IM, int K = 16,
18.64 + typename CMP = std::less<PR> >
18.65 +#endif
18.66 + class KaryHeap {
18.67 + public:
18.68 + /// Type of the item-int map.
18.69 + typedef IM ItemIntMap;
18.70 + /// Type of the priorities.
18.71 + typedef PR Prio;
18.72 + /// Type of the items stored in the heap.
18.73 + typedef typename ItemIntMap::Key Item;
18.74 + /// Type of the item-priority pairs.
18.75 + typedef std::pair<Item,Prio> Pair;
18.76 + /// Functor type for comparing the priorities.
18.77 + typedef CMP Compare;
18.78 +
18.79 + /// \brief Type to represent the states of the items.
18.80 + ///
18.81 + /// Each item has a state associated to it. It can be "in heap",
18.82 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
18.83 + /// heap's point of view, but may be useful to the user.
18.84 + ///
18.85 + /// The item-int map must be initialized in such way that it assigns
18.86 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
18.87 + enum State {
18.88 + IN_HEAP = 0, ///< = 0.
18.89 + PRE_HEAP = -1, ///< = -1.
18.90 + POST_HEAP = -2 ///< = -2.
18.91 + };
18.92 +
18.93 + private:
18.94 + std::vector<Pair> _data;
18.95 + Compare _comp;
18.96 + ItemIntMap &_iim;
18.97 +
18.98 + public:
18.99 + /// \brief Constructor.
18.100 + ///
18.101 + /// Constructor.
18.102 + /// \param map A map that assigns \c int values to the items.
18.103 + /// It is used internally to handle the cross references.
18.104 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
18.105 + explicit KaryHeap(ItemIntMap &map) : _iim(map) {}
18.106 +
18.107 + /// \brief Constructor.
18.108 + ///
18.109 + /// Constructor.
18.110 + /// \param map A map that assigns \c int values to the items.
18.111 + /// It is used internally to handle the cross references.
18.112 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
18.113 + /// \param comp The function object used for comparing the priorities.
18.114 + KaryHeap(ItemIntMap &map, const Compare &comp)
18.115 + : _iim(map), _comp(comp) {}
18.116 +
18.117 + /// \brief The number of items stored in the heap.
18.118 + ///
18.119 + /// This function returns the number of items stored in the heap.
18.120 + int size() const { return _data.size(); }
18.121 +
18.122 + /// \brief Check if the heap is empty.
18.123 + ///
18.124 + /// This function returns \c true if the heap is empty.
18.125 + bool empty() const { return _data.empty(); }
18.126 +
18.127 + /// \brief Make the heap empty.
18.128 + ///
18.129 + /// This functon makes the heap empty.
18.130 + /// It does not change the cross reference map. If you want to reuse
18.131 + /// a heap that is not surely empty, you should first clear it and
18.132 + /// then you should set the cross reference map to \c PRE_HEAP
18.133 + /// for each item.
18.134 + void clear() { _data.clear(); }
18.135 +
18.136 + private:
18.137 + int parent(int i) { return (i-1)/K; }
18.138 + int firstChild(int i) { return K*i+1; }
18.139 +
18.140 + bool less(const Pair &p1, const Pair &p2) const {
18.141 + return _comp(p1.second, p2.second);
18.142 + }
18.143 +
18.144 + void bubbleUp(int hole, Pair p) {
18.145 + int par = parent(hole);
18.146 + while( hole>0 && less(p,_data[par]) ) {
18.147 + move(_data[par],hole);
18.148 + hole = par;
18.149 + par = parent(hole);
18.150 + }
18.151 + move(p, hole);
18.152 + }
18.153 +
18.154 + void bubbleDown(int hole, Pair p, int length) {
18.155 + if( length>1 ) {
18.156 + int child = firstChild(hole);
18.157 + while( child+K<=length ) {
18.158 + int min=child;
18.159 + for (int i=1; i<K; ++i) {
18.160 + if( less(_data[child+i], _data[min]) )
18.161 + min=child+i;
18.162 + }
18.163 + if( !less(_data[min], p) )
18.164 + goto ok;
18.165 + move(_data[min], hole);
18.166 + hole = min;
18.167 + child = firstChild(hole);
18.168 + }
18.169 + if ( child<length ) {
18.170 + int min = child;
18.171 + while (++child < length) {
18.172 + if( less(_data[child], _data[min]) )
18.173 + min=child;
18.174 + }
18.175 + if( less(_data[min], p) ) {
18.176 + move(_data[min], hole);
18.177 + hole = min;
18.178 + }
18.179 + }
18.180 + }
18.181 + ok:
18.182 + move(p, hole);
18.183 + }
18.184 +
18.185 + void move(const Pair &p, int i) {
18.186 + _data[i] = p;
18.187 + _iim.set(p.first, i);
18.188 + }
18.189 +
18.190 + public:
18.191 + /// \brief Insert a pair of item and priority into the heap.
18.192 + ///
18.193 + /// This function inserts \c p.first to the heap with priority
18.194 + /// \c p.second.
18.195 + /// \param p The pair to insert.
18.196 + /// \pre \c p.first must not be stored in the heap.
18.197 + void push(const Pair &p) {
18.198 + int n = _data.size();
18.199 + _data.resize(n+1);
18.200 + bubbleUp(n, p);
18.201 + }
18.202 +
18.203 + /// \brief Insert an item into the heap with the given priority.
18.204 + ///
18.205 + /// This function inserts the given item into the heap with the
18.206 + /// given priority.
18.207 + /// \param i The item to insert.
18.208 + /// \param p The priority of the item.
18.209 + /// \pre \e i must not be stored in the heap.
18.210 + void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
18.211 +
18.212 + /// \brief Return the item having minimum priority.
18.213 + ///
18.214 + /// This function returns the item having minimum priority.
18.215 + /// \pre The heap must be non-empty.
18.216 + Item top() const { return _data[0].first; }
18.217 +
18.218 + /// \brief The minimum priority.
18.219 + ///
18.220 + /// This function returns the minimum priority.
18.221 + /// \pre The heap must be non-empty.
18.222 + Prio prio() const { return _data[0].second; }
18.223 +
18.224 + /// \brief Remove the item having minimum priority.
18.225 + ///
18.226 + /// This function removes the item having minimum priority.
18.227 + /// \pre The heap must be non-empty.
18.228 + void pop() {
18.229 + int n = _data.size()-1;
18.230 + _iim.set(_data[0].first, POST_HEAP);
18.231 + if (n>0) bubbleDown(0, _data[n], n);
18.232 + _data.pop_back();
18.233 + }
18.234 +
18.235 + /// \brief Remove the given item from the heap.
18.236 + ///
18.237 + /// This function removes the given item from the heap if it is
18.238 + /// already stored.
18.239 + /// \param i The item to delete.
18.240 + /// \pre \e i must be in the heap.
18.241 + void erase(const Item &i) {
18.242 + int h = _iim[i];
18.243 + int n = _data.size()-1;
18.244 + _iim.set(_data[h].first, POST_HEAP);
18.245 + if( h<n ) {
18.246 + if( less(_data[parent(h)], _data[n]) )
18.247 + bubbleDown(h, _data[n], n);
18.248 + else
18.249 + bubbleUp(h, _data[n]);
18.250 + }
18.251 + _data.pop_back();
18.252 + }
18.253 +
18.254 + /// \brief The priority of the given item.
18.255 + ///
18.256 + /// This function returns the priority of the given item.
18.257 + /// \param i The item.
18.258 + /// \pre \e i must be in the heap.
18.259 + Prio operator[](const Item &i) const {
18.260 + int idx = _iim[i];
18.261 + return _data[idx].second;
18.262 + }
18.263 +
18.264 + /// \brief Set the priority of an item or insert it, if it is
18.265 + /// not stored in the heap.
18.266 + ///
18.267 + /// This method sets the priority of the given item if it is
18.268 + /// already stored in the heap. Otherwise it inserts the given
18.269 + /// item into the heap with the given priority.
18.270 + /// \param i The item.
18.271 + /// \param p The priority.
18.272 + void set(const Item &i, const Prio &p) {
18.273 + int idx = _iim[i];
18.274 + if( idx<0 )
18.275 + push(i,p);
18.276 + else if( _comp(p, _data[idx].second) )
18.277 + bubbleUp(idx, Pair(i,p));
18.278 + else
18.279 + bubbleDown(idx, Pair(i,p), _data.size());
18.280 + }
18.281 +
18.282 + /// \brief Decrease the priority of an item to the given value.
18.283 + ///
18.284 + /// This function decreases the priority of an item to the given value.
18.285 + /// \param i The item.
18.286 + /// \param p The priority.
18.287 + /// \pre \e i must be stored in the heap with priority at least \e p.
18.288 + void decrease(const Item &i, const Prio &p) {
18.289 + int idx = _iim[i];
18.290 + bubbleUp(idx, Pair(i,p));
18.291 + }
18.292 +
18.293 + /// \brief Increase the priority of an item to the given value.
18.294 + ///
18.295 + /// This function increases the priority of an item to the given value.
18.296 + /// \param i The item.
18.297 + /// \param p The priority.
18.298 + /// \pre \e i must be stored in the heap with priority at most \e p.
18.299 + void increase(const Item &i, const Prio &p) {
18.300 + int idx = _iim[i];
18.301 + bubbleDown(idx, Pair(i,p), _data.size());
18.302 + }
18.303 +
18.304 + /// \brief Return the state of an item.
18.305 + ///
18.306 + /// This method returns \c PRE_HEAP if the given item has never
18.307 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
18.308 + /// and \c POST_HEAP otherwise.
18.309 + /// In the latter case it is possible that the item will get back
18.310 + /// to the heap again.
18.311 + /// \param i The item.
18.312 + State state(const Item &i) const {
18.313 + int s = _iim[i];
18.314 + if (s>=0) s=0;
18.315 + return State(s);
18.316 + }
18.317 +
18.318 + /// \brief Set the state of an item in the heap.
18.319 + ///
18.320 + /// This function sets the state of the given item in the heap.
18.321 + /// It can be used to manually clear the heap when it is important
18.322 + /// to achive better time complexity.
18.323 + /// \param i The item.
18.324 + /// \param st The state. It should not be \c IN_HEAP.
18.325 + void state(const Item& i, State st) {
18.326 + switch (st) {
18.327 + case POST_HEAP:
18.328 + case PRE_HEAP:
18.329 + if (state(i) == IN_HEAP) erase(i);
18.330 + _iim[i] = st;
18.331 + break;
18.332 + case IN_HEAP:
18.333 + break;
18.334 + }
18.335 + }
18.336 +
18.337 + /// \brief Replace an item in the heap.
18.338 + ///
18.339 + /// This function replaces item \c i with item \c j.
18.340 + /// Item \c i must be in the heap, while \c j must be out of the heap.
18.341 + /// After calling this method, item \c i will be out of the
18.342 + /// heap and \c j will be in the heap with the same prioriority
18.343 + /// as item \c i had before.
18.344 + void replace(const Item& i, const Item& j) {
18.345 + int idx=_iim[i];
18.346 + _iim.set(i, _iim[j]);
18.347 + _iim.set(j, idx);
18.348 + _data[idx].first=j;
18.349 + }
18.350 +
18.351 + }; // class KaryHeap
18.352 +
18.353 +} // namespace lemon
18.354 +
18.355 +#endif // LEMON_KARY_HEAP_H
19.1 --- a/lemon/maps.h Sun Aug 02 12:40:20 2009 +0200
19.2 +++ b/lemon/maps.h Fri Sep 25 09:13:03 2009 +0200
19.3 @@ -22,6 +22,7 @@
19.4 #include <iterator>
19.5 #include <functional>
19.6 #include <vector>
19.7 +#include <map>
19.8
19.9 #include <lemon/core.h>
19.10
19.11 @@ -29,8 +30,6 @@
19.12 ///\ingroup maps
19.13 ///\brief Miscellaneous property maps
19.14
19.15 -#include <map>
19.16 -
19.17 namespace lemon {
19.18
19.19 /// \addtogroup maps
19.20 @@ -1818,7 +1817,7 @@
19.21 /// \brief Provides an immutable and unique id for each item in a graph.
19.22 ///
19.23 /// IdMap provides a unique and immutable id for each item of the
19.24 - /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
19.25 + /// same type (\c Node, \c Arc or \c Edge) in a graph. This id is
19.26 /// - \b unique: different items get different ids,
19.27 /// - \b immutable: the id of an item does not change (even if you
19.28 /// delete other nodes).
19.29 @@ -1902,13 +1901,14 @@
19.30 /// \brief General cross reference graph map type.
19.31
19.32 /// This class provides simple invertable graph maps.
19.33 - /// It wraps an arbitrary \ref concepts::ReadWriteMap "ReadWriteMap"
19.34 - /// and if a key is set to a new value then store it
19.35 - /// in the inverse map.
19.36 - ///
19.37 + /// It wraps a standard graph map (\c NodeMap, \c ArcMap or \c EdgeMap)
19.38 + /// and if a key is set to a new value, then stores it in the inverse map.
19.39 /// The values of the map can be accessed
19.40 /// with stl compatible forward iterator.
19.41 ///
19.42 + /// This type is not reference map, so it cannot be modified with
19.43 + /// the subscript operator.
19.44 + ///
19.45 /// \tparam GR The graph type.
19.46 /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
19.47 /// \c GR::Edge).
19.48 @@ -1923,7 +1923,7 @@
19.49 typedef typename ItemSetTraits<GR, K>::
19.50 template Map<V>::Type Map;
19.51
19.52 - typedef std::map<V, K> Container;
19.53 + typedef std::multimap<V, K> Container;
19.54 Container _inv_map;
19.55
19.56 public:
19.57 @@ -1948,6 +1948,8 @@
19.58 /// This iterator is an stl compatible forward
19.59 /// iterator on the values of the map. The values can
19.60 /// be accessed in the <tt>[beginValue, endValue)</tt> range.
19.61 + /// They are considered with multiplicity, so each value is
19.62 + /// traversed for each item it is assigned to.
19.63 class ValueIterator
19.64 : public std::iterator<std::forward_iterator_tag, Value> {
19.65 friend class CrossRefMap;
19.66 @@ -2000,11 +2002,15 @@
19.67 /// Sets the value associated with the given key.
19.68 void set(const Key& key, const Value& val) {
19.69 Value oldval = Map::operator[](key);
19.70 - typename Container::iterator it = _inv_map.find(oldval);
19.71 - if (it != _inv_map.end() && it->second == key) {
19.72 - _inv_map.erase(it);
19.73 + typename Container::iterator it;
19.74 + for (it = _inv_map.equal_range(oldval).first;
19.75 + it != _inv_map.equal_range(oldval).second; ++it) {
19.76 + if (it->second == key) {
19.77 + _inv_map.erase(it);
19.78 + break;
19.79 + }
19.80 }
19.81 - _inv_map.insert(make_pair(val, key));
19.82 + _inv_map.insert(std::make_pair(val, key));
19.83 Map::set(key, val);
19.84 }
19.85
19.86 @@ -2016,11 +2022,14 @@
19.87 return Map::operator[](key);
19.88 }
19.89
19.90 - /// \brief Gives back the item by its value.
19.91 + /// \brief Gives back an item by its value.
19.92 ///
19.93 - /// Gives back the item by its value.
19.94 - Key operator()(const Value& key) const {
19.95 - typename Container::const_iterator it = _inv_map.find(key);
19.96 + /// This function gives back an item that is assigned to
19.97 + /// the given value or \c INVALID if no such item exists.
19.98 + /// If there are more items with the same associated value,
19.99 + /// only one of them is returned.
19.100 + Key operator()(const Value& val) const {
19.101 + typename Container::const_iterator it = _inv_map.find(val);
19.102 return it != _inv_map.end() ? it->second : INVALID;
19.103 }
19.104
19.105 @@ -2032,9 +2041,13 @@
19.106 /// \c AlterationNotifier.
19.107 virtual void erase(const Key& key) {
19.108 Value val = Map::operator[](key);
19.109 - typename Container::iterator it = _inv_map.find(val);
19.110 - if (it != _inv_map.end() && it->second == key) {
19.111 - _inv_map.erase(it);
19.112 + typename Container::iterator it;
19.113 + for (it = _inv_map.equal_range(val).first;
19.114 + it != _inv_map.equal_range(val).second; ++it) {
19.115 + if (it->second == key) {
19.116 + _inv_map.erase(it);
19.117 + break;
19.118 + }
19.119 }
19.120 Map::erase(key);
19.121 }
19.122 @@ -2046,9 +2059,13 @@
19.123 virtual void erase(const std::vector<Key>& keys) {
19.124 for (int i = 0; i < int(keys.size()); ++i) {
19.125 Value val = Map::operator[](keys[i]);
19.126 - typename Container::iterator it = _inv_map.find(val);
19.127 - if (it != _inv_map.end() && it->second == keys[i]) {
19.128 - _inv_map.erase(it);
19.129 + typename Container::iterator it;
19.130 + for (it = _inv_map.equal_range(val).first;
19.131 + it != _inv_map.equal_range(val).second; ++it) {
19.132 + if (it->second == keys[i]) {
19.133 + _inv_map.erase(it);
19.134 + break;
19.135 + }
19.136 }
19.137 }
19.138 Map::erase(keys);
19.139 @@ -2084,8 +2101,9 @@
19.140
19.141 /// \brief Subscript operator.
19.142 ///
19.143 - /// Subscript operator. It gives back the item
19.144 - /// that was last assigned to the given value.
19.145 + /// Subscript operator. It gives back an item
19.146 + /// that is assigned to the given value or \c INVALID
19.147 + /// if no such item exists.
19.148 Value operator[](const Key& key) const {
19.149 return _inverted(key);
19.150 }
19.151 @@ -2254,7 +2272,7 @@
19.152 }
19.153
19.154 /// \brief Gives back the item belonging to a \e RangeId
19.155 - ///
19.156 + ///
19.157 /// Gives back the item belonging to a \e RangeId.
19.158 Item operator()(int id) const {
19.159 return _inv_map[id];
19.160 @@ -2311,6 +2329,903 @@
19.161 }
19.162 };
19.163
19.164 + /// \brief Dynamic iterable \c bool map.
19.165 + ///
19.166 + /// This class provides a special graph map type which can store a
19.167 + /// \c bool value for graph items (\c Node, \c Arc or \c Edge).
19.168 + /// For both \c true and \c false values it is possible to iterate on
19.169 + /// the keys.
19.170 + ///
19.171 + /// This type is a reference map, so it can be modified with the
19.172 + /// subscript operator.
19.173 + ///
19.174 + /// \tparam GR The graph type.
19.175 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
19.176 + /// \c GR::Edge).
19.177 + ///
19.178 + /// \see IterableIntMap, IterableValueMap
19.179 + /// \see CrossRefMap
19.180 + template <typename GR, typename K>
19.181 + class IterableBoolMap
19.182 + : protected ItemSetTraits<GR, K>::template Map<int>::Type {
19.183 + private:
19.184 + typedef GR Graph;
19.185 +
19.186 + typedef typename ItemSetTraits<GR, K>::ItemIt KeyIt;
19.187 + typedef typename ItemSetTraits<GR, K>::template Map<int>::Type Parent;
19.188 +
19.189 + std::vector<K> _array;
19.190 + int _sep;
19.191 +
19.192 + public:
19.193 +
19.194 + /// Indicates that the map is reference map.
19.195 + typedef True ReferenceMapTag;
19.196 +
19.197 + /// The key type
19.198 + typedef K Key;
19.199 + /// The value type
19.200 + typedef bool Value;
19.201 + /// The const reference type.
19.202 + typedef const Value& ConstReference;
19.203 +
19.204 + private:
19.205 +
19.206 + int position(const Key& key) const {
19.207 + return Parent::operator[](key);
19.208 + }
19.209 +
19.210 + public:
19.211 +
19.212 + /// \brief Reference to the value of the map.
19.213 + ///
19.214 + /// This class is similar to the \c bool type. It can be converted to
19.215 + /// \c bool and it provides the same operators.
19.216 + class Reference {
19.217 + friend class IterableBoolMap;
19.218 + private:
19.219 + Reference(IterableBoolMap& map, const Key& key)
19.220 + : _key(key), _map(map) {}
19.221 + public:
19.222 +
19.223 + Reference& operator=(const Reference& value) {
19.224 + _map.set(_key, static_cast<bool>(value));
19.225 + return *this;
19.226 + }
19.227 +
19.228 + operator bool() const {
19.229 + return static_cast<const IterableBoolMap&>(_map)[_key];
19.230 + }
19.231 +
19.232 + Reference& operator=(bool value) {
19.233 + _map.set(_key, value);
19.234 + return *this;
19.235 + }
19.236 + Reference& operator&=(bool value) {
19.237 + _map.set(_key, _map[_key] & value);
19.238 + return *this;
19.239 + }
19.240 + Reference& operator|=(bool value) {
19.241 + _map.set(_key, _map[_key] | value);
19.242 + return *this;
19.243 + }
19.244 + Reference& operator^=(bool value) {
19.245 + _map.set(_key, _map[_key] ^ value);
19.246 + return *this;
19.247 + }
19.248 + private:
19.249 + Key _key;
19.250 + IterableBoolMap& _map;
19.251 + };
19.252 +
19.253 + /// \brief Constructor of the map with a default value.
19.254 + ///
19.255 + /// Constructor of the map with a default value.
19.256 + explicit IterableBoolMap(const Graph& graph, bool def = false)
19.257 + : Parent(graph) {
19.258 + typename Parent::Notifier* nf = Parent::notifier();
19.259 + Key it;
19.260 + for (nf->first(it); it != INVALID; nf->next(it)) {
19.261 + Parent::set(it, _array.size());
19.262 + _array.push_back(it);
19.263 + }
19.264 + _sep = (def ? _array.size() : 0);
19.265 + }
19.266 +
19.267 + /// \brief Const subscript operator of the map.
19.268 + ///
19.269 + /// Const subscript operator of the map.
19.270 + bool operator[](const Key& key) const {
19.271 + return position(key) < _sep;
19.272 + }
19.273 +
19.274 + /// \brief Subscript operator of the map.
19.275 + ///
19.276 + /// Subscript operator of the map.
19.277 + Reference operator[](const Key& key) {
19.278 + return Reference(*this, key);
19.279 + }
19.280 +
19.281 + /// \brief Set operation of the map.
19.282 + ///
19.283 + /// Set operation of the map.
19.284 + void set(const Key& key, bool value) {
19.285 + int pos = position(key);
19.286 + if (value) {
19.287 + if (pos < _sep) return;
19.288 + Key tmp = _array[_sep];
19.289 + _array[_sep] = key;
19.290 + Parent::set(key, _sep);
19.291 + _array[pos] = tmp;
19.292 + Parent::set(tmp, pos);
19.293 + ++_sep;
19.294 + } else {
19.295 + if (pos >= _sep) return;
19.296 + --_sep;
19.297 + Key tmp = _array[_sep];
19.298 + _array[_sep] = key;
19.299 + Parent::set(key, _sep);
19.300 + _array[pos] = tmp;
19.301 + Parent::set(tmp, pos);
19.302 + }
19.303 + }
19.304 +
19.305 + /// \brief Set all items.
19.306 + ///
19.307 + /// Set all items in the map.
19.308 + /// \note Constant time operation.
19.309 + void setAll(bool value) {
19.310 + _sep = (value ? _array.size() : 0);
19.311 + }
19.312 +
19.313 + /// \brief Returns the number of the keys mapped to \c true.
19.314 + ///
19.315 + /// Returns the number of the keys mapped to \c true.
19.316 + int trueNum() const {
19.317 + return _sep;
19.318 + }
19.319 +
19.320 + /// \brief Returns the number of the keys mapped to \c false.
19.321 + ///
19.322 + /// Returns the number of the keys mapped to \c false.
19.323 + int falseNum() const {
19.324 + return _array.size() - _sep;
19.325 + }
19.326 +
19.327 + /// \brief Iterator for the keys mapped to \c true.
19.328 + ///
19.329 + /// Iterator for the keys mapped to \c true. It works
19.330 + /// like a graph item iterator, it can be converted to
19.331 + /// the key type of the map, incremented with \c ++ operator, and
19.332 + /// if the iterator leaves the last valid key, it will be equal to
19.333 + /// \c INVALID.
19.334 + class TrueIt : public Key {
19.335 + public:
19.336 + typedef Key Parent;
19.337 +
19.338 + /// \brief Creates an iterator.
19.339 + ///
19.340 + /// Creates an iterator. It iterates on the
19.341 + /// keys mapped to \c true.
19.342 + /// \param map The IterableBoolMap.
19.343 + explicit TrueIt(const IterableBoolMap& map)
19.344 + : Parent(map._sep > 0 ? map._array[map._sep - 1] : INVALID),
19.345 + _map(&map) {}
19.346 +
19.347 + /// \brief Invalid constructor \& conversion.
19.348 + ///
19.349 + /// This constructor initializes the iterator to be invalid.
19.350 + /// \sa Invalid for more details.
19.351 + TrueIt(Invalid) : Parent(INVALID), _map(0) {}
19.352 +
19.353 + /// \brief Increment operator.
19.354 + ///
19.355 + /// Increment operator.
19.356 + TrueIt& operator++() {
19.357 + int pos = _map->position(*this);
19.358 + Parent::operator=(pos > 0 ? _map->_array[pos - 1] : INVALID);
19.359 + return *this;
19.360 + }
19.361 +
19.362 + private:
19.363 + const IterableBoolMap* _map;
19.364 + };
19.365 +
19.366 + /// \brief Iterator for the keys mapped to \c false.
19.367 + ///
19.368 + /// Iterator for the keys mapped to \c false. It works
19.369 + /// like a graph item iterator, it can be converted to
19.370 + /// the key type of the map, incremented with \c ++ operator, and
19.371 + /// if the iterator leaves the last valid key, it will be equal to
19.372 + /// \c INVALID.
19.373 + class FalseIt : public Key {
19.374 + public:
19.375 + typedef Key Parent;
19.376 +
19.377 + /// \brief Creates an iterator.
19.378 + ///
19.379 + /// Creates an iterator. It iterates on the
19.380 + /// keys mapped to \c false.
19.381 + /// \param map The IterableBoolMap.
19.382 + explicit FalseIt(const IterableBoolMap& map)
19.383 + : Parent(map._sep < int(map._array.size()) ?
19.384 + map._array.back() : INVALID), _map(&map) {}
19.385 +
19.386 + /// \brief Invalid constructor \& conversion.
19.387 + ///
19.388 + /// This constructor initializes the iterator to be invalid.
19.389 + /// \sa Invalid for more details.
19.390 + FalseIt(Invalid) : Parent(INVALID), _map(0) {}
19.391 +
19.392 + /// \brief Increment operator.
19.393 + ///
19.394 + /// Increment operator.
19.395 + FalseIt& operator++() {
19.396 + int pos = _map->position(*this);
19.397 + Parent::operator=(pos > _map->_sep ? _map->_array[pos - 1] : INVALID);
19.398 + return *this;
19.399 + }
19.400 +
19.401 + private:
19.402 + const IterableBoolMap* _map;
19.403 + };
19.404 +
19.405 + /// \brief Iterator for the keys mapped to a given value.
19.406 + ///
19.407 + /// Iterator for the keys mapped to a given value. It works
19.408 + /// like a graph item iterator, it can be converted to
19.409 + /// the key type of the map, incremented with \c ++ operator, and
19.410 + /// if the iterator leaves the last valid key, it will be equal to
19.411 + /// \c INVALID.
19.412 + class ItemIt : public Key {
19.413 + public:
19.414 + typedef Key Parent;
19.415 +
19.416 + /// \brief Creates an iterator with a value.
19.417 + ///
19.418 + /// Creates an iterator with a value. It iterates on the
19.419 + /// keys mapped to the given value.
19.420 + /// \param map The IterableBoolMap.
19.421 + /// \param value The value.
19.422 + ItemIt(const IterableBoolMap& map, bool value)
19.423 + : Parent(value ?
19.424 + (map._sep > 0 ?
19.425 + map._array[map._sep - 1] : INVALID) :
19.426 + (map._sep < int(map._array.size()) ?
19.427 + map._array.back() : INVALID)), _map(&map) {}
19.428 +
19.429 + /// \brief Invalid constructor \& conversion.
19.430 + ///
19.431 + /// This constructor initializes the iterator to be invalid.
19.432 + /// \sa Invalid for more details.
19.433 + ItemIt(Invalid) : Parent(INVALID), _map(0) {}
19.434 +
19.435 + /// \brief Increment operator.
19.436 + ///
19.437 + /// Increment operator.
19.438 + ItemIt& operator++() {
19.439 + int pos = _map->position(*this);
19.440 + int _sep = pos >= _map->_sep ? _map->_sep : 0;
19.441 + Parent::operator=(pos > _sep ? _map->_array[pos - 1] : INVALID);
19.442 + return *this;
19.443 + }
19.444 +
19.445 + private:
19.446 + const IterableBoolMap* _map;
19.447 + };
19.448 +
19.449 + protected:
19.450 +
19.451 + virtual void add(const Key& key) {
19.452 + Parent::add(key);
19.453 + Parent::set(key, _array.size());
19.454 + _array.push_back(key);
19.455 + }
19.456 +
19.457 + virtual void add(const std::vector<Key>& keys) {
19.458 + Parent::add(keys);
19.459 + for (int i = 0; i < int(keys.size()); ++i) {
19.460 + Parent::set(keys[i], _array.size());
19.461 + _array.push_back(keys[i]);
19.462 + }
19.463 + }
19.464 +
19.465 + virtual void erase(const Key& key) {
19.466 + int pos = position(key);
19.467 + if (pos < _sep) {
19.468 + --_sep;
19.469 + Parent::set(_array[_sep], pos);
19.470 + _array[pos] = _array[_sep];
19.471 + Parent::set(_array.back(), _sep);
19.472 + _array[_sep] = _array.back();
19.473 + _array.pop_back();
19.474 + } else {
19.475 + Parent::set(_array.back(), pos);
19.476 + _array[pos] = _array.back();
19.477 + _array.pop_back();
19.478 + }
19.479 + Parent::erase(key);
19.480 + }
19.481 +
19.482 + virtual void erase(const std::vector<Key>& keys) {
19.483 + for (int i = 0; i < int(keys.size()); ++i) {
19.484 + int pos = position(keys[i]);
19.485 + if (pos < _sep) {
19.486 + --_sep;
19.487 + Parent::set(_array[_sep], pos);
19.488 + _array[pos] = _array[_sep];
19.489 + Parent::set(_array.back(), _sep);
19.490 + _array[_sep] = _array.back();
19.491 + _array.pop_back();
19.492 + } else {
19.493 + Parent::set(_array.back(), pos);
19.494 + _array[pos] = _array.back();
19.495 + _array.pop_back();
19.496 + }
19.497 + }
19.498 + Parent::erase(keys);
19.499 + }
19.500 +
19.501 + virtual void build() {
19.502 + Parent::build();
19.503 + typename Parent::Notifier* nf = Parent::notifier();
19.504 + Key it;
19.505 + for (nf->first(it); it != INVALID; nf->next(it)) {
19.506 + Parent::set(it, _array.size());
19.507 + _array.push_back(it);
19.508 + }
19.509 + _sep = 0;
19.510 + }
19.511 +
19.512 + virtual void clear() {
19.513 + _array.clear();
19.514 + _sep = 0;
19.515 + Parent::clear();
19.516 + }
19.517 +
19.518 + };
19.519 +
19.520 +
19.521 + namespace _maps_bits {
19.522 + template <typename Item>
19.523 + struct IterableIntMapNode {
19.524 + IterableIntMapNode() : value(-1) {}
19.525 + IterableIntMapNode(int _value) : value(_value) {}
19.526 + Item prev, next;
19.527 + int value;
19.528 + };
19.529 + }
19.530 +
19.531 + /// \brief Dynamic iterable integer map.
19.532 + ///
19.533 + /// This class provides a special graph map type which can store an
19.534 + /// integer value for graph items (\c Node, \c Arc or \c Edge).
19.535 + /// For each non-negative value it is possible to iterate on the keys
19.536 + /// mapped to the value.
19.537 + ///
19.538 + /// This type is a reference map, so it can be modified with the
19.539 + /// subscript operator.
19.540 + ///
19.541 + /// \note The size of the data structure depends on the largest
19.542 + /// value in the map.
19.543 + ///
19.544 + /// \tparam GR The graph type.
19.545 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
19.546 + /// \c GR::Edge).
19.547 + ///
19.548 + /// \see IterableBoolMap, IterableValueMap
19.549 + /// \see CrossRefMap
19.550 + template <typename GR, typename K>
19.551 + class IterableIntMap
19.552 + : protected ItemSetTraits<GR, K>::
19.553 + template Map<_maps_bits::IterableIntMapNode<K> >::Type {
19.554 + public:
19.555 + typedef typename ItemSetTraits<GR, K>::
19.556 + template Map<_maps_bits::IterableIntMapNode<K> >::Type Parent;
19.557 +
19.558 + /// The key type
19.559 + typedef K Key;
19.560 + /// The value type
19.561 + typedef int Value;
19.562 + /// The graph type
19.563 + typedef GR Graph;
19.564 +
19.565 + /// \brief Constructor of the map.
19.566 + ///
19.567 + /// Constructor of the map. It sets all values to -1.
19.568 + explicit IterableIntMap(const Graph& graph)
19.569 + : Parent(graph) {}
19.570 +
19.571 + /// \brief Constructor of the map with a given value.
19.572 + ///
19.573 + /// Constructor of the map with a given value.
19.574 + explicit IterableIntMap(const Graph& graph, int value)
19.575 + : Parent(graph, _maps_bits::IterableIntMapNode<K>(value)) {
19.576 + if (value >= 0) {
19.577 + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
19.578 + lace(it);
19.579 + }
19.580 + }
19.581 + }
19.582 +
19.583 + private:
19.584 +
19.585 + void unlace(const Key& key) {
19.586 + typename Parent::Value& node = Parent::operator[](key);
19.587 + if (node.value < 0) return;
19.588 + if (node.prev != INVALID) {
19.589 + Parent::operator[](node.prev).next = node.next;
19.590 + } else {
19.591 + _first[node.value] = node.next;
19.592 + }
19.593 + if (node.next != INVALID) {
19.594 + Parent::operator[](node.next).prev = node.prev;
19.595 + }
19.596 + while (!_first.empty() && _first.back() == INVALID) {
19.597 + _first.pop_back();
19.598 + }
19.599 + }
19.600 +
19.601 + void lace(const Key& key) {
19.602 + typename Parent::Value& node = Parent::operator[](key);
19.603 + if (node.value < 0) return;
19.604 + if (node.value >= int(_first.size())) {
19.605 + _first.resize(node.value + 1, INVALID);
19.606 + }
19.607 + node.prev = INVALID;
19.608 + node.next = _first[node.value];
19.609 + if (node.next != INVALID) {
19.610 + Parent::operator[](node.next).prev = key;
19.611 + }
19.612 + _first[node.value] = key;
19.613 + }
19.614 +
19.615 + public:
19.616 +
19.617 + /// Indicates that the map is reference map.
19.618 + typedef True ReferenceMapTag;
19.619 +
19.620 + /// \brief Reference to the value of the map.
19.621 + ///
19.622 + /// This class is similar to the \c int type. It can
19.623 + /// be converted to \c int and it has the same operators.
19.624 + class Reference {
19.625 + friend class IterableIntMap;
19.626 + private:
19.627 + Reference(IterableIntMap& map, const Key& key)
19.628 + : _key(key), _map(map) {}
19.629 + public:
19.630 +
19.631 + Reference& operator=(const Reference& value) {
19.632 + _map.set(_key, static_cast<const int&>(value));
19.633 + return *this;
19.634 + }
19.635 +
19.636 + operator const int&() const {
19.637 + return static_cast<const IterableIntMap&>(_map)[_key];
19.638 + }
19.639 +
19.640 + Reference& operator=(int value) {
19.641 + _map.set(_key, value);
19.642 + return *this;
19.643 + }
19.644 + Reference& operator++() {
19.645 + _map.set(_key, _map[_key] + 1);
19.646 + return *this;
19.647 + }
19.648 + int operator++(int) {
19.649 + int value = _map[_key];
19.650 + _map.set(_key, value + 1);
19.651 + return value;
19.652 + }
19.653 + Reference& operator--() {
19.654 + _map.set(_key, _map[_key] - 1);
19.655 + return *this;
19.656 + }
19.657 + int operator--(int) {
19.658 + int value = _map[_key];
19.659 + _map.set(_key, value - 1);
19.660 + return value;
19.661 + }
19.662 + Reference& operator+=(int value) {
19.663 + _map.set(_key, _map[_key] + value);
19.664 + return *this;
19.665 + }
19.666 + Reference& operator-=(int value) {
19.667 + _map.set(_key, _map[_key] - value);
19.668 + return *this;
19.669 + }
19.670 + Reference& operator*=(int value) {
19.671 + _map.set(_key, _map[_key] * value);
19.672 + return *this;
19.673 + }
19.674 + Reference& operator/=(int value) {
19.675 + _map.set(_key, _map[_key] / value);
19.676 + return *this;
19.677 + }
19.678 + Reference& operator%=(int value) {
19.679 + _map.set(_key, _map[_key] % value);
19.680 + return *this;
19.681 + }
19.682 + Reference& operator&=(int value) {
19.683 + _map.set(_key, _map[_key] & value);
19.684 + return *this;
19.685 + }
19.686 + Reference& operator|=(int value) {
19.687 + _map.set(_key, _map[_key] | value);
19.688 + return *this;
19.689 + }
19.690 + Reference& operator^=(int value) {
19.691 + _map.set(_key, _map[_key] ^ value);
19.692 + return *this;
19.693 + }
19.694 + Reference& operator<<=(int value) {
19.695 + _map.set(_key, _map[_key] << value);
19.696 + return *this;
19.697 + }
19.698 + Reference& operator>>=(int value) {
19.699 + _map.set(_key, _map[_key] >> value);
19.700 + return *this;
19.701 + }
19.702 +
19.703 + private:
19.704 + Key _key;
19.705 + IterableIntMap& _map;
19.706 + };
19.707 +
19.708 + /// The const reference type.
19.709 + typedef const Value& ConstReference;
19.710 +
19.711 + /// \brief Gives back the maximal value plus one.
19.712 + ///
19.713 + /// Gives back the maximal value plus one.
19.714 + int size() const {
19.715 + return _first.size();
19.716 + }
19.717 +
19.718 + /// \brief Set operation of the map.
19.719 + ///
19.720 + /// Set operation of the map.
19.721 + void set(const Key& key, const Value& value) {
19.722 + unlace(key);
19.723 + Parent::operator[](key).value = value;
19.724 + lace(key);
19.725 + }
19.726 +
19.727 + /// \brief Const subscript operator of the map.
19.728 + ///
19.729 + /// Const subscript operator of the map.
19.730 + const Value& operator[](const Key& key) const {
19.731 + return Parent::operator[](key).value;
19.732 + }
19.733 +
19.734 + /// \brief Subscript operator of the map.
19.735 + ///
19.736 + /// Subscript operator of the map.
19.737 + Reference operator[](const Key& key) {
19.738 + return Reference(*this, key);
19.739 + }
19.740 +
19.741 + /// \brief Iterator for the keys with the same value.
19.742 + ///
19.743 + /// Iterator for the keys with the same value. It works
19.744 + /// like a graph item iterator, it can be converted to
19.745 + /// the item type of the map, incremented with \c ++ operator, and
19.746 + /// if the iterator leaves the last valid item, it will be equal to
19.747 + /// \c INVALID.
19.748 + class ItemIt : public Key {
19.749 + public:
19.750 + typedef Key Parent;
19.751 +
19.752 + /// \brief Invalid constructor \& conversion.
19.753 + ///
19.754 + /// This constructor initializes the iterator to be invalid.
19.755 + /// \sa Invalid for more details.
19.756 + ItemIt(Invalid) : Parent(INVALID), _map(0) {}
19.757 +
19.758 + /// \brief Creates an iterator with a value.
19.759 + ///
19.760 + /// Creates an iterator with a value. It iterates on the
19.761 + /// keys mapped to the given value.
19.762 + /// \param map The IterableIntMap.
19.763 + /// \param value The value.
19.764 + ItemIt(const IterableIntMap& map, int value) : _map(&map) {
19.765 + if (value < 0 || value >= int(_map->_first.size())) {
19.766 + Parent::operator=(INVALID);
19.767 + } else {
19.768 + Parent::operator=(_map->_first[value]);
19.769 + }
19.770 + }
19.771 +
19.772 + /// \brief Increment operator.
19.773 + ///
19.774 + /// Increment operator.
19.775 + ItemIt& operator++() {
19.776 + Parent::operator=(_map->IterableIntMap::Parent::
19.777 + operator[](static_cast<Parent&>(*this)).next);
19.778 + return *this;
19.779 + }
19.780 +
19.781 + private:
19.782 + const IterableIntMap* _map;
19.783 + };
19.784 +
19.785 + protected:
19.786 +
19.787 + virtual void erase(const Key& key) {
19.788 + unlace(key);
19.789 + Parent::erase(key);
19.790 + }
19.791 +
19.792 + virtual void erase(const std::vector<Key>& keys) {
19.793 + for (int i = 0; i < int(keys.size()); ++i) {
19.794 + unlace(keys[i]);
19.795 + }
19.796 + Parent::erase(keys);
19.797 + }
19.798 +
19.799 + virtual void clear() {
19.800 + _first.clear();
19.801 + Parent::clear();
19.802 + }
19.803 +
19.804 + private:
19.805 + std::vector<Key> _first;
19.806 + };
19.807 +
19.808 + namespace _maps_bits {
19.809 + template <typename Item, typename Value>
19.810 + struct IterableValueMapNode {
19.811 + IterableValueMapNode(Value _value = Value()) : value(_value) {}
19.812 + Item prev, next;
19.813 + Value value;
19.814 + };
19.815 + }
19.816 +
19.817 + /// \brief Dynamic iterable map for comparable values.
19.818 + ///
19.819 + /// This class provides a special graph map type which can store an
19.820 + /// comparable value for graph items (\c Node, \c Arc or \c Edge).
19.821 + /// For each value it is possible to iterate on the keys mapped to
19.822 + /// the value.
19.823 + ///
19.824 + /// The map stores for each value a linked list with
19.825 + /// the items which mapped to the value, and the values are stored
19.826 + /// in balanced binary tree. The values of the map can be accessed
19.827 + /// with stl compatible forward iterator.
19.828 + ///
19.829 + /// This type is not reference map, so it cannot be modified with
19.830 + /// the subscript operator.
19.831 + ///
19.832 + /// \tparam GR The graph type.
19.833 + /// \tparam K The key type of the map (\c GR::Node, \c GR::Arc or
19.834 + /// \c GR::Edge).
19.835 + /// \tparam V The value type of the map. It can be any comparable
19.836 + /// value type.
19.837 + ///
19.838 + /// \see IterableBoolMap, IterableIntMap
19.839 + /// \see CrossRefMap
19.840 + template <typename GR, typename K, typename V>
19.841 + class IterableValueMap
19.842 + : protected ItemSetTraits<GR, K>::
19.843 + template Map<_maps_bits::IterableValueMapNode<K, V> >::Type {
19.844 + public:
19.845 + typedef typename ItemSetTraits<GR, K>::
19.846 + template Map<_maps_bits::IterableValueMapNode<K, V> >::Type Parent;
19.847 +
19.848 + /// The key type
19.849 + typedef K Key;
19.850 + /// The value type
19.851 + typedef V Value;
19.852 + /// The graph type
19.853 + typedef GR Graph;
19.854 +
19.855 + public:
19.856 +
19.857 + /// \brief Constructor of the map with a given value.
19.858 + ///
19.859 + /// Constructor of the map with a given value.
19.860 + explicit IterableValueMap(const Graph& graph,
19.861 + const Value& value = Value())
19.862 + : Parent(graph, _maps_bits::IterableValueMapNode<K, V>(value)) {
19.863 + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
19.864 + lace(it);
19.865 + }
19.866 + }
19.867 +
19.868 + protected:
19.869 +
19.870 + void unlace(const Key& key) {
19.871 + typename Parent::Value& node = Parent::operator[](key);
19.872 + if (node.prev != INVALID) {
19.873 + Parent::operator[](node.prev).next = node.next;
19.874 + } else {
19.875 + if (node.next != INVALID) {
19.876 + _first[node.value] = node.next;
19.877 + } else {
19.878 + _first.erase(node.value);
19.879 + }
19.880 + }
19.881 + if (node.next != INVALID) {
19.882 + Parent::operator[](node.next).prev = node.prev;
19.883 + }
19.884 + }
19.885 +
19.886 + void lace(const Key& key) {
19.887 + typename Parent::Value& node = Parent::operator[](key);
19.888 + typename std::map<Value, Key>::iterator it = _first.find(node.value);
19.889 + if (it == _first.end()) {
19.890 + node.prev = node.next = INVALID;
19.891 + _first.insert(std::make_pair(node.value, key));
19.892 + } else {
19.893 + node.prev = INVALID;
19.894 + node.next = it->second;
19.895 + if (node.next != INVALID) {
19.896 + Parent::operator[](node.next).prev = key;
19.897 + }
19.898 + it->second = key;
19.899 + }
19.900 + }
19.901 +
19.902 + public:
19.903 +
19.904 + /// \brief Forward iterator for values.
19.905 + ///
19.906 + /// This iterator is an stl compatible forward
19.907 + /// iterator on the values of the map. The values can
19.908 + /// be accessed in the <tt>[beginValue, endValue)</tt> range.
19.909 + class ValueIterator
19.910 + : public std::iterator<std::forward_iterator_tag, Value> {
19.911 + friend class IterableValueMap;
19.912 + private:
19.913 + ValueIterator(typename std::map<Value, Key>::const_iterator _it)
19.914 + : it(_it) {}
19.915 + public:
19.916 +
19.917 + ValueIterator() {}
19.918 +
19.919 + ValueIterator& operator++() { ++it; return *this; }
19.920 + ValueIterator operator++(int) {
19.921 + ValueIterator tmp(*this);
19.922 + operator++();
19.923 + return tmp;
19.924 + }
19.925 +
19.926 + const Value& operator*() const { return it->first; }
19.927 + const Value* operator->() const { return &(it->first); }
19.928 +
19.929 + bool operator==(ValueIterator jt) const { return it == jt.it; }
19.930 + bool operator!=(ValueIterator jt) const { return it != jt.it; }
19.931 +
19.932 + private:
19.933 + typename std::map<Value, Key>::const_iterator it;
19.934 + };
19.935 +
19.936 + /// \brief Returns an iterator to the first value.
19.937 + ///
19.938 + /// Returns an stl compatible iterator to the
19.939 + /// first value of the map. The values of the
19.940 + /// map can be accessed in the <tt>[beginValue, endValue)</tt>
19.941 + /// range.
19.942 + ValueIterator beginValue() const {
19.943 + return ValueIterator(_first.begin());
19.944 + }
19.945 +
19.946 + /// \brief Returns an iterator after the last value.
19.947 + ///
19.948 + /// Returns an stl compatible iterator after the
19.949 + /// last value of the map. The values of the
19.950 + /// map can be accessed in the <tt>[beginValue, endValue)</tt>
19.951 + /// range.
19.952 + ValueIterator endValue() const {
19.953 + return ValueIterator(_first.end());
19.954 + }
19.955 +
19.956 + /// \brief Set operation of the map.
19.957 + ///
19.958 + /// Set operation of the map.
19.959 + void set(const Key& key, const Value& value) {
19.960 + unlace(key);
19.961 + Parent::operator[](key).value = value;
19.962 + lace(key);
19.963 + }
19.964 +
19.965 + /// \brief Const subscript operator of the map.
19.966 + ///
19.967 + /// Const subscript operator of the map.
19.968 + const Value& operator[](const Key& key) const {
19.969 + return Parent::operator[](key).value;
19.970 + }
19.971 +
19.972 + /// \brief Iterator for the keys with the same value.
19.973 + ///
19.974 + /// Iterator for the keys with the same value. It works
19.975 + /// like a graph item iterator, it can be converted to
19.976 + /// the item type of the map, incremented with \c ++ operator, and
19.977 + /// if the iterator leaves the last valid item, it will be equal to
19.978 + /// \c INVALID.
19.979 + class ItemIt : public Key {
19.980 + public:
19.981 + typedef Key Parent;
19.982 +
19.983 + /// \brief Invalid constructor \& conversion.
19.984 + ///
19.985 + /// This constructor initializes the iterator to be invalid.
19.986 + /// \sa Invalid for more details.
19.987 + ItemIt(Invalid) : Parent(INVALID), _map(0) {}
19.988 +
19.989 + /// \brief Creates an iterator with a value.
19.990 + ///
19.991 + /// Creates an iterator with a value. It iterates on the
19.992 + /// keys which have the given value.
19.993 + /// \param map The IterableValueMap
19.994 + /// \param value The value
19.995 + ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
19.996 + typename std::map<Value, Key>::const_iterator it =
19.997 + map._first.find(value);
19.998 + if (it == map._first.end()) {
19.999 + Parent::operator=(INVALID);
19.1000 + } else {
19.1001 + Parent::operator=(it->second);
19.1002 + }
19.1003 + }
19.1004 +
19.1005 + /// \brief Increment operator.
19.1006 + ///
19.1007 + /// Increment Operator.
19.1008 + ItemIt& operator++() {
19.1009 + Parent::operator=(_map->IterableValueMap::Parent::
19.1010 + operator[](static_cast<Parent&>(*this)).next);
19.1011 + return *this;
19.1012 + }
19.1013 +
19.1014 +
19.1015 + private:
19.1016 + const IterableValueMap* _map;
19.1017 + };
19.1018 +
19.1019 + protected:
19.1020 +
19.1021 + virtual void add(const Key& key) {
19.1022 + Parent::add(key);
19.1023 + unlace(key);
19.1024 + }
19.1025 +
19.1026 + virtual void add(const std::vector<Key>& keys) {
19.1027 + Parent::add(keys);
19.1028 + for (int i = 0; i < int(keys.size()); ++i) {
19.1029 + lace(keys[i]);
19.1030 + }
19.1031 + }
19.1032 +
19.1033 + virtual void erase(const Key& key) {
19.1034 + unlace(key);
19.1035 + Parent::erase(key);
19.1036 + }
19.1037 +
19.1038 + virtual void erase(const std::vector<Key>& keys) {
19.1039 + for (int i = 0; i < int(keys.size()); ++i) {
19.1040 + unlace(keys[i]);
19.1041 + }
19.1042 + Parent::erase(keys);
19.1043 + }
19.1044 +
19.1045 + virtual void build() {
19.1046 + Parent::build();
19.1047 + for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
19.1048 + lace(it);
19.1049 + }
19.1050 + }
19.1051 +
19.1052 + virtual void clear() {
19.1053 + _first.clear();
19.1054 + Parent::clear();
19.1055 + }
19.1056 +
19.1057 + private:
19.1058 + std::map<Value, Key> _first;
19.1059 + };
19.1060 +
19.1061 /// \brief Map of the source nodes of arcs in a digraph.
19.1062 ///
19.1063 /// SourceMap provides access for the source node of each arc in a digraph,
19.1064 @@ -2480,7 +3395,7 @@
19.1065 /// in constant time. On the other hand, the values are updated automatically
19.1066 /// whenever the digraph changes.
19.1067 ///
19.1068 - /// \warning Besides \c addNode() and \c addArc(), a digraph structure
19.1069 + /// \warning Besides \c addNode() and \c addArc(), a digraph structure
19.1070 /// may provide alternative ways to modify the digraph.
19.1071 /// The correct behavior of InDegMap is not guarantied if these additional
19.1072 /// features are used. For example the functions
19.1073 @@ -2496,7 +3411,7 @@
19.1074 ::ItemNotifier::ObserverBase {
19.1075
19.1076 public:
19.1077 -
19.1078 +
19.1079 /// The graph type of InDegMap
19.1080 typedef GR Graph;
19.1081 typedef GR Digraph;
19.1082 @@ -2610,7 +3525,7 @@
19.1083 /// in constant time. On the other hand, the values are updated automatically
19.1084 /// whenever the digraph changes.
19.1085 ///
19.1086 - /// \warning Besides \c addNode() and \c addArc(), a digraph structure
19.1087 + /// \warning Besides \c addNode() and \c addArc(), a digraph structure
19.1088 /// may provide alternative ways to modify the digraph.
19.1089 /// The correct behavior of OutDegMap is not guarantied if these additional
19.1090 /// features are used. For example the functions
20.1 --- a/lemon/min_cost_arborescence.h Sun Aug 02 12:40:20 2009 +0200
20.2 +++ b/lemon/min_cost_arborescence.h Fri Sep 25 09:13:03 2009 +0200
20.3 @@ -488,8 +488,8 @@
20.4 /// \name Execution Control
20.5 /// The simplest way to execute the algorithm is to use
20.6 /// one of the member functions called \c run(...). \n
20.7 - /// If you need more control on the execution,
20.8 - /// first you must call \ref init(), then you can add several
20.9 + /// If you need better control on the execution,
20.10 + /// you have to call \ref init() first, then you can add several
20.11 /// source nodes with \ref addSource().
20.12 /// Finally \ref start() will perform the arborescence
20.13 /// computation.
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/lemon/pairing_heap.h Fri Sep 25 09:13:03 2009 +0200
21.3 @@ -0,0 +1,474 @@
21.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
21.5 + *
21.6 + * This file is a part of LEMON, a generic C++ optimization library.
21.7 + *
21.8 + * Copyright (C) 2003-2009
21.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
21.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
21.11 + *
21.12 + * Permission to use, modify and distribute this software is granted
21.13 + * provided that this copyright notice appears in all copies. For
21.14 + * precise terms see the accompanying LICENSE file.
21.15 + *
21.16 + * This software is provided "AS IS" with no warranty of any kind,
21.17 + * express or implied, and with no claim as to its suitability for any
21.18 + * purpose.
21.19 + *
21.20 + */
21.21 +
21.22 +#ifndef LEMON_PAIRING_HEAP_H
21.23 +#define LEMON_PAIRING_HEAP_H
21.24 +
21.25 +///\file
21.26 +///\ingroup heaps
21.27 +///\brief Pairing heap implementation.
21.28 +
21.29 +#include <vector>
21.30 +#include <utility>
21.31 +#include <functional>
21.32 +#include <lemon/math.h>
21.33 +
21.34 +namespace lemon {
21.35 +
21.36 + /// \ingroup heaps
21.37 + ///
21.38 + ///\brief Pairing Heap.
21.39 + ///
21.40 + /// This class implements the \e pairing \e heap data structure.
21.41 + /// It fully conforms to the \ref concepts::Heap "heap concept".
21.42 + ///
21.43 + /// The methods \ref increase() and \ref erase() are not efficient
21.44 + /// in a pairing heap. In case of many calls of these operations,
21.45 + /// it is better to use other heap structure, e.g. \ref BinHeap
21.46 + /// "binary heap".
21.47 + ///
21.48 + /// \tparam PR Type of the priorities of the items.
21.49 + /// \tparam IM A read-writable item map with \c int values, used
21.50 + /// internally to handle the cross references.
21.51 + /// \tparam CMP A functor class for comparing the priorities.
21.52 + /// The default is \c std::less<PR>.
21.53 +#ifdef DOXYGEN
21.54 + template <typename PR, typename IM, typename CMP>
21.55 +#else
21.56 + template <typename PR, typename IM, typename CMP = std::less<PR> >
21.57 +#endif
21.58 + class PairingHeap {
21.59 + public:
21.60 + /// Type of the item-int map.
21.61 + typedef IM ItemIntMap;
21.62 + /// Type of the priorities.
21.63 + typedef PR Prio;
21.64 + /// Type of the items stored in the heap.
21.65 + typedef typename ItemIntMap::Key Item;
21.66 + /// Functor type for comparing the priorities.
21.67 + typedef CMP Compare;
21.68 +
21.69 + /// \brief Type to represent the states of the items.
21.70 + ///
21.71 + /// Each item has a state associated to it. It can be "in heap",
21.72 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
21.73 + /// heap's point of view, but may be useful to the user.
21.74 + ///
21.75 + /// The item-int map must be initialized in such way that it assigns
21.76 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
21.77 + enum State {
21.78 + IN_HEAP = 0, ///< = 0.
21.79 + PRE_HEAP = -1, ///< = -1.
21.80 + POST_HEAP = -2 ///< = -2.
21.81 + };
21.82 +
21.83 + private:
21.84 + class store;
21.85 +
21.86 + std::vector<store> _data;
21.87 + int _min;
21.88 + ItemIntMap &_iim;
21.89 + Compare _comp;
21.90 + int _num_items;
21.91 +
21.92 + public:
21.93 + /// \brief Constructor.
21.94 + ///
21.95 + /// Constructor.
21.96 + /// \param map A map that assigns \c int values to the items.
21.97 + /// It is used internally to handle the cross references.
21.98 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
21.99 + explicit PairingHeap(ItemIntMap &map)
21.100 + : _min(0), _iim(map), _num_items(0) {}
21.101 +
21.102 + /// \brief Constructor.
21.103 + ///
21.104 + /// Constructor.
21.105 + /// \param map A map that assigns \c int values to the items.
21.106 + /// It is used internally to handle the cross references.
21.107 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
21.108 + /// \param comp The function object used for comparing the priorities.
21.109 + PairingHeap(ItemIntMap &map, const Compare &comp)
21.110 + : _min(0), _iim(map), _comp(comp), _num_items(0) {}
21.111 +
21.112 + /// \brief The number of items stored in the heap.
21.113 + ///
21.114 + /// This function returns the number of items stored in the heap.
21.115 + int size() const { return _num_items; }
21.116 +
21.117 + /// \brief Check if the heap is empty.
21.118 + ///
21.119 + /// This function returns \c true if the heap is empty.
21.120 + bool empty() const { return _num_items==0; }
21.121 +
21.122 + /// \brief Make the heap empty.
21.123 + ///
21.124 + /// This functon makes the heap empty.
21.125 + /// It does not change the cross reference map. If you want to reuse
21.126 + /// a heap that is not surely empty, you should first clear it and
21.127 + /// then you should set the cross reference map to \c PRE_HEAP
21.128 + /// for each item.
21.129 + void clear() {
21.130 + _data.clear();
21.131 + _min = 0;
21.132 + _num_items = 0;
21.133 + }
21.134 +
21.135 + /// \brief Set the priority of an item or insert it, if it is
21.136 + /// not stored in the heap.
21.137 + ///
21.138 + /// This method sets the priority of the given item if it is
21.139 + /// already stored in the heap. Otherwise it inserts the given
21.140 + /// item into the heap with the given priority.
21.141 + /// \param item The item.
21.142 + /// \param value The priority.
21.143 + void set (const Item& item, const Prio& value) {
21.144 + int i=_iim[item];
21.145 + if ( i>=0 && _data[i].in ) {
21.146 + if ( _comp(value, _data[i].prio) ) decrease(item, value);
21.147 + if ( _comp(_data[i].prio, value) ) increase(item, value);
21.148 + } else push(item, value);
21.149 + }
21.150 +
21.151 + /// \brief Insert an item into the heap with the given priority.
21.152 + ///
21.153 + /// This function inserts the given item into the heap with the
21.154 + /// given priority.
21.155 + /// \param item The item to insert.
21.156 + /// \param value The priority of the item.
21.157 + /// \pre \e item must not be stored in the heap.
21.158 + void push (const Item& item, const Prio& value) {
21.159 + int i=_iim[item];
21.160 + if( i<0 ) {
21.161 + int s=_data.size();
21.162 + _iim.set(item, s);
21.163 + store st;
21.164 + st.name=item;
21.165 + _data.push_back(st);
21.166 + i=s;
21.167 + } else {
21.168 + _data[i].parent=_data[i].child=-1;
21.169 + _data[i].left_child=false;
21.170 + _data[i].degree=0;
21.171 + _data[i].in=true;
21.172 + }
21.173 +
21.174 + _data[i].prio=value;
21.175 +
21.176 + if ( _num_items!=0 ) {
21.177 + if ( _comp( value, _data[_min].prio) ) {
21.178 + fuse(i,_min);
21.179 + _min=i;
21.180 + }
21.181 + else fuse(_min,i);
21.182 + }
21.183 + else _min=i;
21.184 +
21.185 + ++_num_items;
21.186 + }
21.187 +
21.188 + /// \brief Return the item having minimum priority.
21.189 + ///
21.190 + /// This function returns the item having minimum priority.
21.191 + /// \pre The heap must be non-empty.
21.192 + Item top() const { return _data[_min].name; }
21.193 +
21.194 + /// \brief The minimum priority.
21.195 + ///
21.196 + /// This function returns the minimum priority.
21.197 + /// \pre The heap must be non-empty.
21.198 + const Prio& prio() const { return _data[_min].prio; }
21.199 +
21.200 + /// \brief The priority of the given item.
21.201 + ///
21.202 + /// This function returns the priority of the given item.
21.203 + /// \param item The item.
21.204 + /// \pre \e item must be in the heap.
21.205 + const Prio& operator[](const Item& item) const {
21.206 + return _data[_iim[item]].prio;
21.207 + }
21.208 +
21.209 + /// \brief Remove the item having minimum priority.
21.210 + ///
21.211 + /// This function removes the item having minimum priority.
21.212 + /// \pre The heap must be non-empty.
21.213 + void pop() {
21.214 + std::vector<int> trees;
21.215 + int i=0, child_right = 0;
21.216 + _data[_min].in=false;
21.217 +
21.218 + if( -1!=_data[_min].child ) {
21.219 + i=_data[_min].child;
21.220 + trees.push_back(i);
21.221 + _data[i].parent = -1;
21.222 + _data[_min].child = -1;
21.223 +
21.224 + int ch=-1;
21.225 + while( _data[i].child!=-1 ) {
21.226 + ch=_data[i].child;
21.227 + if( _data[ch].left_child && i==_data[ch].parent ) {
21.228 + break;
21.229 + } else {
21.230 + if( _data[ch].left_child ) {
21.231 + child_right=_data[ch].parent;
21.232 + _data[ch].parent = i;
21.233 + --_data[i].degree;
21.234 + }
21.235 + else {
21.236 + child_right=ch;
21.237 + _data[i].child=-1;
21.238 + _data[i].degree=0;
21.239 + }
21.240 + _data[child_right].parent = -1;
21.241 + trees.push_back(child_right);
21.242 + i = child_right;
21.243 + }
21.244 + }
21.245 +
21.246 + int num_child = trees.size();
21.247 + int other;
21.248 + for( i=0; i<num_child-1; i+=2 ) {
21.249 + if ( !_comp(_data[trees[i]].prio, _data[trees[i+1]].prio) ) {
21.250 + other=trees[i];
21.251 + trees[i]=trees[i+1];
21.252 + trees[i+1]=other;
21.253 + }
21.254 + fuse( trees[i], trees[i+1] );
21.255 + }
21.256 +
21.257 + i = (0==(num_child % 2)) ? num_child-2 : num_child-1;
21.258 + while(i>=2) {
21.259 + if ( _comp(_data[trees[i]].prio, _data[trees[i-2]].prio) ) {
21.260 + other=trees[i];
21.261 + trees[i]=trees[i-2];
21.262 + trees[i-2]=other;
21.263 + }
21.264 + fuse( trees[i-2], trees[i] );
21.265 + i-=2;
21.266 + }
21.267 + _min = trees[0];
21.268 + }
21.269 + else {
21.270 + _min = _data[_min].child;
21.271 + }
21.272 +
21.273 + if (_min >= 0) _data[_min].left_child = false;
21.274 + --_num_items;
21.275 + }
21.276 +
21.277 + /// \brief Remove the given item from the heap.
21.278 + ///
21.279 + /// This function removes the given item from the heap if it is
21.280 + /// already stored.
21.281 + /// \param item The item to delete.
21.282 + /// \pre \e item must be in the heap.
21.283 + void erase (const Item& item) {
21.284 + int i=_iim[item];
21.285 + if ( i>=0 && _data[i].in ) {
21.286 + decrease( item, _data[_min].prio-1 );
21.287 + pop();
21.288 + }
21.289 + }
21.290 +
21.291 + /// \brief Decrease the priority of an item to the given value.
21.292 + ///
21.293 + /// This function decreases the priority of an item to the given value.
21.294 + /// \param item The item.
21.295 + /// \param value The priority.
21.296 + /// \pre \e item must be stored in the heap with priority at least \e value.
21.297 + void decrease (Item item, const Prio& value) {
21.298 + int i=_iim[item];
21.299 + _data[i].prio=value;
21.300 + int p=_data[i].parent;
21.301 +
21.302 + if( _data[i].left_child && i!=_data[p].child ) {
21.303 + p=_data[p].parent;
21.304 + }
21.305 +
21.306 + if ( p!=-1 && _comp(value,_data[p].prio) ) {
21.307 + cut(i,p);
21.308 + if ( _comp(_data[_min].prio,value) ) {
21.309 + fuse(_min,i);
21.310 + } else {
21.311 + fuse(i,_min);
21.312 + _min=i;
21.313 + }
21.314 + }
21.315 + }
21.316 +
21.317 + /// \brief Increase the priority of an item to the given value.
21.318 + ///
21.319 + /// This function increases the priority of an item to the given value.
21.320 + /// \param item The item.
21.321 + /// \param value The priority.
21.322 + /// \pre \e item must be stored in the heap with priority at most \e value.
21.323 + void increase (Item item, const Prio& value) {
21.324 + erase(item);
21.325 + push(item,value);
21.326 + }
21.327 +
21.328 + /// \brief Return the state of an item.
21.329 + ///
21.330 + /// This method returns \c PRE_HEAP if the given item has never
21.331 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
21.332 + /// and \c POST_HEAP otherwise.
21.333 + /// In the latter case it is possible that the item will get back
21.334 + /// to the heap again.
21.335 + /// \param item The item.
21.336 + State state(const Item &item) const {
21.337 + int i=_iim[item];
21.338 + if( i>=0 ) {
21.339 + if( _data[i].in ) i=0;
21.340 + else i=-2;
21.341 + }
21.342 + return State(i);
21.343 + }
21.344 +
21.345 + /// \brief Set the state of an item in the heap.
21.346 + ///
21.347 + /// This function sets the state of the given item in the heap.
21.348 + /// It can be used to manually clear the heap when it is important
21.349 + /// to achive better time complexity.
21.350 + /// \param i The item.
21.351 + /// \param st The state. It should not be \c IN_HEAP.
21.352 + void state(const Item& i, State st) {
21.353 + switch (st) {
21.354 + case POST_HEAP:
21.355 + case PRE_HEAP:
21.356 + if (state(i) == IN_HEAP) erase(i);
21.357 + _iim[i]=st;
21.358 + break;
21.359 + case IN_HEAP:
21.360 + break;
21.361 + }
21.362 + }
21.363 +
21.364 + private:
21.365 +
21.366 + void cut(int a, int b) {
21.367 + int child_a;
21.368 + switch (_data[a].degree) {
21.369 + case 2:
21.370 + child_a = _data[_data[a].child].parent;
21.371 + if( _data[a].left_child ) {
21.372 + _data[child_a].left_child=true;
21.373 + _data[b].child=child_a;
21.374 + _data[child_a].parent=_data[a].parent;
21.375 + }
21.376 + else {
21.377 + _data[child_a].left_child=false;
21.378 + _data[child_a].parent=b;
21.379 + if( a!=_data[b].child )
21.380 + _data[_data[b].child].parent=child_a;
21.381 + else
21.382 + _data[b].child=child_a;
21.383 + }
21.384 + --_data[a].degree;
21.385 + _data[_data[a].child].parent=a;
21.386 + break;
21.387 +
21.388 + case 1:
21.389 + child_a = _data[a].child;
21.390 + if( !_data[child_a].left_child ) {
21.391 + --_data[a].degree;
21.392 + if( _data[a].left_child ) {
21.393 + _data[child_a].left_child=true;
21.394 + _data[child_a].parent=_data[a].parent;
21.395 + _data[b].child=child_a;
21.396 + }
21.397 + else {
21.398 + _data[child_a].left_child=false;
21.399 + _data[child_a].parent=b;
21.400 + if( a!=_data[b].child )
21.401 + _data[_data[b].child].parent=child_a;
21.402 + else
21.403 + _data[b].child=child_a;
21.404 + }
21.405 + _data[a].child=-1;
21.406 + }
21.407 + else {
21.408 + --_data[b].degree;
21.409 + if( _data[a].left_child ) {
21.410 + _data[b].child =
21.411 + (1==_data[b].degree) ? _data[a].parent : -1;
21.412 + } else {
21.413 + if (1==_data[b].degree)
21.414 + _data[_data[b].child].parent=b;
21.415 + else
21.416 + _data[b].child=-1;
21.417 + }
21.418 + }
21.419 + break;
21.420 +
21.421 + case 0:
21.422 + --_data[b].degree;
21.423 + if( _data[a].left_child ) {
21.424 + _data[b].child =
21.425 + (0!=_data[b].degree) ? _data[a].parent : -1;
21.426 + } else {
21.427 + if( 0!=_data[b].degree )
21.428 + _data[_data[b].child].parent=b;
21.429 + else
21.430 + _data[b].child=-1;
21.431 + }
21.432 + break;
21.433 + }
21.434 + _data[a].parent=-1;
21.435 + _data[a].left_child=false;
21.436 + }
21.437 +
21.438 + void fuse(int a, int b) {
21.439 + int child_a = _data[a].child;
21.440 + int child_b = _data[b].child;
21.441 + _data[a].child=b;
21.442 + _data[b].parent=a;
21.443 + _data[b].left_child=true;
21.444 +
21.445 + if( -1!=child_a ) {
21.446 + _data[b].child=child_a;
21.447 + _data[child_a].parent=b;
21.448 + _data[child_a].left_child=false;
21.449 + ++_data[b].degree;
21.450 +
21.451 + if( -1!=child_b ) {
21.452 + _data[b].child=child_b;
21.453 + _data[child_b].parent=child_a;
21.454 + }
21.455 + }
21.456 + else { ++_data[a].degree; }
21.457 + }
21.458 +
21.459 + class store {
21.460 + friend class PairingHeap;
21.461 +
21.462 + Item name;
21.463 + int parent;
21.464 + int child;
21.465 + bool left_child;
21.466 + int degree;
21.467 + bool in;
21.468 + Prio prio;
21.469 +
21.470 + store() : parent(-1), child(-1), left_child(false), degree(0), in(true) {}
21.471 + };
21.472 + };
21.473 +
21.474 +} //namespace lemon
21.475 +
21.476 +#endif //LEMON_PAIRING_HEAP_H
21.477 +
22.1 --- a/lemon/preflow.h Sun Aug 02 12:40:20 2009 +0200
22.2 +++ b/lemon/preflow.h Fri Sep 25 09:13:03 2009 +0200
22.3 @@ -52,7 +52,11 @@
22.4 ///
22.5 /// The type of the map that stores the flow values.
22.6 /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
22.7 +#ifdef DOXYGEN
22.8 + typedef GR::ArcMap<Value> FlowMap;
22.9 +#else
22.10 typedef typename Digraph::template ArcMap<Value> FlowMap;
22.11 +#endif
22.12
22.13 /// \brief Instantiates a FlowMap.
22.14 ///
22.15 @@ -67,9 +71,12 @@
22.16 ///
22.17 /// The elevator type used by Preflow algorithm.
22.18 ///
22.19 - /// \sa Elevator
22.20 - /// \sa LinkedElevator
22.21 - typedef LinkedElevator<Digraph, typename Digraph::Node> Elevator;
22.22 + /// \sa Elevator, LinkedElevator
22.23 +#ifdef DOXYGEN
22.24 + typedef lemon::Elevator<GR, GR::Node> Elevator;
22.25 +#else
22.26 + typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
22.27 +#endif
22.28
22.29 /// \brief Instantiates an Elevator.
22.30 ///
22.31 @@ -97,7 +104,7 @@
22.32 /// \e push-relabel algorithm producing a \ref max_flow
22.33 /// "flow of maximum value" in a digraph.
22.34 /// The preflow algorithms are the fastest known maximum
22.35 - /// flow algorithms. The current implementation use a mixture of the
22.36 + /// flow algorithms. The current implementation uses a mixture of the
22.37 /// \e "highest label" and the \e "bound decrease" heuristics.
22.38 /// The worst case time complexity of the algorithm is \f$O(n^2\sqrt{e})\f$.
22.39 ///
22.40 @@ -371,26 +378,28 @@
22.41 return *_level;
22.42 }
22.43
22.44 - /// \brief Sets the tolerance used by algorithm.
22.45 + /// \brief Sets the tolerance used by the algorithm.
22.46 ///
22.47 - /// Sets the tolerance used by algorithm.
22.48 - Preflow& tolerance(const Tolerance& tolerance) const {
22.49 + /// Sets the tolerance object used by the algorithm.
22.50 + /// \return <tt>(*this)</tt>
22.51 + Preflow& tolerance(const Tolerance& tolerance) {
22.52 _tolerance = tolerance;
22.53 return *this;
22.54 }
22.55
22.56 /// \brief Returns a const reference to the tolerance.
22.57 ///
22.58 - /// Returns a const reference to the tolerance.
22.59 + /// Returns a const reference to the tolerance object used by
22.60 + /// the algorithm.
22.61 const Tolerance& tolerance() const {
22.62 - return tolerance;
22.63 + return _tolerance;
22.64 }
22.65
22.66 /// \name Execution Control
22.67 /// The simplest way to execute the preflow algorithm is to use
22.68 /// \ref run() or \ref runMinCut().\n
22.69 - /// If you need more control on the initial solution or the execution,
22.70 - /// first you have to call one of the \ref init() functions, then
22.71 + /// If you need better control on the initial solution or the execution,
22.72 + /// you have to call one of the \ref init() functions first, then
22.73 /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
22.74
22.75 ///@{
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/lemon/radix_heap.h Fri Sep 25 09:13:03 2009 +0200
23.3 @@ -0,0 +1,438 @@
23.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
23.5 + *
23.6 + * This file is a part of LEMON, a generic C++ optimization library.
23.7 + *
23.8 + * Copyright (C) 2003-2009
23.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
23.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
23.11 + *
23.12 + * Permission to use, modify and distribute this software is granted
23.13 + * provided that this copyright notice appears in all copies. For
23.14 + * precise terms see the accompanying LICENSE file.
23.15 + *
23.16 + * This software is provided "AS IS" with no warranty of any kind,
23.17 + * express or implied, and with no claim as to its suitability for any
23.18 + * purpose.
23.19 + *
23.20 + */
23.21 +
23.22 +#ifndef LEMON_RADIX_HEAP_H
23.23 +#define LEMON_RADIX_HEAP_H
23.24 +
23.25 +///\ingroup heaps
23.26 +///\file
23.27 +///\brief Radix heap implementation.
23.28 +
23.29 +#include <vector>
23.30 +#include <lemon/error.h>
23.31 +
23.32 +namespace lemon {
23.33 +
23.34 +
23.35 + /// \ingroup heaps
23.36 + ///
23.37 + /// \brief Radix heap data structure.
23.38 + ///
23.39 + /// This class implements the \e radix \e heap data structure.
23.40 + /// It practically conforms to the \ref concepts::Heap "heap concept",
23.41 + /// but it has some limitations due its special implementation.
23.42 + /// The type of the priorities must be \c int and the priority of an
23.43 + /// item cannot be decreased under the priority of the last removed item.
23.44 + ///
23.45 + /// \tparam IM A read-writable item map with \c int values, used
23.46 + /// internally to handle the cross references.
23.47 + template <typename IM>
23.48 + class RadixHeap {
23.49 +
23.50 + public:
23.51 +
23.52 + /// Type of the item-int map.
23.53 + typedef IM ItemIntMap;
23.54 + /// Type of the priorities.
23.55 + typedef int Prio;
23.56 + /// Type of the items stored in the heap.
23.57 + typedef typename ItemIntMap::Key Item;
23.58 +
23.59 + /// \brief Exception thrown by RadixHeap.
23.60 + ///
23.61 + /// This exception is thrown when an item is inserted into a
23.62 + /// RadixHeap with a priority smaller than the last erased one.
23.63 + /// \see RadixHeap
23.64 + class PriorityUnderflowError : public Exception {
23.65 + public:
23.66 + virtual const char* what() const throw() {
23.67 + return "lemon::RadixHeap::PriorityUnderflowError";
23.68 + }
23.69 + };
23.70 +
23.71 + /// \brief Type to represent the states of the items.
23.72 + ///
23.73 + /// Each item has a state associated to it. It can be "in heap",
23.74 + /// "pre-heap" or "post-heap". The latter two are indifferent from the
23.75 + /// heap's point of view, but may be useful to the user.
23.76 + ///
23.77 + /// The item-int map must be initialized in such way that it assigns
23.78 + /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
23.79 + enum State {
23.80 + IN_HEAP = 0, ///< = 0.
23.81 + PRE_HEAP = -1, ///< = -1.
23.82 + POST_HEAP = -2 ///< = -2.
23.83 + };
23.84 +
23.85 + private:
23.86 +
23.87 + struct RadixItem {
23.88 + int prev, next, box;
23.89 + Item item;
23.90 + int prio;
23.91 + RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
23.92 + };
23.93 +
23.94 + struct RadixBox {
23.95 + int first;
23.96 + int min, size;
23.97 + RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
23.98 + };
23.99 +
23.100 + std::vector<RadixItem> _data;
23.101 + std::vector<RadixBox> _boxes;
23.102 +
23.103 + ItemIntMap &_iim;
23.104 +
23.105 + public:
23.106 +
23.107 + /// \brief Constructor.
23.108 + ///
23.109 + /// Constructor.
23.110 + /// \param map A map that assigns \c int values to the items.
23.111 + /// It is used internally to handle the cross references.
23.112 + /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
23.113 + /// \param minimum The initial minimum value of the heap.
23.114 + /// \param capacity The initial capacity of the heap.
23.115 + RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0)
23.116 + : _iim(map)
23.117 + {
23.118 + _boxes.push_back(RadixBox(minimum, 1));
23.119 + _boxes.push_back(RadixBox(minimum + 1, 1));
23.120 + while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
23.121 + extend();
23.122 + }
23.123 + }
23.124 +
23.125 + /// \brief The number of items stored in the heap.
23.126 + ///
23.127 + /// This function returns the number of items stored in the heap.
23.128 + int size() const { return _data.size(); }
23.129 +
23.130 + /// \brief Check if the heap is empty.
23.131 + ///
23.132 + /// This function returns \c true if the heap is empty.
23.133 + bool empty() const { return _data.empty(); }
23.134 +
23.135 + /// \brief Make the heap empty.
23.136 + ///
23.137 + /// This functon makes the heap empty.
23.138 + /// It does not change the cross reference map. If you want to reuse
23.139 + /// a heap that is not surely empty, you should first clear it and
23.140 + /// then you should set the cross reference map to \c PRE_HEAP
23.141 + /// for each item.
23.142 + /// \param minimum The minimum value of the heap.
23.143 + /// \param capacity The capacity of the heap.
23.144 + void clear(int minimum = 0, int capacity = 0) {
23.145 + _data.clear(); _boxes.clear();
23.146 + _boxes.push_back(RadixBox(minimum, 1));
23.147 + _boxes.push_back(RadixBox(minimum + 1, 1));
23.148 + while (lower(_boxes.size() - 1, capacity + minimum - 1)) {
23.149 + extend();
23.150 + }
23.151 + }
23.152 +
23.153 + private:
23.154 +
23.155 + bool upper(int box, Prio pr) {
23.156 + return pr < _boxes[box].min;
23.157 + }
23.158 +
23.159 + bool lower(int box, Prio pr) {
23.160 + return pr >= _boxes[box].min + _boxes[box].size;
23.161 + }
23.162 +
23.163 + // Remove item from the box list
23.164 + void remove(int index) {
23.165 + if (_data[index].prev >= 0) {
23.166 + _data[_data[index].prev].next = _data[index].next;
23.167 + } else {
23.168 + _boxes[_data[index].box].first = _data[index].next;
23.169 + }
23.170 + if (_data[index].next >= 0) {
23.171 + _data[_data[index].next].prev = _data[index].prev;
23.172 + }
23.173 + }
23.174 +
23.175 + // Insert item into the box list
23.176 + void insert(int box, int index) {
23.177 + if (_boxes[box].first == -1) {
23.178 + _boxes[box].first = index;
23.179 + _data[index].next = _data[index].prev = -1;
23.180 + } else {
23.181 + _data[index].next = _boxes[box].first;
23.182 + _data[_boxes[box].first].prev = index;
23.183 + _data[index].prev = -1;
23.184 + _boxes[box].first = index;
23.185 + }
23.186 + _data[index].box = box;
23.187 + }
23.188 +
23.189 + // Add a new box to the box list
23.190 + void extend() {
23.191 + int min = _boxes.back().min + _boxes.back().size;
23.192 + int bs = 2 * _boxes.back().size;
23.193 + _boxes.push_back(RadixBox(min, bs));
23.194 + }
23.195 +
23.196 + // Move an item up into the proper box.
23.197 + void bubbleUp(int index) {
23.198 + if (!lower(_data[index].box, _data[index].prio)) return;
23.199 + remove(index);
23.200 + int box = findUp(_data[index].box, _data[index].prio);
23.201 + insert(box, index);
23.202 + }
23.203 +
23.204 + // Find up the proper box for the item with the given priority
23.205 + int findUp(int start, int pr) {
23.206 + while (lower(start, pr)) {
23.207 + if (++start == int(_boxes.size())) {
23.208 + extend();
23.209 + }
23.210 + }
23.211 + return start;
23.212 + }
23.213 +
23.214 + // Move an item down into the proper box
23.215 + void bubbleDown(int index) {
23.216 + if (!upper(_data[index].box, _data[index].prio)) return;
23.217 + remove(index);
23.218 + int box = findDown(_data[index].box, _data[index].prio);
23.219 + insert(box, index);
23.220 + }
23.221 +
23.222 + // Find down the proper box for the item with the given priority
23.223 + int findDown(int start, int pr) {
23.224 + while (upper(start, pr)) {
23.225 + if (--start < 0) throw PriorityUnderflowError();
23.226 + }
23.227 + return start;
23.228 + }
23.229 +
23.230 + // Find the first non-empty box
23.231 + int findFirst() {
23.232 + int first = 0;
23.233 + while (_boxes[first].first == -1) ++first;
23.234 + return first;
23.235 + }
23.236 +
23.237 + // Gives back the minimum priority of the given box
23.238 + int minValue(int box) {
23.239 + int min = _data[_boxes[box].first].prio;
23.240 + for (int k = _boxes[box].first; k != -1; k = _data[k].next) {
23.241 + if (_data[k].prio < min) min = _data[k].prio;
23.242 + }
23.243 + return min;
23.244 + }
23.245 +
23.246 + // Rearrange the items of the heap and make the first box non-empty
23.247 + void moveDown() {
23.248 + int box = findFirst();
23.249 + if (box == 0) return;
23.250 + int min = minValue(box);
23.251 + for (int i = 0; i <= box; ++i) {
23.252 + _boxes[i].min = min;
23.253 + min += _boxes[i].size;
23.254 + }
23.255 + int curr = _boxes[box].first, next;
23.256 + while (curr != -1) {
23.257 + next = _data[curr].next;
23.258 + bubbleDown(curr);
23.259 + curr = next;
23.260 + }
23.261 + }
23.262 +
23.263 + void relocateLast(int index) {
23.264 + if (index != int(_data.size()) - 1) {
23.265 + _data[index] = _data.back();
23.266 + if (_data[index].prev != -1) {
23.267 + _data[_data[index].prev].next = index;
23.268 + } else {
23.269 + _boxes[_data[index].box].first = index;
23.270 + }
23.271 + if (_data[index].next != -1) {
23.272 + _data[_data[index].next].prev = index;
23.273 + }
23.274 + _iim[_data[index].item] = index;
23.275 + }
23.276 + _data.pop_back();
23.277 + }
23.278 +
23.279 + public:
23.280 +
23.281 + /// \brief Insert an item into the heap with the given priority.
23.282 + ///
23.283 + /// This function inserts the given item into the heap with the
23.284 + /// given priority.
23.285 + /// \param i The item to insert.
23.286 + /// \param p The priority of the item.
23.287 + /// \pre \e i must not be stored in the heap.
23.288 + /// \warning This method may throw an \c UnderFlowPriorityException.
23.289 + void push(const Item &i, const Prio &p) {
23.290 + int n = _data.size();
23.291 + _iim.set(i, n);
23.292 + _data.push_back(RadixItem(i, p));
23.293 + while (lower(_boxes.size() - 1, p)) {
23.294 + extend();
23.295 + }
23.296 + int box = findDown(_boxes.size() - 1, p);
23.297 + insert(box, n);
23.298 + }
23.299 +
23.300 + /// \brief Return the item having minimum priority.
23.301 + ///
23.302 + /// This function returns the item having minimum priority.
23.303 + /// \pre The heap must be non-empty.
23.304 + Item top() const {
23.305 + const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
23.306 + return _data[_boxes[0].first].item;
23.307 + }
23.308 +
23.309 + /// \brief The minimum priority.
23.310 + ///
23.311 + /// This function returns the minimum priority.
23.312 + /// \pre The heap must be non-empty.
23.313 + Prio prio() const {
23.314 + const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
23.315 + return _data[_boxes[0].first].prio;
23.316 + }
23.317 +
23.318 + /// \brief Remove the item having minimum priority.
23.319 + ///
23.320 + /// This function removes the item having minimum priority.
23.321 + /// \pre The heap must be non-empty.
23.322 + void pop() {
23.323 + moveDown();
23.324 + int index = _boxes[0].first;
23.325 + _iim[_data[index].item] = POST_HEAP;
23.326 + remove(index);
23.327 + relocateLast(index);
23.328 + }
23.329 +
23.330 + /// \brief Remove the given item from the heap.
23.331 + ///
23.332 + /// This function removes the given item from the heap if it is
23.333 + /// already stored.
23.334 + /// \param i The item to delete.
23.335 + /// \pre \e i must be in the heap.
23.336 + void erase(const Item &i) {
23.337 + int index = _iim[i];
23.338 + _iim[i] = POST_HEAP;
23.339 + remove(index);
23.340 + relocateLast(index);
23.341 + }
23.342 +
23.343 + /// \brief The priority of the given item.
23.344 + ///
23.345 + /// This function returns the priority of the given item.
23.346 + /// \param i The item.
23.347 + /// \pre \e i must be in the heap.
23.348 + Prio operator[](const Item &i) const {
23.349 + int idx = _iim[i];
23.350 + return _data[idx].prio;
23.351 + }
23.352 +
23.353 + /// \brief Set the priority of an item or insert it, if it is
23.354 + /// not stored in the heap.
23.355 + ///
23.356 + /// This method sets the priority of the given item if it is
23.357 + /// already stored in the heap. Otherwise it inserts the given
23.358 + /// item into the heap with the given priority.
23.359 + /// \param i The item.
23.360 + /// \param p The priority.
23.361 + /// \pre \e i must be in the heap.
23.362 + /// \warning This method may throw an \c UnderFlowPriorityException.
23.363 + void set(const Item &i, const Prio &p) {
23.364 + int idx = _iim[i];
23.365 + if( idx < 0 ) {
23.366 + push(i, p);
23.367 + }
23.368 + else if( p >= _data[idx].prio ) {
23.369 + _data[idx].prio = p;
23.370 + bubbleUp(idx);
23.371 + } else {
23.372 + _data[idx].prio = p;
23.373 + bubbleDown(idx);
23.374 + }
23.375 + }
23.376 +
23.377 + /// \brief Decrease the priority of an item to the given value.
23.378 + ///
23.379 + /// This function decreases the priority of an item to the given value.
23.380 + /// \param i The item.
23.381 + /// \param p The priority.
23.382 + /// \pre \e i must be stored in the heap with priority at least \e p.
23.383 + /// \warning This method may throw an \c UnderFlowPriorityException.
23.384 + void decrease(const Item &i, const Prio &p) {
23.385 + int idx = _iim[i];
23.386 + _data[idx].prio = p;
23.387 + bubbleDown(idx);
23.388 + }
23.389 +
23.390 + /// \brief Increase the priority of an item to the given value.
23.391 + ///
23.392 + /// This function increases the priority of an item to the given value.
23.393 + /// \param i The item.
23.394 + /// \param p The priority.
23.395 + /// \pre \e i must be stored in the heap with priority at most \e p.
23.396 + void increase(const Item &i, const Prio &p) {
23.397 + int idx = _iim[i];
23.398 + _data[idx].prio = p;
23.399 + bubbleUp(idx);
23.400 + }
23.401 +
23.402 + /// \brief Return the state of an item.
23.403 + ///
23.404 + /// This method returns \c PRE_HEAP if the given item has never
23.405 + /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
23.406 + /// and \c POST_HEAP otherwise.
23.407 + /// In the latter case it is possible that the item will get back
23.408 + /// to the heap again.
23.409 + /// \param i The item.
23.410 + State state(const Item &i) const {
23.411 + int s = _iim[i];
23.412 + if( s >= 0 ) s = 0;
23.413 + return State(s);
23.414 + }
23.415 +
23.416 + /// \brief Set the state of an item in the heap.
23.417 + ///
23.418 + /// This function sets the state of the given item in the heap.
23.419 + /// It can be used to manually clear the heap when it is important
23.420 + /// to achive better time complexity.
23.421 + /// \param i The item.
23.422 + /// \param st The state. It should not be \c IN_HEAP.
23.423 + void state(const Item& i, State st) {
23.424 + switch (st) {
23.425 + case POST_HEAP:
23.426 + case PRE_HEAP:
23.427 + if (state(i) == IN_HEAP) {
23.428 + erase(i);
23.429 + }
23.430 + _iim[i] = st;
23.431 + break;
23.432 + case IN_HEAP:
23.433 + break;
23.434 + }
23.435 + }
23.436 +
23.437 + }; // class RadixHeap
23.438 +
23.439 +} // namespace lemon
23.440 +
23.441 +#endif // LEMON_RADIX_HEAP_H
24.1 --- a/test/CMakeLists.txt Sun Aug 02 12:40:20 2009 +0200
24.2 +++ b/test/CMakeLists.txt Fri Sep 25 09:13:03 2009 +0200
24.3 @@ -9,6 +9,7 @@
24.4
24.5 SET(TESTS
24.6 adaptors_test
24.7 + bellman_ford_test
24.8 bfs_test
24.9 circulation_test
24.10 connectivity_test
25.1 --- a/test/Makefile.am Sun Aug 02 12:40:20 2009 +0200
25.2 +++ b/test/Makefile.am Fri Sep 25 09:13:03 2009 +0200
25.3 @@ -7,6 +7,7 @@
25.4
25.5 check_PROGRAMS += \
25.6 test/adaptors_test \
25.7 + test/bellman_ford_test \
25.8 test/bfs_test \
25.9 test/circulation_test \
25.10 test/connectivity_test \
25.11 @@ -52,6 +53,7 @@
25.12 XFAIL_TESTS += test/test_tools_fail$(EXEEXT)
25.13
25.14 test_adaptors_test_SOURCES = test/adaptors_test.cc
25.15 +test_bellman_ford_test_SOURCES = test/bellman_ford_test.cc
25.16 test_bfs_test_SOURCES = test/bfs_test.cc
25.17 test_circulation_test_SOURCES = test/circulation_test.cc
25.18 test_counter_test_SOURCES = test/counter_test.cc
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/test/bellman_ford_test.cc Fri Sep 25 09:13:03 2009 +0200
26.3 @@ -0,0 +1,283 @@
26.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
26.5 + *
26.6 + * This file is a part of LEMON, a generic C++ optimization library.
26.7 + *
26.8 + * Copyright (C) 2003-2009
26.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
26.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
26.11 + *
26.12 + * Permission to use, modify and distribute this software is granted
26.13 + * provided that this copyright notice appears in all copies. For
26.14 + * precise terms see the accompanying LICENSE file.
26.15 + *
26.16 + * This software is provided "AS IS" with no warranty of any kind,
26.17 + * express or implied, and with no claim as to its suitability for any
26.18 + * purpose.
26.19 + *
26.20 + */
26.21 +
26.22 +#include <lemon/concepts/digraph.h>
26.23 +#include <lemon/smart_graph.h>
26.24 +#include <lemon/list_graph.h>
26.25 +#include <lemon/lgf_reader.h>
26.26 +#include <lemon/bellman_ford.h>
26.27 +#include <lemon/path.h>
26.28 +
26.29 +#include "graph_test.h"
26.30 +#include "test_tools.h"
26.31 +
26.32 +using namespace lemon;
26.33 +
26.34 +char test_lgf[] =
26.35 + "@nodes\n"
26.36 + "label\n"
26.37 + "0\n"
26.38 + "1\n"
26.39 + "2\n"
26.40 + "3\n"
26.41 + "4\n"
26.42 + "@arcs\n"
26.43 + " length\n"
26.44 + "0 1 3\n"
26.45 + "1 2 -3\n"
26.46 + "1 2 -5\n"
26.47 + "1 3 -2\n"
26.48 + "0 2 -1\n"
26.49 + "1 2 -4\n"
26.50 + "0 3 2\n"
26.51 + "4 2 -5\n"
26.52 + "2 3 1\n"
26.53 + "@attributes\n"
26.54 + "source 0\n"
26.55 + "target 3\n";
26.56 +
26.57 +
26.58 +void checkBellmanFordCompile()
26.59 +{
26.60 + typedef int Value;
26.61 + typedef concepts::Digraph Digraph;
26.62 + typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
26.63 + typedef BellmanFord<Digraph, LengthMap> BF;
26.64 + typedef Digraph::Node Node;
26.65 + typedef Digraph::Arc Arc;
26.66 +
26.67 + Digraph gr;
26.68 + Node s, t, n;
26.69 + Arc e;
26.70 + Value l;
26.71 + int k;
26.72 + bool b;
26.73 + BF::DistMap d(gr);
26.74 + BF::PredMap p(gr);
26.75 + LengthMap length;
26.76 + concepts::Path<Digraph> pp;
26.77 +
26.78 + {
26.79 + BF bf_test(gr,length);
26.80 + const BF& const_bf_test = bf_test;
26.81 +
26.82 + bf_test.run(s);
26.83 + bf_test.run(s,k);
26.84 +
26.85 + bf_test.init();
26.86 + bf_test.addSource(s);
26.87 + bf_test.addSource(s, 1);
26.88 + b = bf_test.processNextRound();
26.89 + b = bf_test.processNextWeakRound();
26.90 +
26.91 + bf_test.start();
26.92 + bf_test.checkedStart();
26.93 + bf_test.limitedStart(k);
26.94 +
26.95 + l = const_bf_test.dist(t);
26.96 + e = const_bf_test.predArc(t);
26.97 + s = const_bf_test.predNode(t);
26.98 + b = const_bf_test.reached(t);
26.99 + d = const_bf_test.distMap();
26.100 + p = const_bf_test.predMap();
26.101 + pp = const_bf_test.path(t);
26.102 +
26.103 + for (BF::ActiveIt it(const_bf_test); it != INVALID; ++it) {}
26.104 + }
26.105 + {
26.106 + BF::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
26.107 + ::SetDistMap<concepts::ReadWriteMap<Node,Value> >
26.108 + ::SetOperationTraits<BellmanFordDefaultOperationTraits<Value> >
26.109 + ::Create bf_test(gr,length);
26.110 +
26.111 + LengthMap length_map;
26.112 + concepts::ReadWriteMap<Node,Arc> pred_map;
26.113 + concepts::ReadWriteMap<Node,Value> dist_map;
26.114 +
26.115 + bf_test
26.116 + .lengthMap(length_map)
26.117 + .predMap(pred_map)
26.118 + .distMap(dist_map);
26.119 +
26.120 + bf_test.run(s);
26.121 + bf_test.run(s,k);
26.122 +
26.123 + bf_test.init();
26.124 + bf_test.addSource(s);
26.125 + bf_test.addSource(s, 1);
26.126 + b = bf_test.processNextRound();
26.127 + b = bf_test.processNextWeakRound();
26.128 +
26.129 + bf_test.start();
26.130 + bf_test.checkedStart();
26.131 + bf_test.limitedStart(k);
26.132 +
26.133 + l = bf_test.dist(t);
26.134 + e = bf_test.predArc(t);
26.135 + s = bf_test.predNode(t);
26.136 + b = bf_test.reached(t);
26.137 + pp = bf_test.path(t);
26.138 + }
26.139 +}
26.140 +
26.141 +void checkBellmanFordFunctionCompile()
26.142 +{
26.143 + typedef int Value;
26.144 + typedef concepts::Digraph Digraph;
26.145 + typedef Digraph::Arc Arc;
26.146 + typedef Digraph::Node Node;
26.147 + typedef concepts::ReadMap<Digraph::Arc,Value> LengthMap;
26.148 +
26.149 + Digraph g;
26.150 + bool b;
26.151 + bellmanFord(g,LengthMap()).run(Node());
26.152 + b = bellmanFord(g,LengthMap()).run(Node(),Node());
26.153 + bellmanFord(g,LengthMap())
26.154 + .predMap(concepts::ReadWriteMap<Node,Arc>())
26.155 + .distMap(concepts::ReadWriteMap<Node,Value>())
26.156 + .run(Node());
26.157 + b=bellmanFord(g,LengthMap())
26.158 + .predMap(concepts::ReadWriteMap<Node,Arc>())
26.159 + .distMap(concepts::ReadWriteMap<Node,Value>())
26.160 + .path(concepts::Path<Digraph>())
26.161 + .dist(Value())
26.162 + .run(Node(),Node());
26.163 +}
26.164 +
26.165 +
26.166 +template <typename Digraph, typename Value>
26.167 +void checkBellmanFord() {
26.168 + TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
26.169 + typedef typename Digraph::template ArcMap<Value> LengthMap;
26.170 +
26.171 + Digraph gr;
26.172 + Node s, t;
26.173 + LengthMap length(gr);
26.174 +
26.175 + std::istringstream input(test_lgf);
26.176 + digraphReader(gr, input).
26.177 + arcMap("length", length).
26.178 + node("source", s).
26.179 + node("target", t).
26.180 + run();
26.181 +
26.182 + BellmanFord<Digraph, LengthMap>
26.183 + bf(gr, length);
26.184 + bf.run(s);
26.185 + Path<Digraph> p = bf.path(t);
26.186 +
26.187 + check(bf.reached(t) && bf.dist(t) == -1, "Bellman-Ford found a wrong path.");
26.188 + check(p.length() == 3, "path() found a wrong path.");
26.189 + check(checkPath(gr, p), "path() found a wrong path.");
26.190 + check(pathSource(gr, p) == s, "path() found a wrong path.");
26.191 + check(pathTarget(gr, p) == t, "path() found a wrong path.");
26.192 +
26.193 + ListPath<Digraph> path;
26.194 + Value dist;
26.195 + bool reached = bellmanFord(gr,length).path(path).dist(dist).run(s,t);
26.196 +
26.197 + check(reached && dist == -1, "Bellman-Ford found a wrong path.");
26.198 + check(path.length() == 3, "path() found a wrong path.");
26.199 + check(checkPath(gr, path), "path() found a wrong path.");
26.200 + check(pathSource(gr, path) == s, "path() found a wrong path.");
26.201 + check(pathTarget(gr, path) == t, "path() found a wrong path.");
26.202 +
26.203 + for(ArcIt e(gr); e!=INVALID; ++e) {
26.204 + Node u=gr.source(e);
26.205 + Node v=gr.target(e);
26.206 + check(!bf.reached(u) || (bf.dist(v) - bf.dist(u) <= length[e]),
26.207 + "Wrong output. dist(target)-dist(source)-arc_length=" <<
26.208 + bf.dist(v) - bf.dist(u) - length[e]);
26.209 + }
26.210 +
26.211 + for(NodeIt v(gr); v!=INVALID; ++v) {
26.212 + if (bf.reached(v)) {
26.213 + check(v==s || bf.predArc(v)!=INVALID, "Wrong tree.");
26.214 + if (bf.predArc(v)!=INVALID ) {
26.215 + Arc e=bf.predArc(v);
26.216 + Node u=gr.source(e);
26.217 + check(u==bf.predNode(v),"Wrong tree.");
26.218 + check(bf.dist(v) - bf.dist(u) == length[e],
26.219 + "Wrong distance! Difference: " <<
26.220 + bf.dist(v) - bf.dist(u) - length[e]);
26.221 + }
26.222 + }
26.223 + }
26.224 +}
26.225 +
26.226 +void checkBellmanFordNegativeCycle() {
26.227 + DIGRAPH_TYPEDEFS(SmartDigraph);
26.228 +
26.229 + SmartDigraph gr;
26.230 + IntArcMap length(gr);
26.231 +
26.232 + Node n1 = gr.addNode();
26.233 + Node n2 = gr.addNode();
26.234 + Node n3 = gr.addNode();
26.235 + Node n4 = gr.addNode();
26.236 +
26.237 + Arc a1 = gr.addArc(n1, n2);
26.238 + Arc a2 = gr.addArc(n2, n2);
26.239 +
26.240 + length[a1] = 2;
26.241 + length[a2] = -1;
26.242 +
26.243 + {
26.244 + BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
26.245 + bf.run(n1);
26.246 + StaticPath<SmartDigraph> p = bf.negativeCycle();
26.247 + check(p.length() == 1 && p.front() == p.back() && p.front() == a2,
26.248 + "Wrong negative cycle.");
26.249 + }
26.250 +
26.251 + length[a2] = 0;
26.252 +
26.253 + {
26.254 + BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
26.255 + bf.run(n1);
26.256 + check(bf.negativeCycle().empty(),
26.257 + "Negative cycle should not be found.");
26.258 + }
26.259 +
26.260 + length[gr.addArc(n1, n3)] = 5;
26.261 + length[gr.addArc(n4, n3)] = 1;
26.262 + length[gr.addArc(n2, n4)] = 2;
26.263 + length[gr.addArc(n3, n2)] = -4;
26.264 +
26.265 + {
26.266 + BellmanFord<SmartDigraph, IntArcMap> bf(gr, length);
26.267 + bf.init();
26.268 + bf.addSource(n1);
26.269 + for (int i = 0; i < 4; ++i) {
26.270 + check(bf.negativeCycle().empty(),
26.271 + "Negative cycle should not be found.");
26.272 + bf.processNextRound();
26.273 + }
26.274 + StaticPath<SmartDigraph> p = bf.negativeCycle();
26.275 + check(p.length() == 3, "Wrong negative cycle.");
26.276 + check(length[p.nth(0)] + length[p.nth(1)] + length[p.nth(2)] == -1,
26.277 + "Wrong negative cycle.");
26.278 + }
26.279 +}
26.280 +
26.281 +int main() {
26.282 + checkBellmanFord<ListDigraph, int>();
26.283 + checkBellmanFord<SmartDigraph, double>();
26.284 + checkBellmanFordNegativeCycle();
26.285 + return 0;
26.286 +}
27.1 --- a/test/circulation_test.cc Sun Aug 02 12:40:20 2009 +0200
27.2 +++ b/test/circulation_test.cc Fri Sep 25 09:13:03 2009 +0200
27.3 @@ -87,6 +87,11 @@
27.4 .upperMap(ucap)
27.5 .supplyMap(supply)
27.6 .flowMap(flow);
27.7 +
27.8 + const CirculationType::Elevator& elev = const_circ_test.elevator();
27.9 + circ_test.elevator(const_cast<CirculationType::Elevator&>(elev));
27.10 + CirculationType::Tolerance tol = const_circ_test.tolerance();
27.11 + circ_test.tolerance(tol);
27.12
27.13 circ_test.init();
27.14 circ_test.greedyInit();
28.1 --- a/test/heap_test.cc Sun Aug 02 12:40:20 2009 +0200
28.2 +++ b/test/heap_test.cc Fri Sep 25 09:13:03 2009 +0200
28.3 @@ -25,12 +25,18 @@
28.4 #include <lemon/concepts/heap.h>
28.5
28.6 #include <lemon/smart_graph.h>
28.7 -
28.8 #include <lemon/lgf_reader.h>
28.9 #include <lemon/dijkstra.h>
28.10 #include <lemon/maps.h>
28.11
28.12 #include <lemon/bin_heap.h>
28.13 +#include <lemon/fourary_heap.h>
28.14 +#include <lemon/kary_heap.h>
28.15 +#include <lemon/fib_heap.h>
28.16 +#include <lemon/pairing_heap.h>
28.17 +#include <lemon/radix_heap.h>
28.18 +#include <lemon/binom_heap.h>
28.19 +#include <lemon/bucket_heap.h>
28.20
28.21 #include "test_tools.h"
28.22
28.23 @@ -86,18 +92,16 @@
28.24 template <typename Heap>
28.25 void heapSortTest() {
28.26 RangeMap<int> map(test_len, -1);
28.27 -
28.28 Heap heap(map);
28.29
28.30 std::vector<int> v(test_len);
28.31 -
28.32 for (int i = 0; i < test_len; ++i) {
28.33 v[i] = test_seq[i];
28.34 heap.push(i, v[i]);
28.35 }
28.36 std::sort(v.begin(), v.end());
28.37 for (int i = 0; i < test_len; ++i) {
28.38 - check(v[i] == heap.prio() ,"Wrong order in heap sort.");
28.39 + check(v[i] == heap.prio(), "Wrong order in heap sort.");
28.40 heap.pop();
28.41 }
28.42 }
28.43 @@ -109,7 +113,6 @@
28.44 Heap heap(map);
28.45
28.46 std::vector<int> v(test_len);
28.47 -
28.48 for (int i = 0; i < test_len; ++i) {
28.49 v[i] = test_seq[i];
28.50 heap.push(i, v[i]);
28.51 @@ -120,13 +123,11 @@
28.52 }
28.53 std::sort(v.begin(), v.end());
28.54 for (int i = 0; i < test_len; ++i) {
28.55 - check(v[i] == heap.prio() ,"Wrong order in heap increase test.");
28.56 + check(v[i] == heap.prio(), "Wrong order in heap increase test.");
28.57 heap.pop();
28.58 }
28.59 }
28.60
28.61 -
28.62 -
28.63 template <typename Heap>
28.64 void dijkstraHeapTest(const Digraph& digraph, const IntArcMap& length,
28.65 Node source) {
28.66 @@ -141,7 +142,7 @@
28.67 Node t = digraph.target(a);
28.68 if (dijkstra.reached(s)) {
28.69 check( dijkstra.dist(t) - dijkstra.dist(s) <= length[a],
28.70 - "Error in a shortest path tree!");
28.71 + "Error in shortest path tree.");
28.72 }
28.73 }
28.74
28.75 @@ -150,7 +151,7 @@
28.76 Arc a = dijkstra.predArc(n);
28.77 Node s = digraph.source(a);
28.78 check( dijkstra.dist(n) - dijkstra.dist(s) == length[a],
28.79 - "Error in a shortest path tree!");
28.80 + "Error in shortest path tree.");
28.81 }
28.82 }
28.83
28.84 @@ -172,6 +173,7 @@
28.85 node("source", source).
28.86 run();
28.87
28.88 + // BinHeap
28.89 {
28.90 typedef BinHeap<Prio, ItemIntMap> IntHeap;
28.91 checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
28.92 @@ -183,5 +185,92 @@
28.93 dijkstraHeapTest<NodeHeap>(digraph, length, source);
28.94 }
28.95
28.96 + // FouraryHeap
28.97 + {
28.98 + typedef FouraryHeap<Prio, ItemIntMap> IntHeap;
28.99 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
28.100 + heapSortTest<IntHeap>();
28.101 + heapIncreaseTest<IntHeap>();
28.102 +
28.103 + typedef FouraryHeap<Prio, IntNodeMap > NodeHeap;
28.104 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
28.105 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
28.106 + }
28.107 +
28.108 + // KaryHeap
28.109 + {
28.110 + typedef KaryHeap<Prio, ItemIntMap> IntHeap;
28.111 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
28.112 + heapSortTest<IntHeap>();
28.113 + heapIncreaseTest<IntHeap>();
28.114 +
28.115 + typedef KaryHeap<Prio, IntNodeMap > NodeHeap;
28.116 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
28.117 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
28.118 + }
28.119 +
28.120 + // FibHeap
28.121 + {
28.122 + typedef FibHeap<Prio, ItemIntMap> IntHeap;
28.123 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
28.124 + heapSortTest<IntHeap>();
28.125 + heapIncreaseTest<IntHeap>();
28.126 +
28.127 + typedef FibHeap<Prio, IntNodeMap > NodeHeap;
28.128 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
28.129 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
28.130 + }
28.131 +
28.132 + // PairingHeap
28.133 + {
28.134 + typedef PairingHeap<Prio, ItemIntMap> IntHeap;
28.135 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
28.136 + heapSortTest<IntHeap>();
28.137 + heapIncreaseTest<IntHeap>();
28.138 +
28.139 + typedef PairingHeap<Prio, IntNodeMap > NodeHeap;
28.140 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
28.141 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
28.142 + }
28.143 +
28.144 + // RadixHeap
28.145 + {
28.146 + typedef RadixHeap<ItemIntMap> IntHeap;
28.147 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
28.148 + heapSortTest<IntHeap>();
28.149 + heapIncreaseTest<IntHeap>();
28.150 +
28.151 + typedef RadixHeap<IntNodeMap > NodeHeap;
28.152 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
28.153 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
28.154 + }
28.155 +
28.156 + // BinomHeap
28.157 + {
28.158 + typedef BinomHeap<Prio, ItemIntMap> IntHeap;
28.159 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
28.160 + heapSortTest<IntHeap>();
28.161 + heapIncreaseTest<IntHeap>();
28.162 +
28.163 + typedef BinomHeap<Prio, IntNodeMap > NodeHeap;
28.164 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
28.165 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
28.166 + }
28.167 +
28.168 + // BucketHeap, SimpleBucketHeap
28.169 + {
28.170 + typedef BucketHeap<ItemIntMap> IntHeap;
28.171 + checkConcept<Heap<Prio, ItemIntMap>, IntHeap>();
28.172 + heapSortTest<IntHeap>();
28.173 + heapIncreaseTest<IntHeap>();
28.174 +
28.175 + typedef BucketHeap<IntNodeMap > NodeHeap;
28.176 + checkConcept<Heap<Prio, IntNodeMap >, NodeHeap>();
28.177 + dijkstraHeapTest<NodeHeap>(digraph, length, source);
28.178 +
28.179 + typedef SimpleBucketHeap<ItemIntMap> SimpleIntHeap;
28.180 + heapSortTest<SimpleIntHeap>();
28.181 + }
28.182 +
28.183 return 0;
28.184 }
29.1 --- a/test/maps_test.cc Sun Aug 02 12:40:20 2009 +0200
29.2 +++ b/test/maps_test.cc Fri Sep 25 09:13:03 2009 +0200
29.3 @@ -22,6 +22,7 @@
29.4 #include <lemon/concept_check.h>
29.5 #include <lemon/concepts/maps.h>
29.6 #include <lemon/maps.h>
29.7 +#include <lemon/smart_graph.h>
29.8
29.9 #include "test_tools.h"
29.10
29.11 @@ -349,5 +350,226 @@
29.12 check(v1[i++] == *it, "Something is wrong with LoggerBoolMap");
29.13 }
29.14
29.15 + // CrossRefMap
29.16 + {
29.17 + typedef SmartDigraph Graph;
29.18 + DIGRAPH_TYPEDEFS(Graph);
29.19 +
29.20 + checkConcept<ReadWriteMap<Node, int>,
29.21 + CrossRefMap<Graph, Node, int> >();
29.22 +
29.23 + Graph gr;
29.24 + typedef CrossRefMap<Graph, Node, char> CRMap;
29.25 + typedef CRMap::ValueIterator ValueIt;
29.26 + CRMap map(gr);
29.27 +
29.28 + Node n0 = gr.addNode();
29.29 + Node n1 = gr.addNode();
29.30 + Node n2 = gr.addNode();
29.31 +
29.32 + map.set(n0, 'A');
29.33 + map.set(n1, 'B');
29.34 + map.set(n2, 'C');
29.35 + map.set(n2, 'A');
29.36 + map.set(n0, 'C');
29.37 +
29.38 + check(map[n0] == 'C' && map[n1] == 'B' && map[n2] == 'A',
29.39 + "Wrong CrossRefMap");
29.40 + check(map('A') == n2 && map.inverse()['A'] == n2, "Wrong CrossRefMap");
29.41 + check(map('B') == n1 && map.inverse()['B'] == n1, "Wrong CrossRefMap");
29.42 + check(map('C') == n0 && map.inverse()['C'] == n0, "Wrong CrossRefMap");
29.43 +
29.44 + ValueIt it = map.beginValue();
29.45 + check(*it++ == 'A' && *it++ == 'B' && *it++ == 'C' &&
29.46 + it == map.endValue(), "Wrong value iterator");
29.47 + }
29.48 +
29.49 + // Iterable bool map
29.50 + {
29.51 + typedef SmartGraph Graph;
29.52 + typedef SmartGraph::Node Item;
29.53 +
29.54 + typedef IterableBoolMap<SmartGraph, SmartGraph::Node> Ibm;
29.55 + checkConcept<ReferenceMap<Item, bool, bool&, const bool&>, Ibm>();
29.56 +
29.57 + const int num = 10;
29.58 + Graph g;
29.59 + std::vector<Item> items;
29.60 + for (int i = 0; i < num; ++i) {
29.61 + items.push_back(g.addNode());
29.62 + }
29.63 +
29.64 + Ibm map1(g, true);
29.65 + int n = 0;
29.66 + for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
29.67 + check(map1[static_cast<Item>(it)], "Wrong TrueIt");
29.68 + ++n;
29.69 + }
29.70 + check(n == num, "Wrong number");
29.71 +
29.72 + n = 0;
29.73 + for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
29.74 + check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
29.75 + ++n;
29.76 + }
29.77 + check(n == num, "Wrong number");
29.78 + check(Ibm::FalseIt(map1) == INVALID, "Wrong FalseIt");
29.79 + check(Ibm::ItemIt(map1, false) == INVALID, "Wrong ItemIt for false");
29.80 +
29.81 + map1[items[5]] = true;
29.82 +
29.83 + n = 0;
29.84 + for (Ibm::ItemIt it(map1, true); it != INVALID; ++it) {
29.85 + check(map1[static_cast<Item>(it)], "Wrong ItemIt for true");
29.86 + ++n;
29.87 + }
29.88 + check(n == num, "Wrong number");
29.89 +
29.90 + map1[items[num / 2]] = false;
29.91 + check(map1[items[num / 2]] == false, "Wrong map value");
29.92 +
29.93 + n = 0;
29.94 + for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
29.95 + check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
29.96 + ++n;
29.97 + }
29.98 + check(n == num - 1, "Wrong number");
29.99 +
29.100 + n = 0;
29.101 + for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
29.102 + check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
29.103 + ++n;
29.104 + }
29.105 + check(n == 1, "Wrong number");
29.106 +
29.107 + map1[items[0]] = false;
29.108 + check(map1[items[0]] == false, "Wrong map value");
29.109 +
29.110 + map1[items[num - 1]] = false;
29.111 + check(map1[items[num - 1]] == false, "Wrong map value");
29.112 +
29.113 + n = 0;
29.114 + for (Ibm::TrueIt it(map1); it != INVALID; ++it) {
29.115 + check(map1[static_cast<Item>(it)], "Wrong TrueIt for true");
29.116 + ++n;
29.117 + }
29.118 + check(n == num - 3, "Wrong number");
29.119 + check(map1.trueNum() == num - 3, "Wrong number");
29.120 +
29.121 + n = 0;
29.122 + for (Ibm::FalseIt it(map1); it != INVALID; ++it) {
29.123 + check(!map1[static_cast<Item>(it)], "Wrong FalseIt for true");
29.124 + ++n;
29.125 + }
29.126 + check(n == 3, "Wrong number");
29.127 + check(map1.falseNum() == 3, "Wrong number");
29.128 + }
29.129 +
29.130 + // Iterable int map
29.131 + {
29.132 + typedef SmartGraph Graph;
29.133 + typedef SmartGraph::Node Item;
29.134 + typedef IterableIntMap<SmartGraph, SmartGraph::Node> Iim;
29.135 +
29.136 + checkConcept<ReferenceMap<Item, int, int&, const int&>, Iim>();
29.137 +
29.138 + const int num = 10;
29.139 + Graph g;
29.140 + std::vector<Item> items;
29.141 + for (int i = 0; i < num; ++i) {
29.142 + items.push_back(g.addNode());
29.143 + }
29.144 +
29.145 + Iim map1(g);
29.146 + check(map1.size() == 0, "Wrong size");
29.147 +
29.148 + for (int i = 0; i < num; ++i) {
29.149 + map1[items[i]] = i;
29.150 + }
29.151 + check(map1.size() == num, "Wrong size");
29.152 +
29.153 + for (int i = 0; i < num; ++i) {
29.154 + Iim::ItemIt it(map1, i);
29.155 + check(static_cast<Item>(it) == items[i], "Wrong value");
29.156 + ++it;
29.157 + check(static_cast<Item>(it) == INVALID, "Wrong value");
29.158 + }
29.159 +
29.160 + for (int i = 0; i < num; ++i) {
29.161 + map1[items[i]] = i % 2;
29.162 + }
29.163 + check(map1.size() == 2, "Wrong size");
29.164 +
29.165 + int n = 0;
29.166 + for (Iim::ItemIt it(map1, 0); it != INVALID; ++it) {
29.167 + check(map1[static_cast<Item>(it)] == 0, "Wrong value");
29.168 + ++n;
29.169 + }
29.170 + check(n == (num + 1) / 2, "Wrong number");
29.171 +
29.172 + for (Iim::ItemIt it(map1, 1); it != INVALID; ++it) {
29.173 + check(map1[static_cast<Item>(it)] == 1, "Wrong value");
29.174 + ++n;
29.175 + }
29.176 + check(n == num, "Wrong number");
29.177 +
29.178 + }
29.179 +
29.180 + // Iterable value map
29.181 + {
29.182 + typedef SmartGraph Graph;
29.183 + typedef SmartGraph::Node Item;
29.184 + typedef IterableValueMap<SmartGraph, SmartGraph::Node, double> Ivm;
29.185 +
29.186 + checkConcept<ReadWriteMap<Item, double>, Ivm>();
29.187 +
29.188 + const int num = 10;
29.189 + Graph g;
29.190 + std::vector<Item> items;
29.191 + for (int i = 0; i < num; ++i) {
29.192 + items.push_back(g.addNode());
29.193 + }
29.194 +
29.195 + Ivm map1(g, 0.0);
29.196 + check(distance(map1.beginValue(), map1.endValue()) == 1, "Wrong size");
29.197 + check(*map1.beginValue() == 0.0, "Wrong value");
29.198 +
29.199 + for (int i = 0; i < num; ++i) {
29.200 + map1.set(items[i], static_cast<double>(i));
29.201 + }
29.202 + check(distance(map1.beginValue(), map1.endValue()) == num, "Wrong size");
29.203 +
29.204 + for (int i = 0; i < num; ++i) {
29.205 + Ivm::ItemIt it(map1, static_cast<double>(i));
29.206 + check(static_cast<Item>(it) == items[i], "Wrong value");
29.207 + ++it;
29.208 + check(static_cast<Item>(it) == INVALID, "Wrong value");
29.209 + }
29.210 +
29.211 + for (Ivm::ValueIterator vit = map1.beginValue();
29.212 + vit != map1.endValue(); ++vit) {
29.213 + check(map1[static_cast<Item>(Ivm::ItemIt(map1, *vit))] == *vit,
29.214 + "Wrong ValueIterator");
29.215 + }
29.216 +
29.217 + for (int i = 0; i < num; ++i) {
29.218 + map1.set(items[i], static_cast<double>(i % 2));
29.219 + }
29.220 + check(distance(map1.beginValue(), map1.endValue()) == 2, "Wrong size");
29.221 +
29.222 + int n = 0;
29.223 + for (Ivm::ItemIt it(map1, 0.0); it != INVALID; ++it) {
29.224 + check(map1[static_cast<Item>(it)] == 0.0, "Wrong value");
29.225 + ++n;
29.226 + }
29.227 + check(n == (num + 1) / 2, "Wrong number");
29.228 +
29.229 + for (Ivm::ItemIt it(map1, 1.0); it != INVALID; ++it) {
29.230 + check(map1[static_cast<Item>(it)] == 1.0, "Wrong value");
29.231 + ++n;
29.232 + }
29.233 + check(n == num, "Wrong number");
29.234 +
29.235 + }
29.236 return 0;
29.237 }
30.1 --- a/test/preflow_test.cc Sun Aug 02 12:40:20 2009 +0200
30.2 +++ b/test/preflow_test.cc Fri Sep 25 09:13:03 2009 +0200
30.3 @@ -94,6 +94,11 @@
30.4 ::Create PreflowType;
30.5 PreflowType preflow_test(g, cap, n, n);
30.6 const PreflowType& const_preflow_test = preflow_test;
30.7 +
30.8 + const PreflowType::Elevator& elev = const_preflow_test.elevator();
30.9 + preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
30.10 + PreflowType::Tolerance tol = const_preflow_test.tolerance();
30.11 + preflow_test.tolerance(tol);
30.12
30.13 preflow_test
30.14 .capacityMap(cap)
31.1 --- a/tools/lemon-0.x-to-1.x.sh Sun Aug 02 12:40:20 2009 +0200
31.2 +++ b/tools/lemon-0.x-to-1.x.sh Fri Sep 25 09:13:03 2009 +0200
31.3 @@ -35,10 +35,10 @@
31.4 -e "s/IncEdgeIt/_In_cEd_geIt_label_/g"\
31.5 -e "s/Edge\>/_Ar_c_label_/g"\
31.6 -e "s/\<edge\>/_ar_c_label_/g"\
31.7 - -e "s/_edge\>/_ar_c_label_/g"\
31.8 + -e "s/_edge\>/__ar_c_label_/g"\
31.9 -e "s/Edges\>/_Ar_c_label_s/g"\
31.10 -e "s/\<edges\>/_ar_c_label_s/g"\
31.11 - -e "s/_edges\>/_ar_c_label_s/g"\
31.12 + -e "s/_edges\>/__ar_c_label_s/g"\
31.13 -e "s/\([Ee]\)dge\([a-z]\)/_\1d_ge_label_\2/g"\
31.14 -e "s/\([a-z]\)edge/\1_ed_ge_label_/g"\
31.15 -e "s/Edge/_Ar_c_label_/g"\
31.16 @@ -68,6 +68,11 @@
31.17 -e "s/_blu_e_label_/blue/g"\
31.18 -e "s/_GR_APH_TY_PEDE_FS_label_/GRAPH_TYPEDEFS/g"\
31.19 -e "s/_DIGR_APH_TY_PEDE_FS_label_/DIGRAPH_TYPEDEFS/g"\
31.20 + -e "s/\<digraph_adaptor\.h\>/adaptors.h/g"\
31.21 + -e "s/\<digraph_utils\.h\>/core.h/g"\
31.22 + -e "s/\<digraph_reader\.h\>/lgf_reader.h/g"\
31.23 + -e "s/\<digraph_writer\.h\>/lgf_writer.h/g"\
31.24 + -e "s/\<topology\.h\>/connectivity.h/g"\
31.25 -e "s/DigraphToEps/GraphToEps/g"\
31.26 -e "s/digraphToEps/graphToEps/g"\
31.27 -e "s/\<DefPredMap\>/SetPredMap/g"\