lemon/bfs.h
changeset 2459 ea943997a8fe
parent 2438 718479989797
child 2476 059dcdda37c5
equal deleted inserted replaced
28:2723ffb700f9 29:f53a43d50388
   513     }
   513     }
   514 
   514 
   515     ///Processes the next node.
   515     ///Processes the next node.
   516 
   516 
   517     ///Processes the next node. And checks that at least one of
   517     ///Processes the next node. And checks that at least one of
   518     ///reached node has true value in the \c nm nodemap. If one node
   518     ///reached node has true value in the \c nm node map. If one node
   519     ///with true value is reachable from the processed node then the
   519     ///with true value is reachable from the processed node then the
   520     ///reached parameter will be set true. The reached parameter
   520     ///rnode parameter will be set to the first of such nodes.
   521     ///should be initially false.
   521     ///
   522     ///
   522     ///\param nm The node map of possible targets.
   523     ///\param nm The nodemaps of possible targets.
   523     ///\retval rnode The reached target node.
   524     ///\retval reach Indicates that one of the target nodes is reached.
       
   525     ///\return The processed node.
   524     ///\return The processed node.
   526     ///
   525     ///
   527     ///\warning The queue must not be empty!
   526     ///\warning The queue must not be empty!
   528     template<class NM>
   527     template<class NM>
   529     Node processNextNode(const NM& nm, bool& reach)
   528     Node processNextNode(const NM& nm, Node& rnode)
   530     {
   529     {
   531       if(_queue_tail==_queue_next_dist) {
   530       if(_queue_tail==_queue_next_dist) {
   532 	_curr_dist++;
   531 	_curr_dist++;
   533 	_queue_next_dist=_queue_head;
   532 	_queue_next_dist=_queue_head;
   534       }
   533       }
   539 	if(!(*_reached)[m=G->target(e)]) {
   538 	if(!(*_reached)[m=G->target(e)]) {
   540 	  _queue[_queue_head++]=m;
   539 	  _queue[_queue_head++]=m;
   541 	  _reached->set(m,true);
   540 	  _reached->set(m,true);
   542 	  _pred->set(m,e);
   541 	  _pred->set(m,e);
   543 	  _dist->set(m,_curr_dist);
   542 	  _dist->set(m,_curr_dist);
   544           reach = reach || nm[m];
   543 	  if (nm[m] && rnode == INVALID) rnode = m;
   545 	}
   544 	}
   546       return n;
   545       return n;
   547     }
   546     }
   548       
   547       
   549     ///Next node to be processed.
   548     ///Next node to be processed.
   564     ///to be processed in the queue
   563     ///to be processed in the queue
   565     bool emptyQueue() { return _queue_tail==_queue_head; }
   564     bool emptyQueue() { return _queue_tail==_queue_head; }
   566     ///Returns the number of the nodes to be processed.
   565     ///Returns the number of the nodes to be processed.
   567     
   566     
   568     ///Returns the number of the nodes to be processed in the queue.
   567     ///Returns the number of the nodes to be processed in the queue.
   569     ///
       
   570     int queueSize() { return _queue_head-_queue_tail; }
   568     int queueSize() { return _queue_head-_queue_tail; }
   571     
   569     
   572     ///Executes the algorithm.
   570     ///Executes the algorithm.
   573 
   571 
   574     ///Executes the algorithm.
   572     ///Executes the algorithm.
   580     ///in order to
   578     ///in order to
   581     ///compute the
   579     ///compute the
   582     ///shortest path to each node. The algorithm computes
   580     ///shortest path to each node. The algorithm computes
   583     ///- The shortest path tree.
   581     ///- The shortest path tree.
   584     ///- The distance of each node from the root(s).
   582     ///- The distance of each node from the root(s).
   585     ///
       
   586     void start()
   583     void start()
   587     {
   584     {
   588       while ( !emptyQueue() ) processNextNode();
   585       while ( !emptyQueue() ) processNextNode();
   589     }
   586     }
   590     
   587     
   599     ///in order to
   596     ///in order to
   600     ///compute the
   597     ///compute the
   601     ///shortest path to \c dest. The algorithm computes
   598     ///shortest path to \c dest. The algorithm computes
   602     ///- The shortest path to \c  dest.
   599     ///- The shortest path to \c  dest.
   603     ///- The distance of \c dest from the root(s).
   600     ///- The distance of \c dest from the root(s).
   604     ///
       
   605     void start(Node dest)
   601     void start(Node dest)
   606     {
   602     {
   607       bool reach = false;
   603       bool reach = false;
   608       while ( !emptyQueue() && !reach ) processNextNode(dest, reach);
   604       while ( !emptyQueue() && !reach ) processNextNode(dest, reach);
   609     }
   605     }
   614     ///
   610     ///
   615     ///\pre init() must be called and at least one node should be added
   611     ///\pre init() must be called and at least one node should be added
   616     ///with addSource() before using this function.
   612     ///with addSource() before using this function.
   617     ///
   613     ///
   618     ///\param nm must be a bool (or convertible) node map. The
   614     ///\param nm must be a bool (or convertible) node map. The
   619     ///algorithm will stop when it reached a node \c v with
   615     ///algorithm will stop when it reaches a node \c v with
   620     /// <tt>nm[v]</tt> true.
   616     /// <tt>nm[v]</tt> true.
   621     ///\todo query the reached target
   617     ///
       
   618     ///\return The reached node \c v with <tt>nm[v]<\tt> true or
       
   619     ///\c INVALID if no such node was found.
   622     template<class NM>
   620     template<class NM>
   623     void start(const NM &nm)
   621     Node start(const NM &nm)
   624     {
   622     {
   625       bool reach = false;
   623       Node rnode = INVALID;
   626       while ( !emptyQueue() && !reach ) processNextNode(nm, reach);
   624       while ( !emptyQueue() && rnode == INVALID ) {
       
   625 	processNextNode(nm, rnode);
       
   626       }
       
   627       return rnode;
   627     }
   628     }
   628     
   629     
   629     ///Runs %BFS algorithm from node \c s.
   630     ///Runs %BFS algorithm from node \c s.
   630     
   631     
   631     ///This method runs the %BFS algorithm from a root node \c s
   632     ///This method runs the %BFS algorithm from a root node \c s
  1431     }
  1432     }
  1432 
  1433 
  1433     /// \brief Processes the next node.
  1434     /// \brief Processes the next node.
  1434     ///
  1435     ///
  1435     /// Processes the next node. And checks that at least one of
  1436     /// Processes the next node. And checks that at least one of
  1436     /// reached node has true value in the \c nm nodemap. If one node
  1437     /// reached node has true value in the \c nm node map. If one node
  1437     /// with true value is reachable from the processed node then the
  1438     /// with true value is reachable from the processed node then the
  1438     /// reached parameter will be set true. The reached parameter
  1439     /// rnode parameter will be set to the first of such nodes.
  1439     /// should be initially false.
  1440     ///
  1440     ///
  1441     /// \param nm The node map of possible targets.
  1441     /// \param nm The nodemaps of possible targets.
  1442     /// \retval rnode The reached target node.
  1442     /// \retval reached Indicates that one of the target nodes is reached.
       
  1443     /// \return The processed node.
  1443     /// \return The processed node.
  1444     ///
  1444     ///
  1445     /// \warning The queue must not be empty!
  1445     /// \warning The queue must not be empty!
  1446     template <typename NM>
  1446     template <typename NM>
  1447     Node processNextNode(const NM& nm, bool& reach) {
  1447     Node processNextNode(const NM& nm, Node& rnode) {
  1448       Node n = _list[++_list_front];
  1448       Node n = _list[++_list_front];
  1449       _visitor->process(n);
  1449       _visitor->process(n);
  1450       Edge e;
  1450       Edge e;
  1451       for (_graph->firstOut(e, n); e != INVALID; _graph->nextOut(e)) {
  1451       for (_graph->firstOut(e, n); e != INVALID; _graph->nextOut(e)) {
  1452         Node m = _graph->target(e);
  1452         Node m = _graph->target(e);
  1453         if (!(*_reached)[m]) {
  1453         if (!(*_reached)[m]) {
  1454           _visitor->discover(e);
  1454           _visitor->discover(e);
  1455           _visitor->reach(m);
  1455           _visitor->reach(m);
  1456           _reached->set(m, true);
  1456           _reached->set(m, true);
  1457           _list[++_list_back] = m;
  1457           _list[++_list_back] = m;
  1458           reach = reach || nm[m];
  1458           if (nm[m] && rnode == INVALID) rnode = m;
  1459         } else {
  1459         } else {
  1460           _visitor->examine(e);
  1460           _visitor->examine(e);
  1461         }
  1461         }
  1462       }
  1462       }
  1463       return n;
  1463       return n;
  1512     ///
  1512     ///
  1513     /// \pre init() must be called and at least one node should be added
  1513     /// \pre init() must be called and at least one node should be added
  1514     /// with addSource() before using this function.
  1514     /// with addSource() before using this function.
  1515     ///
  1515     ///
  1516     ///\param nm must be a bool (or convertible) node map. The
  1516     ///\param nm must be a bool (or convertible) node map. The
  1517     ///algorithm will stop when it reached a node \c v with
  1517     ///algorithm will stop when it reaches a node \c v with
  1518     /// <tt>nm[v]</tt> true.
  1518     /// <tt>nm[v]</tt> true.
       
  1519     ///
       
  1520     ///\return The reached node \c v with <tt>nm[v]<\tt> true or
       
  1521     ///\c INVALID if no such node was found.
  1519     template <typename NM>
  1522     template <typename NM>
  1520     void start(const NM &nm) {
  1523     Node start(const NM &nm) {
  1521       bool reach = false;
  1524       Node rnode = INVALID;
  1522       while ( !emptyQueue() && !reach ) processNextNode(nm, reach);
  1525       while ( !emptyQueue() && rnode == INVALID ) {
       
  1526 	processNextNode(nm, rnode);
       
  1527       }
       
  1528       return rnode;
  1523     }
  1529     }
  1524 
  1530 
  1525     /// \brief Runs %BFSVisit algorithm from node \c s.
  1531     /// \brief Runs %BFSVisit algorithm from node \c s.
  1526     ///
  1532     ///
  1527     /// This method runs the %BFS algorithm from a root node \c s.
  1533     /// This method runs the %BFS algorithm from a root node \c s.