COIN-OR::LEMON - Graph Library

source: lemon/lemon/dfs.h @ 1243:79f149ee0230

1.1
Last change on this file since 1243:79f149ee0230 was 1126:a30455cd0107, checked in by Alpar Juttner <alpar@…>, 12 years ago

Merge Intel C++ compatibility fixes to branch 1.1

File size: 50.5 KB
RevLine 
[209]1/* -*- mode: C++; indent-tabs-mode: nil; -*-
[100]2 *
[209]3 * This file is a part of LEMON, a generic C++ optimization library.
[100]4 *
[1081]5 * Copyright (C) 2003-2011
[100]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_DFS_H
20#define LEMON_DFS_H
21
22///\ingroup search
23///\file
[244]24///\brief DFS algorithm.
[100]25
26#include <lemon/list_graph.h>
27#include <lemon/bits/path_dump.h>
[220]28#include <lemon/core.h>
[100]29#include <lemon/error.h>
30#include <lemon/maps.h>
[278]31#include <lemon/path.h>
[100]32
33namespace lemon {
34
35  ///Default traits class of Dfs class.
36
37  ///Default traits class of Dfs class.
[157]38  ///\tparam GR Digraph type.
[100]39  template<class GR>
40  struct DfsDefaultTraits
41  {
[244]42    ///The type of the digraph the algorithm runs on.
[100]43    typedef GR Digraph;
[244]44
45    ///\brief The type of the map that stores the predecessor
[100]46    ///arcs of the %DFS paths.
[209]47    ///
[244]48    ///The type of the map that stores the predecessor
[100]49    ///arcs of the %DFS paths.
50    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
[244]51    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
[525]52    ///Instantiates a \c PredMap.
[209]53
[525]54    ///This function instantiates a \ref PredMap.
[244]55    ///\param g is the digraph, to which we would like to define the
[525]56    ///\ref PredMap.
[244]57    static PredMap *createPredMap(const Digraph &g)
[100]58    {
[244]59      return new PredMap(g);
[100]60    }
61
62    ///The type of the map that indicates which nodes are processed.
[209]63
[100]64    ///The type of the map that indicates which nodes are processed.
65    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
66    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
[525]67    ///Instantiates a \c ProcessedMap.
[209]68
[525]69    ///This function instantiates a \ref ProcessedMap.
[100]70    ///\param g is the digraph, to which
[525]71    ///we would like to define the \ref ProcessedMap.
[100]72#ifdef DOXYGEN
[244]73    static ProcessedMap *createProcessedMap(const Digraph &g)
[100]74#else
[244]75    static ProcessedMap *createProcessedMap(const Digraph &)
[100]76#endif
77    {
78      return new ProcessedMap();
79    }
[244]80
[100]81    ///The type of the map that indicates which nodes are reached.
[209]82
[100]83    ///The type of the map that indicates which nodes are reached.
[244]84    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
[100]85    typedef typename Digraph::template NodeMap<bool> ReachedMap;
[525]86    ///Instantiates a \c ReachedMap.
[209]87
[525]88    ///This function instantiates a \ref ReachedMap.
[244]89    ///\param g is the digraph, to which
[525]90    ///we would like to define the \ref ReachedMap.
[244]91    static ReachedMap *createReachedMap(const Digraph &g)
[100]92    {
[244]93      return new ReachedMap(g);
[100]94    }
[209]95
[244]96    ///The type of the map that stores the distances of the nodes.
97
98    ///The type of the map that stores the distances of the nodes.
[100]99    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
100    typedef typename Digraph::template NodeMap<int> DistMap;
[525]101    ///Instantiates a \c DistMap.
[209]102
[525]103    ///This function instantiates a \ref DistMap.
[244]104    ///\param g is the digraph, to which we would like to define the
[525]105    ///\ref DistMap.
[244]106    static DistMap *createDistMap(const Digraph &g)
[100]107    {
[244]108      return new DistMap(g);
[100]109    }
110  };
[209]111
[100]112  ///%DFS algorithm class.
[209]113
[100]114  ///\ingroup search
115  ///This class provides an efficient implementation of the %DFS algorithm.
116  ///
[278]117  ///There is also a \ref dfs() "function-type interface" for the DFS
[244]118  ///algorithm, which is convenient in the simplier cases and it can be
119  ///used easier.
120  ///
121  ///\tparam GR The type of the digraph the algorithm runs on.
[421]122  ///The default type is \ref ListDigraph.
[100]123#ifdef DOXYGEN
124  template <typename GR,
[209]125            typename TR>
[100]126#else
127  template <typename GR=ListDigraph,
[209]128            typename TR=DfsDefaultTraits<GR> >
[100]129#endif
130  class Dfs {
131  public:
132
[244]133    ///The type of the digraph the algorithm runs on.
134    typedef typename TR::Digraph Digraph;
135
136    ///\brief The type of the map that stores the predecessor arcs of the
137    ///DFS paths.
138    typedef typename TR::PredMap PredMap;
139    ///The type of the map that stores the distances of the nodes.
140    typedef typename TR::DistMap DistMap;
141    ///The type of the map that indicates which nodes are reached.
142    typedef typename TR::ReachedMap ReachedMap;
143    ///The type of the map that indicates which nodes are processed.
144    typedef typename TR::ProcessedMap ProcessedMap;
145    ///The type of the paths.
146    typedef PredMapPath<Digraph, PredMap> Path;
147
[421]148    ///The \ref DfsDefaultTraits "traits class" of the algorithm.
[100]149    typedef TR Traits;
[244]150
151  private:
152
[100]153    typedef typename Digraph::Node Node;
154    typedef typename Digraph::NodeIt NodeIt;
155    typedef typename Digraph::Arc Arc;
156    typedef typename Digraph::OutArcIt OutArcIt;
[209]157
[244]158    //Pointer to the underlying digraph.
[100]159    const Digraph *G;
[244]160    //Pointer to the map of predecessor arcs.
[100]161    PredMap *_pred;
[244]162    //Indicates if _pred is locally allocated (true) or not.
[100]163    bool local_pred;
[244]164    //Pointer to the map of distances.
[100]165    DistMap *_dist;
[244]166    //Indicates if _dist is locally allocated (true) or not.
[100]167    bool local_dist;
[244]168    //Pointer to the map of reached status of the nodes.
[100]169    ReachedMap *_reached;
[244]170    //Indicates if _reached is locally allocated (true) or not.
[100]171    bool local_reached;
[244]172    //Pointer to the map of processed status of the nodes.
[100]173    ProcessedMap *_processed;
[244]174    //Indicates if _processed is locally allocated (true) or not.
[100]175    bool local_processed;
176
177    std::vector<typename Digraph::OutArcIt> _stack;
178    int _stack_head;
179
[280]180    //Creates the maps if necessary.
[209]181    void create_maps()
[100]182    {
183      if(!_pred) {
[209]184        local_pred = true;
185        _pred = Traits::createPredMap(*G);
[100]186      }
187      if(!_dist) {
[209]188        local_dist = true;
189        _dist = Traits::createDistMap(*G);
[100]190      }
191      if(!_reached) {
[209]192        local_reached = true;
193        _reached = Traits::createReachedMap(*G);
[100]194      }
195      if(!_processed) {
[209]196        local_processed = true;
197        _processed = Traits::createProcessedMap(*G);
[100]198      }
199    }
200
201  protected:
202
203    Dfs() {}
[209]204
[100]205  public:
206
207    typedef Dfs Create;
208
[631]209    ///\name Named Template Parameters
[100]210
211    ///@{
212
213    template <class T>
[257]214    struct SetPredMapTraits : public Traits {
[100]215      typedef T PredMap;
[244]216      static PredMap *createPredMap(const Digraph &)
[100]217      {
[290]218        LEMON_ASSERT(false, "PredMap is not initialized");
219        return 0; // ignore warnings
[100]220      }
221    };
222    ///\brief \ref named-templ-param "Named parameter" for setting
[525]223    ///\c PredMap type.
[100]224    ///
[244]225    ///\ref named-templ-param "Named parameter" for setting
[525]226    ///\c PredMap type.
[421]227    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
[100]228    template <class T>
[257]229    struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
230      typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
[100]231    };
[209]232
[100]233    template <class T>
[257]234    struct SetDistMapTraits : public Traits {
[100]235      typedef T DistMap;
[209]236      static DistMap *createDistMap(const Digraph &)
[100]237      {
[290]238        LEMON_ASSERT(false, "DistMap is not initialized");
239        return 0; // ignore warnings
[100]240      }
241    };
242    ///\brief \ref named-templ-param "Named parameter" for setting
[525]243    ///\c DistMap type.
[100]244    ///
[244]245    ///\ref named-templ-param "Named parameter" for setting
[525]246    ///\c DistMap type.
[421]247    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
[100]248    template <class T>
[257]249    struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
250      typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
[100]251    };
[209]252
[100]253    template <class T>
[257]254    struct SetReachedMapTraits : public Traits {
[100]255      typedef T ReachedMap;
[209]256      static ReachedMap *createReachedMap(const Digraph &)
[100]257      {
[290]258        LEMON_ASSERT(false, "ReachedMap is not initialized");
259        return 0; // ignore warnings
[100]260      }
261    };
262    ///\brief \ref named-templ-param "Named parameter" for setting
[525]263    ///\c ReachedMap type.
[100]264    ///
[244]265    ///\ref named-templ-param "Named parameter" for setting
[525]266    ///\c ReachedMap type.
[421]267    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
[100]268    template <class T>
[257]269    struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
270      typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
[100]271    };
272
273    template <class T>
[257]274    struct SetProcessedMapTraits : public Traits {
[100]275      typedef T ProcessedMap;
[209]276      static ProcessedMap *createProcessedMap(const Digraph &)
[100]277      {
[290]278        LEMON_ASSERT(false, "ProcessedMap is not initialized");
279        return 0; // ignore warnings
[100]280      }
281    };
282    ///\brief \ref named-templ-param "Named parameter" for setting
[525]283    ///\c ProcessedMap type.
[100]284    ///
[244]285    ///\ref named-templ-param "Named parameter" for setting
[525]286    ///\c ProcessedMap type.
[421]287    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
[100]288    template <class T>
[257]289    struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
290      typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
[100]291    };
[209]292
[257]293    struct SetStandardProcessedMapTraits : public Traits {
[100]294      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
[244]295      static ProcessedMap *createProcessedMap(const Digraph &g)
[100]296      {
[244]297        return new ProcessedMap(g);
[100]298      }
299    };
[244]300    ///\brief \ref named-templ-param "Named parameter" for setting
[525]301    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
[100]302    ///
[244]303    ///\ref named-templ-param "Named parameter" for setting
[525]304    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
[244]305    ///If you don't set it explicitly, it will be automatically allocated.
[257]306    struct SetStandardProcessedMap :
307      public Dfs< Digraph, SetStandardProcessedMapTraits > {
308      typedef Dfs< Digraph, SetStandardProcessedMapTraits > Create;
[100]309    };
[209]310
[100]311    ///@}
312
[209]313  public:
314
[100]315    ///Constructor.
[209]316
[244]317    ///Constructor.
318    ///\param g The digraph the algorithm runs on.
319    Dfs(const Digraph &g) :
320      G(&g),
[100]321      _pred(NULL), local_pred(false),
322      _dist(NULL), local_dist(false),
323      _reached(NULL), local_reached(false),
324      _processed(NULL), local_processed(false)
325    { }
[209]326
[100]327    ///Destructor.
[209]328    ~Dfs()
[100]329    {
330      if(local_pred) delete _pred;
331      if(local_dist) delete _dist;
332      if(local_reached) delete _reached;
333      if(local_processed) delete _processed;
334    }
335
[244]336    ///Sets the map that stores the predecessor arcs.
[100]337
[244]338    ///Sets the map that stores the predecessor arcs.
[421]339    ///If you don't use this function before calling \ref run(Node) "run()"
340    ///or \ref init(), an instance will be allocated automatically.
341    ///The destructor deallocates this automatically allocated map,
342    ///of course.
[100]343    ///\return <tt> (*this) </tt>
[209]344    Dfs &predMap(PredMap &m)
[100]345    {
346      if(local_pred) {
[209]347        delete _pred;
348        local_pred=false;
[100]349      }
350      _pred = &m;
351      return *this;
352    }
353
[244]354    ///Sets the map that indicates which nodes are reached.
[100]355
[244]356    ///Sets the map that indicates which nodes are reached.
[421]357    ///If you don't use this function before calling \ref run(Node) "run()"
358    ///or \ref init(), an instance will be allocated automatically.
359    ///The destructor deallocates this automatically allocated map,
360    ///of course.
[244]361    ///\return <tt> (*this) </tt>
362    Dfs &reachedMap(ReachedMap &m)
363    {
364      if(local_reached) {
365        delete _reached;
366        local_reached=false;
367      }
368      _reached = &m;
369      return *this;
370    }
371
372    ///Sets the map that indicates which nodes are processed.
373
374    ///Sets the map that indicates which nodes are processed.
[421]375    ///If you don't use this function before calling \ref run(Node) "run()"
376    ///or \ref init(), an instance will be allocated automatically.
377    ///The destructor deallocates this automatically allocated map,
378    ///of course.
[244]379    ///\return <tt> (*this) </tt>
380    Dfs &processedMap(ProcessedMap &m)
381    {
382      if(local_processed) {
383        delete _processed;
384        local_processed=false;
385      }
386      _processed = &m;
387      return *this;
388    }
389
390    ///Sets the map that stores the distances of the nodes.
391
392    ///Sets the map that stores the distances of the nodes calculated by
393    ///the algorithm.
[421]394    ///If you don't use this function before calling \ref run(Node) "run()"
395    ///or \ref init(), an instance will be allocated automatically.
396    ///The destructor deallocates this automatically allocated map,
397    ///of course.
[100]398    ///\return <tt> (*this) </tt>
[209]399    Dfs &distMap(DistMap &m)
[100]400    {
401      if(local_dist) {
[209]402        delete _dist;
403        local_dist=false;
[100]404      }
405      _dist = &m;
406      return *this;
407    }
408
[244]409  public:
[100]410
[421]411    ///\name Execution Control
412    ///The simplest way to execute the DFS algorithm is to use one of the
413    ///member functions called \ref run(Node) "run()".\n
414    ///If you need more control on the execution, first you have to call
415    ///\ref init(), then you can add a source node with \ref addSource()
416    ///and perform the actual computation with \ref start().
417    ///This procedure can be repeated if there are nodes that have not
418    ///been reached.
[100]419
420    ///@{
421
[421]422    ///\brief Initializes the internal data structures.
423    ///
[100]424    ///Initializes the internal data structures.
425    void init()
426    {
427      create_maps();
428      _stack.resize(countNodes(*G));
429      _stack_head=-1;
430      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
[209]431        _pred->set(u,INVALID);
432        _reached->set(u,false);
433        _processed->set(u,false);
[100]434      }
435    }
[209]436
[100]437    ///Adds a new source node.
438
439    ///Adds a new source node to the set of nodes to be processed.
440    ///
[421]441    ///\pre The stack must be empty. Otherwise the algorithm gives
442    ///wrong results. (One of the outgoing arcs of all the source nodes
443    ///except for the last one will not be visited and distances will
444    ///also be wrong.)
[100]445    void addSource(Node s)
446    {
[244]447      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
[100]448      if(!(*_reached)[s])
[209]449        {
450          _reached->set(s,true);
451          _pred->set(s,INVALID);
452          OutArcIt e(*G,s);
453          if(e!=INVALID) {
454            _stack[++_stack_head]=e;
455            _dist->set(s,_stack_head);
456          }
457          else {
458            _processed->set(s,true);
459            _dist->set(s,0);
460          }
461        }
[100]462    }
[209]463
[100]464    ///Processes the next arc.
465
466    ///Processes the next arc.
467    ///
468    ///\return The processed arc.
469    ///
[244]470    ///\pre The stack must not be empty.
[100]471    Arc processNextArc()
[209]472    {
[100]473      Node m;
474      Arc e=_stack[_stack_head];
475      if(!(*_reached)[m=G->target(e)]) {
[209]476        _pred->set(m,e);
477        _reached->set(m,true);
478        ++_stack_head;
479        _stack[_stack_head] = OutArcIt(*G, m);
480        _dist->set(m,_stack_head);
[100]481      }
482      else {
[209]483        m=G->source(e);
484        ++_stack[_stack_head];
[100]485      }
486      while(_stack_head>=0 && _stack[_stack_head]==INVALID) {
[209]487        _processed->set(m,true);
488        --_stack_head;
489        if(_stack_head>=0) {
490          m=G->source(_stack[_stack_head]);
491          ++_stack[_stack_head];
492        }
[100]493      }
494      return e;
495    }
[244]496
[100]497    ///Next arc to be processed.
498
499    ///Next arc to be processed.
500    ///
[244]501    ///\return The next arc to be processed or \c INVALID if the stack
502    ///is empty.
503    OutArcIt nextArc() const
[209]504    {
[100]505      return _stack_head>=0?_stack[_stack_head]:INVALID;
506    }
507
[421]508    ///Returns \c false if there are nodes to be processed.
509
510    ///Returns \c false if there are nodes to be processed
511    ///in the queue (stack).
[244]512    bool emptyQueue() const { return _stack_head<0; }
513
[100]514    ///Returns the number of the nodes to be processed.
[209]515
[421]516    ///Returns the number of the nodes to be processed
517    ///in the queue (stack).
[244]518    int queueSize() const { return _stack_head+1; }
[209]519
[100]520    ///Executes the algorithm.
521
522    ///Executes the algorithm.
523    ///
[244]524    ///This method runs the %DFS algorithm from the root node
525    ///in order to compute the DFS path to each node.
[100]526    ///
[244]527    /// The algorithm computes
528    ///- the %DFS tree,
529    ///- the distance of each node from the root in the %DFS tree.
[100]530    ///
[244]531    ///\pre init() must be called and a root node should be
532    ///added with addSource() before using this function.
533    ///
534    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
535    ///\code
536    ///  while ( !d.emptyQueue() ) {
537    ///    d.processNextArc();
538    ///  }
539    ///\endcode
[100]540    void start()
541    {
542      while ( !emptyQueue() ) processNextArc();
543    }
[209]544
[244]545    ///Executes the algorithm until the given target node is reached.
[100]546
[244]547    ///Executes the algorithm until the given target node is reached.
[100]548    ///
[244]549    ///This method runs the %DFS algorithm from the root node
[286]550    ///in order to compute the DFS path to \c t.
[100]551    ///
[244]552    ///The algorithm computes
[286]553    ///- the %DFS path to \c t,
554    ///- the distance of \c t from the root in the %DFS tree.
[100]555    ///
[244]556    ///\pre init() must be called and a root node should be
557    ///added with addSource() before using this function.
[286]558    void start(Node t)
[100]559    {
[1007]560      while ( !emptyQueue() && !(*_reached)[t] )
[209]561        processNextArc();
[100]562    }
[209]563
[100]564    ///Executes the algorithm until a condition is met.
565
566    ///Executes the algorithm until a condition is met.
567    ///
[244]568    ///This method runs the %DFS algorithm from the root node
569    ///until an arc \c a with <tt>am[a]</tt> true is found.
[100]570    ///
[244]571    ///\param am A \c bool (or convertible) arc map. The algorithm
572    ///will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
[100]573    ///
[244]574    ///\return The reached arc \c a with <tt>am[a]</tt> true or
[100]575    ///\c INVALID if no such arc was found.
576    ///
[244]577    ///\pre init() must be called and a root node should be
578    ///added with addSource() before using this function.
579    ///
580    ///\warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
[100]581    ///not a node map.
[244]582    template<class ArcBoolMap>
583    Arc start(const ArcBoolMap &am)
[100]584    {
[244]585      while ( !emptyQueue() && !am[_stack[_stack_head]] )
[100]586        processNextArc();
587      return emptyQueue() ? INVALID : _stack[_stack_head];
588    }
589
[286]590    ///Runs the algorithm from the given source node.
[209]591
[244]592    ///This method runs the %DFS algorithm from node \c s
593    ///in order to compute the DFS path to each node.
[100]594    ///
[244]595    ///The algorithm computes
596    ///- the %DFS tree,
597    ///- the distance of each node from the root in the %DFS tree.
598    ///
599    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
[100]600    ///\code
601    ///  d.init();
[244]602    ///  d.addSource(s);
603    ///  d.start();
604    ///\endcode
605    void run(Node s) {
606      init();
607      addSource(s);
608      start();
609    }
610
611    ///Finds the %DFS path between \c s and \c t.
612
613    ///This method runs the %DFS algorithm from node \c s
[286]614    ///in order to compute the DFS path to node \c t
615    ///(it stops searching when \c t is processed)
[244]616    ///
[286]617    ///\return \c true if \c t is reachable form \c s.
[244]618    ///
619    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is
620    ///just a shortcut of the following code.
621    ///\code
622    ///  d.init();
623    ///  d.addSource(s);
624    ///  d.start(t);
625    ///\endcode
[286]626    bool run(Node s,Node t) {
[244]627      init();
628      addSource(s);
629      start(t);
[286]630      return reached(t);
[244]631    }
632
633    ///Runs the algorithm to visit all nodes in the digraph.
634
635    ///This method runs the %DFS algorithm in order to compute the
636    ///%DFS path to each node.
637    ///
638    ///The algorithm computes
[421]639    ///- the %DFS tree (forest),
640    ///- the distance of each node from the root(s) in the %DFS tree.
[244]641    ///
642    ///\note <tt>d.run()</tt> is just a shortcut of the following code.
643    ///\code
644    ///  d.init();
645    ///  for (NodeIt n(digraph); n != INVALID; ++n) {
646    ///    if (!d.reached(n)) {
647    ///      d.addSource(n);
[100]648    ///      d.start();
649    ///    }
650    ///  }
651    ///\endcode
652    void run() {
653      init();
654      for (NodeIt it(*G); it != INVALID; ++it) {
655        if (!reached(it)) {
656          addSource(it);
657          start();
658        }
659      }
660    }
661
662    ///@}
663
664    ///\name Query Functions
[421]665    ///The results of the DFS algorithm can be obtained using these
[100]666    ///functions.\n
[421]667    ///Either \ref run(Node) "run()" or \ref start() should be called
668    ///before using them.
[209]669
[100]670    ///@{
671
[244]672    ///The DFS path to a node.
[100]673
[244]674    ///Returns the DFS path to a node.
675    ///
[421]676    ///\warning \c t should be reached from the root(s).
[244]677    ///
[421]678    ///\pre Either \ref run(Node) "run()" or \ref init()
679    ///must be called before using this function.
[244]680    Path path(Node t) const { return Path(*G, *_pred, t); }
[209]681
[421]682    ///The distance of a node from the root(s).
[100]683
[421]684    ///Returns the distance of a node from the root(s).
[244]685    ///
[421]686    ///\warning If node \c v is not reached from the root(s), then
[244]687    ///the return value of this function is undefined.
688    ///
[421]689    ///\pre Either \ref run(Node) "run()" or \ref init()
690    ///must be called before using this function.
[100]691    int dist(Node v) const { return (*_dist)[v]; }
692
[244]693    ///Returns the 'previous arc' of the %DFS tree for a node.
[100]694
[244]695    ///This function returns the 'previous arc' of the %DFS tree for the
[421]696    ///node \c v, i.e. it returns the last arc of a %DFS path from a
697    ///root to \c v. It is \c INVALID if \c v is not reached from the
698    ///root(s) or if \c v is a root.
[244]699    ///
700    ///The %DFS tree used here is equal to the %DFS tree used in
[100]701    ///\ref predNode().
[244]702    ///
[421]703    ///\pre Either \ref run(Node) "run()" or \ref init()
704    ///must be called before using this function.
[100]705    Arc predArc(Node v) const { return (*_pred)[v];}
706
707    ///Returns the 'previous node' of the %DFS tree.
708
[244]709    ///This function returns the 'previous node' of the %DFS
710    ///tree for the node \c v, i.e. it returns the last but one node
[421]711    ///from a %DFS path from a root to \c v. It is \c INVALID
712    ///if \c v is not reached from the root(s) or if \c v is a root.
[244]713    ///
714    ///The %DFS tree used here is equal to the %DFS tree used in
715    ///\ref predArc().
716    ///
[421]717    ///\pre Either \ref run(Node) "run()" or \ref init()
718    ///must be called before using this function.
[100]719    Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
[209]720                                  G->source((*_pred)[v]); }
721
[244]722    ///\brief Returns a const reference to the node map that stores the
723    ///distances of the nodes.
724    ///
725    ///Returns a const reference to the node map that stores the
726    ///distances of the nodes calculated by the algorithm.
727    ///
[421]728    ///\pre Either \ref run(Node) "run()" or \ref init()
[244]729    ///must be called before using this function.
[100]730    const DistMap &distMap() const { return *_dist;}
[209]731
[244]732    ///\brief Returns a const reference to the node map that stores the
733    ///predecessor arcs.
734    ///
735    ///Returns a const reference to the node map that stores the predecessor
736    ///arcs, which form the DFS tree.
737    ///
[421]738    ///\pre Either \ref run(Node) "run()" or \ref init()
[100]739    ///must be called before using this function.
740    const PredMap &predMap() const { return *_pred;}
[209]741
[421]742    ///Checks if a node is reached from the root(s).
[100]743
[421]744    ///Returns \c true if \c v is reached from the root(s).
745    ///
746    ///\pre Either \ref run(Node) "run()" or \ref init()
[100]747    ///must be called before using this function.
[244]748    bool reached(Node v) const { return (*_reached)[v]; }
[209]749
[100]750    ///@}
751  };
752
[244]753  ///Default traits class of dfs() function.
[100]754
[244]755  ///Default traits class of dfs() function.
[157]756  ///\tparam GR Digraph type.
[100]757  template<class GR>
758  struct DfsWizardDefaultTraits
759  {
[244]760    ///The type of the digraph the algorithm runs on.
[100]761    typedef GR Digraph;
[244]762
763    ///\brief The type of the map that stores the predecessor
[100]764    ///arcs of the %DFS paths.
[209]765    ///
[244]766    ///The type of the map that stores the predecessor
[100]767    ///arcs of the %DFS paths.
768    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
[278]769    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
[301]770    ///Instantiates a PredMap.
[209]771
[301]772    ///This function instantiates a PredMap.
[244]773    ///\param g is the digraph, to which we would like to define the
[301]774    ///PredMap.
[244]775    static PredMap *createPredMap(const Digraph &g)
[100]776    {
[278]777      return new PredMap(g);
[100]778    }
779
780    ///The type of the map that indicates which nodes are processed.
[209]781
[100]782    ///The type of the map that indicates which nodes are processed.
783    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
[278]784    ///By default it is a NullMap.
[100]785    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
[301]786    ///Instantiates a ProcessedMap.
[209]787
[301]788    ///This function instantiates a ProcessedMap.
[100]789    ///\param g is the digraph, to which
[301]790    ///we would like to define the ProcessedMap.
[100]791#ifdef DOXYGEN
[244]792    static ProcessedMap *createProcessedMap(const Digraph &g)
[100]793#else
[244]794    static ProcessedMap *createProcessedMap(const Digraph &)
[100]795#endif
796    {
797      return new ProcessedMap();
798    }
[244]799
[100]800    ///The type of the map that indicates which nodes are reached.
[209]801
[100]802    ///The type of the map that indicates which nodes are reached.
[244]803    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
[100]804    typedef typename Digraph::template NodeMap<bool> ReachedMap;
[301]805    ///Instantiates a ReachedMap.
[209]806
[301]807    ///This function instantiates a ReachedMap.
[244]808    ///\param g is the digraph, to which
[301]809    ///we would like to define the ReachedMap.
[244]810    static ReachedMap *createReachedMap(const Digraph &g)
[100]811    {
[244]812      return new ReachedMap(g);
[100]813    }
[209]814
[244]815    ///The type of the map that stores the distances of the nodes.
816
817    ///The type of the map that stores the distances of the nodes.
[100]818    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
[278]819    typedef typename Digraph::template NodeMap<int> DistMap;
[301]820    ///Instantiates a DistMap.
[209]821
[301]822    ///This function instantiates a DistMap.
[210]823    ///\param g is the digraph, to which we would like to define
[301]824    ///the DistMap
[244]825    static DistMap *createDistMap(const Digraph &g)
[100]826    {
[278]827      return new DistMap(g);
[100]828    }
[278]829
830    ///The type of the DFS paths.
831
832    ///The type of the DFS paths.
833    ///It must meet the \ref concepts::Path "Path" concept.
834    typedef lemon::Path<Digraph> Path;
[100]835  };
[209]836
[313]837  /// Default traits class used by DfsWizard
[100]838
839  /// To make it easier to use Dfs algorithm
[244]840  /// we have created a wizard class.
[100]841  /// This \ref DfsWizard class needs default traits,
[244]842  /// as well as the \ref Dfs class.
[100]843  /// The \ref DfsWizardBase is a class to be the default traits of the
844  /// \ref DfsWizard class.
845  template<class GR>
846  class DfsWizardBase : public DfsWizardDefaultTraits<GR>
847  {
848
849    typedef DfsWizardDefaultTraits<GR> Base;
850  protected:
[244]851    //The type of the nodes in the digraph.
[100]852    typedef typename Base::Digraph::Node Node;
853
[244]854    //Pointer to the digraph the algorithm runs on.
[100]855    void *_g;
[244]856    //Pointer to the map of reached nodes.
[100]857    void *_reached;
[244]858    //Pointer to the map of processed nodes.
[100]859    void *_processed;
[244]860    //Pointer to the map of predecessors arcs.
[100]861    void *_pred;
[244]862    //Pointer to the map of distances.
[100]863    void *_dist;
[278]864    //Pointer to the DFS path to the target node.
865    void *_path;
866    //Pointer to the distance of the target node.
867    int *_di;
[209]868
[100]869    public:
870    /// Constructor.
[209]871
[100]872    /// This constructor does not require parameters, therefore it initiates
[278]873    /// all of the attributes to \c 0.
[100]874    DfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
[278]875                      _dist(0), _path(0), _di(0) {}
[100]876
877    /// Constructor.
[209]878
[278]879    /// This constructor requires one parameter,
880    /// others are initiated to \c 0.
[244]881    /// \param g The digraph the algorithm runs on.
[278]882    DfsWizardBase(const GR &g) :
[209]883      _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
[278]884      _reached(0), _processed(0), _pred(0), _dist(0),  _path(0), _di(0) {}
[100]885
886  };
[209]887
[278]888  /// Auxiliary class for the function-type interface of DFS algorithm.
[100]889
[278]890  /// This auxiliary class is created to implement the
891  /// \ref dfs() "function-type interface" of \ref Dfs algorithm.
[421]892  /// It does not have own \ref run(Node) "run()" method, it uses the
893  /// functions and features of the plain \ref Dfs.
[100]894  ///
[278]895  /// This class should only be used through the \ref dfs() function,
896  /// which makes it easier to use the algorithm.
[100]897  template<class TR>
898  class DfsWizard : public TR
899  {
900    typedef TR Base;
901
[244]902    ///The type of the digraph the algorithm runs on.
[100]903    typedef typename TR::Digraph Digraph;
[244]904
[100]905    typedef typename Digraph::Node Node;
906    typedef typename Digraph::NodeIt NodeIt;
907    typedef typename Digraph::Arc Arc;
908    typedef typename Digraph::OutArcIt OutArcIt;
[209]909
[244]910    ///\brief The type of the map that stores the predecessor
[278]911    ///arcs of the DFS paths.
[244]912    typedef typename TR::PredMap PredMap;
913    ///\brief The type of the map that stores the distances of the nodes.
914    typedef typename TR::DistMap DistMap;
915    ///\brief The type of the map that indicates which nodes are reached.
[100]916    typedef typename TR::ReachedMap ReachedMap;
[244]917    ///\brief The type of the map that indicates which nodes are processed.
[100]918    typedef typename TR::ProcessedMap ProcessedMap;
[278]919    ///The type of the DFS paths
920    typedef typename TR::Path Path;
[100]921
922  public:
[244]923
[100]924    /// Constructor.
925    DfsWizard() : TR() {}
926
927    /// Constructor that requires parameters.
928
929    /// Constructor that requires parameters.
930    /// These parameters will be the default values for the traits class.
[278]931    /// \param g The digraph the algorithm runs on.
932    DfsWizard(const Digraph &g) :
933      TR(g) {}
[100]934
935    ///Copy constructor
936    DfsWizard(const TR &b) : TR(b) {}
937
938    ~DfsWizard() {}
939
[278]940    ///Runs DFS algorithm from the given source node.
[209]941
[278]942    ///This method runs DFS algorithm from node \c s
943    ///in order to compute the DFS path to each node.
944    void run(Node s)
945    {
946      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
947      if (Base::_pred)
948        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
949      if (Base::_dist)
950        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
951      if (Base::_reached)
952        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
953      if (Base::_processed)
954        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
955      if (s!=INVALID)
956        alg.run(s);
957      else
958        alg.run();
959    }
960
961    ///Finds the DFS path between \c s and \c t.
962
963    ///This method runs DFS algorithm from node \c s
964    ///in order to compute the DFS path to node \c t
965    ///(it stops searching when \c t is processed).
966    ///
967    ///\return \c true if \c t is reachable form \c s.
968    bool run(Node s, Node t)
969    {
970      Dfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
971      if (Base::_pred)
972        alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
973      if (Base::_dist)
974        alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
975      if (Base::_reached)
976        alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
977      if (Base::_processed)
978        alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
979      alg.run(s,t);
980      if (Base::_path)
981        *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
982      if (Base::_di)
983        *Base::_di = alg.dist(t);
984      return alg.reached(t);
985      }
986
987    ///Runs DFS algorithm to visit all nodes in the digraph.
988
989    ///This method runs DFS algorithm in order to compute
990    ///the DFS path to each node.
[100]991    void run()
992    {
[278]993      run(INVALID);
[244]994    }
995
[100]996    template<class T>
[257]997    struct SetPredMapBase : public Base {
[100]998      typedef T PredMap;
999      static PredMap *createPredMap(const Digraph &) { return 0; };
[257]1000      SetPredMapBase(const TR &b) : TR(b) {}
[100]1001    };
[278]1002    ///\brief \ref named-func-param "Named parameter"
[301]1003    ///for setting PredMap object.
[100]1004    ///
[278]1005    ///\ref named-func-param "Named parameter"
[301]1006    ///for setting PredMap object.
[100]1007    template<class T>
[257]1008    DfsWizard<SetPredMapBase<T> > predMap(const T &t)
[100]1009    {
1010      Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
[257]1011      return DfsWizard<SetPredMapBase<T> >(*this);
[100]1012    }
[209]1013
[100]1014    template<class T>
[257]1015    struct SetReachedMapBase : public Base {
[100]1016      typedef T ReachedMap;
1017      static ReachedMap *createReachedMap(const Digraph &) { return 0; };
[257]1018      SetReachedMapBase(const TR &b) : TR(b) {}
[100]1019    };
[278]1020    ///\brief \ref named-func-param "Named parameter"
[301]1021    ///for setting ReachedMap object.
[100]1022    ///
[278]1023    /// \ref named-func-param "Named parameter"
[301]1024    ///for setting ReachedMap object.
[100]1025    template<class T>
[257]1026    DfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
[100]1027    {
[158]1028      Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
[257]1029      return DfsWizard<SetReachedMapBase<T> >(*this);
[100]1030    }
[209]1031
[100]1032    template<class T>
[278]1033    struct SetDistMapBase : public Base {
1034      typedef T DistMap;
1035      static DistMap *createDistMap(const Digraph &) { return 0; };
1036      SetDistMapBase(const TR &b) : TR(b) {}
1037    };
1038    ///\brief \ref named-func-param "Named parameter"
[301]1039    ///for setting DistMap object.
[278]1040    ///
1041    /// \ref named-func-param "Named parameter"
[301]1042    ///for setting DistMap object.
[278]1043    template<class T>
1044    DfsWizard<SetDistMapBase<T> > distMap(const T &t)
1045    {
1046      Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
1047      return DfsWizard<SetDistMapBase<T> >(*this);
1048    }
1049
1050    template<class T>
[257]1051    struct SetProcessedMapBase : public Base {
[100]1052      typedef T ProcessedMap;
1053      static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
[257]1054      SetProcessedMapBase(const TR &b) : TR(b) {}
[100]1055    };
[278]1056    ///\brief \ref named-func-param "Named parameter"
[301]1057    ///for setting ProcessedMap object.
[100]1058    ///
[278]1059    /// \ref named-func-param "Named parameter"
[301]1060    ///for setting ProcessedMap object.
[100]1061    template<class T>
[257]1062    DfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
[100]1063    {
[158]1064      Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
[257]1065      return DfsWizard<SetProcessedMapBase<T> >(*this);
[100]1066    }
[209]1067
[100]1068    template<class T>
[278]1069    struct SetPathBase : public Base {
1070      typedef T Path;
1071      SetPathBase(const TR &b) : TR(b) {}
[100]1072    };
[278]1073    ///\brief \ref named-func-param "Named parameter"
1074    ///for getting the DFS path to the target node.
[100]1075    ///
[278]1076    ///\ref named-func-param "Named parameter"
1077    ///for getting the DFS path to the target node.
[100]1078    template<class T>
[278]1079    DfsWizard<SetPathBase<T> > path(const T &t)
[100]1080    {
[278]1081      Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
1082      return DfsWizard<SetPathBase<T> >(*this);
1083    }
1084
1085    ///\brief \ref named-func-param "Named parameter"
1086    ///for getting the distance of the target node.
1087    ///
1088    ///\ref named-func-param "Named parameter"
1089    ///for getting the distance of the target node.
1090    DfsWizard dist(const int &d)
1091    {
1092      Base::_di=const_cast<int*>(&d);
1093      return *this;
[100]1094    }
[209]1095
[100]1096  };
[209]1097
[278]1098  ///Function-type interface for DFS algorithm.
[100]1099
1100  ///\ingroup search
[278]1101  ///Function-type interface for DFS algorithm.
[100]1102  ///
[278]1103  ///This function also has several \ref named-func-param "named parameters",
[100]1104  ///they are declared as the members of class \ref DfsWizard.
[278]1105  ///The following examples show how to use these parameters.
[100]1106  ///\code
[278]1107  ///  // Compute the DFS tree
1108  ///  dfs(g).predMap(preds).distMap(dists).run(s);
1109  ///
1110  ///  // Compute the DFS path from s to t
1111  ///  bool reached = dfs(g).path(p).dist(d).run(s,t);
[100]1112  ///\endcode
[421]1113  ///\warning Don't forget to put the \ref DfsWizard::run(Node) "run()"
[100]1114  ///to the end of the parameter list.
1115  ///\sa DfsWizard
1116  ///\sa Dfs
1117  template<class GR>
1118  DfsWizard<DfsWizardBase<GR> >
[278]1119  dfs(const GR &digraph)
[100]1120  {
[278]1121    return DfsWizard<DfsWizardBase<GR> >(digraph);
[100]1122  }
1123
1124#ifdef DOXYGEN
[244]1125  /// \brief Visitor class for DFS.
[209]1126  ///
[244]1127  /// This class defines the interface of the DfsVisit events, and
1128  /// it could be the base of a real visitor class.
[525]1129  template <typename GR>
[100]1130  struct DfsVisitor {
[525]1131    typedef GR Digraph;
[100]1132    typedef typename Digraph::Arc Arc;
1133    typedef typename Digraph::Node Node;
[244]1134    /// \brief Called for the source node of the DFS.
[209]1135    ///
[244]1136    /// This function is called for the source node of the DFS.
1137    void start(const Node& node) {}
1138    /// \brief Called when the source node is leaved.
1139    ///
1140    /// This function is called when the source node is leaved.
1141    void stop(const Node& node) {}
1142    /// \brief Called when a node is reached first time.
1143    ///
1144    /// This function is called when a node is reached first time.
1145    void reach(const Node& node) {}
1146    /// \brief Called when an arc reaches a new node.
1147    ///
1148    /// This function is called when the DFS finds an arc whose target node
1149    /// is not reached yet.
[100]1150    void discover(const Arc& arc) {}
[244]1151    /// \brief Called when an arc is examined but its target node is
[100]1152    /// already discovered.
[209]1153    ///
[244]1154    /// This function is called when an arc is examined but its target node is
[100]1155    /// already discovered.
1156    void examine(const Arc& arc) {}
[244]1157    /// \brief Called when the DFS steps back from a node.
[209]1158    ///
[244]1159    /// This function is called when the DFS steps back from a node.
1160    void leave(const Node& node) {}
1161    /// \brief Called when the DFS steps back on an arc.
[209]1162    ///
[244]1163    /// This function is called when the DFS steps back on an arc.
1164    void backtrack(const Arc& arc) {}
[100]1165  };
1166#else
[525]1167  template <typename GR>
[100]1168  struct DfsVisitor {
[525]1169    typedef GR Digraph;
[100]1170    typedef typename Digraph::Arc Arc;
1171    typedef typename Digraph::Node Node;
1172    void start(const Node&) {}
1173    void stop(const Node&) {}
[244]1174    void reach(const Node&) {}
1175    void discover(const Arc&) {}
1176    void examine(const Arc&) {}
1177    void leave(const Node&) {}
1178    void backtrack(const Arc&) {}
[100]1179
1180    template <typename _Visitor>
1181    struct Constraints {
1182      void constraints() {
[209]1183        Arc arc;
1184        Node node;
1185        visitor.start(node);
1186        visitor.stop(arc);
[244]1187        visitor.reach(node);
1188        visitor.discover(arc);
1189        visitor.examine(arc);
1190        visitor.leave(node);
1191        visitor.backtrack(arc);
[100]1192      }
1193      _Visitor& visitor;
[1125]1194      Constraints() {}
[100]1195    };
1196  };
1197#endif
1198
1199  /// \brief Default traits class of DfsVisit class.
1200  ///
1201  /// Default traits class of DfsVisit class.
[244]1202  /// \tparam _Digraph The type of the digraph the algorithm runs on.
[525]1203  template<class GR>
[100]1204  struct DfsVisitDefaultTraits {
1205
[244]1206    /// \brief The type of the digraph the algorithm runs on.
[525]1207    typedef GR Digraph;
[100]1208
1209    /// \brief The type of the map that indicates which nodes are reached.
[209]1210    ///
[100]1211    /// The type of the map that indicates which nodes are reached.
[244]1212    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
[100]1213    typedef typename Digraph::template NodeMap<bool> ReachedMap;
1214
[301]1215    /// \brief Instantiates a ReachedMap.
[100]1216    ///
[301]1217    /// This function instantiates a ReachedMap.
[100]1218    /// \param digraph is the digraph, to which
[301]1219    /// we would like to define the ReachedMap.
[100]1220    static ReachedMap *createReachedMap(const Digraph &digraph) {
1221      return new ReachedMap(digraph);
1222    }
1223
1224  };
[209]1225
[100]1226  /// \ingroup search
[244]1227  ///
[525]1228  /// \brief DFS algorithm class with visitor interface.
[244]1229  ///
[525]1230  /// This class provides an efficient implementation of the DFS algorithm
[100]1231  /// with visitor interface.
1232  ///
[525]1233  /// The DfsVisit class provides an alternative interface to the Dfs
[100]1234  /// class. It works with callback mechanism, the DfsVisit object calls
[244]1235  /// the member functions of the \c Visitor class on every DFS event.
[100]1236  ///
[252]1237  /// This interface of the DFS algorithm should be used in special cases
1238  /// when extra actions have to be performed in connection with certain
1239  /// events of the DFS algorithm. Otherwise consider to use Dfs or dfs()
1240  /// instead.
1241  ///
[525]1242  /// \tparam GR The type of the digraph the algorithm runs on.
1243  /// The default type is \ref ListDigraph.
1244  /// The value of GR is not used directly by \ref DfsVisit,
1245  /// it is only passed to \ref DfsVisitDefaultTraits.
1246  /// \tparam VS The Visitor type that is used by the algorithm.
1247  /// \ref DfsVisitor "DfsVisitor<GR>" is an empty visitor, which
[244]1248  /// does not observe the DFS events. If you want to observe the DFS
1249  /// events, you should implement your own visitor class.
[525]1250  /// \tparam TR Traits class to set various data types used by the
[100]1251  /// algorithm. The default traits class is
[525]1252  /// \ref DfsVisitDefaultTraits "DfsVisitDefaultTraits<GR>".
[100]1253  /// See \ref DfsVisitDefaultTraits for the documentation of
[244]1254  /// a DFS visit traits class.
[100]1255#ifdef DOXYGEN
[525]1256  template <typename GR, typename VS, typename TR>
[100]1257#else
[525]1258  template <typename GR = ListDigraph,
1259            typename VS = DfsVisitor<GR>,
1260            typename TR = DfsVisitDefaultTraits<GR> >
[100]1261#endif
1262  class DfsVisit {
1263  public:
[209]1264
[244]1265    ///The traits class.
[525]1266    typedef TR Traits;
[100]1267
[244]1268    ///The type of the digraph the algorithm runs on.
[100]1269    typedef typename Traits::Digraph Digraph;
1270
[244]1271    ///The visitor type used by the algorithm.
[525]1272    typedef VS Visitor;
[100]1273
[244]1274    ///The type of the map that indicates which nodes are reached.
[100]1275    typedef typename Traits::ReachedMap ReachedMap;
1276
1277  private:
1278
1279    typedef typename Digraph::Node Node;
1280    typedef typename Digraph::NodeIt NodeIt;
1281    typedef typename Digraph::Arc Arc;
1282    typedef typename Digraph::OutArcIt OutArcIt;
1283
[244]1284    //Pointer to the underlying digraph.
[100]1285    const Digraph *_digraph;
[244]1286    //Pointer to the visitor object.
[100]1287    Visitor *_visitor;
[244]1288    //Pointer to the map of reached status of the nodes.
[100]1289    ReachedMap *_reached;
[244]1290    //Indicates if _reached is locally allocated (true) or not.
[100]1291    bool local_reached;
1292
1293    std::vector<typename Digraph::Arc> _stack;
1294    int _stack_head;
1295
[280]1296    //Creates the maps if necessary.
[100]1297    void create_maps() {
1298      if(!_reached) {
[209]1299        local_reached = true;
1300        _reached = Traits::createReachedMap(*_digraph);
[100]1301      }
1302    }
1303
1304  protected:
1305
1306    DfsVisit() {}
[209]1307
[100]1308  public:
1309
1310    typedef DfsVisit Create;
1311
[421]1312    /// \name Named Template Parameters
[100]1313
1314    ///@{
1315    template <class T>
[257]1316    struct SetReachedMapTraits : public Traits {
[100]1317      typedef T ReachedMap;
1318      static ReachedMap *createReachedMap(const Digraph &digraph) {
[290]1319        LEMON_ASSERT(false, "ReachedMap is not initialized");
1320        return 0; // ignore warnings
[100]1321      }
1322    };
[209]1323    /// \brief \ref named-templ-param "Named parameter" for setting
[244]1324    /// ReachedMap type.
[100]1325    ///
[244]1326    /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
[100]1327    template <class T>
[257]1328    struct SetReachedMap : public DfsVisit< Digraph, Visitor,
1329                                            SetReachedMapTraits<T> > {
1330      typedef DfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
[100]1331    };
1332    ///@}
1333
[209]1334  public:
1335
[100]1336    /// \brief Constructor.
1337    ///
1338    /// Constructor.
1339    ///
[244]1340    /// \param digraph The digraph the algorithm runs on.
1341    /// \param visitor The visitor object of the algorithm.
[209]1342    DfsVisit(const Digraph& digraph, Visitor& visitor)
[100]1343      : _digraph(&digraph), _visitor(&visitor),
[209]1344        _reached(0), local_reached(false) {}
1345
[100]1346    /// \brief Destructor.
1347    ~DfsVisit() {
1348      if(local_reached) delete _reached;
1349    }
1350
[244]1351    /// \brief Sets the map that indicates which nodes are reached.
[100]1352    ///
[244]1353    /// Sets the map that indicates which nodes are reached.
[421]1354    /// If you don't use this function before calling \ref run(Node) "run()"
1355    /// or \ref init(), an instance will be allocated automatically.
1356    /// The destructor deallocates this automatically allocated map,
1357    /// of course.
[100]1358    /// \return <tt> (*this) </tt>
1359    DfsVisit &reachedMap(ReachedMap &m) {
1360      if(local_reached) {
[209]1361        delete _reached;
1362        local_reached=false;
[100]1363      }
1364      _reached = &m;
1365      return *this;
1366    }
1367
1368  public:
[244]1369
[421]1370    /// \name Execution Control
1371    /// The simplest way to execute the DFS algorithm is to use one of the
1372    /// member functions called \ref run(Node) "run()".\n
1373    /// If you need more control on the execution, first you have to call
1374    /// \ref init(), then you can add a source node with \ref addSource()
1375    /// and perform the actual computation with \ref start().
1376    /// This procedure can be repeated if there are nodes that have not
1377    /// been reached.
[100]1378
1379    /// @{
[244]1380
[100]1381    /// \brief Initializes the internal data structures.
1382    ///
1383    /// Initializes the internal data structures.
1384    void init() {
1385      create_maps();
1386      _stack.resize(countNodes(*_digraph));
1387      _stack_head = -1;
1388      for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
[209]1389        _reached->set(u, false);
[100]1390      }
1391    }
[209]1392
[421]1393    /// \brief Adds a new source node.
[100]1394    ///
[421]1395    /// Adds a new source node to the set of nodes to be processed.
[244]1396    ///
[421]1397    /// \pre The stack must be empty. Otherwise the algorithm gives
1398    /// wrong results. (One of the outgoing arcs of all the source nodes
1399    /// except for the last one will not be visited and distances will
1400    /// also be wrong.)
[244]1401    void addSource(Node s)
1402    {
1403      LEMON_DEBUG(emptyQueue(), "The stack is not empty.");
[100]1404      if(!(*_reached)[s]) {
[209]1405          _reached->set(s,true);
1406          _visitor->start(s);
1407          _visitor->reach(s);
1408          Arc e;
1409          _digraph->firstOut(e, s);
1410          if (e != INVALID) {
1411            _stack[++_stack_head] = e;
1412          } else {
1413            _visitor->leave(s);
[435]1414            _visitor->stop(s);
[209]1415          }
1416        }
[100]1417    }
[209]1418
[100]1419    /// \brief Processes the next arc.
1420    ///
1421    /// Processes the next arc.
1422    ///
1423    /// \return The processed arc.
1424    ///
[244]1425    /// \pre The stack must not be empty.
[209]1426    Arc processNextArc() {
[100]1427      Arc e = _stack[_stack_head];
1428      Node m = _digraph->target(e);
1429      if(!(*_reached)[m]) {
[209]1430        _visitor->discover(e);
1431        _visitor->reach(m);
1432        _reached->set(m, true);
1433        _digraph->firstOut(_stack[++_stack_head], m);
[100]1434      } else {
[209]1435        _visitor->examine(e);
1436        m = _digraph->source(e);
1437        _digraph->nextOut(_stack[_stack_head]);
[100]1438      }
1439      while (_stack_head>=0 && _stack[_stack_head] == INVALID) {
[209]1440        _visitor->leave(m);
1441        --_stack_head;
1442        if (_stack_head >= 0) {
1443          _visitor->backtrack(_stack[_stack_head]);
1444          m = _digraph->source(_stack[_stack_head]);
1445          _digraph->nextOut(_stack[_stack_head]);
1446        } else {
1447          _visitor->stop(m);
1448        }
[100]1449      }
1450      return e;
1451    }
1452
1453    /// \brief Next arc to be processed.
1454    ///
1455    /// Next arc to be processed.
1456    ///
1457    /// \return The next arc to be processed or INVALID if the stack is
1458    /// empty.
[244]1459    Arc nextArc() const {
[100]1460      return _stack_head >= 0 ? _stack[_stack_head] : INVALID;
1461    }
1462
1463    /// \brief Returns \c false if there are nodes
[244]1464    /// to be processed.
[100]1465    ///
1466    /// Returns \c false if there are nodes
[244]1467    /// to be processed in the queue (stack).
1468    bool emptyQueue() const { return _stack_head < 0; }
[100]1469
1470    /// \brief Returns the number of the nodes to be processed.
1471    ///
[244]1472    /// Returns the number of the nodes to be processed in the queue (stack).
1473    int queueSize() const { return _stack_head + 1; }
[209]1474
[100]1475    /// \brief Executes the algorithm.
1476    ///
1477    /// Executes the algorithm.
1478    ///
[244]1479    /// This method runs the %DFS algorithm from the root node
1480    /// in order to compute the %DFS path to each node.
1481    ///
1482    /// The algorithm computes
1483    /// - the %DFS tree,
1484    /// - the distance of each node from the root in the %DFS tree.
1485    ///
1486    /// \pre init() must be called and a root node should be
1487    /// added with addSource() before using this function.
1488    ///
1489    /// \note <tt>d.start()</tt> is just a shortcut of the following code.
1490    /// \code
1491    ///   while ( !d.emptyQueue() ) {
1492    ///     d.processNextArc();
1493    ///   }
1494    /// \endcode
[100]1495    void start() {
1496      while ( !emptyQueue() ) processNextArc();
1497    }
[209]1498
[244]1499    /// \brief Executes the algorithm until the given target node is reached.
[100]1500    ///
[244]1501    /// Executes the algorithm until the given target node is reached.
[100]1502    ///
[244]1503    /// This method runs the %DFS algorithm from the root node
[286]1504    /// in order to compute the DFS path to \c t.
[244]1505    ///
1506    /// The algorithm computes
[286]1507    /// - the %DFS path to \c t,
1508    /// - the distance of \c t from the root in the %DFS tree.
[244]1509    ///
1510    /// \pre init() must be called and a root node should be added
[100]1511    /// with addSource() before using this function.
[286]1512    void start(Node t) {
[1007]1513      while ( !emptyQueue() && !(*_reached)[t] )
[209]1514        processNextArc();
[100]1515    }
[209]1516
[100]1517    /// \brief Executes the algorithm until a condition is met.
1518    ///
1519    /// Executes the algorithm until a condition is met.
1520    ///
[244]1521    /// This method runs the %DFS algorithm from the root node
1522    /// until an arc \c a with <tt>am[a]</tt> true is found.
1523    ///
1524    /// \param am A \c bool (or convertible) arc map. The algorithm
1525    /// will stop when it reaches an arc \c a with <tt>am[a]</tt> true.
1526    ///
1527    /// \return The reached arc \c a with <tt>am[a]</tt> true or
1528    /// \c INVALID if no such arc was found.
1529    ///
1530    /// \pre init() must be called and a root node should be added
[100]1531    /// with addSource() before using this function.
1532    ///
[244]1533    /// \warning Contrary to \ref Bfs and \ref Dijkstra, \c am is an arc map,
[100]1534    /// not a node map.
[244]1535    template <typename AM>
1536    Arc start(const AM &am) {
1537      while ( !emptyQueue() && !am[_stack[_stack_head]] )
[100]1538        processNextArc();
1539      return emptyQueue() ? INVALID : _stack[_stack_head];
1540    }
1541
[286]1542    /// \brief Runs the algorithm from the given source node.
[100]1543    ///
[244]1544    /// This method runs the %DFS algorithm from node \c s.
1545    /// in order to compute the DFS path to each node.
1546    ///
1547    /// The algorithm computes
1548    /// - the %DFS tree,
1549    /// - the distance of each node from the root in the %DFS tree.
1550    ///
1551    /// \note <tt>d.run(s)</tt> is just a shortcut of the following code.
[100]1552    ///\code
1553    ///   d.init();
1554    ///   d.addSource(s);
1555    ///   d.start();
1556    ///\endcode
1557    void run(Node s) {
1558      init();
1559      addSource(s);
1560      start();
1561    }
1562
[244]1563    /// \brief Finds the %DFS path between \c s and \c t.
1564
1565    /// This method runs the %DFS algorithm from node \c s
[286]1566    /// in order to compute the DFS path to node \c t
1567    /// (it stops searching when \c t is processed).
[244]1568    ///
[286]1569    /// \return \c true if \c t is reachable form \c s.
[244]1570    ///
1571    /// \note Apart from the return value, <tt>d.run(s,t)</tt> is
1572    /// just a shortcut of the following code.
1573    ///\code
1574    ///   d.init();
1575    ///   d.addSource(s);
1576    ///   d.start(t);
1577    ///\endcode
[286]1578    bool run(Node s,Node t) {
[244]1579      init();
1580      addSource(s);
1581      start(t);
[286]1582      return reached(t);
[244]1583    }
1584
1585    /// \brief Runs the algorithm to visit all nodes in the digraph.
[209]1586
[100]1587    /// This method runs the %DFS algorithm in order to
[244]1588    /// compute the %DFS path to each node.
[100]1589    ///
[244]1590    /// The algorithm computes
[421]1591    /// - the %DFS tree (forest),
1592    /// - the distance of each node from the root(s) in the %DFS tree.
[244]1593    ///
1594    /// \note <tt>d.run()</tt> is just a shortcut of the following code.
[100]1595    ///\code
[244]1596    ///   d.init();
1597    ///   for (NodeIt n(digraph); n != INVALID; ++n) {
1598    ///     if (!d.reached(n)) {
1599    ///       d.addSource(n);
1600    ///       d.start();
1601    ///     }
1602    ///   }
[100]1603    ///\endcode
1604    void run() {
1605      init();
1606      for (NodeIt it(*_digraph); it != INVALID; ++it) {
1607        if (!reached(it)) {
1608          addSource(it);
1609          start();
1610        }
1611      }
1612    }
[244]1613
[100]1614    ///@}
1615
1616    /// \name Query Functions
[421]1617    /// The results of the DFS algorithm can be obtained using these
[100]1618    /// functions.\n
[421]1619    /// Either \ref run(Node) "run()" or \ref start() should be called
1620    /// before using them.
1621
[100]1622    ///@{
[244]1623
[421]1624    /// \brief Checks if a node is reached from the root(s).
[100]1625    ///
[421]1626    /// Returns \c true if \c v is reached from the root(s).
1627    ///
1628    /// \pre Either \ref run(Node) "run()" or \ref init()
[100]1629    /// must be called before using this function.
[437]1630    bool reached(Node v) const { return (*_reached)[v]; }
[244]1631
[100]1632    ///@}
[244]1633
[100]1634  };
1635
1636} //END OF NAMESPACE LEMON
1637
1638#endif
Note: See TracBrowser for help on using the repository browser.