lemon/floyd_warshall.h
author alpar
Tue, 24 Oct 2006 17:19:16 +0000
changeset 2260 4274224f8a7d
parent 2184 05a5e48010ab
child 2335 27aa03cd3121
permissions -rw-r--r--
concept -> concepts (namespace & directory)
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2006
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #ifndef LEMON_FLOYD_WARSHALL_H
    20 #define LEMON_FLOYD_WARSHALL_H
    21 
    22 ///\ingroup flowalgs
    23 /// \file
    24 /// \brief FloydWarshall algorithm.
    25 ///
    26 
    27 #include <lemon/list_graph.h>
    28 #include <lemon/graph_utils.h>
    29 #include <lemon/bits/invalid.h>
    30 #include <lemon/error.h>
    31 #include <lemon/matrix_maps.h>
    32 #include <lemon/maps.h>
    33 
    34 #include <limits>
    35 
    36 namespace lemon {
    37 
    38   /// \brief Default OperationTraits for the FloydWarshall algorithm class.
    39   ///  
    40   /// It defines all computational operations and constants which are
    41   /// used in the Floyd-Warshall algorithm. The default implementation
    42   /// is based on the numeric_limits class. If the numeric type does not
    43   /// have infinity value then the maximum value is used as extremal
    44   /// infinity value.
    45   template <
    46     typename Value, 
    47     bool has_infinity = std::numeric_limits<Value>::has_infinity>
    48   struct FloydWarshallDefaultOperationTraits {
    49     /// \brief Gives back the zero value of the type.
    50     static Value zero() {
    51       return static_cast<Value>(0);
    52     }
    53     /// \brief Gives back the positive infinity value of the type.
    54     static Value infinity() {
    55       return std::numeric_limits<Value>::infinity();
    56     }
    57     /// \brief Gives back the sum of the given two elements.
    58     static Value plus(const Value& left, const Value& right) {
    59       return left + right;
    60     }
    61     /// \brief Gives back true only if the first value less than the second.
    62     static bool less(const Value& left, const Value& right) {
    63       return left < right;
    64     }
    65   };
    66 
    67   template <typename Value>
    68   struct FloydWarshallDefaultOperationTraits<Value, false> {
    69     static Value zero() {
    70       return static_cast<Value>(0);
    71     }
    72     static Value infinity() {
    73       return std::numeric_limits<Value>::max();
    74     }
    75     static Value plus(const Value& left, const Value& right) {
    76       if (left == infinity() || right == infinity()) return infinity();
    77       return left + right;
    78     }
    79     static bool less(const Value& left, const Value& right) {
    80       return left < right;
    81     }
    82   };
    83   
    84   /// \brief Default traits class of FloydWarshall class.
    85   ///
    86   /// Default traits class of FloydWarshall class.
    87   /// \param _Graph Graph type.
    88   /// \param _LegthMap Type of length map.
    89   template<class _Graph, class _LengthMap>
    90   struct FloydWarshallDefaultTraits {
    91     /// The graph type the algorithm runs on. 
    92     typedef _Graph Graph;
    93 
    94     /// \brief The type of the map that stores the edge lengths.
    95     ///
    96     /// The type of the map that stores the edge lengths.
    97     /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
    98     typedef _LengthMap LengthMap;
    99 
   100     // The type of the length of the edges.
   101     typedef typename _LengthMap::Value Value;
   102 
   103     /// \brief Operation traits for floyd-warshall algorithm.
   104     ///
   105     /// It defines the infinity type on the given Value type
   106     /// and the used operation.
   107     /// \see FloydWarshallDefaultOperationTraits
   108     typedef FloydWarshallDefaultOperationTraits<Value> OperationTraits;
   109  
   110     /// \brief The type of the matrix map that stores the last edges of the 
   111     /// shortest paths.
   112     /// 
   113     /// The type of the map that stores the last edges of the shortest paths.
   114     /// It must be a matrix map with \c Graph::Edge value type.
   115     ///
   116     typedef DynamicMatrixMap<Graph, typename Graph::Node, 
   117 			     typename Graph::Edge> PredMap;
   118 
   119     /// \brief Instantiates a PredMap.
   120     /// 
   121     /// This function instantiates a \ref PredMap. 
   122     /// \param graph is the graph,
   123     /// to which we would like to define the PredMap.
   124     /// \todo The graph alone may be insufficient for the initialization
   125     static PredMap *createPredMap(const _Graph& graph) {
   126       return new PredMap(graph);
   127     }
   128 
   129     /// \brief The type of the map that stores the dists of the nodes.
   130     ///
   131     /// The type of the map that stores the dists of the nodes.
   132     /// It must meet the \ref concepts::WriteMatrixMap "WriteMatrixMap" concept.
   133     ///
   134     typedef DynamicMatrixMap<Graph, typename Graph::Node, Value> DistMap;
   135 
   136     /// \brief Instantiates a DistMap.
   137     ///
   138     /// This function instantiates a \ref DistMap. 
   139     /// \param graph is the graph, to which we would like to define the 
   140     /// \ref DistMap
   141     static DistMap *createDistMap(const _Graph& graph) {
   142       return new DistMap(graph);
   143     }
   144 
   145   };
   146   
   147   /// \brief %FloydWarshall algorithm class.
   148   ///
   149   /// \ingroup flowalgs
   150   /// This class provides an efficient implementation of \c Floyd-Warshall 
   151   /// algorithm. The edge lengths are passed to the algorithm using a
   152   /// \ref concepts::ReadMap "ReadMap", so it is easy to change it to any 
   153   /// kind of length.
   154   ///
   155   /// The algorithm solves the shortest path problem for each pair
   156   /// of node when the edges can have negative length but the graph should
   157   /// not contain cycles with negative sum of length. If we can assume
   158   /// that all edge is non-negative in the graph then the dijkstra algorithm
   159   /// should be used from each node rather and if the graph is sparse and
   160   /// there are negative circles then the johnson algorithm.
   161   ///
   162   /// The complexity of this algorithm is \f$ O(n^3+e) \f$.
   163   ///
   164   /// The type of the length is determined by the
   165   /// \ref concepts::ReadMap::Value "Value" of the length map.
   166   ///
   167   /// \param _Graph The graph type the algorithm runs on. The default value
   168   /// is \ref ListGraph. The value of _Graph is not used directly by
   169   /// FloydWarshall, it is only passed to \ref FloydWarshallDefaultTraits.
   170   /// \param _LengthMap This read-only EdgeMap determines the lengths of the
   171   /// edges. It is read once for each edge, so the map may involve in
   172   /// relatively time consuming process to compute the edge length if
   173   /// it is necessary. The default map type is \ref
   174   /// concepts::Graph::EdgeMap "Graph::EdgeMap<int>".  The value
   175   /// of _LengthMap is not used directly by FloydWarshall, it is only passed 
   176   /// to \ref FloydWarshallDefaultTraits.  \param _Traits Traits class to set
   177   /// various data types used by the algorithm.  The default traits
   178   /// class is \ref FloydWarshallDefaultTraits
   179   /// "FloydWarshallDefaultTraits<_Graph,_LengthMap>".  See \ref
   180   /// FloydWarshallDefaultTraits for the documentation of a FloydWarshall 
   181   /// traits class.
   182   ///
   183   /// \author Balazs Dezso
   184   /// \todo A function type interface would be nice.
   185   /// \todo Implement \c nextNode() and \c nextEdge()
   186 #ifdef DOXYGEN
   187   template <typename _Graph, typename _LengthMap, typename _Traits >
   188 #else
   189   template <typename _Graph=ListGraph,
   190 	    typename _LengthMap=typename _Graph::template EdgeMap<int>,
   191 	    typename _Traits=FloydWarshallDefaultTraits<_Graph,_LengthMap> >
   192 #endif
   193   class FloydWarshall {
   194   public:
   195     
   196     /// \brief \ref Exception for uninitialized parameters.
   197     ///
   198     /// This error represents problems in the initialization
   199     /// of the parameters of the algorithms.
   200 
   201     class UninitializedParameter : public lemon::UninitializedParameter {
   202     public:
   203       virtual const char* what() const throw() {
   204 	return "lemon::FloydWarshall::UninitializedParameter";
   205       }
   206     };
   207 
   208     typedef _Traits Traits;
   209     ///The type of the underlying graph.
   210     typedef typename _Traits::Graph Graph;
   211 
   212     typedef typename Graph::Node Node;
   213     typedef typename Graph::NodeIt NodeIt;
   214     typedef typename Graph::Edge Edge;
   215     typedef typename Graph::EdgeIt EdgeIt;
   216     
   217     /// \brief The type of the length of the edges.
   218     typedef typename _Traits::LengthMap::Value Value;
   219     /// \brief The type of the map that stores the edge lengths.
   220     typedef typename _Traits::LengthMap LengthMap;
   221     /// \brief The type of the map that stores the last
   222     /// edges of the shortest paths. The type of the PredMap
   223     /// is a matrix map for Edges
   224     typedef typename _Traits::PredMap PredMap;
   225     /// \brief The type of the map that stores the dists of the nodes.
   226     /// The type of the DistMap is a matrix map for Values
   227     ///
   228     /// \todo It should rather be
   229     /// called \c DistMatrix
   230     typedef typename _Traits::DistMap DistMap;
   231     /// \brief The operation traits.
   232     typedef typename _Traits::OperationTraits OperationTraits;
   233   private:
   234     /// Pointer to the underlying graph.
   235     const Graph *graph;
   236     /// Pointer to the length map
   237     const LengthMap *length;
   238     ///Pointer to the map of predecessors edges.
   239     PredMap *_pred;
   240     ///Indicates if \ref _pred is locally allocated (\c true) or not.
   241     bool local_pred;
   242     ///Pointer to the map of distances.
   243     DistMap *_dist;
   244     ///Indicates if \ref _dist is locally allocated (\c true) or not.
   245     bool local_dist;
   246 
   247     /// Creates the maps if necessary.
   248     void create_maps() {
   249       if(!_pred) {
   250 	local_pred = true;
   251 	_pred = Traits::createPredMap(*graph);
   252       }
   253       if(!_dist) {
   254 	local_dist = true;
   255 	_dist = Traits::createDistMap(*graph);
   256       }
   257     }
   258     
   259   public :
   260  
   261     /// \name Named template parameters
   262 
   263     ///@{
   264 
   265     template <class T>
   266     struct DefPredMapTraits : public Traits {
   267       typedef T PredMap;
   268       static PredMap *createPredMap(const Graph& graph) {
   269 	throw UninitializedParameter();
   270       }
   271     };
   272 
   273     /// \brief \ref named-templ-param "Named parameter" for setting PredMap 
   274     /// type
   275     /// \ref named-templ-param "Named parameter" for setting PredMap type
   276     ///
   277     template <class T>
   278     struct DefPredMap 
   279       : public FloydWarshall< Graph, LengthMap, DefPredMapTraits<T> > {
   280       typedef FloydWarshall< Graph, LengthMap, DefPredMapTraits<T> > Create;
   281     };
   282     
   283     template <class T>
   284     struct DefDistMapTraits : public Traits {
   285       typedef T DistMap;
   286       static DistMap *createDistMap(const Graph& graph) {
   287 	throw UninitializedParameter();
   288       }
   289     };
   290     /// \brief \ref named-templ-param "Named parameter" for setting DistMap 
   291     /// type
   292     ///
   293     /// \ref named-templ-param "Named parameter" for setting DistMap type
   294     ///
   295     template <class T>
   296     struct DefDistMap 
   297       : public FloydWarshall< Graph, LengthMap, DefDistMapTraits<T> > {
   298       typedef FloydWarshall< Graph, LengthMap, DefDistMapTraits<T> > Create;
   299     };
   300     
   301     template <class T>
   302     struct DefOperationTraitsTraits : public Traits {
   303       typedef T OperationTraits;
   304     };
   305     
   306     /// \brief \ref named-templ-param "Named parameter" for setting 
   307     /// OperationTraits type
   308     ///
   309     /// \ref named-templ-param "Named parameter" for setting PredMap type
   310     template <class T>
   311     struct DefOperationTraits
   312       : public FloydWarshall< Graph, LengthMap, DefOperationTraitsTraits<T> > {
   313       typedef FloydWarshall< Graph, LengthMap, DefOperationTraitsTraits<T> >
   314       Create;
   315     };
   316     
   317     ///@}
   318 
   319   protected:
   320 
   321     FloydWarshall() {}
   322 
   323   public:      
   324 
   325     typedef FloydWarshall Create;
   326     
   327     /// \brief Constructor.
   328     ///
   329     /// \param _graph the graph the algorithm will run on.
   330     /// \param _length the length map used by the algorithm.
   331     FloydWarshall(const Graph& _graph, const LengthMap& _length) :
   332       graph(&_graph), length(&_length),
   333       _pred(0), local_pred(false),
   334       _dist(0), local_dist(false) {}
   335     
   336     ///Destructor.
   337     ~FloydWarshall() {
   338       if(local_pred) delete _pred;
   339       if(local_dist) delete _dist;
   340     }
   341 
   342     /// \brief Sets the length map.
   343     ///
   344     /// Sets the length map.
   345     /// \return \c (*this)
   346     FloydWarshall &lengthMap(const LengthMap &m) {
   347       length = &m;
   348       return *this;
   349     }
   350 
   351     /// \brief Sets the map storing the predecessor edges.
   352     ///
   353     /// Sets the map storing the predecessor edges.
   354     /// If you don't use this function before calling \ref run(),
   355     /// it will allocate one. The destuctor deallocates this
   356     /// automatically allocated map, of course.
   357     /// \return \c (*this)
   358     FloydWarshall &predMap(PredMap &m) {
   359       if(local_pred) {
   360 	delete _pred;
   361 	local_pred=false;
   362       }
   363       _pred = &m;
   364       return *this;
   365     }
   366 
   367     /// \brief Sets the map storing the distances calculated by the algorithm.
   368     ///
   369     /// Sets the map storing the distances calculated by the algorithm.
   370     /// If you don't use this function before calling \ref run(),
   371     /// it will allocate one. The destuctor deallocates this
   372     /// automatically allocated map, of course.
   373     /// \return \c (*this)
   374     FloydWarshall &distMap(DistMap &m) {
   375       if(local_dist) {
   376 	delete _dist;
   377 	local_dist=false;
   378       }
   379       _dist = &m;
   380       return *this;
   381     }
   382 
   383     ///\name Execution control
   384     /// The simplest way to execute the algorithm is to use
   385     /// one of the member functions called \c run(...).
   386     /// \n
   387     /// If you need more control on the execution,
   388     /// Finally \ref start() will perform the actual path
   389     /// computation.
   390 
   391     ///@{
   392 
   393     /// \brief Initializes the internal data structures.
   394     /// 
   395     /// Initializes the internal data structures.
   396     void init() {
   397       create_maps();
   398       for (NodeIt it(*graph); it != INVALID; ++it) {
   399 	for (NodeIt jt(*graph); jt != INVALID; ++jt) {
   400 	  _pred->set(it, jt, INVALID);
   401 	  _dist->set(it, jt, OperationTraits::infinity());
   402 	}
   403 	_dist->set(it, it, OperationTraits::zero());
   404       }
   405       for (EdgeIt it(*graph); it != INVALID; ++it) {
   406 	Node source = graph->source(it);
   407 	Node target = graph->target(it);	
   408 	if (OperationTraits::less((*length)[it], (*_dist)(source, target))) {
   409 	  _dist->set(source, target, (*length)[it]);
   410 	  _pred->set(source, target, it);
   411 	}
   412       }
   413     }
   414     
   415     /// \brief Executes the algorithm.
   416     ///
   417     /// This method runs the %FloydWarshall algorithm in order to compute 
   418     /// the shortest path to each node pairs. The algorithm 
   419     /// computes 
   420     /// - The shortest path tree for each node.
   421     /// - The distance between each node pairs.
   422     void start() {
   423       for (NodeIt kt(*graph); kt != INVALID; ++kt) {
   424 	for (NodeIt it(*graph); it != INVALID; ++it) {
   425 	  for (NodeIt jt(*graph); jt != INVALID; ++jt) {
   426 	    Value relaxed = OperationTraits::plus((*_dist)(it, kt),
   427 						  (*_dist)(kt, jt));
   428 	    if (OperationTraits::less(relaxed, (*_dist)(it, jt))) {
   429 	      _dist->set(it, jt, relaxed);
   430 	      _pred->set(it, jt, (*_pred)(kt, jt));
   431 	    }
   432 	  }
   433 	}
   434       }
   435     }
   436 
   437     /// \brief Executes the algorithm and checks the negative cycles.
   438     ///
   439     /// This method runs the %FloydWarshall algorithm in order to compute 
   440     /// the shortest path to each node pairs. If there is a negative cycle 
   441     /// in the graph it gives back false. 
   442     /// The algorithm computes 
   443     /// - The shortest path tree for each node.
   444     /// - The distance between each node pairs.
   445     bool checkedStart() {
   446       start();
   447       for (NodeIt it(*graph); it != INVALID; ++it) {
   448 	if (OperationTraits::less((*dist)(it, it), OperationTraits::zero())) {
   449 	  return false;
   450 	}
   451       }
   452       return true;
   453     }
   454     
   455     /// \brief Runs %FloydWarshall algorithm.
   456     ///    
   457     /// This method runs the %FloydWarshall algorithm from a each node
   458     /// in order to compute the shortest path to each node pairs. 
   459     /// The algorithm computes
   460     /// - The shortest path tree for each node.
   461     /// - The distance between each node pairs.
   462     ///
   463     /// \note d.run(s) is just a shortcut of the following code.
   464     ///\code
   465     ///  d.init();
   466     ///  d.start();
   467     ///\endcode
   468     void run() {
   469       init();
   470       start();
   471     }
   472     
   473     ///@}
   474 
   475     /// \name Query Functions
   476     /// The result of the %FloydWarshall algorithm can be obtained using these
   477     /// functions.\n
   478     /// Before the use of these functions,
   479     /// either run() or start() must be called.
   480     
   481     ///@{
   482 
   483     /// \brief Copies the shortest path to \c t into \c p
   484     ///    
   485     /// This function copies the shortest path to \c t into \c p.
   486     /// If it \c t is a source itself or unreachable, then it does not
   487     /// alter \c p.
   488     /// \return Returns \c true if a path to \c t was actually copied to \c p,
   489     /// \c false otherwise.
   490     /// \sa DirPath
   491     template <typename Path>
   492     bool getPath(Path &p, Node source, Node target) {
   493       if (connected(source, target)) {
   494 	p.clear();
   495 	typename Path::Builder b(target);
   496 	for(b.setStartNode(target); predEdge(source, target) != INVALID;
   497 	    target = predNode(target)) {
   498 	  b.pushFront(predEdge(source, target));
   499 	}
   500 	b.commit();
   501 	return true;
   502       }
   503       return false;
   504     }
   505 	  
   506     /// \brief The distance between two nodes.
   507     ///
   508     /// Returns the distance between two nodes.
   509     /// \pre \ref run() must be called before using this function.
   510     /// \warning If node \c v in unreachable from the root the return value
   511     /// of this funcion is undefined.
   512     Value dist(Node source, Node target) const { 
   513       return (*_dist)(source, target); 
   514     }
   515 
   516     /// \brief Returns the 'previous edge' of the shortest path tree.
   517     ///
   518     /// For the node \c node it returns the 'previous edge' of the shortest 
   519     /// path tree to direction of the node \c root 
   520     /// i.e. it returns the last edge of a shortest path from the node \c root 
   521     /// to \c node. It is \ref INVALID if \c node is unreachable from the root
   522     /// or if \c node=root. The shortest path tree used here is equal to the 
   523     /// shortest path tree used in \ref predNode(). 
   524     /// \pre \ref run() must be called before using this function.
   525     Edge predEdge(Node root, Node node) const { 
   526       return (*_pred)(root, node); 
   527     }
   528 
   529     /// \brief Returns the 'previous node' of the shortest path tree.
   530     ///
   531     /// For a node \c node it returns the 'previous node' of the shortest path 
   532     /// tree to direction of the node \c root, i.e. it returns the last but 
   533     /// one node from a shortest path from the \c root to \c node. It is 
   534     /// INVALID if \c node is unreachable from the root or if \c node=root. 
   535     /// The shortest path tree used here is equal to the 
   536     /// shortest path tree used in \ref predEdge().  
   537     /// \pre \ref run() must be called before using this function.
   538     Node predNode(Node root, Node node) const { 
   539       return (*_pred)(root, node) == INVALID ? 
   540       INVALID : graph->source((*_pred)(root, node)); 
   541     }
   542     
   543     /// \brief Returns a reference to the matrix node map of distances.
   544     ///
   545     /// Returns a reference to the matrix node map of distances. 
   546     ///
   547     /// \pre \ref run() must be called before using this function.
   548     const DistMap &distMap() const { return *_dist;}
   549  
   550     /// \brief Returns a reference to the shortest path tree map.
   551     ///
   552     /// Returns a reference to the matrix node map of the edges of the
   553     /// shortest path tree.
   554     /// \pre \ref run() must be called before using this function.
   555     const PredMap &predMap() const { return *_pred;}
   556  
   557     /// \brief Checks if a node is reachable from the root.
   558     ///
   559     /// Returns \c true if \c v is reachable from the root.
   560     /// \pre \ref run() must be called before using this function.
   561     ///
   562     bool connected(Node source, Node target) { 
   563       return (*_dist)(source, target) != OperationTraits::infinity(); 
   564     }
   565     
   566     ///@}
   567   };
   568  
   569 } //END OF NAMESPACE LEMON
   570 
   571 #endif
   572