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

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

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

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