lemon/dfs.h
author alpar
Tue, 30 Aug 2005 14:55:11 +0000
changeset 1665 fdeb961110ac
parent 1664 72f1f24b73c9
child 1666 30d7e673781f
permissions -rw-r--r--
Functions to query the next node/edge to be processed.
     1 /* -*- C++ -*-
     2  * lemon/dfs.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_DFS_H
    18 #define LEMON_DFS_H
    19 
    20 ///\ingroup flowalgs
    21 ///\file
    22 ///\brief Dfs algorithm.
    23 
    24 #include <lemon/list_graph.h>
    25 #include <lemon/graph_utils.h>
    26 #include <lemon/invalid.h>
    27 #include <lemon/error.h>
    28 #include <lemon/maps.h>
    29 
    30 namespace lemon {
    31 
    32 
    33   
    34   ///Default traits class of Dfs class.
    35 
    36   ///Default traits class of Dfs class.
    37   ///\param GR Graph type.
    38   template<class GR>
    39   struct DfsDefaultTraits
    40   {
    41     ///The graph type the algorithm runs on. 
    42     typedef GR Graph;
    43     ///\brief The type of the map that stores the last
    44     ///edges of the %DFS paths.
    45     /// 
    46     ///The type of the map that stores the last
    47     ///edges of the %DFS paths.
    48     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
    49     ///
    50     typedef typename Graph::template NodeMap<typename GR::Edge> PredMap;
    51     ///Instantiates a PredMap.
    52  
    53     ///This function instantiates a \ref PredMap. 
    54     ///\param G is the graph, to which we would like to define the PredMap.
    55     ///\todo The graph alone may be insufficient to initialize
    56     static PredMap *createPredMap(const GR &G) 
    57     {
    58       return new PredMap(G);
    59     }
    60 //     ///\brief The type of the map that stores the last but one
    61 //     ///nodes of the %DFS paths.
    62 //     ///
    63 //     ///The type of the map that stores the last but one
    64 //     ///nodes of the %DFS paths.
    65 //     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
    66 //     ///
    67 //     typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
    68 //     ///Instantiates a PredNodeMap.
    69     
    70 //     ///This function instantiates a \ref PredNodeMap. 
    71 //     ///\param G is the graph, to which
    72 //     ///we would like to define the \ref PredNodeMap
    73 //     static PredNodeMap *createPredNodeMap(const GR &G)
    74 //     {
    75 //       return new PredNodeMap();
    76 //     }
    77 
    78     ///The type of the map that indicates which nodes are processed.
    79  
    80     ///The type of the map that indicates which nodes are processed.
    81     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
    82     ///\todo named parameter to set this type, function to read and write.
    83     typedef NullMap<typename Graph::Node,bool> ProcessedMap;
    84     ///Instantiates a ProcessedMap.
    85  
    86     ///This function instantiates a \ref ProcessedMap. 
    87     ///\param g is the graph, to which
    88     ///we would like to define the \ref ProcessedMap
    89 #ifdef DOXYGEN
    90     static ProcessedMap *createProcessedMap(const GR &g)
    91 #else
    92     static ProcessedMap *createProcessedMap(const GR &)
    93 #endif
    94     {
    95       return new ProcessedMap();
    96     }
    97     ///The type of the map that indicates which nodes are reached.
    98  
    99     ///The type of the map that indicates which nodes are reached.
   100     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
   101     ///\todo named parameter to set this type, function to read and write.
   102     typedef typename Graph::template NodeMap<bool> ReachedMap;
   103     ///Instantiates a ReachedMap.
   104  
   105     ///This function instantiates a \ref ReachedMap. 
   106     ///\param G is the graph, to which
   107     ///we would like to define the \ref ReachedMap.
   108     static ReachedMap *createReachedMap(const GR &G)
   109     {
   110       return new ReachedMap(G);
   111     }
   112     ///The type of the map that stores the dists of the nodes.
   113  
   114     ///The type of the map that stores the dists of the nodes.
   115     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
   116     ///
   117     typedef typename Graph::template NodeMap<int> DistMap;
   118     ///Instantiates a DistMap.
   119  
   120     ///This function instantiates a \ref DistMap. 
   121     ///\param G is the graph, to which we would like to define the \ref DistMap
   122     static DistMap *createDistMap(const GR &G)
   123     {
   124       return new DistMap(G);
   125     }
   126   };
   127   
   128   ///%DFS algorithm class.
   129   
   130   ///\ingroup flowalgs
   131   ///This class provides an efficient implementation of the %DFS algorithm.
   132   ///
   133   ///\param GR The graph type the algorithm runs on. The default value is
   134   ///\ref ListGraph. The value of GR is not used directly by Dfs, it
   135   ///is only passed to \ref DfsDefaultTraits.
   136   ///\param TR Traits class to set various data types used by the algorithm.
   137   ///The default traits class is
   138   ///\ref DfsDefaultTraits "DfsDefaultTraits<GR>".
   139   ///See \ref DfsDefaultTraits for the documentation of
   140   ///a Dfs traits class.
   141   ///
   142   ///\author Jacint Szabo and Alpar Juttner
   143   ///\todo A compare object would be nice.
   144 
   145 #ifdef DOXYGEN
   146   template <typename GR,
   147 	    typename TR>
   148 #else
   149   template <typename GR=ListGraph,
   150 	    typename TR=DfsDefaultTraits<GR> >
   151 #endif
   152   class Dfs {
   153   public:
   154     /**
   155      * \brief \ref Exception for uninitialized parameters.
   156      *
   157      * This error represents problems in the initialization
   158      * of the parameters of the algorithms.
   159      */
   160     class UninitializedParameter : public lemon::UninitializedParameter {
   161     public:
   162       virtual const char* exceptionName() const {
   163 	return "lemon::Dfs::UninitializedParameter";
   164       }
   165     };
   166 
   167     typedef TR Traits;
   168     ///The type of the underlying graph.
   169     typedef typename TR::Graph Graph;
   170     ///\e
   171     typedef typename Graph::Node Node;
   172     ///\e
   173     typedef typename Graph::NodeIt NodeIt;
   174     ///\e
   175     typedef typename Graph::Edge Edge;
   176     ///\e
   177     typedef typename Graph::OutEdgeIt OutEdgeIt;
   178     
   179     ///\brief The type of the map that stores the last
   180     ///edges of the %DFS paths.
   181     typedef typename TR::PredMap PredMap;
   182 //     ///\brief The type of the map that stores the last but one
   183 //     ///nodes of the %DFS paths.
   184 //     typedef typename TR::PredNodeMap PredNodeMap;
   185     ///The type of the map indicating which nodes are reached.
   186     typedef typename TR::ReachedMap ReachedMap;
   187     ///The type of the map indicating which nodes are processed.
   188     typedef typename TR::ProcessedMap ProcessedMap;
   189     ///The type of the map that stores the dists of the nodes.
   190     typedef typename TR::DistMap DistMap;
   191   private:
   192     /// Pointer to the underlying graph.
   193     const Graph *G;
   194     ///Pointer to the map of predecessors edges.
   195     PredMap *_pred;
   196     ///Indicates if \ref _pred is locally allocated (\c true) or not.
   197     bool local_pred;
   198 //     ///Pointer to the map of predecessors nodes.
   199 //     PredNodeMap *_predNode;
   200 //     ///Indicates if \ref _predNode is locally allocated (\c true) or not.
   201 //     bool local_predNode;
   202     ///Pointer to the map of distances.
   203     DistMap *_dist;
   204     ///Indicates if \ref _dist is locally allocated (\c true) or not.
   205     bool local_dist;
   206     ///Pointer to the map of reached status of the nodes.
   207     ReachedMap *_reached;
   208     ///Indicates if \ref _reached is locally allocated (\c true) or not.
   209     bool local_reached;
   210     ///Pointer to the map of processed status of the nodes.
   211     ProcessedMap *_processed;
   212     ///Indicates if \ref _processed is locally allocated (\c true) or not.
   213     bool local_processed;
   214 
   215     std::vector<typename Graph::OutEdgeIt> _stack;
   216     int _stack_head;
   217 //     ///The source node of the last execution.
   218 //     Node source;
   219 
   220     ///Creates the maps if necessary.
   221     
   222     ///\todo Error if \c G are \c NULL.
   223     ///\todo Better memory allocation (instead of new).
   224     void create_maps() 
   225     {
   226       if(!_pred) {
   227 	local_pred = true;
   228 	_pred = Traits::createPredMap(*G);
   229       }
   230 //       if(!_predNode) {
   231 // 	local_predNode = true;
   232 // 	_predNode = Traits::createPredNodeMap(*G);
   233 //       }
   234       if(!_dist) {
   235 	local_dist = true;
   236 	_dist = Traits::createDistMap(*G);
   237       }
   238       if(!_reached) {
   239 	local_reached = true;
   240 	_reached = Traits::createReachedMap(*G);
   241       }
   242       if(!_processed) {
   243 	local_processed = true;
   244 	_processed = Traits::createProcessedMap(*G);
   245       }
   246     }
   247     
   248   public :
   249  
   250     ///\name Named template parameters
   251 
   252     ///@{
   253 
   254     template <class T>
   255     struct DefPredMapTraits : public Traits {
   256       typedef T PredMap;
   257       static PredMap *createPredMap(const Graph &G) 
   258       {
   259 	throw UninitializedParameter();
   260       }
   261     };
   262     ///\ref named-templ-param "Named parameter" for setting PredMap type
   263 
   264     ///\ref named-templ-param "Named parameter" for setting PredMap type
   265     ///
   266     template <class T>
   267     class DefPredMap : public Dfs< Graph,
   268 					DefPredMapTraits<T> > { };
   269     
   270 //     template <class T>
   271 //     struct DefPredNodeMapTraits : public Traits {
   272 //       typedef T PredNodeMap;
   273 //       static PredNodeMap *createPredNodeMap(const Graph &G) 
   274 //       {
   275 // 	throw UninitializedParameter();
   276 //       }
   277 //     };
   278 //     ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
   279 
   280 //     ///\ref named-templ-param "Named parameter" for setting PredNodeMap type
   281 //     ///
   282 //     template <class T>
   283 //     class DefPredNodeMap : public Dfs< Graph,
   284 // 					    LengthMap,
   285 // 					    DefPredNodeMapTraits<T> > { };
   286     
   287     template <class T>
   288     struct DefDistMapTraits : public Traits {
   289       typedef T DistMap;
   290       static DistMap *createDistMap(const Graph &G) 
   291       {
   292 	throw UninitializedParameter();
   293       }
   294     };
   295     ///\ref named-templ-param "Named parameter" for setting DistMap type
   296 
   297     ///\ref named-templ-param "Named parameter" for setting DistMap type
   298     ///
   299     template <class T>
   300     class DefDistMap : public Dfs< Graph,
   301 				   DefDistMapTraits<T> > { };
   302     
   303     template <class T>
   304     struct DefReachedMapTraits : public Traits {
   305       typedef T ReachedMap;
   306       static ReachedMap *createReachedMap(const Graph &G) 
   307       {
   308 	throw UninitializedParameter();
   309       }
   310     };
   311     ///\ref named-templ-param "Named parameter" for setting ReachedMap type
   312 
   313     ///\ref named-templ-param "Named parameter" for setting ReachedMap type
   314     ///
   315     template <class T>
   316     class DefReachedMap : public Dfs< Graph,
   317 				      DefReachedMapTraits<T> > { };
   318     
   319     struct DefGraphReachedMapTraits : public Traits {
   320       typedef typename Graph::template NodeMap<bool> ReachedMap;
   321       static ReachedMap *createReachedMap(const Graph &G) 
   322       {
   323 	return new ReachedMap(G);
   324       }
   325     };
   326     template <class T>
   327     struct DefProcessedMapTraits : public Traits {
   328       typedef T ProcessedMap;
   329       static ProcessedMap *createProcessedMap(const Graph &G) 
   330       {
   331 	throw UninitializedParameter();
   332       }
   333     };
   334     ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
   335 
   336     ///\ref named-templ-param "Named parameter" for setting ProcessedMap type
   337     ///
   338     template <class T>
   339     class DefProcessedMap : public Dfs< Graph,
   340 					DefProcessedMapTraits<T> > { };
   341     
   342     struct DefGraphProcessedMapTraits : public Traits {
   343       typedef typename Graph::template NodeMap<bool> ProcessedMap;
   344       static ProcessedMap *createProcessedMap(const Graph &G) 
   345       {
   346 	return new ProcessedMap(G);
   347       }
   348     };
   349     ///\brief \ref named-templ-param "Named parameter"
   350     ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
   351     ///
   352     ///\ref named-templ-param "Named parameter"
   353     ///for setting the ProcessedMap type to be Graph::NodeMap<bool>.
   354     ///If you don't set it explicitely, it will be automatically allocated.
   355     template <class T>
   356     class DefProcessedMapToBeDefaultMap :
   357       public Dfs< Graph,
   358 		  DefGraphProcessedMapTraits> { };
   359     
   360     ///@}
   361 
   362   public:      
   363     
   364     ///Constructor.
   365     
   366     ///\param _G the graph the algorithm will run on.
   367     ///
   368     Dfs(const Graph& _G) :
   369       G(&_G),
   370       _pred(NULL), local_pred(false),
   371 //       _predNode(NULL), local_predNode(false),
   372       _dist(NULL), local_dist(false),
   373       _reached(NULL), local_reached(false),
   374       _processed(NULL), local_processed(false)
   375     { }
   376     
   377     ///Destructor.
   378     ~Dfs() 
   379     {
   380       if(local_pred) delete _pred;
   381 //       if(local_predNode) delete _predNode;
   382       if(local_dist) delete _dist;
   383       if(local_reached) delete _reached;
   384       if(local_processed) delete _processed;
   385     }
   386 
   387     ///Sets the map storing the predecessor edges.
   388 
   389     ///Sets the map storing the predecessor edges.
   390     ///If you don't use this function before calling \ref run(),
   391     ///it will allocate one. The destuctor deallocates this
   392     ///automatically allocated map, of course.
   393     ///\return <tt> (*this) </tt>
   394     Dfs &predMap(PredMap &m) 
   395     {
   396       if(local_pred) {
   397 	delete _pred;
   398 	local_pred=false;
   399       }
   400       _pred = &m;
   401       return *this;
   402     }
   403 
   404 //     ///Sets the map storing the predecessor nodes.
   405 
   406 //     ///Sets the map storing the predecessor nodes.
   407 //     ///If you don't use this function before calling \ref run(),
   408 //     ///it will allocate one. The destuctor deallocates this
   409 //     ///automatically allocated map, of course.
   410 //     ///\return <tt> (*this) </tt>
   411 //     Dfs &predNodeMap(PredNodeMap &m) 
   412 //     {
   413 //       if(local_predNode) {
   414 // 	delete _predNode;
   415 // 	local_predNode=false;
   416 //       }
   417 //       _predNode = &m;
   418 //       return *this;
   419 //     }
   420 
   421     ///Sets the map storing the distances calculated by the algorithm.
   422 
   423     ///Sets the map storing the distances calculated by the algorithm.
   424     ///If you don't use this function before calling \ref run(),
   425     ///it will allocate one. The destuctor deallocates this
   426     ///automatically allocated map, of course.
   427     ///\return <tt> (*this) </tt>
   428     Dfs &distMap(DistMap &m) 
   429     {
   430       if(local_dist) {
   431 	delete _dist;
   432 	local_dist=false;
   433       }
   434       _dist = &m;
   435       return *this;
   436     }
   437 
   438     ///Sets the map indicating if a node is reached.
   439 
   440     ///Sets the map indicating if a node is reached.
   441     ///If you don't use this function before calling \ref run(),
   442     ///it will allocate one. The destuctor deallocates this
   443     ///automatically allocated map, of course.
   444     ///\return <tt> (*this) </tt>
   445     Dfs &reachedMap(ReachedMap &m) 
   446     {
   447       if(local_reached) {
   448 	delete _reached;
   449 	local_reached=false;
   450       }
   451       _reached = &m;
   452       return *this;
   453     }
   454 
   455     ///Sets the map indicating if a node is processed.
   456 
   457     ///Sets the map indicating if a node is processed.
   458     ///If you don't use this function before calling \ref run(),
   459     ///it will allocate one. The destuctor deallocates this
   460     ///automatically allocated map, of course.
   461     ///\return <tt> (*this) </tt>
   462     Dfs &processedMap(ProcessedMap &m) 
   463     {
   464       if(local_processed) {
   465 	delete _processed;
   466 	local_processed=false;
   467       }
   468       _processed = &m;
   469       return *this;
   470     }
   471 
   472   public:
   473     ///\name Execution control
   474     ///The simplest way to execute the algorithm is to use
   475     ///one of the member functions called \c run(...).
   476     ///\n
   477     ///If you need more control on the execution,
   478     ///first you must call \ref init(), then you can add several source nodes
   479     ///with \ref addSource().
   480     ///Finally \ref start() will perform the actual path
   481     ///computation.
   482 
   483     ///@{
   484 
   485     ///Initializes the internal data structures.
   486 
   487     ///Initializes the internal data structures.
   488     ///
   489     void init()
   490     {
   491       create_maps();
   492       _stack.resize(countNodes(*G));
   493       _stack_head=-1;
   494       for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
   495 	_pred->set(u,INVALID);
   496 	// _predNode->set(u,INVALID);
   497 	_reached->set(u,false);
   498 	_processed->set(u,false);
   499       }
   500     }
   501     
   502     ///Adds a new source node.
   503 
   504     ///Adds a new source node to the set of nodes to be processed.
   505     ///
   506     ///\bug dists are wrong (or at least strange) in case of multiple sources.
   507     void addSource(Node s)
   508     {
   509       if(!(*_reached)[s])
   510 	{
   511 	  _reached->set(s,true);
   512 	  _pred->set(s,INVALID);
   513 	  // _predNode->set(u,INVALID);
   514 	  OutEdgeIt e(*G,s);
   515 	  if(e!=INVALID) _stack[++_stack_head]=e;
   516 	  else _processed->set(s,true);
   517 	  _dist->set(s,_stack_head);
   518 	}
   519     }
   520     
   521     ///Processes the next edge.
   522 
   523     ///Processes the next edge.
   524     ///
   525     ///\return The processed edge.
   526     ///
   527     ///\pre The stack must not be empty!
   528     Edge processNextEdge()
   529     { 
   530       Node m;
   531       Edge e=_stack[_stack_head];
   532       if(!(*_reached)[m=G->target(e)]) {
   533 	_pred->set(m,e);
   534 	_reached->set(m,true);
   535 	//	  _pred_node->set(m,G->source(e));
   536 	++_stack_head;
   537 	_stack[_stack_head] = OutEdgeIt(*G, m);
   538 	_dist->set(m,_stack_head);
   539       }
   540       else {
   541 	m=G->source(e);
   542 	++_stack[_stack_head];
   543       }
   544       //'m' is now the (original) source of the _stack[_stack_head] 
   545       while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
   546 	_processed->set(m,true);
   547 	--_stack_head;
   548 	if(_stack_head>=0) {
   549 	  m=G->source(_stack[_stack_head]);
   550 	  ++_stack[_stack_head];
   551 	}
   552       }
   553       return e;
   554     }
   555     ///Next edge to be processed.
   556 
   557     ///Next edge to be processed.
   558     ///
   559     ///\return The next edge to be processed or INVALID if the stack is
   560     /// empty.
   561     OutEdgeIt NextEdge()
   562     { 
   563       return _stack_head>=0?_stack[_stack_head]:INVALID;
   564     }
   565       
   566     ///\brief Returns \c false if there are nodes
   567     ///to be processed in the queue
   568     ///
   569     ///Returns \c false if there are nodes
   570     ///to be processed in the queue
   571     ///
   572     ///\todo This should be called emptyStack() or some "neutral" name.
   573     bool emptyQueue() { return _stack_head<0; }
   574     ///Returns the number of the nodes to be processed.
   575     
   576     ///Returns the number of the nodes to be processed in the queue.
   577     ///
   578     ///\todo This should be called stackSize() or some "neutral" name.
   579     int queueSize() { return _stack_head+1; }
   580     
   581     ///Executes the algorithm.
   582 
   583     ///Executes the algorithm.
   584     ///
   585     ///\pre init() must be called and at least one node should be added
   586     ///with addSource() before using this function.
   587     ///
   588     ///This method runs the %DFS algorithm from the root node(s)
   589     ///in order to
   590     ///compute the
   591     ///%DFS path to each node. The algorithm computes
   592     ///- The %DFS tree.
   593     ///- The distance of each node from the root(s) in the %DFS tree.
   594     ///
   595     void start()
   596     {
   597       while ( !emptyQueue() ) processNextEdge();
   598     }
   599     
   600     ///Executes the algorithm until \c dest is reached.
   601 
   602     ///Executes the algorithm until \c dest is reached.
   603     ///
   604     ///\pre init() must be called and at least one node should be added
   605     ///with addSource() before using this function.
   606     ///
   607     ///This method runs the %DFS algorithm from the root node(s)
   608     ///in order to
   609     ///compute the
   610     ///%DFS path to \c dest. The algorithm computes
   611     ///- The %DFS path to \c  dest.
   612     ///- The distance of \c dest from the root(s) in the %DFS tree.
   613     ///
   614     void start(Node dest)
   615     {
   616       while ( !emptyQueue() && G->target(_stack[_stack_head])!=dest ) 
   617 	processNextEdge();
   618     }
   619     
   620     ///Executes the algorithm until a condition is met.
   621 
   622     ///Executes the algorithm until a condition is met.
   623     ///
   624     ///\pre init() must be called and at least one node should be added
   625     ///with addSource() before using this function.
   626     ///
   627     ///\param nm must be a bool (or convertible) edge map. The algorithm
   628     ///will stop when it reaches an edge \c e with <tt>nm[e]==true</tt>.
   629     ///
   630     ///\warning Contrary to \ref Dfs and \ref Dijkstra, \c nm is an edge map,
   631     ///not a node map.
   632     template<class NM>
   633       void start(const NM &nm)
   634       {
   635 	while ( !emptyQueue() && !nm[_stack[_stack_head]] ) processNextEdge();
   636       }
   637     
   638     ///Runs %DFS algorithm from node \c s.
   639     
   640     ///This method runs the %DFS algorithm from a root node \c s
   641     ///in order to
   642     ///compute the
   643     ///%DFS path to each node. The algorithm computes
   644     ///- The %DFS tree.
   645     ///- The distance of each node from the root in the %DFS tree.
   646     ///
   647     ///\note d.run(s) is just a shortcut of the following code.
   648     ///\code
   649     ///  d.init();
   650     ///  d.addSource(s);
   651     ///  d.start();
   652     ///\endcode
   653     void run(Node s) {
   654       init();
   655       addSource(s);
   656       start();
   657     }
   658     
   659     ///Finds the %DFS path between \c s and \c t.
   660     
   661     ///Finds the %DFS path between \c s and \c t.
   662     ///
   663     ///\return The length of the %DFS s---t path if there exists one,
   664     ///0 otherwise.
   665     ///\note Apart from the return value, d.run(s,t) is
   666     ///just a shortcut of the following code.
   667     ///\code
   668     ///  d.init();
   669     ///  d.addSource(s);
   670     ///  d.start(t);
   671     ///\endcode
   672     int run(Node s,Node t) {
   673       init();
   674       addSource(s);
   675       start(t);
   676       return reached(t)?_stack_head+1:0;
   677     }
   678     
   679     ///@}
   680 
   681     ///\name Query Functions
   682     ///The result of the %DFS algorithm can be obtained using these
   683     ///functions.\n
   684     ///Before the use of these functions,
   685     ///either run() or start() must be called.
   686     
   687     ///@{
   688 
   689     ///Copies the path to \c t on the DFS tree into \c p
   690     
   691     ///This function copies the path to \c t on the DFS tree  into \c p.
   692     ///If \c t is a source itself or unreachable, then it does not
   693     ///alter \c p.
   694     ///\todo Is this the right way to handle unreachable nodes?
   695     ///
   696     ///\return Returns \c true if a path to \c t was actually copied to \c p,
   697     ///\c false otherwise.
   698     ///\sa DirPath
   699     template<class P>
   700     bool getPath(P &p,Node t) 
   701     {
   702       if(reached(t)) {
   703 	p.clear();
   704 	typename P::Builder b(p);
   705 	for(b.setStartNode(t);pred(t)!=INVALID;t=predNode(t))
   706 	  b.pushFront(pred(t));
   707 	b.commit();
   708 	return true;
   709       }
   710       return false;
   711     }
   712 
   713     ///The distance of a node from the root(s).
   714 
   715     ///Returns the distance of a node from the root(s).
   716     ///\pre \ref run() must be called before using this function.
   717     ///\warning If node \c v is unreachable from the root(s) then the return value
   718     ///of this funcion is undefined.
   719     int dist(Node v) const { return (*_dist)[v]; }
   720 
   721     ///Returns the 'previous edge' of the %DFS tree.
   722 
   723     ///For a node \c v it returns the 'previous edge'
   724     ///of the %DFS path,
   725     ///i.e. it returns the last edge of a %DFS path from the root(s) to \c
   726     ///v. It is \ref INVALID
   727     ///if \c v is unreachable from the root(s) or \c v is a root. The
   728     ///%DFS tree used here is equal to the %DFS tree used in
   729     ///\ref predNode().
   730     ///\pre Either \ref run() or \ref start() must be called before using
   731     ///this function.
   732     ///\todo predEdge could be a better name.
   733     Edge pred(Node v) const { return (*_pred)[v];}
   734 
   735     ///Returns the 'previous node' of the %DFS tree.
   736 
   737     ///For a node \c v it returns the 'previous node'
   738     ///of the %DFS tree,
   739     ///i.e. it returns the last but one node from a %DFS path from the
   740     ///root(a) to \c /v.
   741     ///It is INVALID if \c v is unreachable from the root(s) or
   742     ///if \c v itself a root.
   743     ///The %DFS tree used here is equal to the %DFS
   744     ///tree used in \ref pred().
   745     ///\pre Either \ref run() or \ref start() must be called before
   746     ///using this function.
   747     Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
   748 				  G->source((*_pred)[v]); }
   749     
   750     ///Returns a reference to the NodeMap of distances.
   751 
   752     ///Returns a reference to the NodeMap of distances.
   753     ///\pre Either \ref run() or \ref init() must
   754     ///be called before using this function.
   755     const DistMap &distMap() const { return *_dist;}
   756  
   757     ///Returns a reference to the %DFS edge-tree map.
   758 
   759     ///Returns a reference to the NodeMap of the edges of the
   760     ///%DFS tree.
   761     ///\pre Either \ref run() or \ref init()
   762     ///must be called before using this function.
   763     const PredMap &predMap() const { return *_pred;}
   764  
   765 //     ///Returns a reference to the map of nodes of %DFS paths.
   766 
   767 //     ///Returns a reference to the NodeMap of the last but one nodes of the
   768 //     ///%DFS tree.
   769 //     ///\pre \ref run() must be called before using this function.
   770 //     const PredNodeMap &predNodeMap() const { return *_predNode;}
   771 
   772     ///Checks if a node is reachable from the root.
   773 
   774     ///Returns \c true if \c v is reachable from the root(s).
   775     ///\warning The source nodes are inditated as unreachable.
   776     ///\pre Either \ref run() or \ref start()
   777     ///must be called before using this function.
   778     ///
   779     bool reached(Node v) { return (*_reached)[v]; }
   780     
   781     ///@}
   782   };
   783 
   784   ///Default traits class of Dfs function.
   785 
   786   ///Default traits class of Dfs function.
   787   ///\param GR Graph type.
   788   template<class GR>
   789   struct DfsWizardDefaultTraits
   790   {
   791     ///The graph type the algorithm runs on. 
   792     typedef GR Graph;
   793     ///\brief The type of the map that stores the last
   794     ///edges of the %DFS paths.
   795     /// 
   796     ///The type of the map that stores the last
   797     ///edges of the %DFS paths.
   798     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
   799     ///
   800     typedef NullMap<typename Graph::Node,typename GR::Edge> PredMap;
   801     ///Instantiates a PredMap.
   802  
   803     ///This function instantiates a \ref PredMap. 
   804     ///\param g is the graph, to which we would like to define the PredMap.
   805     ///\todo The graph alone may be insufficient to initialize
   806 #ifdef DOXYGEN
   807     static PredMap *createPredMap(const GR &g) 
   808 #else
   809     static PredMap *createPredMap(const GR &) 
   810 #endif
   811     {
   812       return new PredMap();
   813     }
   814 //     ///\brief The type of the map that stores the last but one
   815 //     ///nodes of the %DFS paths.
   816 //     ///
   817 //     ///The type of the map that stores the last but one
   818 //     ///nodes of the %DFS paths.
   819 //     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
   820 //     ///
   821 //     typedef NullMap<typename Graph::Node,typename Graph::Node> PredNodeMap;
   822 //     ///Instantiates a PredNodeMap.
   823     
   824 //     ///This function instantiates a \ref PredNodeMap. 
   825 //     ///\param G is the graph, to which
   826 //     ///we would like to define the \ref PredNodeMap
   827 //     static PredNodeMap *createPredNodeMap(const GR &G)
   828 //     {
   829 //       return new PredNodeMap();
   830 //     }
   831 
   832     ///The type of the map that indicates which nodes are processed.
   833  
   834     ///The type of the map that indicates which nodes are processed.
   835     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
   836     ///\todo named parameter to set this type, function to read and write.
   837     typedef NullMap<typename Graph::Node,bool> ProcessedMap;
   838     ///Instantiates a ProcessedMap.
   839  
   840     ///This function instantiates a \ref ProcessedMap. 
   841     ///\param g is the graph, to which
   842     ///we would like to define the \ref ProcessedMap
   843 #ifdef DOXYGEN
   844     static ProcessedMap *createProcessedMap(const GR &g)
   845 #else
   846     static ProcessedMap *createProcessedMap(const GR &)
   847 #endif
   848     {
   849       return new ProcessedMap();
   850     }
   851     ///The type of the map that indicates which nodes are reached.
   852  
   853     ///The type of the map that indicates which nodes are reached.
   854     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
   855     ///\todo named parameter to set this type, function to read and write.
   856     typedef typename Graph::template NodeMap<bool> ReachedMap;
   857     ///Instantiates a ReachedMap.
   858  
   859     ///This function instantiates a \ref ReachedMap. 
   860     ///\param G is the graph, to which
   861     ///we would like to define the \ref ReachedMap.
   862     static ReachedMap *createReachedMap(const GR &G)
   863     {
   864       return new ReachedMap(G);
   865     }
   866     ///The type of the map that stores the dists of the nodes.
   867  
   868     ///The type of the map that stores the dists of the nodes.
   869     ///It must meet the \ref concept::WriteMap "WriteMap" concept.
   870     ///
   871     typedef NullMap<typename Graph::Node,int> DistMap;
   872     ///Instantiates a DistMap.
   873  
   874     ///This function instantiates a \ref DistMap. 
   875     ///\param g is the graph, to which we would like to define the \ref DistMap
   876 #ifdef DOXYGEN
   877     static DistMap *createDistMap(const GR &g)
   878 #else
   879     static DistMap *createDistMap(const GR &)
   880 #endif
   881     {
   882       return new DistMap();
   883     }
   884   };
   885   
   886   /// Default traits used by \ref DfsWizard
   887 
   888   /// To make it easier to use Dfs algorithm
   889   ///we have created a wizard class.
   890   /// This \ref DfsWizard class needs default traits,
   891   ///as well as the \ref Dfs class.
   892   /// The \ref DfsWizardBase is a class to be the default traits of the
   893   /// \ref DfsWizard class.
   894   template<class GR>
   895   class DfsWizardBase : public DfsWizardDefaultTraits<GR>
   896   {
   897 
   898     typedef DfsWizardDefaultTraits<GR> Base;
   899   protected:
   900     /// Type of the nodes in the graph.
   901     typedef typename Base::Graph::Node Node;
   902 
   903     /// Pointer to the underlying graph.
   904     void *_g;
   905     ///Pointer to the map of reached nodes.
   906     void *_reached;
   907     ///Pointer to the map of processed nodes.
   908     void *_processed;
   909     ///Pointer to the map of predecessors edges.
   910     void *_pred;
   911 //     ///Pointer to the map of predecessors nodes.
   912 //     void *_predNode;
   913     ///Pointer to the map of distances.
   914     void *_dist;
   915     ///Pointer to the source node.
   916     Node _source;
   917     
   918     public:
   919     /// Constructor.
   920     
   921     /// This constructor does not require parameters, therefore it initiates
   922     /// all of the attributes to default values (0, INVALID).
   923     DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
   924 // 			   _predNode(0),
   925 			   _dist(0), _source(INVALID) {}
   926 
   927     /// Constructor.
   928     
   929     /// This constructor requires some parameters,
   930     /// listed in the parameters list.
   931     /// Others are initiated to 0.
   932     /// \param g is the initial value of  \ref _g
   933     /// \param s is the initial value of  \ref _source
   934     DfsWizardBase(const GR &g, Node s=INVALID) :
   935       _g((void *)&g), _reached(0), _processed(0), _pred(0),
   936 //       _predNode(0),
   937       _dist(0), _source(s) {}
   938 
   939   };
   940   
   941   /// A class to make the usage of the Dfs algorithm easier
   942 
   943   /// This class is created to make it easier to use the Dfs algorithm.
   944   /// It uses the functions and features of the plain \ref Dfs,
   945   /// but it is much simpler to use it.
   946   ///
   947   /// Simplicity means that the way to change the types defined
   948   /// in the traits class is based on functions that returns the new class
   949   /// and not on templatable built-in classes.
   950   /// When using the plain \ref Dfs
   951   /// the new class with the modified type comes from
   952   /// the original class by using the ::
   953   /// operator. In the case of \ref DfsWizard only
   954   /// a function have to be called and it will
   955   /// return the needed class.
   956   ///
   957   /// It does not have own \ref run method. When its \ref run method is called
   958   /// it initiates a plain \ref Dfs object, and calls the \ref Dfs::run
   959   /// method of it.
   960   template<class TR>
   961   class DfsWizard : public TR
   962   {
   963     typedef TR Base;
   964 
   965     ///The type of the underlying graph.
   966     typedef typename TR::Graph Graph;
   967     //\e
   968     typedef typename Graph::Node Node;
   969     //\e
   970     typedef typename Graph::NodeIt NodeIt;
   971     //\e
   972     typedef typename Graph::Edge Edge;
   973     //\e
   974     typedef typename Graph::OutEdgeIt OutEdgeIt;
   975     
   976     ///\brief The type of the map that stores
   977     ///the reached nodes
   978     typedef typename TR::ReachedMap ReachedMap;
   979     ///\brief The type of the map that stores
   980     ///the processed nodes
   981     typedef typename TR::ProcessedMap ProcessedMap;
   982     ///\brief The type of the map that stores the last
   983     ///edges of the %DFS paths.
   984     typedef typename TR::PredMap PredMap;
   985 //     ///\brief The type of the map that stores the last but one
   986 //     ///nodes of the %DFS paths.
   987 //     typedef typename TR::PredNodeMap PredNodeMap;
   988     ///The type of the map that stores the distances of the nodes.
   989     typedef typename TR::DistMap DistMap;
   990 
   991 public:
   992     /// Constructor.
   993     DfsWizard() : TR() {}
   994 
   995     /// Constructor that requires parameters.
   996 
   997     /// Constructor that requires parameters.
   998     /// These parameters will be the default values for the traits class.
   999     DfsWizard(const Graph &g, Node s=INVALID) :
  1000       TR(g,s) {}
  1001 
  1002     ///Copy constructor
  1003     DfsWizard(const TR &b) : TR(b) {}
  1004 
  1005     ~DfsWizard() {}
  1006 
  1007     ///Runs Dfs algorithm from a given node.
  1008     
  1009     ///Runs Dfs algorithm from a given node.
  1010     ///The node can be given by the \ref source function.
  1011     void run()
  1012     {
  1013       if(Base::_source==INVALID) throw UninitializedParameter();
  1014       Dfs<Graph,TR> alg(*(Graph*)Base::_g);
  1015       if(Base::_reached) alg.reachedMap(*(ReachedMap*)Base::_reached);
  1016       if(Base::_processed) alg.processedMap(*(ProcessedMap*)Base::_processed);
  1017       if(Base::_pred) alg.predMap(*(PredMap*)Base::_pred);
  1018 //       if(Base::_predNode) alg.predNodeMap(*(PredNodeMap*)Base::_predNode);
  1019       if(Base::_dist) alg.distMap(*(DistMap*)Base::_dist);
  1020       alg.run(Base::_source);
  1021     }
  1022 
  1023     ///Runs Dfs algorithm from the given node.
  1024 
  1025     ///Runs Dfs algorithm from the given node.
  1026     ///\param s is the given source.
  1027     void run(Node s)
  1028     {
  1029       Base::_source=s;
  1030       run();
  1031     }
  1032 
  1033     template<class T>
  1034     struct DefPredMapBase : public Base {
  1035       typedef T PredMap;
  1036       static PredMap *createPredMap(const Graph &) { return 0; };
  1037       DefPredMapBase(const TR &b) : TR(b) {}
  1038     };
  1039     
  1040     ///\brief \ref named-templ-param "Named parameter"
  1041     ///function for setting PredMap type
  1042     ///
  1043     /// \ref named-templ-param "Named parameter"
  1044     ///function for setting PredMap type
  1045     ///
  1046     template<class T>
  1047     DfsWizard<DefPredMapBase<T> > predMap(const T &t) 
  1048     {
  1049       Base::_pred=(void *)&t;
  1050       return DfsWizard<DefPredMapBase<T> >(*this);
  1051     }
  1052     
  1053  
  1054     template<class T>
  1055     struct DefReachedMapBase : public Base {
  1056       typedef T ReachedMap;
  1057       static ReachedMap *createReachedMap(const Graph &) { return 0; };
  1058       DefReachedMapBase(const TR &b) : TR(b) {}
  1059     };
  1060     
  1061     ///\brief \ref named-templ-param "Named parameter"
  1062     ///function for setting ReachedMap
  1063     ///
  1064     /// \ref named-templ-param "Named parameter"
  1065     ///function for setting ReachedMap
  1066     ///
  1067     template<class T>
  1068     DfsWizard<DefReachedMapBase<T> > reachedMap(const T &t) 
  1069     {
  1070       Base::_pred=(void *)&t;
  1071       return DfsWizard<DefReachedMapBase<T> >(*this);
  1072     }
  1073     
  1074 
  1075     template<class T>
  1076     struct DefProcessedMapBase : public Base {
  1077       typedef T ProcessedMap;
  1078       static ProcessedMap *createProcessedMap(const Graph &) { return 0; };
  1079       DefProcessedMapBase(const TR &b) : TR(b) {}
  1080     };
  1081     
  1082     ///\brief \ref named-templ-param "Named parameter"
  1083     ///function for setting ProcessedMap
  1084     ///
  1085     /// \ref named-templ-param "Named parameter"
  1086     ///function for setting ProcessedMap
  1087     ///
  1088     template<class T>
  1089     DfsWizard<DefProcessedMapBase<T> > processedMap(const T &t) 
  1090     {
  1091       Base::_pred=(void *)&t;
  1092       return DfsWizard<DefProcessedMapBase<T> >(*this);
  1093     }
  1094     
  1095 
  1096 //     template<class T>
  1097 //     struct DefPredNodeMapBase : public Base {
  1098 //       typedef T PredNodeMap;
  1099 //       static PredNodeMap *createPredNodeMap(const Graph &G) { return 0; };
  1100 //       DefPredNodeMapBase(const TR &b) : TR(b) {}
  1101 //     };
  1102     
  1103 //     ///\brief \ref named-templ-param "Named parameter"
  1104 //     ///function for setting PredNodeMap type
  1105 //     ///
  1106 //     /// \ref named-templ-param "Named parameter"
  1107 //     ///function for setting PredNodeMap type
  1108 //     ///
  1109 //     template<class T>
  1110 //     DfsWizard<DefPredNodeMapBase<T> > predNodeMap(const T &t) 
  1111 //     {
  1112 //       Base::_predNode=(void *)&t;
  1113 //       return DfsWizard<DefPredNodeMapBase<T> >(*this);
  1114 //     }
  1115    
  1116     template<class T>
  1117     struct DefDistMapBase : public Base {
  1118       typedef T DistMap;
  1119       static DistMap *createDistMap(const Graph &) { return 0; };
  1120       DefDistMapBase(const TR &b) : TR(b) {}
  1121     };
  1122     
  1123     ///\brief \ref named-templ-param "Named parameter"
  1124     ///function for setting DistMap type
  1125     ///
  1126     /// \ref named-templ-param "Named parameter"
  1127     ///function for setting DistMap type
  1128     ///
  1129     template<class T>
  1130     DfsWizard<DefDistMapBase<T> > distMap(const T &t) 
  1131     {
  1132       Base::_dist=(void *)&t;
  1133       return DfsWizard<DefDistMapBase<T> >(*this);
  1134     }
  1135     
  1136     /// Sets the source node, from which the Dfs algorithm runs.
  1137 
  1138     /// Sets the source node, from which the Dfs algorithm runs.
  1139     /// \param s is the source node.
  1140     DfsWizard<TR> &source(Node s) 
  1141     {
  1142       Base::_source=s;
  1143       return *this;
  1144     }
  1145     
  1146   };
  1147   
  1148   ///Function type interface for Dfs algorithm.
  1149 
  1150   /// \ingroup flowalgs
  1151   ///Function type interface for Dfs algorithm.
  1152   ///
  1153   ///This function also has several
  1154   ///\ref named-templ-func-param "named parameters",
  1155   ///they are declared as the members of class \ref DfsWizard.
  1156   ///The following
  1157   ///example shows how to use these parameters.
  1158   ///\code
  1159   ///  dfs(g,source).predMap(preds).run();
  1160   ///\endcode
  1161   ///\warning Don't forget to put the \ref DfsWizard::run() "run()"
  1162   ///to the end of the parameter list.
  1163   ///\sa DfsWizard
  1164   ///\sa Dfs
  1165   template<class GR>
  1166   DfsWizard<DfsWizardBase<GR> >
  1167   dfs(const GR &g,typename GR::Node s=INVALID)
  1168   {
  1169     return DfsWizard<DfsWizardBase<GR> >(g,s);
  1170   }
  1171 
  1172 } //END OF NAMESPACE LEMON
  1173 
  1174 #endif
  1175