Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/quadriflow/3rd/lemon-1.3.1/lemon/bfs.h')
-rw-r--r--extern/quadriflow/3rd/lemon-1.3.1/lemon/bfs.h1754
1 files changed, 1754 insertions, 0 deletions
diff --git a/extern/quadriflow/3rd/lemon-1.3.1/lemon/bfs.h b/extern/quadriflow/3rd/lemon-1.3.1/lemon/bfs.h
new file mode 100644
index 00000000000..e5f4e5c5a31
--- /dev/null
+++ b/extern/quadriflow/3rd/lemon-1.3.1/lemon/bfs.h
@@ -0,0 +1,1754 @@
+/* -*- mode: C++; indent-tabs-mode: nil; -*-
+ *
+ * This file is a part of LEMON, a generic C++ optimization library.
+ *
+ * Copyright (C) 2003-2013
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
+ *
+ * Permission to use, modify and distribute this software is granted
+ * provided that this copyright notice appears in all copies. For
+ * precise terms see the accompanying LICENSE file.
+ *
+ * This software is provided "AS IS" with no warranty of any kind,
+ * express or implied, and with no claim as to its suitability for any
+ * purpose.
+ *
+ */
+
+#ifndef LEMON_BFS_H
+#define LEMON_BFS_H
+
+///\ingroup search
+///\file
+///\brief BFS algorithm.
+
+#include <lemon/list_graph.h>
+#include <lemon/bits/path_dump.h>
+#include <lemon/core.h>
+#include <lemon/error.h>
+#include <lemon/maps.h>
+#include <lemon/path.h>
+
+namespace lemon {
+
+ ///Default traits class of Bfs class.
+
+ ///Default traits class of Bfs class.
+ ///\tparam GR Digraph type.
+ template<class GR>
+ struct BfsDefaultTraits
+ {
+ ///The type of the digraph the algorithm runs on.
+ typedef GR Digraph;
+
+ ///\brief The type of the map that stores the predecessor
+ ///arcs of the shortest paths.
+ ///
+ ///The type of the map that stores the predecessor
+ ///arcs of the shortest paths.
+ ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+ typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
+ ///Instantiates a \c PredMap.
+
+ ///This function instantiates a \ref PredMap.
+ ///\param g is the digraph, to which we would like to define the
+ ///\ref PredMap.
+ static PredMap *createPredMap(const Digraph &g)
+ {
+ return new PredMap(g);
+ }
+
+ ///The type of the map that indicates which nodes are processed.
+
+ ///The type of the map that indicates which nodes are processed.
+ ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+ ///By default, it is a NullMap.
+ typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
+ ///Instantiates a \c ProcessedMap.
+
+ ///This function instantiates a \ref ProcessedMap.
+ ///\param g is the digraph, to which
+ ///we would like to define the \ref ProcessedMap
+#ifdef DOXYGEN
+ static ProcessedMap *createProcessedMap(const Digraph &g)
+#else
+ static ProcessedMap *createProcessedMap(const Digraph &)
+#endif
+ {
+ return new ProcessedMap();
+ }
+
+ ///The type of the map that indicates which nodes are reached.
+
+ ///The type of the map that indicates which nodes are reached.
+ ///It must conform to
+ ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+ typedef typename Digraph::template NodeMap<bool> ReachedMap;
+ ///Instantiates a \c ReachedMap.
+
+ ///This function instantiates a \ref ReachedMap.
+ ///\param g is the digraph, to which
+ ///we would like to define the \ref ReachedMap.
+ static ReachedMap *createReachedMap(const Digraph &g)
+ {
+ return new ReachedMap(g);
+ }
+
+ ///The type of the map that stores the distances of the nodes.
+
+ ///The type of the map that stores the distances of the nodes.
+ ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+ typedef typename Digraph::template NodeMap<int> DistMap;
+ ///Instantiates a \c DistMap.
+
+ ///This function instantiates a \ref DistMap.
+ ///\param g is the digraph, to which we would like to define the
+ ///\ref DistMap.
+ static DistMap *createDistMap(const Digraph &g)
+ {
+ return new DistMap(g);
+ }
+ };
+
+ ///%BFS algorithm class.
+
+ ///\ingroup search
+ ///This class provides an efficient implementation of the %BFS algorithm.
+ ///
+ ///There is also a \ref bfs() "function-type interface" for the BFS
+ ///algorithm, which is convenient in the simplier cases and it can be
+ ///used easier.
+ ///
+ ///\tparam GR The type of the digraph the algorithm runs on.
+ ///The default type is \ref ListDigraph.
+ ///\tparam TR The traits class that defines various types used by the
+ ///algorithm. By default, it is \ref BfsDefaultTraits
+ ///"BfsDefaultTraits<GR>".
+ ///In most cases, this parameter should not be set directly,
+ ///consider to use the named template parameters instead.
+#ifdef DOXYGEN
+ template <typename GR,
+ typename TR>
+#else
+ template <typename GR=ListDigraph,
+ typename TR=BfsDefaultTraits<GR> >
+#endif
+ class Bfs {
+ public:
+
+ ///The type of the digraph the algorithm runs on.
+ typedef typename TR::Digraph Digraph;
+
+ ///\brief The type of the map that stores the predecessor arcs of the
+ ///shortest paths.
+ typedef typename TR::PredMap PredMap;
+ ///The type of the map that stores the distances of the nodes.
+ typedef typename TR::DistMap DistMap;
+ ///The type of the map that indicates which nodes are reached.
+ typedef typename TR::ReachedMap ReachedMap;
+ ///The type of the map that indicates which nodes are processed.
+ typedef typename TR::ProcessedMap ProcessedMap;
+ ///The type of the paths.
+ typedef PredMapPath<Digraph, PredMap> Path;
+
+ ///The \ref lemon::BfsDefaultTraits "traits class" of the algorithm.
+ typedef TR Traits;
+
+ private:
+
+ typedef typename Digraph::Node Node;
+ typedef typename Digraph::NodeIt NodeIt;
+ typedef typename Digraph::Arc Arc;
+ typedef typename Digraph::OutArcIt OutArcIt;
+
+ //Pointer to the underlying digraph.
+ const Digraph *G;
+ //Pointer to the map of predecessor arcs.
+ PredMap *_pred;
+ //Indicates if _pred is locally allocated (true) or not.
+ bool local_pred;
+ //Pointer to the map of distances.
+ DistMap *_dist;
+ //Indicates if _dist is locally allocated (true) or not.
+ bool local_dist;
+ //Pointer to the map of reached status of the nodes.
+ ReachedMap *_reached;
+ //Indicates if _reached is locally allocated (true) or not.
+ bool local_reached;
+ //Pointer to the map of processed status of the nodes.
+ ProcessedMap *_processed;
+ //Indicates if _processed is locally allocated (true) or not.
+ bool local_processed;
+
+ std::vector<typename Digraph::Node> _queue;
+ int _queue_head,_queue_tail,_queue_next_dist;
+ int _curr_dist;
+
+ //Creates the maps if necessary.
+ void create_maps()
+ {
+ if(!_pred) {
+ local_pred = true;
+ _pred = Traits::createPredMap(*G);
+ }
+ if(!_dist) {
+ local_dist = true;
+ _dist = Traits::createDistMap(*G);
+ }
+ if(!_reached) {
+ local_reached = true;
+ _reached = Traits::createReachedMap(*G);
+ }
+ if(!_processed) {
+ local_processed = true;
+ _processed = Traits::createProcessedMap(*G);
+ }
+ }
+
+ protected:
+
+ Bfs() {}
+
+ public:
+
+ typedef Bfs Create;
+
+ ///\name Named Template Parameters
+
+ ///@{
+
+ template <class T>
+ struct SetPredMapTraits : public Traits {
+ typedef T PredMap;
+ static PredMap *createPredMap(const Digraph &)
+ {
+ LEMON_ASSERT(false, "PredMap is not initialized");
+ return 0; // ignore warnings
+ }
+ };
+ ///\brief \ref named-templ-param "Named parameter" for setting
+ ///\c PredMap type.
+ ///
+ ///\ref named-templ-param "Named parameter" for setting
+ ///\c PredMap type.
+ ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+ template <class T>
+ struct SetPredMap : public Bfs< Digraph, SetPredMapTraits<T> > {
+ typedef Bfs< Digraph, SetPredMapTraits<T> > Create;
+ };
+
+ template <class T>
+ struct SetDistMapTraits : public Traits {
+ typedef T DistMap;
+ static DistMap *createDistMap(const Digraph &)
+ {
+ LEMON_ASSERT(false, "DistMap is not initialized");
+ return 0; // ignore warnings
+ }
+ };
+ ///\brief \ref named-templ-param "Named parameter" for setting
+ ///\c DistMap type.
+ ///
+ ///\ref named-templ-param "Named parameter" for setting
+ ///\c DistMap type.
+ ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+ template <class T>
+ struct SetDistMap : public Bfs< Digraph, SetDistMapTraits<T> > {
+ typedef Bfs< Digraph, SetDistMapTraits<T> > Create;
+ };
+
+ template <class T>
+ struct SetReachedMapTraits : public Traits {
+ typedef T ReachedMap;
+ static ReachedMap *createReachedMap(const Digraph &)
+ {
+ LEMON_ASSERT(false, "ReachedMap is not initialized");
+ return 0; // ignore warnings
+ }
+ };
+ ///\brief \ref named-templ-param "Named parameter" for setting
+ ///\c ReachedMap type.
+ ///
+ ///\ref named-templ-param "Named parameter" for setting
+ ///\c ReachedMap type.
+ ///It must conform to
+ ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+ template <class T>
+ struct SetReachedMap : public Bfs< Digraph, SetReachedMapTraits<T> > {
+ typedef Bfs< Digraph, SetReachedMapTraits<T> > Create;
+ };
+
+ template <class T>
+ struct SetProcessedMapTraits : public Traits {
+ typedef T ProcessedMap;
+ static ProcessedMap *createProcessedMap(const Digraph &)
+ {
+ LEMON_ASSERT(false, "ProcessedMap is not initialized");
+ return 0; // ignore warnings
+ }
+ };
+ ///\brief \ref named-templ-param "Named parameter" for setting
+ ///\c ProcessedMap type.
+ ///
+ ///\ref named-templ-param "Named parameter" for setting
+ ///\c ProcessedMap type.
+ ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+ template <class T>
+ struct SetProcessedMap : public Bfs< Digraph, SetProcessedMapTraits<T> > {
+ typedef Bfs< Digraph, SetProcessedMapTraits<T> > Create;
+ };
+
+ struct SetStandardProcessedMapTraits : public Traits {
+ typedef typename Digraph::template NodeMap<bool> ProcessedMap;
+ static ProcessedMap *createProcessedMap(const Digraph &g)
+ {
+ return new ProcessedMap(g);
+ return 0; // ignore warnings
+ }
+ };
+ ///\brief \ref named-templ-param "Named parameter" for setting
+ ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+ ///
+ ///\ref named-templ-param "Named parameter" for setting
+ ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
+ ///If you don't set it explicitly, it will be automatically allocated.
+ struct SetStandardProcessedMap :
+ public Bfs< Digraph, SetStandardProcessedMapTraits > {
+ typedef Bfs< Digraph, SetStandardProcessedMapTraits > Create;
+ };
+
+ ///@}
+
+ public:
+
+ ///Constructor.
+
+ ///Constructor.
+ ///\param g The digraph the algorithm runs on.
+ Bfs(const Digraph &g) :
+ G(&g),
+ _pred(NULL), local_pred(false),
+ _dist(NULL), local_dist(false),
+ _reached(NULL), local_reached(false),
+ _processed(NULL), local_processed(false)
+ { }
+
+ ///Destructor.
+ ~Bfs()
+ {
+ if(local_pred) delete _pred;
+ if(local_dist) delete _dist;
+ if(local_reached) delete _reached;
+ if(local_processed) delete _processed;
+ }
+
+ ///Sets the map that stores the predecessor arcs.
+
+ ///Sets the map that stores the predecessor arcs.
+ ///If you don't use this function before calling \ref run(Node) "run()"
+ ///or \ref init(), an instance will be allocated automatically.
+ ///The destructor deallocates this automatically allocated map,
+ ///of course.
+ ///\return <tt> (*this) </tt>
+ Bfs &predMap(PredMap &m)
+ {
+ if(local_pred) {
+ delete _pred;
+ local_pred=false;
+ }
+ _pred = &m;
+ return *this;
+ }
+
+ ///Sets the map that indicates which nodes are reached.
+
+ ///Sets the map that indicates which nodes are reached.
+ ///If you don't use this function before calling \ref run(Node) "run()"
+ ///or \ref init(), an instance will be allocated automatically.
+ ///The destructor deallocates this automatically allocated map,
+ ///of course.
+ ///\return <tt> (*this) </tt>
+ Bfs &reachedMap(ReachedMap &m)
+ {
+ if(local_reached) {
+ delete _reached;
+ local_reached=false;
+ }
+ _reached = &m;
+ return *this;
+ }
+
+ ///Sets the map that indicates which nodes are processed.
+
+ ///Sets the map that indicates which nodes are processed.
+ ///If you don't use this function before calling \ref run(Node) "run()"
+ ///or \ref init(), an instance will be allocated automatically.
+ ///The destructor deallocates this automatically allocated map,
+ ///of course.
+ ///\return <tt> (*this) </tt>
+ Bfs &processedMap(ProcessedMap &m)
+ {
+ if(local_processed) {
+ delete _processed;
+ local_processed=false;
+ }
+ _processed = &m;
+ return *this;
+ }
+
+ ///Sets the map that stores the distances of the nodes.
+
+ ///Sets the map that stores the distances of the nodes calculated by
+ ///the algorithm.
+ ///If you don't use this function before calling \ref run(Node) "run()"
+ ///or \ref init(), an instance will be allocated automatically.
+ ///The destructor deallocates this automatically allocated map,
+ ///of course.
+ ///\return <tt> (*this) </tt>
+ Bfs &distMap(DistMap &m)
+ {
+ if(local_dist) {
+ delete _dist;
+ local_dist=false;
+ }
+ _dist = &m;
+ return *this;
+ }
+
+ public:
+
+ ///\name Execution Control
+ ///The simplest way to execute the BFS algorithm is to use one of the
+ ///member functions called \ref run(Node) "run()".\n
+ ///If you need better control on the execution, you have to call
+ ///\ref init() first, then you can add several source nodes with
+ ///\ref addSource(). Finally the actual path computation can be
+ ///performed with one of the \ref start() functions.
+
+ ///@{
+
+ ///\brief Initializes the internal data structures.
+ ///
+ ///Initializes the internal data structures.
+ void init()
+ {
+ create_maps();
+ _queue.resize(countNodes(*G));
+ _queue_head=_queue_tail=0;
+ _curr_dist=1;
+ for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
+ _pred->set(u,INVALID);
+ _reached->set(u,false);
+ _processed->set(u,false);
+ }
+ }
+
+ ///Adds a new source node.
+
+ ///Adds a new source node to the set of nodes to be processed.
+ ///
+ void addSource(Node s)
+ {
+ if(!(*_reached)[s])
+ {
+ _reached->set(s,true);
+ _pred->set(s,INVALID);
+ _dist->set(s,0);
+ _queue[_queue_head++]=s;
+ _queue_next_dist=_queue_head;
+ }
+ }
+
+ ///Processes the next node.
+
+ ///Processes the next node.
+ ///
+ ///\return The processed node.
+ ///
+ ///\pre The queue must not be empty.
+ Node processNextNode()
+ {
+ if(_queue_tail==_queue_next_dist) {
+ _curr_dist++;
+ _queue_next_dist=_queue_head;
+ }
+ Node n=_queue[_queue_tail++];
+ _processed->set(n,true);
+ Node m;
+ for(OutArcIt e(*G,n);e!=INVALID;++e)
+ if(!(*_reached)[m=G->target(e)]) {
+ _queue[_queue_head++]=m;
+ _reached->set(m,true);
+ _pred->set(m,e);
+ _dist->set(m,_curr_dist);
+ }
+ return n;
+ }
+
+ ///Processes the next node.
+
+ ///Processes the next node and checks if the given target node
+ ///is reached. If the target node is reachable from the processed
+ ///node, then the \c reach parameter will be set to \c true.
+ ///
+ ///\param target The target node.
+ ///\retval reach Indicates if the target node is reached.
+ ///It should be initially \c false.
+ ///
+ ///\return The processed node.
+ ///
+ ///\pre The queue must not be empty.
+ Node processNextNode(Node target, bool& reach)
+ {
+ if(_queue_tail==_queue_next_dist) {
+ _curr_dist++;
+ _queue_next_dist=_queue_head;
+ }
+ Node n=_queue[_queue_tail++];
+ _processed->set(n,true);
+ Node m;
+ for(OutArcIt e(*G,n);e!=INVALID;++e)
+ if(!(*_reached)[m=G->target(e)]) {
+ _queue[_queue_head++]=m;
+ _reached->set(m,true);
+ _pred->set(m,e);
+ _dist->set(m,_curr_dist);
+ reach = reach || (target == m);
+ }
+ return n;
+ }
+
+ ///Processes the next node.
+
+ ///Processes the next node and checks if at least one of reached
+ ///nodes has \c true value in the \c nm node map. If one node
+ ///with \c true value is reachable from the processed node, then the
+ ///\c rnode parameter will be set to the first of such nodes.
+ ///
+ ///\param nm A \c bool (or convertible) node map that indicates the
+ ///possible targets.
+ ///\retval rnode The reached target node.
+ ///It should be initially \c INVALID.
+ ///
+ ///\return The processed node.
+ ///
+ ///\pre The queue must not be empty.
+ template<class NM>
+ Node processNextNode(const NM& nm, Node& rnode)
+ {
+ if(_queue_tail==_queue_next_dist) {
+ _curr_dist++;
+ _queue_next_dist=_queue_head;
+ }
+ Node n=_queue[_queue_tail++];
+ _processed->set(n,true);
+ Node m;
+ for(OutArcIt e(*G,n);e!=INVALID;++e)
+ if(!(*_reached)[m=G->target(e)]) {
+ _queue[_queue_head++]=m;
+ _reached->set(m,true);
+ _pred->set(m,e);
+ _dist->set(m,_curr_dist);
+ if (nm[m] && rnode == INVALID) rnode = m;
+ }
+ return n;
+ }
+
+ ///The next node to be processed.
+
+ ///Returns the next node to be processed or \c INVALID if the queue
+ ///is empty.
+ Node nextNode() const
+ {
+ return _queue_tail<_queue_head?_queue[_queue_tail]:INVALID;
+ }
+
+ ///Returns \c false if there are nodes to be processed.
+
+ ///Returns \c false if there are nodes to be processed
+ ///in the queue.
+ bool emptyQueue() const { return _queue_tail==_queue_head; }
+
+ ///Returns the number of the nodes to be processed.
+
+ ///Returns the number of the nodes to be processed
+ ///in the queue.
+ int queueSize() const { return _queue_head-_queue_tail; }
+
+ ///Executes the algorithm.
+
+ ///Executes the algorithm.
+ ///
+ ///This method runs the %BFS algorithm from the root node(s)
+ ///in order to compute the shortest path to each node.
+ ///
+ ///The algorithm computes
+ ///- the shortest path tree (forest),
+ ///- the distance of each node from the root(s).
+ ///
+ ///\pre init() must be called and at least one root node should be
+ ///added with addSource() before using this function.
+ ///
+ ///\note <tt>b.start()</tt> is just a shortcut of the following code.
+ ///\code
+ /// while ( !b.emptyQueue() ) {
+ /// b.processNextNode();
+ /// }
+ ///\endcode
+ void start()
+ {
+ while ( !emptyQueue() ) processNextNode();
+ }
+
+ ///Executes the algorithm until the given target node is reached.
+
+ ///Executes the algorithm until the given target node is reached.
+ ///
+ ///This method runs the %BFS algorithm from the root node(s)
+ ///in order to compute the shortest path to \c t.
+ ///
+ ///The algorithm computes
+ ///- the shortest path to \c t,
+ ///- the distance of \c t from the root(s).
+ ///
+ ///\pre init() must be called and at least one root node should be
+ ///added with addSource() before using this function.
+ ///
+ ///\note <tt>b.start(t)</tt> is just a shortcut of the following code.
+ ///\code
+ /// bool reach = false;
+ /// while ( !b.emptyQueue() && !reach ) {
+ /// b.processNextNode(t, reach);
+ /// }
+ ///\endcode
+ void start(Node t)
+ {
+ bool reach = false;
+ while ( !emptyQueue() && !reach ) processNextNode(t, reach);
+ }
+
+ ///Executes the algorithm until a condition is met.
+
+ ///Executes the algorithm until a condition is met.
+ ///
+ ///This method runs the %BFS algorithm from the root node(s) in
+ ///order to compute the shortest path to a node \c v with
+ /// <tt>nm[v]</tt> true, if such a node can be found.
+ ///
+ ///\param nm A \c bool (or convertible) node map. The algorithm
+ ///will stop when it reaches a node \c v with <tt>nm[v]</tt> true.
+ ///
+ ///\return The reached node \c v with <tt>nm[v]</tt> true or
+ ///\c INVALID if no such node was found.
+ ///
+ ///\pre init() must be called and at least one root node should be
+ ///added with addSource() before using this function.
+ ///
+ ///\note <tt>b.start(nm)</tt> is just a shortcut of the following code.
+ ///\code
+ /// Node rnode = INVALID;
+ /// while ( !b.emptyQueue() && rnode == INVALID ) {
+ /// b.processNextNode(nm, rnode);
+ /// }
+ /// return rnode;
+ ///\endcode
+ template<class NodeBoolMap>
+ Node start(const NodeBoolMap &nm)
+ {
+ Node rnode = INVALID;
+ while ( !emptyQueue() && rnode == INVALID ) {
+ processNextNode(nm, rnode);
+ }
+ return rnode;
+ }
+
+ ///Runs the algorithm from the given source node.
+
+ ///This method runs the %BFS algorithm from node \c s
+ ///in order to compute the shortest path to each node.
+ ///
+ ///The algorithm computes
+ ///- the shortest path tree,
+ ///- the distance of each node from the root.
+ ///
+ ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
+ ///\code
+ /// b.init();
+ /// b.addSource(s);
+ /// b.start();
+ ///\endcode
+ void run(Node s) {
+ init();
+ addSource(s);
+ start();
+ }
+
+ ///Finds the shortest path between \c s and \c t.
+
+ ///This method runs the %BFS algorithm from node \c s
+ ///in order to compute the shortest path to node \c t
+ ///(it stops searching when \c t is processed).
+ ///
+ ///\return \c true if \c t is reachable form \c s.
+ ///
+ ///\note Apart from the return value, <tt>b.run(s,t)</tt> is just a
+ ///shortcut of the following code.
+ ///\code
+ /// b.init();
+ /// b.addSource(s);
+ /// b.start(t);
+ ///\endcode
+ bool run(Node s,Node t) {
+ init();
+ addSource(s);
+ start(t);
+ return reached(t);
+ }
+
+ ///Runs the algorithm to visit all nodes in the digraph.
+
+ ///This method runs the %BFS algorithm in order to visit all nodes
+ ///in the digraph.
+ ///
+ ///\note <tt>b.run(s)</tt> is just a shortcut of the following code.
+ ///\code
+ /// b.init();
+ /// for (NodeIt n(gr); n != INVALID; ++n) {
+ /// if (!b.reached(n)) {
+ /// b.addSource(n);
+ /// b.start();
+ /// }
+ /// }
+ ///\endcode
+ void run() {
+ init();
+ for (NodeIt n(*G); n != INVALID; ++n) {
+ if (!reached(n)) {
+ addSource(n);
+ start();
+ }
+ }
+ }
+
+ ///@}
+
+ ///\name Query Functions
+ ///The results of the BFS algorithm can be obtained using these
+ ///functions.\n
+ ///Either \ref run(Node) "run()" or \ref start() should be called
+ ///before using them.
+
+ ///@{
+
+ ///The shortest path to the given node.
+
+ ///Returns the shortest path to the given node from the root(s).
+ ///
+ ///\warning \c t should be reached from the root(s).
+ ///
+ ///\pre Either \ref run(Node) "run()" or \ref init()
+ ///must be called before using this function.
+ Path path(Node t) const { return Path(*G, *_pred, t); }
+
+ ///The distance of the given node from the root(s).
+
+ ///Returns the distance of the given node from the root(s).
+ ///
+ ///\warning If node \c v is not reached from the root(s), then
+ ///the return value of this function is undefined.
+ ///
+ ///\pre Either \ref run(Node) "run()" or \ref init()
+ ///must be called before using this function.
+ int dist(Node v) const { return (*_dist)[v]; }
+
+ ///\brief Returns the 'previous arc' of the shortest path tree for
+ ///the given node.
+ ///
+ ///This function returns the 'previous arc' of the shortest path
+ ///tree for the node \c v, i.e. it returns the last arc of a
+ ///shortest path from a root to \c v. It is \c INVALID if \c v
+ ///is not reached from the root(s) or if \c v is a root.
+ ///
+ ///The shortest path tree used here is equal to the shortest path
+ ///tree used in \ref predNode() and \ref predMap().
+ ///
+ ///\pre Either \ref run(Node) "run()" or \ref init()
+ ///must be called before using this function.
+ Arc predArc(Node v) const { return (*_pred)[v];}
+
+ ///\brief Returns the 'previous node' of the shortest path tree for
+ ///the given node.
+ ///
+ ///This function returns the 'previous node' of the shortest path
+ ///tree for the node \c v, i.e. it returns the last but one node
+ ///of a shortest path from a root to \c v. It is \c INVALID
+ ///if \c v is not reached from the root(s) or if \c v is a root.
+ ///
+ ///The shortest path tree used here is equal to the shortest path
+ ///tree used in \ref predArc() and \ref predMap().
+ ///
+ ///\pre Either \ref run(Node) "run()" or \ref init()
+ ///must be called before using this function.
+ Node predNode(Node v) const { return (*_pred)[v]==INVALID ? INVALID:
+ G->source((*_pred)[v]); }
+
+ ///\brief Returns a const reference to the node map that stores the
+ /// distances of the nodes.
+ ///
+ ///Returns a const reference to the node map that stores the distances
+ ///of the nodes calculated by the algorithm.
+ ///
+ ///\pre Either \ref run(Node) "run()" or \ref init()
+ ///must be called before using this function.
+ const DistMap &distMap() const { return *_dist;}
+
+ ///\brief Returns a const reference to the node map that stores the
+ ///predecessor arcs.
+ ///
+ ///Returns a const reference to the node map that stores the predecessor
+ ///arcs, which form the shortest path tree (forest).
+ ///
+ ///\pre Either \ref run(Node) "run()" or \ref init()
+ ///must be called before using this function.
+ const PredMap &predMap() const { return *_pred;}
+
+ ///Checks if the given node is reached from the root(s).
+
+ ///Returns \c true if \c v is reached from the root(s).
+ ///
+ ///\pre Either \ref run(Node) "run()" or \ref init()
+ ///must be called before using this function.
+ bool reached(Node v) const { return (*_reached)[v]; }
+
+ ///@}
+ };
+
+ ///Default traits class of bfs() function.
+
+ ///Default traits class of bfs() function.
+ ///\tparam GR Digraph type.
+ template<class GR>
+ struct BfsWizardDefaultTraits
+ {
+ ///The type of the digraph the algorithm runs on.
+ typedef GR Digraph;
+
+ ///\brief The type of the map that stores the predecessor
+ ///arcs of the shortest paths.
+ ///
+ ///The type of the map that stores the predecessor
+ ///arcs of the shortest paths.
+ ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+ typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
+ ///Instantiates a PredMap.
+
+ ///This function instantiates a PredMap.
+ ///\param g is the digraph, to which we would like to define the
+ ///PredMap.
+ static PredMap *createPredMap(const Digraph &g)
+ {
+ return new PredMap(g);
+ }
+
+ ///The type of the map that indicates which nodes are processed.
+
+ ///The type of the map that indicates which nodes are processed.
+ ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+ ///By default, it is a NullMap.
+ typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
+ ///Instantiates a ProcessedMap.
+
+ ///This function instantiates a ProcessedMap.
+ ///\param g is the digraph, to which
+ ///we would like to define the ProcessedMap.
+#ifdef DOXYGEN
+ static ProcessedMap *createProcessedMap(const Digraph &g)
+#else
+ static ProcessedMap *createProcessedMap(const Digraph &)
+#endif
+ {
+ return new ProcessedMap();
+ }
+
+ ///The type of the map that indicates which nodes are reached.
+
+ ///The type of the map that indicates which nodes are reached.
+ ///It must conform to
+ ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+ typedef typename Digraph::template NodeMap<bool> ReachedMap;
+ ///Instantiates a ReachedMap.
+
+ ///This function instantiates a ReachedMap.
+ ///\param g is the digraph, to which
+ ///we would like to define the ReachedMap.
+ static ReachedMap *createReachedMap(const Digraph &g)
+ {
+ return new ReachedMap(g);
+ }
+
+ ///The type of the map that stores the distances of the nodes.
+
+ ///The type of the map that stores the distances of the nodes.
+ ///It must conform to the \ref concepts::WriteMap "WriteMap" concept.
+ typedef typename Digraph::template NodeMap<int> DistMap;
+ ///Instantiates a DistMap.
+
+ ///This function instantiates a DistMap.
+ ///\param g is the digraph, to which we would like to define
+ ///the DistMap
+ static DistMap *createDistMap(const Digraph &g)
+ {
+ return new DistMap(g);
+ }
+
+ ///The type of the shortest paths.
+
+ ///The type of the shortest paths.
+ ///It must conform to the \ref concepts::Path "Path" concept.
+ typedef lemon::Path<Digraph> Path;
+ };
+
+ /// Default traits class used by BfsWizard
+
+ /// Default traits class used by BfsWizard.
+ /// \tparam GR The type of the digraph.
+ template<class GR>
+ class BfsWizardBase : public BfsWizardDefaultTraits<GR>
+ {
+
+ typedef BfsWizardDefaultTraits<GR> Base;
+ protected:
+ //The type of the nodes in the digraph.
+ typedef typename Base::Digraph::Node Node;
+
+ //Pointer to the digraph the algorithm runs on.
+ void *_g;
+ //Pointer to the map of reached nodes.
+ void *_reached;
+ //Pointer to the map of processed nodes.
+ void *_processed;
+ //Pointer to the map of predecessors arcs.
+ void *_pred;
+ //Pointer to the map of distances.
+ void *_dist;
+ //Pointer to the shortest path to the target node.
+ void *_path;
+ //Pointer to the distance of the target node.
+ int *_di;
+
+ public:
+ /// Constructor.
+
+ /// This constructor does not require parameters, it initiates
+ /// all of the attributes to \c 0.
+ BfsWizardBase() : _g(0), _reached(0), _processed(0), _pred(0),
+ _dist(0), _path(0), _di(0) {}
+
+ /// Constructor.
+
+ /// This constructor requires one parameter,
+ /// others are initiated to \c 0.
+ /// \param g The digraph the algorithm runs on.
+ BfsWizardBase(const GR &g) :
+ _g(reinterpret_cast<void*>(const_cast<GR*>(&g))),
+ _reached(0), _processed(0), _pred(0), _dist(0), _path(0), _di(0) {}
+
+ };
+
+ /// Auxiliary class for the function-type interface of BFS algorithm.
+
+ /// This auxiliary class is created to implement the
+ /// \ref bfs() "function-type interface" of \ref Bfs algorithm.
+ /// It does not have own \ref run(Node) "run()" method, it uses the
+ /// functions and features of the plain \ref Bfs.
+ ///
+ /// This class should only be used through the \ref bfs() function,
+ /// which makes it easier to use the algorithm.
+ ///
+ /// \tparam TR The traits class that defines various types used by the
+ /// algorithm.
+ template<class TR>
+ class BfsWizard : public TR
+ {
+ typedef TR Base;
+
+ typedef typename TR::Digraph Digraph;
+
+ typedef typename Digraph::Node Node;
+ typedef typename Digraph::NodeIt NodeIt;
+ typedef typename Digraph::Arc Arc;
+ typedef typename Digraph::OutArcIt OutArcIt;
+
+ typedef typename TR::PredMap PredMap;
+ typedef typename TR::DistMap DistMap;
+ typedef typename TR::ReachedMap ReachedMap;
+ typedef typename TR::ProcessedMap ProcessedMap;
+ typedef typename TR::Path Path;
+
+ public:
+
+ /// Constructor.
+ BfsWizard() : TR() {}
+
+ /// Constructor that requires parameters.
+
+ /// Constructor that requires parameters.
+ /// These parameters will be the default values for the traits class.
+ /// \param g The digraph the algorithm runs on.
+ BfsWizard(const Digraph &g) :
+ TR(g) {}
+
+ ///Copy constructor
+ BfsWizard(const TR &b) : TR(b) {}
+
+ ~BfsWizard() {}
+
+ ///Runs BFS algorithm from the given source node.
+
+ ///This method runs BFS algorithm from node \c s
+ ///in order to compute the shortest path to each node.
+ void run(Node s)
+ {
+ Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
+ if (Base::_pred)
+ alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+ if (Base::_dist)
+ alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+ if (Base::_reached)
+ alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
+ if (Base::_processed)
+ alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
+ if (s!=INVALID)
+ alg.run(s);
+ else
+ alg.run();
+ }
+
+ ///Finds the shortest path between \c s and \c t.
+
+ ///This method runs BFS algorithm from node \c s
+ ///in order to compute the shortest path to node \c t
+ ///(it stops searching when \c t is processed).
+ ///
+ ///\return \c true if \c t is reachable form \c s.
+ bool run(Node s, Node t)
+ {
+ Bfs<Digraph,TR> alg(*reinterpret_cast<const Digraph*>(Base::_g));
+ if (Base::_pred)
+ alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred));
+ if (Base::_dist)
+ alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist));
+ if (Base::_reached)
+ alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached));
+ if (Base::_processed)
+ alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed));
+ alg.run(s,t);
+ if (Base::_path)
+ *reinterpret_cast<Path*>(Base::_path) = alg.path(t);
+ if (Base::_di)
+ *Base::_di = alg.dist(t);
+ return alg.reached(t);
+ }
+
+ ///Runs BFS algorithm to visit all nodes in the digraph.
+
+ ///This method runs BFS algorithm in order to visit all nodes
+ ///in the digraph.
+ void run()
+ {
+ run(INVALID);
+ }
+
+ template<class T>
+ struct SetPredMapBase : public Base {
+ typedef T PredMap;
+ static PredMap *createPredMap(const Digraph &) { return 0; };
+ SetPredMapBase(const TR &b) : TR(b) {}
+ };
+
+ ///\brief \ref named-templ-param "Named parameter" for setting
+ ///the predecessor map.
+ ///
+ ///\ref named-templ-param "Named parameter" function for setting
+ ///the map that stores the predecessor arcs of the nodes.
+ template<class T>
+ BfsWizard<SetPredMapBase<T> > predMap(const T &t)
+ {
+ Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
+ return BfsWizard<SetPredMapBase<T> >(*this);
+ }
+
+ template<class T>
+ struct SetReachedMapBase : public Base {
+ typedef T ReachedMap;
+ static ReachedMap *createReachedMap(const Digraph &) { return 0; };
+ SetReachedMapBase(const TR &b) : TR(b) {}
+ };
+
+ ///\brief \ref named-templ-param "Named parameter" for setting
+ ///the reached map.
+ ///
+ ///\ref named-templ-param "Named parameter" function for setting
+ ///the map that indicates which nodes are reached.
+ template<class T>
+ BfsWizard<SetReachedMapBase<T> > reachedMap(const T &t)
+ {
+ Base::_reached=reinterpret_cast<void*>(const_cast<T*>(&t));
+ return BfsWizard<SetReachedMapBase<T> >(*this);
+ }
+
+ template<class T>
+ struct SetDistMapBase : public Base {
+ typedef T DistMap;
+ static DistMap *createDistMap(const Digraph &) { return 0; };
+ SetDistMapBase(const TR &b) : TR(b) {}
+ };
+
+ ///\brief \ref named-templ-param "Named parameter" for setting
+ ///the distance map.
+ ///
+ ///\ref named-templ-param "Named parameter" function for setting
+ ///the map that stores the distances of the nodes calculated
+ ///by the algorithm.
+ template<class T>
+ BfsWizard<SetDistMapBase<T> > distMap(const T &t)
+ {
+ Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t));
+ return BfsWizard<SetDistMapBase<T> >(*this);
+ }
+
+ template<class T>
+ struct SetProcessedMapBase : public Base {
+ typedef T ProcessedMap;
+ static ProcessedMap *createProcessedMap(const Digraph &) { return 0; };
+ SetProcessedMapBase(const TR &b) : TR(b) {}
+ };
+
+ ///\brief \ref named-func-param "Named parameter" for setting
+ ///the processed map.
+ ///
+ ///\ref named-templ-param "Named parameter" function for setting
+ ///the map that indicates which nodes are processed.
+ template<class T>
+ BfsWizard<SetProcessedMapBase<T> > processedMap(const T &t)
+ {
+ Base::_processed=reinterpret_cast<void*>(const_cast<T*>(&t));
+ return BfsWizard<SetProcessedMapBase<T> >(*this);
+ }
+
+ template<class T>
+ struct SetPathBase : public Base {
+ typedef T Path;
+ SetPathBase(const TR &b) : TR(b) {}
+ };
+ ///\brief \ref named-func-param "Named parameter"
+ ///for getting the shortest path to the target node.
+ ///
+ ///\ref named-func-param "Named parameter"
+ ///for getting the shortest path to the target node.
+ template<class T>
+ BfsWizard<SetPathBase<T> > path(const T &t)
+ {
+ Base::_path=reinterpret_cast<void*>(const_cast<T*>(&t));
+ return BfsWizard<SetPathBase<T> >(*this);
+ }
+
+ ///\brief \ref named-func-param "Named parameter"
+ ///for getting the distance of the target node.
+ ///
+ ///\ref named-func-param "Named parameter"
+ ///for getting the distance of the target node.
+ BfsWizard dist(const int &d)
+ {
+ Base::_di=const_cast<int*>(&d);
+ return *this;
+ }
+
+ };
+
+ ///Function-type interface for BFS algorithm.
+
+ /// \ingroup search
+ ///Function-type interface for BFS algorithm.
+ ///
+ ///This function also has several \ref named-func-param "named parameters",
+ ///they are declared as the members of class \ref BfsWizard.
+ ///The following examples show how to use these parameters.
+ ///\code
+ /// // Compute shortest path from node s to each node
+ /// bfs(g).predMap(preds).distMap(dists).run(s);
+ ///
+ /// // Compute shortest path from s to t
+ /// bool reached = bfs(g).path(p).dist(d).run(s,t);
+ ///\endcode
+ ///\warning Don't forget to put the \ref BfsWizard::run(Node) "run()"
+ ///to the end of the parameter list.
+ ///\sa BfsWizard
+ ///\sa Bfs
+ template<class GR>
+ BfsWizard<BfsWizardBase<GR> >
+ bfs(const GR &digraph)
+ {
+ return BfsWizard<BfsWizardBase<GR> >(digraph);
+ }
+
+#ifdef DOXYGEN
+ /// \brief Visitor class for BFS.
+ ///
+ /// This class defines the interface of the BfsVisit events, and
+ /// it could be the base of a real visitor class.
+ template <typename GR>
+ struct BfsVisitor {
+ typedef GR Digraph;
+ typedef typename Digraph::Arc Arc;
+ typedef typename Digraph::Node Node;
+ /// \brief Called for the source node(s) of the BFS.
+ ///
+ /// This function is called for the source node(s) of the BFS.
+ void start(const Node& node) {}
+ /// \brief Called when a node is reached first time.
+ ///
+ /// This function is called when a node is reached first time.
+ void reach(const Node& node) {}
+ /// \brief Called when a node is processed.
+ ///
+ /// This function is called when a node is processed.
+ void process(const Node& node) {}
+ /// \brief Called when an arc reaches a new node.
+ ///
+ /// This function is called when the BFS finds an arc whose target node
+ /// is not reached yet.
+ void discover(const Arc& arc) {}
+ /// \brief Called when an arc is examined but its target node is
+ /// already discovered.
+ ///
+ /// This function is called when an arc is examined but its target node is
+ /// already discovered.
+ void examine(const Arc& arc) {}
+ };
+#else
+ template <typename GR>
+ struct BfsVisitor {
+ typedef GR Digraph;
+ typedef typename Digraph::Arc Arc;
+ typedef typename Digraph::Node Node;
+ void start(const Node&) {}
+ void reach(const Node&) {}
+ void process(const Node&) {}
+ void discover(const Arc&) {}
+ void examine(const Arc&) {}
+
+ template <typename _Visitor>
+ struct Constraints {
+ void constraints() {
+ Arc arc;
+ Node node;
+ visitor.start(node);
+ visitor.reach(node);
+ visitor.process(node);
+ visitor.discover(arc);
+ visitor.examine(arc);
+ }
+ _Visitor& visitor;
+ Constraints() {}
+ };
+ };
+#endif
+
+ /// \brief Default traits class of BfsVisit class.
+ ///
+ /// Default traits class of BfsVisit class.
+ /// \tparam GR The type of the digraph the algorithm runs on.
+ template<class GR>
+ struct BfsVisitDefaultTraits {
+
+ /// \brief The type of the digraph the algorithm runs on.
+ typedef GR Digraph;
+
+ /// \brief The type of the map that indicates which nodes are reached.
+ ///
+ /// The type of the map that indicates which nodes are reached.
+ /// It must conform to
+ ///the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
+ typedef typename Digraph::template NodeMap<bool> ReachedMap;
+
+ /// \brief Instantiates a ReachedMap.
+ ///
+ /// This function instantiates a ReachedMap.
+ /// \param digraph is the digraph, to which
+ /// we would like to define the ReachedMap.
+ static ReachedMap *createReachedMap(const Digraph &digraph) {
+ return new ReachedMap(digraph);
+ }
+
+ };
+
+ /// \ingroup search
+ ///
+ /// \brief BFS algorithm class with visitor interface.
+ ///
+ /// This class provides an efficient implementation of the BFS algorithm
+ /// with visitor interface.
+ ///
+ /// The BfsVisit class provides an alternative interface to the Bfs
+ /// class. It works with callback mechanism, the BfsVisit object calls
+ /// the member functions of the \c Visitor class on every BFS event.
+ ///
+ /// This interface of the BFS algorithm should be used in special cases
+ /// when extra actions have to be performed in connection with certain
+ /// events of the BFS algorithm. Otherwise consider to use Bfs or bfs()
+ /// instead.
+ ///
+ /// \tparam GR The type of the digraph the algorithm runs on.
+ /// The default type is \ref ListDigraph.
+ /// The value of GR is not used directly by \ref BfsVisit,
+ /// it is only passed to \ref BfsVisitDefaultTraits.
+ /// \tparam VS The Visitor type that is used by the algorithm.
+ /// \ref BfsVisitor "BfsVisitor<GR>" is an empty visitor, which
+ /// does not observe the BFS events. If you want to observe the BFS
+ /// events, you should implement your own visitor class.
+ /// \tparam TR The traits class that defines various types used by the
+ /// algorithm. By default, it is \ref BfsVisitDefaultTraits
+ /// "BfsVisitDefaultTraits<GR>".
+ /// In most cases, this parameter should not be set directly,
+ /// consider to use the named template parameters instead.
+#ifdef DOXYGEN
+ template <typename GR, typename VS, typename TR>
+#else
+ template <typename GR = ListDigraph,
+ typename VS = BfsVisitor<GR>,
+ typename TR = BfsVisitDefaultTraits<GR> >
+#endif
+ class BfsVisit {
+ public:
+
+ ///The traits class.
+ typedef TR Traits;
+
+ ///The type of the digraph the algorithm runs on.
+ typedef typename Traits::Digraph Digraph;
+
+ ///The visitor type used by the algorithm.
+ typedef VS Visitor;
+
+ ///The type of the map that indicates which nodes are reached.
+ typedef typename Traits::ReachedMap ReachedMap;
+
+ private:
+
+ typedef typename Digraph::Node Node;
+ typedef typename Digraph::NodeIt NodeIt;
+ typedef typename Digraph::Arc Arc;
+ typedef typename Digraph::OutArcIt OutArcIt;
+
+ //Pointer to the underlying digraph.
+ const Digraph *_digraph;
+ //Pointer to the visitor object.
+ Visitor *_visitor;
+ //Pointer to the map of reached status of the nodes.
+ ReachedMap *_reached;
+ //Indicates if _reached is locally allocated (true) or not.
+ bool local_reached;
+
+ std::vector<typename Digraph::Node> _list;
+ int _list_front, _list_back;
+
+ //Creates the maps if necessary.
+ void create_maps() {
+ if(!_reached) {
+ local_reached = true;
+ _reached = Traits::createReachedMap(*_digraph);
+ }
+ }
+
+ protected:
+
+ BfsVisit() {}
+
+ public:
+
+ typedef BfsVisit Create;
+
+ /// \name Named Template Parameters
+
+ ///@{
+ template <class T>
+ struct SetReachedMapTraits : public Traits {
+ typedef T ReachedMap;
+ static ReachedMap *createReachedMap(const Digraph &digraph) {
+ LEMON_ASSERT(false, "ReachedMap is not initialized");
+ return 0; // ignore warnings
+ }
+ };
+ /// \brief \ref named-templ-param "Named parameter" for setting
+ /// ReachedMap type.
+ ///
+ /// \ref named-templ-param "Named parameter" for setting ReachedMap type.
+ template <class T>
+ struct SetReachedMap : public BfsVisit< Digraph, Visitor,
+ SetReachedMapTraits<T> > {
+ typedef BfsVisit< Digraph, Visitor, SetReachedMapTraits<T> > Create;
+ };
+ ///@}
+
+ public:
+
+ /// \brief Constructor.
+ ///
+ /// Constructor.
+ ///
+ /// \param digraph The digraph the algorithm runs on.
+ /// \param visitor The visitor object of the algorithm.
+ BfsVisit(const Digraph& digraph, Visitor& visitor)
+ : _digraph(&digraph), _visitor(&visitor),
+ _reached(0), local_reached(false) {}
+
+ /// \brief Destructor.
+ ~BfsVisit() {
+ if(local_reached) delete _reached;
+ }
+
+ /// \brief Sets the map that indicates which nodes are reached.
+ ///
+ /// Sets the map that indicates which nodes are reached.
+ /// If you don't use this function before calling \ref run(Node) "run()"
+ /// or \ref init(), an instance will be allocated automatically.
+ /// The destructor deallocates this automatically allocated map,
+ /// of course.
+ /// \return <tt> (*this) </tt>
+ BfsVisit &reachedMap(ReachedMap &m) {
+ if(local_reached) {
+ delete _reached;
+ local_reached = false;
+ }
+ _reached = &m;
+ return *this;
+ }
+
+ public:
+
+ /// \name Execution Control
+ /// The simplest way to execute the BFS algorithm is to use one of the
+ /// member functions called \ref run(Node) "run()".\n
+ /// If you need better control on the execution, you have to call
+ /// \ref init() first, then you can add several source nodes with
+ /// \ref addSource(). Finally the actual path computation can be
+ /// performed with one of the \ref start() functions.
+
+ /// @{
+
+ /// \brief Initializes the internal data structures.
+ ///
+ /// Initializes the internal data structures.
+ void init() {
+ create_maps();
+ _list.resize(countNodes(*_digraph));
+ _list_front = _list_back = -1;
+ for (NodeIt u(*_digraph) ; u != INVALID ; ++u) {
+ _reached->set(u, false);
+ }
+ }
+
+ /// \brief Adds a new source node.
+ ///
+ /// Adds a new source node to the set of nodes to be processed.
+ void addSource(Node s) {
+ if(!(*_reached)[s]) {
+ _reached->set(s,true);
+ _visitor->start(s);
+ _visitor->reach(s);
+ _list[++_list_back] = s;
+ }
+ }
+
+ /// \brief Processes the next node.
+ ///
+ /// Processes the next node.
+ ///
+ /// \return The processed node.
+ ///
+ /// \pre The queue must not be empty.
+ Node processNextNode() {
+ Node n = _list[++_list_front];
+ _visitor->process(n);
+ Arc e;
+ for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
+ Node m = _digraph->target(e);
+ if (!(*_reached)[m]) {
+ _visitor->discover(e);
+ _visitor->reach(m);
+ _reached->set(m, true);
+ _list[++_list_back] = m;
+ } else {
+ _visitor->examine(e);
+ }
+ }
+ return n;
+ }
+
+ /// \brief Processes the next node.
+ ///
+ /// Processes the next node and checks if the given target node
+ /// is reached. If the target node is reachable from the processed
+ /// node, then the \c reach parameter will be set to \c true.
+ ///
+ /// \param target The target node.
+ /// \retval reach Indicates if the target node is reached.
+ /// It should be initially \c false.
+ ///
+ /// \return The processed node.
+ ///
+ /// \pre The queue must not be empty.
+ Node processNextNode(Node target, bool& reach) {
+ Node n = _list[++_list_front];
+ _visitor->process(n);
+ Arc e;
+ for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
+ Node m = _digraph->target(e);
+ if (!(*_reached)[m]) {
+ _visitor->discover(e);
+ _visitor->reach(m);
+ _reached->set(m, true);
+ _list[++_list_back] = m;
+ reach = reach || (target == m);
+ } else {
+ _visitor->examine(e);
+ }
+ }
+ return n;
+ }
+
+ /// \brief Processes the next node.
+ ///
+ /// Processes the next node and checks if at least one of reached
+ /// nodes has \c true value in the \c nm node map. If one node
+ /// with \c true value is reachable from the processed node, then the
+ /// \c rnode parameter will be set to the first of such nodes.
+ ///
+ /// \param nm A \c bool (or convertible) node map that indicates the
+ /// possible targets.
+ /// \retval rnode The reached target node.
+ /// It should be initially \c INVALID.
+ ///
+ /// \return The processed node.
+ ///
+ /// \pre The queue must not be empty.
+ template <typename NM>
+ Node processNextNode(const NM& nm, Node& rnode) {
+ Node n = _list[++_list_front];
+ _visitor->process(n);
+ Arc e;
+ for (_digraph->firstOut(e, n); e != INVALID; _digraph->nextOut(e)) {
+ Node m = _digraph->target(e);
+ if (!(*_reached)[m]) {
+ _visitor->discover(e);
+ _visitor->reach(m);
+ _reached->set(m, true);
+ _list[++_list_back] = m;
+ if (nm[m] && rnode == INVALID) rnode = m;
+ } else {
+ _visitor->examine(e);
+ }
+ }
+ return n;
+ }
+
+ /// \brief The next node to be processed.
+ ///
+ /// Returns the next node to be processed or \c INVALID if the queue
+ /// is empty.
+ Node nextNode() const {
+ return _list_front != _list_back ? _list[_list_front + 1] : INVALID;
+ }
+
+ /// \brief Returns \c false if there are nodes
+ /// to be processed.
+ ///
+ /// Returns \c false if there are nodes
+ /// to be processed in the queue.
+ bool emptyQueue() const { return _list_front == _list_back; }
+
+ /// \brief Returns the number of the nodes to be processed.
+ ///
+ /// Returns the number of the nodes to be processed in the queue.
+ int queueSize() const { return _list_back - _list_front; }
+
+ /// \brief Executes the algorithm.
+ ///
+ /// Executes the algorithm.
+ ///
+ /// This method runs the %BFS algorithm from the root node(s)
+ /// in order to compute the shortest path to each node.
+ ///
+ /// The algorithm computes
+ /// - the shortest path tree (forest),
+ /// - the distance of each node from the root(s).
+ ///
+ /// \pre init() must be called and at least one root node should be added
+ /// with addSource() before using this function.
+ ///
+ /// \note <tt>b.start()</tt> is just a shortcut of the following code.
+ /// \code
+ /// while ( !b.emptyQueue() ) {
+ /// b.processNextNode();
+ /// }
+ /// \endcode
+ void start() {
+ while ( !emptyQueue() ) processNextNode();
+ }
+
+ /// \brief Executes the algorithm until the given target node is reached.
+ ///
+ /// Executes the algorithm until the given target node is reached.
+ ///
+ /// This method runs the %BFS algorithm from the root node(s)
+ /// in order to compute the shortest path to \c t.
+ ///
+ /// The algorithm computes
+ /// - the shortest path to \c t,
+ /// - the distance of \c t from the root(s).
+ ///
+ /// \pre init() must be called and at least one root node should be
+ /// added with addSource() before using this function.
+ ///
+ /// \note <tt>b.start(t)</tt> is just a shortcut of the following code.
+ /// \code
+ /// bool reach = false;
+ /// while ( !b.emptyQueue() && !reach ) {
+ /// b.processNextNode(t, reach);
+ /// }
+ /// \endcode
+ void start(Node t) {
+ bool reach = false;
+ while ( !emptyQueue() && !reach ) processNextNode(t, reach);
+ }
+
+ /// \brief Executes the algorithm until a condition is met.
+ ///
+ /// Executes the algorithm until a condition is met.
+ ///
+ /// This method runs the %BFS algorithm from the root node(s) in
+ /// order to compute the shortest path to a node \c v with
+ /// <tt>nm[v]</tt> true, if such a node can be found.
+ ///
+ /// \param nm must be a bool (or convertible) node map. The
+ /// algorithm will stop when it reaches a node \c v with
+ /// <tt>nm[v]</tt> true.
+ ///
+ /// \return The reached node \c v with <tt>nm[v]</tt> true or
+ /// \c INVALID if no such node was found.
+ ///
+ /// \pre init() must be called and at least one root node should be
+ /// added with addSource() before using this function.
+ ///
+ /// \note <tt>b.start(nm)</tt> is just a shortcut of the following code.
+ /// \code
+ /// Node rnode = INVALID;
+ /// while ( !b.emptyQueue() && rnode == INVALID ) {
+ /// b.processNextNode(nm, rnode);
+ /// }
+ /// return rnode;
+ /// \endcode
+ template <typename NM>
+ Node start(const NM &nm) {
+ Node rnode = INVALID;
+ while ( !emptyQueue() && rnode == INVALID ) {
+ processNextNode(nm, rnode);
+ }
+ return rnode;
+ }
+
+ /// \brief Runs the algorithm from the given source node.
+ ///
+ /// This method runs the %BFS algorithm from node \c s
+ /// in order to compute the shortest path to each node.
+ ///
+ /// The algorithm computes
+ /// - the shortest path tree,
+ /// - the distance of each node from the root.
+ ///
+ /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
+ ///\code
+ /// b.init();
+ /// b.addSource(s);
+ /// b.start();
+ ///\endcode
+ void run(Node s) {
+ init();
+ addSource(s);
+ start();
+ }
+
+ /// \brief Finds the shortest path between \c s and \c t.
+ ///
+ /// This method runs the %BFS algorithm from node \c s
+ /// in order to compute the shortest path to node \c t
+ /// (it stops searching when \c t is processed).
+ ///
+ /// \return \c true if \c t is reachable form \c s.
+ ///
+ /// \note Apart from the return value, <tt>b.run(s,t)</tt> is just a
+ /// shortcut of the following code.
+ ///\code
+ /// b.init();
+ /// b.addSource(s);
+ /// b.start(t);
+ ///\endcode
+ bool run(Node s,Node t) {
+ init();
+ addSource(s);
+ start(t);
+ return reached(t);
+ }
+
+ /// \brief Runs the algorithm to visit all nodes in the digraph.
+ ///
+ /// This method runs the %BFS algorithm in order to visit all nodes
+ /// in the digraph.
+ ///
+ /// \note <tt>b.run(s)</tt> is just a shortcut of the following code.
+ ///\code
+ /// b.init();
+ /// for (NodeIt n(gr); n != INVALID; ++n) {
+ /// if (!b.reached(n)) {
+ /// b.addSource(n);
+ /// b.start();
+ /// }
+ /// }
+ ///\endcode
+ void run() {
+ init();
+ for (NodeIt it(*_digraph); it != INVALID; ++it) {
+ if (!reached(it)) {
+ addSource(it);
+ start();
+ }
+ }
+ }
+
+ ///@}
+
+ /// \name Query Functions
+ /// The results of the BFS algorithm can be obtained using these
+ /// functions.\n
+ /// Either \ref run(Node) "run()" or \ref start() should be called
+ /// before using them.
+
+ ///@{
+
+ /// \brief Checks if the given node is reached from the root(s).
+ ///
+ /// Returns \c true if \c v is reached from the root(s).
+ ///
+ /// \pre Either \ref run(Node) "run()" or \ref init()
+ /// must be called before using this function.
+ bool reached(Node v) const { return (*_reached)[v]; }
+
+ ///@}
+
+ };
+
+} //END OF NAMESPACE LEMON
+
+#endif