486 ///is reached. If the target node is reachable from the processed |
486 ///is reached. If the target node is reachable from the processed |
487 ///node then the reached parameter will be set true. The reached |
487 ///node then the reached parameter will be set true. The reached |
488 ///parameter should be initially false. |
488 ///parameter should be initially false. |
489 /// |
489 /// |
490 ///\param target The target node. |
490 ///\param target The target node. |
491 ///\retval reached Indicates that the target node is reached. |
491 ///\retval reach Indicates that the target node is reached. |
492 ///\return The processed node. |
492 ///\return The processed node. |
493 /// |
493 /// |
494 ///\warning The queue must not be empty! |
494 ///\warning The queue must not be empty! |
495 Node processNextNode(Node target, bool& reached) |
495 Node processNextNode(Node target, bool& reach) |
496 { |
496 { |
497 if(_queue_tail==_queue_next_dist) { |
497 if(_queue_tail==_queue_next_dist) { |
498 _curr_dist++; |
498 _curr_dist++; |
499 _queue_next_dist=_queue_head; |
499 _queue_next_dist=_queue_head; |
500 } |
500 } |
505 if(!(*_reached)[m=G->target(e)]) { |
505 if(!(*_reached)[m=G->target(e)]) { |
506 _queue[_queue_head++]=m; |
506 _queue[_queue_head++]=m; |
507 _reached->set(m,true); |
507 _reached->set(m,true); |
508 _pred->set(m,e); |
508 _pred->set(m,e); |
509 _dist->set(m,_curr_dist); |
509 _dist->set(m,_curr_dist); |
510 reached = reached || (target == m); |
510 reach = reach || (target == m); |
511 } |
511 } |
512 return n; |
512 return n; |
513 } |
513 } |
514 |
514 |
515 ///Processes the next node. |
515 ///Processes the next 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 ///reached parameter will be set true. The reached parameter |
521 ///should be initially false. |
521 ///should be initially false. |
522 /// |
522 /// |
523 ///\param nm The nodemaps of possible targets. |
523 ///\param nm The nodemaps of possible targets. |
524 ///\retval reached Indicates that one of the target nodes is reached. |
524 ///\retval reach Indicates that one of the target nodes is reached. |
525 ///\return The processed node. |
525 ///\return The processed node. |
526 /// |
526 /// |
527 ///\warning The queue must not be empty! |
527 ///\warning The queue must not be empty! |
528 template<class NM> |
528 template<class NM> |
529 Node processNextNode(const NM& nm, bool& reached) |
529 Node processNextNode(const NM& nm, bool& reach) |
530 { |
530 { |
531 if(_queue_tail==_queue_next_dist) { |
531 if(_queue_tail==_queue_next_dist) { |
532 _curr_dist++; |
532 _curr_dist++; |
533 _queue_next_dist=_queue_head; |
533 _queue_next_dist=_queue_head; |
534 } |
534 } |
539 if(!(*_reached)[m=G->target(e)]) { |
539 if(!(*_reached)[m=G->target(e)]) { |
540 _queue[_queue_head++]=m; |
540 _queue[_queue_head++]=m; |
541 _reached->set(m,true); |
541 _reached->set(m,true); |
542 _pred->set(m,e); |
542 _pred->set(m,e); |
543 _dist->set(m,_curr_dist); |
543 _dist->set(m,_curr_dist); |
544 reached = reached || nm[m]; |
544 reached = reach || nm[m]; |
545 } |
545 } |
546 return n; |
546 return n; |
547 } |
547 } |
548 |
548 |
549 ///Next node to be processed. |
549 ///Next node to be processed. |
602 ///- The shortest path to \c dest. |
602 ///- The shortest path to \c dest. |
603 ///- The distance of \c dest from the root(s). |
603 ///- The distance of \c dest from the root(s). |
604 /// |
604 /// |
605 void start(Node dest) |
605 void start(Node dest) |
606 { |
606 { |
607 bool reached = false; |
607 bool reach = false; |
608 while ( !emptyQueue() && !reached) processNextNode(dest, reached); |
608 while ( !emptyQueue() && !reach) processNextNode(dest, reach); |
609 } |
609 } |
610 |
610 |
611 ///Executes the algorithm until a condition is met. |
611 ///Executes the algorithm until a condition is met. |
612 |
612 |
613 ///Executes the algorithm until a condition is met. |
613 ///Executes the algorithm until a condition is met. |
620 /// <tt>nm[v]</tt> true. |
620 /// <tt>nm[v]</tt> true. |
621 ///\todo query the reached target |
621 ///\todo query the reached target |
622 template<class NM> |
622 template<class NM> |
623 void start(const NM &nm) |
623 void start(const NM &nm) |
624 { |
624 { |
625 bool reached = false; |
625 bool reach = false; |
626 while ( !emptyQueue() && !reached) processNextNode(nm, reached); |
626 while ( !emptyQueue() && !reach) processNextNode(nm, reach); |
627 } |
627 } |
628 |
628 |
629 ///Runs %BFS algorithm from node \c s. |
629 ///Runs %BFS algorithm from node \c s. |
630 |
630 |
631 ///This method runs the %BFS algorithm from a root node \c s |
631 ///This method runs the %BFS algorithm from a root node \c s |
880 /// listed in the parameters list. |
880 /// listed in the parameters list. |
881 /// Others are initiated to 0. |
881 /// Others are initiated to 0. |
882 /// \param g is the initial value of \ref _g |
882 /// \param g is the initial value of \ref _g |
883 /// \param s is the initial value of \ref _source |
883 /// \param s is the initial value of \ref _source |
884 BfsWizardBase(const GR &g, Node s=INVALID) : |
884 BfsWizardBase(const GR &g, Node s=INVALID) : |
885 _g((void *)&g), _reached(0), _processed(0), _pred(0), |
885 _g(reinterpret_cast<void*>(const_cast<GR*>(&g))), |
886 _dist(0), _source(s) {} |
886 _reached(0), _processed(0), _pred(0), _dist(0), _source(s) {} |
887 |
887 |
888 }; |
888 }; |
889 |
889 |
890 /// A class to make the usage of Bfs algorithm easier |
890 /// A class to make the usage of Bfs algorithm easier |
891 |
891 |
955 ///Runs Bfs algorithm from a given node. |
955 ///Runs Bfs algorithm from a given node. |
956 ///The node can be given by the \ref source function. |
956 ///The node can be given by the \ref source function. |
957 void run() |
957 void run() |
958 { |
958 { |
959 if(Base::_source==INVALID) throw UninitializedParameter(); |
959 if(Base::_source==INVALID) throw UninitializedParameter(); |
960 Bfs<Graph,TR> alg(*(Graph*)Base::_g); |
960 Bfs<Graph,TR> alg(*reinterpret_cast<const Graph*>(Base::_g)); |
961 if(Base::_reached) |
961 if(Base::_reached) |
962 alg.reachedMap(*(ReachedMap*)Base::_reached); |
962 alg.reachedMap(*reinterpret_cast<ReachedMap*>(Base::_reached)); |
963 if(Base::_processed) alg.processedMap(*(ProcessedMap*)Base::_processed); |
963 if(Base::_processed) |
964 if(Base::_pred) alg.predMap(*(PredMap*)Base::_pred); |
964 alg.processedMap(*reinterpret_cast<ProcessedMap*>(Base::_processed)); |
965 if(Base::_dist) alg.distMap(*(DistMap*)Base::_dist); |
965 if(Base::_pred) |
|
966 alg.predMap(*reinterpret_cast<PredMap*>(Base::_pred)); |
|
967 if(Base::_dist) |
|
968 alg.distMap(*reinterpret_cast<DistMap*>(Base::_dist)); |
966 alg.run(Base::_source); |
969 alg.run(Base::_source); |
967 } |
970 } |
968 |
971 |
969 ///Runs Bfs algorithm from the given node. |
972 ///Runs Bfs algorithm from the given node. |
970 |
973 |
1053 ///function for setting DistMap type |
1056 ///function for setting DistMap type |
1054 /// |
1057 /// |
1055 template<class T> |
1058 template<class T> |
1056 BfsWizard<DefDistMapBase<T> > distMap(const T &t) |
1059 BfsWizard<DefDistMapBase<T> > distMap(const T &t) |
1057 { |
1060 { |
1058 Base::_dist=(void *)&t; |
1061 Base::_dist=reinterpret_cast<void*>(const_cast<T*>(&t)); |
1059 return BfsWizard<DefDistMapBase<T> >(*this); |
1062 return BfsWizard<DefDistMapBase<T> >(*this); |
1060 } |
1063 } |
1061 |
1064 |
1062 /// Sets the source node, from which the Bfs algorithm runs. |
1065 /// Sets the source node, from which the Bfs algorithm runs. |
1063 |
1066 |
1402 /// is reached. If the target node is reachable from the processed |
1405 /// is reached. If the target node is reachable from the processed |
1403 /// node then the reached parameter will be set true. The reached |
1406 /// node then the reached parameter will be set true. The reached |
1404 /// parameter should be initially false. |
1407 /// parameter should be initially false. |
1405 /// |
1408 /// |
1406 /// \param target The target node. |
1409 /// \param target The target node. |
1407 /// \retval reached Indicates that the target node is reached. |
1410 /// \retval reach Indicates that the target node is reached. |
1408 /// \return The processed node. |
1411 /// \return The processed node. |
1409 /// |
1412 /// |
1410 /// \warning The queue must not be empty! |
1413 /// \warning The queue must not be empty! |
1411 Node processNextNode(Node target, bool& reached) { |
1414 Node processNextNode(Node target, bool& reach) { |
1412 Node n = _list[++_list_front]; |
1415 Node n = _list[++_list_front]; |
1413 _visitor->process(n); |
1416 _visitor->process(n); |
1414 Edge e; |
1417 Edge e; |
1415 for (_graph->firstOut(e, n); e != INVALID; _graph->nextOut(e)) { |
1418 for (_graph->firstOut(e, n); e != INVALID; _graph->nextOut(e)) { |
1416 Node m = _graph->target(e); |
1419 Node m = _graph->target(e); |
1417 if (!(*_reached)[m]) { |
1420 if (!(*_reached)[m]) { |
1418 _visitor->discover(e); |
1421 _visitor->discover(e); |
1419 _visitor->reach(m); |
1422 _visitor->reach(m); |
1420 _reached->set(m, true); |
1423 _reached->set(m, true); |
1421 _list[++_list_back] = m; |
1424 _list[++_list_back] = m; |
1422 reached = reached || (target == m); |
1425 reach = reach || (target == m); |
1423 } else { |
1426 } else { |
1424 _visitor->examine(e); |
1427 _visitor->examine(e); |
1425 } |
1428 } |
1426 } |
1429 } |
1427 return n; |
1430 return n; |
1439 /// \retval reached Indicates that one of the target nodes is reached. |
1442 /// \retval reached Indicates that one of the target nodes is reached. |
1440 /// \return The processed node. |
1443 /// \return The processed node. |
1441 /// |
1444 /// |
1442 /// \warning The queue must not be empty! |
1445 /// \warning The queue must not be empty! |
1443 template <typename NM> |
1446 template <typename NM> |
1444 Node processNextNode(const NM& nm, bool& reached) { |
1447 Node processNextNode(const NM& nm, bool& reach) { |
1445 Node n = _list[++_list_front]; |
1448 Node n = _list[++_list_front]; |
1446 _visitor->process(n); |
1449 _visitor->process(n); |
1447 Edge e; |
1450 Edge e; |
1448 for (_graph->firstOut(e, n); e != INVALID; _graph->nextOut(e)) { |
1451 for (_graph->firstOut(e, n); e != INVALID; _graph->nextOut(e)) { |
1449 Node m = _graph->target(e); |
1452 Node m = _graph->target(e); |
1450 if (!(*_reached)[m]) { |
1453 if (!(*_reached)[m]) { |
1451 _visitor->discover(e); |
1454 _visitor->discover(e); |
1452 _visitor->reach(m); |
1455 _visitor->reach(m); |
1453 _reached->set(m, true); |
1456 _reached->set(m, true); |
1454 _list[++_list_back] = m; |
1457 _list[++_list_back] = m; |
1455 reached = reached || nm[m]; |
1458 reach = reach || nm[m]; |
1456 } else { |
1459 } else { |
1457 _visitor->examine(e); |
1460 _visitor->examine(e); |
1458 } |
1461 } |
1459 } |
1462 } |
1460 return n; |
1463 return n; |
1497 /// Executes the algorithm until \c dest is reached. |
1500 /// Executes the algorithm until \c dest is reached. |
1498 /// |
1501 /// |
1499 /// \pre init() must be called and at least one node should be added |
1502 /// \pre init() must be called and at least one node should be added |
1500 /// with addSource() before using this function. |
1503 /// with addSource() before using this function. |
1501 void start(Node dest) { |
1504 void start(Node dest) { |
1502 bool reached = false; |
1505 bool reach = false; |
1503 while (!emptyQueue() && !reached) { |
1506 while (!emptyQueue() && !reach) { |
1504 processNextNode(dest, reached); |
1507 processNextNode(dest, reach); |
1505 } |
1508 } |
1506 } |
1509 } |
1507 |
1510 |
1508 /// \brief Executes the algorithm until a condition is met. |
1511 /// \brief Executes the algorithm until a condition is met. |
1509 /// |
1512 /// |
1515 ///\param nm must be a bool (or convertible) node map. The |
1518 ///\param nm must be a bool (or convertible) node map. The |
1516 ///algorithm will stop when it reached a node \c v with |
1519 ///algorithm will stop when it reached a node \c v with |
1517 /// <tt>nm[v]</tt> true. |
1520 /// <tt>nm[v]</tt> true. |
1518 template <typename NM> |
1521 template <typename NM> |
1519 void start(const NM &nm) { |
1522 void start(const NM &nm) { |
1520 bool reached = false; |
1523 bool reach = false; |
1521 while (!emptyQueue() && !reached) { |
1524 while (!emptyQueue() && !reach) { |
1522 processNextNode(nm, reached); |
1525 processNextNode(nm, reach); |
1523 } |
1526 } |
1524 } |
1527 } |
1525 |
1528 |
1526 /// \brief Runs %BFSVisit algorithm from node \c s. |
1529 /// \brief Runs %BFSVisit algorithm from node \c s. |
1527 /// |
1530 /// |