lemon/floyd_warshall.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2151 38ec4a930c05
child 2260 4274224f8a7d
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

The tests have been modified to the current implementation
     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 concept::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 concept::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 concept::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 concept::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   /// concept::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