lemon/dfs.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
parent 877 141f9c0db4a3
parent 906 e24922c56bc2
child 966 c8fce9beb46a
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

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