lemon/bfs.h
changeset 2386 81b47fc5c444
parent 2376 0ed45a6c74b1
child 2391 14a343be7a5a
equal deleted inserted replaced
25:12be059e8bce 26:cb617e9cdb04
   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 
   990     ///function for setting PredMap
   993     ///function for setting PredMap
   991     ///
   994     ///
   992     template<class T>
   995     template<class T>
   993     BfsWizard<DefPredMapBase<T> > predMap(const T &t) 
   996     BfsWizard<DefPredMapBase<T> > predMap(const T &t) 
   994     {
   997     {
   995       Base::_pred=(void *)&t;
   998       Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
   996       return BfsWizard<DefPredMapBase<T> >(*this);
   999       return BfsWizard<DefPredMapBase<T> >(*this);
   997     }
  1000     }
   998     
  1001     
   999  
  1002  
  1000     template<class T>
  1003     template<class T>
  1011     ///function for setting ReachedMap
  1014     ///function for setting ReachedMap
  1012     ///
  1015     ///
  1013     template<class T>
  1016     template<class T>
  1014     BfsWizard<DefReachedMapBase<T> > reachedMap(const T &t) 
  1017     BfsWizard<DefReachedMapBase<T> > reachedMap(const T &t) 
  1015     {
  1018     {
  1016       Base::_pred=(void *)&t;
  1019       Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
  1017       return BfsWizard<DefReachedMapBase<T> >(*this);
  1020       return BfsWizard<DefReachedMapBase<T> >(*this);
  1018     }
  1021     }
  1019     
  1022     
  1020 
  1023 
  1021     template<class T>
  1024     template<class T>
  1032     ///function for setting ProcessedMap
  1035     ///function for setting ProcessedMap
  1033     ///
  1036     ///
  1034     template<class T>
  1037     template<class T>
  1035     BfsWizard<DefProcessedMapBase<T> > processedMap(const T &t) 
  1038     BfsWizard<DefProcessedMapBase<T> > processedMap(const T &t) 
  1036     {
  1039     {
  1037       Base::_pred=(void *)&t;
  1040       Base::_pred=reinterpret_cast<void*>(const_cast<T*>(&t));
  1038       return BfsWizard<DefProcessedMapBase<T> >(*this);
  1041       return BfsWizard<DefProcessedMapBase<T> >(*this);
  1039     }
  1042     }
  1040     
  1043     
  1041    
  1044    
  1042     template<class T>
  1045     template<class T>
  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     ///