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