[Lemon-commits] Peter Kovacs: Port Bellman-Ford algorithm from S...
Lemon HG
hg at lemon.cs.elte.hu
Mon Aug 31 08:38:23 CEST 2009
details: http://lemon.cs.elte.hu/hg/lemon/rev/c9b9da1a90a0
changeset: 749:c9b9da1a90a0
user: Peter Kovacs <kpeter [at] inf.elte.hu>
date: Fri Jul 24 23:19:43 2009 +0200
description:
Port Bellman-Ford algorithm from SVN -r3524 (#51)
diffstat:
lemon/Makefile.am | 1 +
lemon/bellman_ford.h | 1042 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 1043 insertions(+), 0 deletions(-)
diffs (truncated from 1058 to 300 lines):
diff --git a/lemon/Makefile.am b/lemon/Makefile.am
--- a/lemon/Makefile.am
+++ b/lemon/Makefile.am
@@ -57,6 +57,7 @@
lemon/adaptors.h \
lemon/arg_parser.h \
lemon/assert.h \
+ lemon/bellman_ford.h \
lemon/bfs.h \
lemon/bin_heap.h \
lemon/bucket_heap.h \
diff --git a/lemon/bellman_ford.h b/lemon/bellman_ford.h
new file mode 100644
--- /dev/null
+++ b/lemon/bellman_ford.h
@@ -0,0 +1,1042 @@
+/* -*- C++ -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library
+ *
+ * Copyright (C) 2003-2008
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BELMANN_FORD_H
+#define LEMON_BELMANN_FORD_H
+
+/// \ingroup shortest_path
+/// \file
+/// \brief Bellman-Ford algorithm.
+///
+
+#include <lemon/bits/path_dump.h>
+#include <lemon/core.h>
+#include <lemon/error.h>
+#include <lemon/maps.h>
+
+#include <limits>
+
+namespace lemon {
+
+ /// \brief Default OperationTraits for the BellmanFord algorithm class.
+ ///
+ /// It defines all computational operations and constants which are
+ /// used in the Bellman-Ford algorithm. The default implementation
+ /// is based on the numeric_limits class. If the numeric type does not
+ /// have infinity value then the maximum value is used as extremal
+ /// infinity value.
+ template <
+ typename Value,
+ bool has_infinity = std::numeric_limits<Value>::has_infinity>
+ struct BellmanFordDefaultOperationTraits {
+ /// \brief Gives back the zero value of the type.
+ static Value zero() {
+ return static_cast<Value>(0);
+ }
+ /// \brief Gives back the positive infinity value of the type.
+ static Value infinity() {
+ return std::numeric_limits<Value>::infinity();
+ }
+ /// \brief Gives back the sum of the given two elements.
+ static Value plus(const Value& left, const Value& right) {
+ return left + right;
+ }
+ /// \brief Gives back true only if the first value less than the second.
+ static bool less(const Value& left, const Value& right) {
+ return left < right;
+ }
+ };
+
+ template <typename Value>
+ struct BellmanFordDefaultOperationTraits<Value, false> {
+ static Value zero() {
+ return static_cast<Value>(0);
+ }
+ static Value infinity() {
+ return std::numeric_limits<Value>::max();
+ }
+ static Value plus(const Value& left, const Value& right) {
+ if (left == infinity() || right == infinity()) return infinity();
+ return left + right;
+ }
+ static bool less(const Value& left, const Value& right) {
+ return left < right;
+ }
+ };
+
+ /// \brief Default traits class of BellmanFord class.
+ ///
+ /// Default traits class of BellmanFord class.
+ /// \param _Digraph Digraph type.
+ /// \param _LegthMap Type of length map.
+ template<class _Digraph, class _LengthMap>
+ struct BellmanFordDefaultTraits {
+ /// The digraph type the algorithm runs on.
+ typedef _Digraph Digraph;
+
+ /// \brief The type of the map that stores the arc lengths.
+ ///
+ /// The type of the map that stores the arc lengths.
+ /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
+ typedef _LengthMap LengthMap;
+
+ // The type of the length of the arcs.
+ typedef typename _LengthMap::Value Value;
+
+ /// \brief Operation traits for Bellman-Ford algorithm.
+ ///
+ /// It defines the infinity type on the given Value type
+ /// and the used operation.
+ /// \see BellmanFordDefaultOperationTraits
+ typedef BellmanFordDefaultOperationTraits<Value> OperationTraits;
+
+ /// \brief The type of the map that stores the last arcs of the
+ /// shortest paths.
+ ///
+ /// The type of the map that stores the last
+ /// arcs of the shortest paths.
+ /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
+ ///
+ typedef typename Digraph::template NodeMap<typename _Digraph::Arc> PredMap;
+
+ /// \brief Instantiates a PredMap.
+ ///
+ /// This function instantiates a \ref PredMap.
+ /// \param digraph is the digraph, to which we would like to define the PredMap.
+ static PredMap *createPredMap(const _Digraph& digraph) {
+ return new PredMap(digraph);
+ }
+
+ /// \brief The type of the map that stores the dists of the nodes.
+ ///
+ /// The type of the map that stores the dists of the nodes.
+ /// It must meet the \ref concepts::WriteMap "WriteMap" concept.
+ ///
+ typedef typename Digraph::template NodeMap<typename _LengthMap::Value>
+ DistMap;
+
+ /// \brief Instantiates a DistMap.
+ ///
+ /// This function instantiates a \ref DistMap.
+ /// \param digraph is the digraph, to which we would like to define the
+ /// \ref DistMap
+ static DistMap *createDistMap(const _Digraph& digraph) {
+ return new DistMap(digraph);
+ }
+
+ };
+
+ /// \brief %BellmanFord algorithm class.
+ ///
+ /// \ingroup shortest_path
+ /// This class provides an efficient implementation of \c Bellman-Ford
+ /// algorithm. The arc lengths are passed to the algorithm using a
+ /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any
+ /// kind of length.
+ ///
+ /// The Bellman-Ford algorithm solves the shortest path from one node
+ /// problem when the arcs can have negative length but the digraph should
+ /// not contain cycles with negative sum of length. If we can assume
+ /// that all arc is non-negative in the digraph then the dijkstra algorithm
+ /// should be used rather.
+ ///
+ /// The maximal time complexity of the algorithm is \f$ O(ne) \f$.
+ ///
+ /// The type of the length is determined by the
+ /// \ref concepts::ReadMap::Value "Value" of the length map.
+ ///
+ /// \param _Digraph The digraph type the algorithm runs on. The default value
+ /// is \ref ListDigraph. The value of _Digraph is not used directly by
+ /// BellmanFord, it is only passed to \ref BellmanFordDefaultTraits.
+ /// \param _LengthMap This read-only ArcMap determines the lengths of the
+ /// arcs. The default map type is \ref concepts::Digraph::ArcMap
+ /// "Digraph::ArcMap<int>". The value of _LengthMap is not used directly
+ /// by BellmanFord, it is only passed to \ref BellmanFordDefaultTraits.
+ /// \param _Traits Traits class to set various data types used by the
+ /// algorithm. The default traits class is \ref BellmanFordDefaultTraits
+ /// "BellmanFordDefaultTraits<_Digraph,_LengthMap>". See \ref
+ /// BellmanFordDefaultTraits for the documentation of a BellmanFord traits
+ /// class.
+#ifdef DOXYGEN
+ template <typename _Digraph, typename _LengthMap, typename _Traits>
+#else
+ template <typename _Digraph,
+ typename _LengthMap=typename _Digraph::template ArcMap<int>,
+ typename _Traits=BellmanFordDefaultTraits<_Digraph,_LengthMap> >
+#endif
+ class BellmanFord {
+ public:
+
+ typedef _Traits Traits;
+ ///The type of the underlying digraph.
+ typedef typename _Traits::Digraph Digraph;
+
+ typedef typename Digraph::Node Node;
+ typedef typename Digraph::NodeIt NodeIt;
+ typedef typename Digraph::Arc Arc;
+ typedef typename Digraph::OutArcIt OutArcIt;
+
+ /// \brief The type of the length of the arcs.
+ typedef typename _Traits::LengthMap::Value Value;
+ /// \brief The type of the map that stores the arc lengths.
+ typedef typename _Traits::LengthMap LengthMap;
+ /// \brief The type of the map that stores the last
+ /// arcs of the shortest paths.
+ typedef typename _Traits::PredMap PredMap;
+ /// \brief The type of the map that stores the dists of the nodes.
+ typedef typename _Traits::DistMap DistMap;
+ /// \brief The operation traits.
+ typedef typename _Traits::OperationTraits OperationTraits;
+ private:
+ /// Pointer to the underlying digraph.
+ const Digraph *digraph;
+ /// Pointer to the length map
+ const LengthMap *length;
+ ///Pointer to the map of predecessors arcs.
+ PredMap *_pred;
+ ///Indicates if \ref _pred is locally allocated (\c true) or not.
+ bool local_pred;
+ ///Pointer to the map of distances.
+ DistMap *_dist;
+ ///Indicates if \ref _dist is locally allocated (\c true) or not.
+ bool local_dist;
+
+ typedef typename Digraph::template NodeMap<bool> MaskMap;
+ MaskMap *_mask;
+
+ std::vector<Node> _process;
+
+ /// Creates the maps if necessary.
+ void create_maps() {
+ if(!_pred) {
+ local_pred = true;
+ _pred = Traits::createPredMap(*digraph);
+ }
+ if(!_dist) {
+ local_dist = true;
+ _dist = Traits::createDistMap(*digraph);
+ }
+ _mask = new MaskMap(*digraph, false);
+ }
+
+ public :
+
+ typedef BellmanFord Create;
+
+ /// \name Named template parameters
+
+ ///@{
+
+ template <class T>
+ struct DefPredMapTraits : public Traits {
+ typedef T PredMap;
+ static PredMap *createPredMap(const Digraph&) {
+ LEMON_ASSERT(false, "PredMap is not initialized");
+ return 0; // ignore warnings
+ }
+ };
+
+ /// \brief \ref named-templ-param "Named parameter" for setting PredMap
+ /// type
+ /// \ref named-templ-param "Named parameter" for setting PredMap type
+ ///
+ template <class T>
+ struct SetPredMap
+ : public BellmanFord< Digraph, LengthMap, DefPredMapTraits<T> > {
+ typedef BellmanFord< Digraph, LengthMap, DefPredMapTraits<T> > Create;
+ };
+
+ template <class T>
+ struct DefDistMapTraits : public Traits {
+ typedef T DistMap;
+ static DistMap *createDistMap(const Digraph&) {
+ LEMON_ASSERT(false, "DistMap is not initialized");
+ return 0; // ignore warnings
+ }
+ };
+
+ /// \brief \ref named-templ-param "Named parameter" for setting DistMap
+ /// type
+ ///
+ /// \ref named-templ-param "Named parameter" for setting DistMap type
+ ///
+ template <class T>
+ struct SetDistMap
+ : public BellmanFord< Digraph, LengthMap, DefDistMapTraits<T> > {
+ typedef BellmanFord< Digraph, LengthMap, DefDistMapTraits<T> > Create;
+ };
+
+ template <class T>
More information about the Lemon-commits
mailing list