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. |
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. |