src/hugo/path.h
changeset 846 a7a406fdb006
parent 835 eb9587f09b42
child 852 d50d89b86870
equal deleted inserted replaced
3:fa4945e50886 4:4b245f3c8b79
    38   //! \brief A structure for representing directed paths in a graph.
    38   //! \brief A structure for representing directed paths in a graph.
    39   //!
    39   //!
    40   //! A structure for representing directed path in a graph.
    40   //! A structure for representing directed path in a graph.
    41   //! \param Graph The graph type in which the path is.
    41   //! \param Graph The graph type in which the path is.
    42   //! \param DM DebugMode, defaults to DefaultDebugMode.
    42   //! \param DM DebugMode, defaults to DefaultDebugMode.
    43   //! 
    43   //!
    44   //! In a sense, the path can be treated as a graph, for is has \c NodeIt
    44   //! In a sense, the path can be treated as a graph, for is has \c NodeIt
    45   //! and \c EdgeIt with the same usage. These types converts to the \c Node
    45   //! and \c EdgeIt with the same usage. These types converts to the \c Node
    46   //! and \c Edge of the original graph.
    46   //! and \c Edge of the original graph.
    47   //!
    47   //!
    48   //! \todo Thoroughfully check all the range and consistency tests.
    48   //! \todo Thoroughfully check all the range and consistency tests.
    49   template<typename Graph>
    49   template<typename Graph>
    50   class DirPath {
    50   class DirPath {
    51   public:
    51   public:
    52     /// Edge type of the underlying graph.
    52     /// Edge type of the underlying graph.
    53     typedef typename Graph::Edge GraphEdge; 
    53     typedef typename Graph::Edge GraphEdge;
    54     /// Node type of the underlying graph.
    54     /// Node type of the underlying graph.
    55     typedef typename Graph::Node GraphNode;
    55     typedef typename Graph::Node GraphNode;
    56     class NodeIt;
    56     class NodeIt;
    57     class EdgeIt;
    57     class EdgeIt;
    58 
    58 
   152 
   152 
   153     /* Iterator classes */
   153     /* Iterator classes */
   154 
   154 
   155     /**
   155     /**
   156      * \brief Iterator class to iterate on the edges of the paths
   156      * \brief Iterator class to iterate on the edges of the paths
   157      * 
   157      *
   158      * \ingroup paths
   158      * \ingroup paths
   159      * This class is used to iterate on the edges of the paths
   159      * This class is used to iterate on the edges of the paths
   160      *
   160      *
   161      * Of course it converts to Graph::Edge
   161      * Of course it converts to Graph::Edge
   162      * 
   162      *
   163      * \todo Its interface differs from the standard edge iterator.
   163      * \todo Its interface differs from the standard edge iterator.
   164      * Yes, it shouldn't.
   164      * Yes, it shouldn't.
   165      */
   165      */
   166     class EdgeIt {
   166     class EdgeIt {
   167       friend class DirPath;
   167       friend class DirPath;
   201       void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
   201       void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
   202     };
   202     };
   203 
   203 
   204     /**
   204     /**
   205      * \brief Iterator class to iterate on the nodes of the paths
   205      * \brief Iterator class to iterate on the nodes of the paths
   206      * 
   206      *
   207      * \ingroup paths
   207      * \ingroup paths
   208      * This class is used to iterate on the nodes of the paths
   208      * This class is used to iterate on the nodes of the paths
   209      *
   209      *
   210      * Of course it converts to Graph::Node
   210      * Of course it converts to Graph::Node
   211      * 
   211      *
   212      * \todo Its interface differs from the standard node iterator.
   212      * \todo Its interface differs from the standard node iterator.
   213      * Yes, it shouldn't.
   213      * Yes, it shouldn't.
   214      */
   214      */
   215     class NodeIt {
   215     class NodeIt {
   216       friend class DirPath;
   216       friend class DirPath;
   250 
   250 
   251     private:
   251     private:
   252       void validate() { if( size_t(idx) > p->length() ) idx=-1; }
   252       void validate() { if( size_t(idx) > p->length() ) idx=-1; }
   253     };
   253     };
   254 
   254 
   255     friend class Builder;    
   255     friend class Builder;
   256 
   256 
   257     /**
   257     /**
   258      * \brief Class to build paths
   258      * \brief Class to build paths
   259      * 
   259      *
   260      * \ingroup paths
   260      * \ingroup paths
   261      * This class is used to fill a path with edges.
   261      * This class is used to fill a path with edges.
   262      *
   262      *
   263      * You can push new edges to the front and to the back of the path in
   263      * You can push new edges to the front and to the back of the path in
   264      * arbitrary order then you should commit these changes to the graph.
   264      * arbitrary order then you should commit these changes to the graph.
   278       ///\param _P the path you want to fill in.
   278       ///\param _P the path you want to fill in.
   279       ///
   279       ///
   280       Builder(DirPath &_P) : P(_P) {}
   280       Builder(DirPath &_P) : P(_P) {}
   281 
   281 
   282       /// Sets the starting node of the path.
   282       /// Sets the starting node of the path.
   283       
   283 
   284       /// Sets the starting node of the path. Edge added to the path
   284       /// Sets the starting node of the path. Edge added to the path
   285       /// afterwards have to be incident to this node.
   285       /// afterwards have to be incident to this node.
   286       /// It should be called iff the path is empty and before any call to
   286       /// It should be called iff the path is empty and before any call to
   287       /// \ref pushFront() or \ref pushBack()
   287       /// \ref pushFront() or \ref pushBack()
   288       void setStartNode(const GraphNode &) {}
   288       void setStartNode(const GraphNode &) {}
   303 	back.push_back(e);
   303 	back.push_back(e);
   304       }
   304       }
   305 
   305 
   306       ///Commit the changes to the path.
   306       ///Commit the changes to the path.
   307       void commit() {
   307       void commit() {
   308 	if( !(front.empty() && back.empty()) ) {
   308 	if( !front.empty() || !back.empty() ) {
   309 	  Container tmp;
   309 	  Container tmp;
   310 	  tmp.reserve(front.size()+back.size()+P.length());
   310 	  tmp.reserve(front.size()+back.size()+P.length());
   311 	  tmp.insert(tmp.end(), front.rbegin(), front.rend());
   311 	  tmp.insert(tmp.end(), front.rbegin(), front.rend());
   312 	  tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
   312 	  tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
   313 	  tmp.insert(tmp.end(), back.begin(), back.end());
   313 	  tmp.insert(tmp.end(), back.begin(), back.end());
   315 	  front.clear();
   315 	  front.clear();
   316 	  back.clear();
   316 	  back.clear();
   317 	}
   317 	}
   318       }
   318       }
   319 
   319 
   320       // FIXME: Hmm, pontosan hogy is kene ezt csinalni?
       
   321       // Hogy kenyelmes egy ilyet hasznalni?
       
   322   
       
   323       ///Reserve storage for the builder in advance.
   320       ///Reserve storage for the builder in advance.
   324 
   321 
   325       ///If you know an reasonable upper bound of the number of the edges
   322       ///If you know a reasonable upper bound of the number of the edges
   326       ///to add, using this function you can speed up the building.
   323       ///to add to the front, using this function you can speed up the building.
   327       void reserve(size_t r) {
   324 
   328 	front.reserve(r);
   325       void reserveFront(size_t r) {front.reserve(r);}
   329 	back.reserve(r);
   326 
   330       }
   327       ///Reserve storage for the builder in advance.
   331 
   328 
   332       void reserveFront(size_t r) {}
   329       ///If you know a reasonable upper bound of the number of the edges
   333       void reserveBack(size_t r) {}
   330       ///to add to the back, using this function you can speed up the building.
       
   331 
       
   332       void reserveBack(size_t r) {back.reserve(r);}
   334 
   333 
   335     private:
   334     private:
   336       bool empty() {
   335       bool empty() {
   337 	return front.empty() && back.empty() && P.empty();
   336 	return front.empty() && back.empty() && P.empty();
   338       }
   337       }
   380   //! a path in a \e directed graph but the edges should not be directed
   379   //! a path in a \e directed graph but the edges should not be directed
   381   //! forward.
   380   //! forward.
   382   //!
   381   //!
   383   //! \param Graph The graph type in which the path is.
   382   //! \param Graph The graph type in which the path is.
   384   //! \param DM DebugMode, defaults to DefaultDebugMode.
   383   //! \param DM DebugMode, defaults to DefaultDebugMode.
   385   //! 
   384   //!
   386   //! In a sense, the path can be treated as a graph, for is has \c NodeIt
   385   //! In a sense, the path can be treated as a graph, for is has \c NodeIt
   387   //! and \c EdgeIt with the same usage. These types converts to the \c Node
   386   //! and \c EdgeIt with the same usage. These types converts to the \c Node
   388   //! and \c Edge of the original graph.
   387   //! and \c Edge of the original graph.
   389   //!
   388   //!
   390   //! \todo Thoroughfully check all the range and consistency tests.
   389   //! \todo Thoroughfully check all the range and consistency tests.
   493 
   492 
   494 
   493 
   495 
   494 
   496     /**
   495     /**
   497      * \brief Iterator class to iterate on the edges of the paths
   496      * \brief Iterator class to iterate on the edges of the paths
   498      * 
   497      *
   499      * \ingroup paths
   498      * \ingroup paths
   500      * This class is used to iterate on the edges of the paths
   499      * This class is used to iterate on the edges of the paths
   501      *
   500      *
   502      * Of course it converts to Graph::Edge
   501      * Of course it converts to Graph::Edge
   503      * 
   502      *
   504      * \todo Its interface differs from the standard edge iterator.
   503      * \todo Its interface differs from the standard edge iterator.
   505      * Yes, it shouldn't.
   504      * Yes, it shouldn't.
   506      */
   505      */
   507     class EdgeIt {
   506     class EdgeIt {
   508       friend class UndirPath;
   507       friend class UndirPath;
   541       void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
   540       void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
   542     };
   541     };
   543 
   542 
   544     /**
   543     /**
   545      * \brief Iterator class to iterate on the nodes of the paths
   544      * \brief Iterator class to iterate on the nodes of the paths
   546      * 
   545      *
   547      * \ingroup paths
   546      * \ingroup paths
   548      * This class is used to iterate on the nodes of the paths
   547      * This class is used to iterate on the nodes of the paths
   549      *
   548      *
   550      * Of course it converts to Graph::Node
   549      * Of course it converts to Graph::Node
   551      * 
   550      *
   552      * \todo Its interface differs from the standard node iterator.
   551      * \todo Its interface differs from the standard node iterator.
   553      * Yes, it shouldn't.
   552      * Yes, it shouldn't.
   554      */
   553      */
   555     class NodeIt {
   554     class NodeIt {
   556       friend class UndirPath;
   555       friend class UndirPath;
   590 
   589 
   591     private:
   590     private:
   592       void validate() { if( size_t(idx) > p->length() ) idx=-1; }
   591       void validate() { if( size_t(idx) > p->length() ) idx=-1; }
   593     };
   592     };
   594 
   593 
   595     friend class Builder;    
   594     friend class Builder;
   596 
   595 
   597     /**
   596     /**
   598      * \brief Class to build paths
   597      * \brief Class to build paths
   599      * 
   598      *
   600      * \ingroup paths
   599      * \ingroup paths
   601      * This class is used to fill a path with edges.
   600      * This class is used to fill a path with edges.
   602      *
   601      *
   603      * You can push new edges to the front and to the back of the path in
   602      * You can push new edges to the front and to the back of the path in
   604      * arbitrary order then you should commit these changes to the graph.
   603      * arbitrary order then you should commit these changes to the graph.
   618       ///\param _P the path you want to fill in.
   617       ///\param _P the path you want to fill in.
   619       ///
   618       ///
   620       Builder(UndirPath &_P) : P(_P) {}
   619       Builder(UndirPath &_P) : P(_P) {}
   621 
   620 
   622       /// Sets the starting node of the path.
   621       /// Sets the starting node of the path.
   623       
   622 
   624       /// Sets the starting node of the path. Edge added to the path
   623       /// Sets the starting node of the path. Edge added to the path
   625       /// afterwards have to be incident to this node.
   624       /// afterwards have to be incident to this node.
   626       /// It should be called iff the path is empty and before any call to
   625       /// It should be called iff the path is empty and before any call to
   627       /// \ref pushFront() or \ref pushBack()
   626       /// \ref pushFront() or \ref pushBack()
   628       void setStartNode(const GraphNode &) {}
   627       void setStartNode(const GraphNode &) {}
   655 	  front.clear();
   654 	  front.clear();
   656 	  back.clear();
   655 	  back.clear();
   657 	}
   656 	}
   658       }
   657       }
   659 
   658 
   660       // FIXME: Hmm, pontosan hogy is kene ezt csinalni?
       
   661       // Hogy kenyelmes egy ilyet hasznalni?
       
   662 
   659 
   663       ///Reserve storage for the builder in advance.
   660       ///Reserve storage for the builder in advance.
   664 
   661 
   665       ///If you know an reasonable upper bound of the number of the edges
   662       ///If you know a reasonable upper bound of the number of the edges
   666       ///to add, using this function you can speed up the building.
   663       ///to add to the front, using this function you can speed up the building.
   667        void reserve(size_t r) {
   664 
   668 	front.reserve(r);
   665       void reserveFront(size_t r) {front.reserve(r);}
   669 	back.reserve(r);
   666 
   670       }
   667       ///Reserve storage for the builder in advance.
   671 
   668 
   672       void reserveFront(size_t r) {}
   669       ///If you know a reasonable upper bound of the number of the edges
   673       void reserveBack(size_t r) {}
   670       ///to add to the back, using this function you can speed up the building.
       
   671 
       
   672       void reserveBack(size_t r) {back.reserve(r);}
   674 
   673 
   675     private:
   674     private:
   676       bool empty() {
   675       bool empty() {
   677 	return front.empty() && back.empty() && P.empty();
   676 	return front.empty() && back.empty() && P.empty();
   678       }
   677       }
   701     };
   700     };
   702 
   701 
   703   };
   702   };
   704 
   703 
   705 
   704 
   706 
       
   707 
       
   708 
       
   709 
       
   710 
       
   711 
       
   712 
       
   713 
       
   714   /**********************************************************************/
       
   715 
       
   716 
       
   717   /* Ennek az allocatorosdinak sokkal jobban utana kene nezni a hasznalata
       
   718      elott. Eleg bonyinak nez ki, ahogyan azokat az STL-ben hasznaljak. */
       
   719 
       
   720   template<typename Graph>
       
   721   class DynamicPath {
       
   722 
       
   723   public:
       
   724     typedef typename Graph::Edge GraphEdge;
       
   725     typedef typename Graph::Node GraphNode;
       
   726     class NodeIt;
       
   727     class EdgeIt;
       
   728 
       
   729   protected:
       
   730     Graph& G;
       
   731     // FIXME: ehelyett eleg lenne tarolni ket boolt: a ket szelso el
       
   732     // iranyitasat:
       
   733     GraphNode _first, _last;
       
   734     typedef std::deque<GraphEdge> Container;
       
   735     Container edges;
       
   736 
       
   737   public:
       
   738 
       
   739     DynamicPath(Graph &_G) : G(_G), _first(INVALID), _last(INVALID) {}
       
   740 
       
   741     /// Subpath defined by two nodes.
       
   742     /// Nodes may be in reversed order, then
       
   743     /// we contstruct the reversed path.
       
   744     DynamicPath(const DynamicPath &P, const NodeIt &a, const NodeIt &b);
       
   745     /// Subpath defined by two edges. Contains edges in [a,b)
       
   746     /// It is an error if the two edges are not in order!
       
   747     DynamicPath(const DynamicPath &P, const EdgeIt &a, const EdgeIt &b);
       
   748     
       
   749     size_t length() const { return edges.size(); }
       
   750     GraphNode tail() const { return _first; }
       
   751     GraphNode head() const { return _last; }
       
   752 
       
   753     NodeIt& first(NodeIt &n) const { return nth(n, 0); }
       
   754     EdgeIt& first(EdgeIt &e) const { return nth(e, 0); }
       
   755     template<typename It>
       
   756     It first() const { 
       
   757       It e;
       
   758       first(e);
       
   759       return e; 
       
   760     }
       
   761 
       
   762     NodeIt& nth(NodeIt &, size_t) const;
       
   763     EdgeIt& nth(EdgeIt &, size_t) const;
       
   764     template<typename It>
       
   765     It nth(size_t n) const { 
       
   766       It e;
       
   767       nth(e, n);
       
   768       return e; 
       
   769     }
       
   770 
       
   771     bool valid(const NodeIt &n) const { return n.idx <= length(); }
       
   772     bool valid(const EdgeIt &e) const { return e.it < edges.end(); }
       
   773 
       
   774     bool isForward(const EdgeIt &e) const { return e.forw; }
       
   775 
       
   776     /// index of a node on the path. Returns length+2 for the invalid NodeIt
       
   777     int index(const NodeIt &n) const { return n.idx; }
       
   778     /// index of an edge on the path. Returns length+1 for the invalid EdgeIt
       
   779     int index(const EdgeIt &e) const { return e.it - edges.begin(); }
       
   780 
       
   781     EdgeIt& next(EdgeIt &e) const;
       
   782     NodeIt& next(NodeIt &n) const;
       
   783     template <typename It>
       
   784     It getNext(It it) const {
       
   785       It tmp(it); return next(tmp);
       
   786     }
       
   787 
       
   788     // A path is constructed using the following four functions.
       
   789     // They return false if the requested operation is inconsistent
       
   790     // with the path constructed so far.
       
   791     // If your path has only one edge you MUST set either "from" or "to"!
       
   792     // So you probably SHOULD call it in any case to be safe (and check the
       
   793     // returned value to check if your path is consistent with your idea).
       
   794     bool pushFront(const GraphEdge &e);
       
   795     bool pushBack(const GraphEdge &e);
       
   796     bool setFrom(const GraphNode &n);
       
   797     bool setTo(const GraphNode &n);
       
   798 
       
   799     // WARNING: these two functions return the head/tail of an edge with
       
   800     // respect to the direction of the path!
       
   801     // So G.head(P.graphEdge(e)) == P.graphNode(P.head(e)) holds only if 
       
   802     // P.forward(e) is true (or the edge is a loop)!
       
   803     NodeIt head(const EdgeIt& e) const;
       
   804     NodeIt tail(const EdgeIt& e) const;
       
   805 
       
   806     // FIXME: ezeknek valami jobb nev kellene!!!
       
   807     GraphEdge graphEdge(const EdgeIt& e) const;
       
   808     GraphNode graphNode(const NodeIt& n) const;
       
   809 
       
   810 
       
   811     /*** Iterator classes ***/
       
   812     class EdgeIt {
       
   813       friend class DynamicPath;
       
   814 
       
   815       typename Container::const_iterator it;
       
   816       bool forw;
       
   817     public:
       
   818       // FIXME: jarna neki ilyen is...
       
   819       // EdgeIt(Invalid);
       
   820 
       
   821       bool forward() const { return forw; }
       
   822 
       
   823       bool operator==(const EdgeIt& e) const { return it==e.it; }
       
   824       bool operator!=(const EdgeIt& e) const { return it!=e.it; }
       
   825       bool operator<(const EdgeIt& e) const { return it<e.it; }
       
   826     };
       
   827 
       
   828     class NodeIt {
       
   829       friend class DynamicPath;
       
   830 
       
   831       size_t idx;
       
   832       bool tail;  // Is this node the tail of the edge with same idx?
       
   833 
       
   834     public:
       
   835       // FIXME: jarna neki ilyen is...
       
   836       // NodeIt(Invalid);
       
   837 
       
   838       bool operator==(const NodeIt& n) const { return idx==n.idx; }
       
   839       bool operator!=(const NodeIt& n) const { return idx!=n.idx; }
       
   840       bool operator<(const NodeIt& n) const { return idx<n.idx; }
       
   841     };
       
   842 
       
   843   private:
       
   844     bool edgeIncident(const GraphEdge &e, const GraphNode &a,
       
   845 		      GraphNode &b);
       
   846     bool connectTwoEdges(const GraphEdge &e, const GraphEdge &f);
       
   847   };
       
   848 
       
   849   template<typename Gr>
       
   850   typename DynamicPath<Gr>::EdgeIt&
       
   851   DynamicPath<Gr>::next(DynamicPath::EdgeIt &e) const {
       
   852     if( e.it == edges.end() ) 
       
   853       return e;
       
   854 
       
   855     GraphNode common_node = ( e.forw ? G.head(*e.it) : G.tail(*e.it) );
       
   856     ++e.it;
       
   857 
       
   858     // Invalid edgeit is always forward :)
       
   859     if( e.it == edges.end() ) {
       
   860       e.forw = true;
       
   861       return e;
       
   862     }
       
   863 
       
   864     e.forw = ( G.tail(*e.it) == common_node );
       
   865     return e;
       
   866   }
       
   867 
       
   868   template<typename Gr>
       
   869   typename DynamicPath<Gr>::NodeIt& DynamicPath<Gr>::next(NodeIt &n) const {
       
   870     if( n.idx >= length() ) {
       
   871       // FIXME: invalid
       
   872       n.idx = length()+1;
       
   873       return n;
       
   874     }
       
   875 
       
   876     
       
   877     GraphNode next_node = ( n.tail ? G.head(edges[n.idx]) :
       
   878 			      G.tail(edges[n.idx]) );
       
   879     ++n.idx;
       
   880     if( n.idx < length() ) {
       
   881       n.tail = ( next_node == G.tail(edges[n.idx]) );
       
   882     }
       
   883     else {
       
   884       n.tail = true;
       
   885     }
       
   886 
       
   887     return n;
       
   888   }
       
   889 
       
   890   template<typename Gr>
       
   891   bool DynamicPath<Gr>::edgeIncident(const GraphEdge &e, const GraphNode &a,
       
   892 			  GraphNode &b) {
       
   893     if( G.tail(e) == a ) {
       
   894       b=G.head(e);
       
   895       return true;
       
   896     }
       
   897     if( G.head(e) == a ) {
       
   898       b=G.tail(e);
       
   899       return true;
       
   900     }
       
   901     return false;
       
   902   }
       
   903 
       
   904   template<typename Gr>
       
   905   bool DynamicPath<Gr>::connectTwoEdges(const GraphEdge &e,
       
   906 			     const GraphEdge &f) {
       
   907     if( edgeIncident(f, G.tail(e), _last) ) {
       
   908       _first = G.head(e);
       
   909       return true;
       
   910     }
       
   911     if( edgeIncident(f, G.head(e), _last) ) {
       
   912       _first = G.tail(e);
       
   913       return true;
       
   914     }
       
   915     return false;
       
   916   }
       
   917 
       
   918   template<typename Gr>
       
   919   bool DynamicPath<Gr>::pushFront(const GraphEdge &e) {
       
   920     if( G.valid(_first) ) {
       
   921 	if( edgeIncident(e, _first, _first) ) {
       
   922 	  edges.push_front(e);
       
   923 	  return true;
       
   924 	}
       
   925 	else
       
   926 	  return false;
       
   927     }
       
   928     else if( length() < 1 || connectTwoEdges(e, edges[0]) ) {
       
   929       edges.push_front(e);
       
   930       return true;
       
   931     }
       
   932     else
       
   933       return false;
       
   934   }
       
   935 
       
   936   template<typename Gr>
       
   937   bool DynamicPath<Gr>::pushBack(const GraphEdge &e) {
       
   938     if( G.valid(_last) ) {
       
   939 	if( edgeIncident(e, _last, _last) ) {
       
   940 	  edges.push_back(e);
       
   941 	  return true;
       
   942 	}
       
   943 	else
       
   944 	  return false;
       
   945     }
       
   946     else if( length() < 1 || connectTwoEdges(edges[0], e) ) {
       
   947       edges.push_back(e);
       
   948       return true;
       
   949     }
       
   950     else
       
   951       return false;
       
   952   }
       
   953 
       
   954 
       
   955   template<typename Gr>
       
   956   bool DynamicPath<Gr>::setFrom(const GraphNode &n) {
       
   957     if( G.valid(_first) ) {
       
   958       return _first == n;
       
   959     }
       
   960     else {
       
   961       if( length() > 0) {
       
   962 	if( edgeIncident(edges[0], n, _last) ) {
       
   963 	  _first = n;
       
   964 	  return true;
       
   965 	}
       
   966 	else return false;
       
   967       }
       
   968       else {
       
   969 	_first = _last = n;
       
   970 	return true;
       
   971       }
       
   972     }
       
   973   }
       
   974 
       
   975   template<typename Gr>
       
   976   bool DynamicPath<Gr>::setTo(const GraphNode &n) {
       
   977     if( G.valid(_last) ) {
       
   978       return _last == n;
       
   979     }
       
   980     else {
       
   981       if( length() > 0) {
       
   982 	if( edgeIncident(edges[0], n, _first) ) {
       
   983 	  _last = n;
       
   984 	  return true;
       
   985 	}
       
   986 	else return false;
       
   987       }
       
   988       else {
       
   989 	_first = _last = n;
       
   990 	return true;
       
   991       }
       
   992     }
       
   993   }
       
   994 
       
   995 
       
   996   template<typename Gr>
       
   997   typename DynamicPath<Gr>::NodeIt
       
   998   DynamicPath<Gr>::tail(const EdgeIt& e) const {
       
   999     NodeIt n;
       
  1000 
       
  1001     if( e.it == edges.end() ) {
       
  1002       // FIXME: invalid-> invalid
       
  1003       n.idx = length() + 1;
       
  1004       n.tail = true;
       
  1005       return n;
       
  1006     }
       
  1007 
       
  1008     n.idx = e.it-edges.begin();
       
  1009     n.tail = e.forw;
       
  1010     return n;
       
  1011   }
       
  1012 
       
  1013   template<typename Gr>
       
  1014   typename DynamicPath<Gr>::NodeIt
       
  1015   DynamicPath<Gr>::head(const EdgeIt& e) const {
       
  1016     if( e.it == edges.end()-1 ) {
       
  1017       return _last;
       
  1018     }
       
  1019 
       
  1020     EdgeIt next_edge = e;
       
  1021     next(next_edge);
       
  1022     return tail(next_edge);
       
  1023   }
       
  1024       
       
  1025   template<typename Gr>
       
  1026   typename DynamicPath<Gr>::GraphEdge
       
  1027   DynamicPath<Gr>::graphEdge(const EdgeIt& e) const {
       
  1028     if( e.it != edges.end() ) {
       
  1029       return *e.it;
       
  1030     }
       
  1031     else {
       
  1032       return INVALID;
       
  1033     }
       
  1034   }
       
  1035   
       
  1036   template<typename Gr>
       
  1037   typename DynamicPath<Gr>::GraphNode
       
  1038   DynamicPath<Gr>::graphNode(const NodeIt& n) const {
       
  1039     if( n.idx < length() ) {
       
  1040       return n.tail ? G.tail(edges[n.idx]) : G.head(edges[n.idx]);
       
  1041     }
       
  1042     else if( n.idx == length() ) {
       
  1043       return _last;
       
  1044     }
       
  1045     else {
       
  1046       return INVALID;
       
  1047     }
       
  1048   }
       
  1049 
       
  1050   template<typename Gr>
       
  1051   typename DynamicPath<Gr>::EdgeIt&
       
  1052   DynamicPath<Gr>::nth(EdgeIt &e, size_t k) const {
       
  1053     if( k>=length() ) {
       
  1054       // FIXME: invalid EdgeIt
       
  1055       e.it = edges.end();
       
  1056       e.forw = true;
       
  1057       return e;
       
  1058     }
       
  1059 
       
  1060     e.it = edges.begin()+k;
       
  1061     if(k==0) {
       
  1062       e.forw = ( G.tail(*e.it) == _first );
       
  1063     }
       
  1064     else {
       
  1065       e.forw = ( G.tail(*e.it) == G.tail(edges[k-1]) ||
       
  1066 		 G.tail(*e.it) == G.head(edges[k-1]) );
       
  1067     }
       
  1068     return e;
       
  1069   }
       
  1070     
       
  1071   template<typename Gr>
       
  1072   typename DynamicPath<Gr>::NodeIt&
       
  1073   DynamicPath<Gr>::nth(NodeIt &n, size_t k) const {
       
  1074     if( k>length() ) {
       
  1075       // FIXME: invalid NodeIt
       
  1076       n.idx = length()+1;
       
  1077       n.tail = true;
       
  1078       return n;
       
  1079     }
       
  1080     if( k==length() ) {
       
  1081       n.idx = length();
       
  1082       n.tail = true;
       
  1083       return n;
       
  1084     }
       
  1085     n = tail(nth<EdgeIt>(k));
       
  1086     return n;
       
  1087   }
       
  1088 
       
  1089   // Reszut konstruktorok:
       
  1090 
       
  1091 
       
  1092   template<typename Gr>
       
  1093   DynamicPath<Gr>::DynamicPath(const DynamicPath &P, const EdgeIt &a,
       
  1094 			       const EdgeIt &b) :
       
  1095     G(P.G), edges(a.it, b.it)    // WARNING: if b.it < a.it this will blow up! 
       
  1096   {
       
  1097     if( G.valid(P._first) && a.it < P.edges.end() ) {
       
  1098       _first = ( a.forw ? G.tail(*a.it) : G.head(*a.it) );
       
  1099       if( b.it < P.edges.end() ) {
       
  1100 	_last = ( b.forw ? G.tail(*b.it) : G.head(*b.it) );
       
  1101       }
       
  1102       else {
       
  1103 	_last = P._last;
       
  1104       }
       
  1105     }
       
  1106   }
       
  1107 
       
  1108   template<typename Gr>
       
  1109   DynamicPath<Gr>::DynamicPath(const DynamicPath &P, const NodeIt &a,
       
  1110 			       const NodeIt &b) : G(P.G)
       
  1111   {
       
  1112     if( !P.valid(a) || !P.valid(b) )
       
  1113       return;
       
  1114 
       
  1115     int ai = a.idx, bi = b.idx;
       
  1116     if( bi<ai )
       
  1117       std::swap(ai,bi);
       
  1118     
       
  1119     edges.resize(bi-ai);
       
  1120     copy(P.edges.begin()+ai, P.edges.begin()+bi, edges.begin());
       
  1121 
       
  1122     _first = P.graphNode(a);
       
  1123     _last = P.graphNode(b);
       
  1124   }
       
  1125 
       
  1126   ///@}
   705   ///@}
  1127 
   706 
  1128 } // namespace hugo
   707 } // namespace hugo
  1129 
   708 
  1130 #endif // HUGO_PATH_H
   709 #endif // HUGO_PATH_H