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