lemon/bfs.h
author Balazs Dezso <deba@inf.elte.hu>
Thu, 24 Jun 2010 09:27:53 +0200
changeset 894 bb70ad62c95f
parent 440 88ed40ad0d4f
child 713 4ac30454f1c1
child 716 f47b6c94577e
child 953 b873350e6258
permissions -rw-r--r--
Fix critical bug in preflow (#372)

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