[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