Bug fix.
Default assign operator should be
overrided by that calls the template
assign operator.
     2  * lemon/path.h - Part of LEMON, a generic C++ optimization library
 
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
 
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
 
     7  * Permission to use, modify and distribute this software is granted
 
     8  * provided that this copyright notice appears in all copies. For
 
     9  * precise terms see the accompanying LICENSE file.
 
    11  * This software is provided "AS IS" with no warranty of any kind,
 
    12  * express or implied, and with no claim as to its suitability for any
 
    18 @defgroup paths Path Structures
 
    20 \brief Path structures implemented in LEMON.
 
    22 LEMON provides flexible data structures
 
    25 All of them have the same interface, especially they can be built or extended
 
    26 using a standard Builder subclass. This make is easy to have e.g. the Dijkstra
 
    27 algorithm to store its result in any kind of path structure.
 
    29 \sa lemon::concept::Path
 
    35 ///\brief Classes for representing paths in graphs.
 
    37 ///\todo Iterators have obsolete style
 
    46 #include <lemon/invalid.h>
 
    54   //! \brief A structure for representing directed paths in a graph.
 
    56   //! A structure for representing directed path in a graph.
 
    57   //! \param Graph The graph type in which the path is.
 
    58   //! \param DM DebugMode, defaults to DefaultDebugMode.
 
    60   //! In a sense, the path can be treated as a graph, for is has \c NodeIt
 
    61   //! and \c EdgeIt with the same usage. These types converts to the \c Node
 
    62   //! and \c Edge of the original graph.
 
    64   //! \todo Thoroughfully check all the range and consistency tests.
 
    65   template<typename Graph>
 
    68     /// Edge type of the underlying graph.
 
    69     typedef typename Graph::Edge GraphEdge;
 
    70     /// Node type of the underlying graph.
 
    71     typedef typename Graph::Node GraphNode;
 
    77     typedef std::vector<GraphEdge> Container;
 
    82     /// \param _G The graph in which the path is.
 
    84     DirPath(const Graph &_G) : gr(&_G) {}
 
    86     /// \brief Subpath constructor.
 
    88     /// Subpath defined by two nodes.
 
    89     /// \warning It is an error if the two edges are not in order!
 
    90     DirPath(const DirPath &P, const NodeIt &a, const NodeIt &b) {
 
    92       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
 
    95     /// \brief Subpath constructor.
 
    97     /// Subpath defined by two edges. Contains edges in [a,b)
 
    98     /// \warning It is an error if the two edges are not in order!
 
    99     DirPath(const DirPath &P, const EdgeIt &a, const EdgeIt &b) {
 
   101       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
 
   104     /// Length of the path.
 
   105     int length() const { return edges.size(); }
 
   106     /// Returns whether the path is empty.
 
   107     bool empty() const { return edges.empty(); }
 
   109     /// Resets the path to an empty path.
 
   110     void clear() { edges.clear(); }
 
   112     /// \brief Starting point of the path.
 
   114     /// Starting point of the path.
 
   115     /// Returns INVALID if the path is empty.
 
   116     GraphNode source() const {
 
   117       return empty() ? INVALID : gr->source(edges[0]);
 
   119     /// \brief End point of the path.
 
   121     /// End point of the path.
 
   122     /// Returns INVALID if the path is empty.
 
   123     GraphNode target() const {
 
   124       return empty() ? INVALID : gr->target(edges[length()-1]);
 
   127     /// \brief Initializes node or edge iterator to point to the first
 
   131     template<typename It>
 
   132     It& first(It &i) const { return i=It(*this); }
 
   134     /// \brief Initializes node iterator to point to the node of a given index.
 
   135     NodeIt& nth(NodeIt &i, int n) const {
 
   136       return i=NodeIt(*this, n);
 
   139     /// \brief Initializes edge iterator to point to the edge of a given index.
 
   140     EdgeIt& nth(EdgeIt &i, int n) const {
 
   141       return i=EdgeIt(*this, n);
 
   144     /// \brief Returns node iterator pointing to the target node of the
 
   145     /// given edge iterator.
 
   146     NodeIt target(const EdgeIt& e) const {
 
   147       return NodeIt(*this, e.idx+1);
 
   150     /// \brief Returns node iterator pointing to the source node of the
 
   151     /// given edge iterator.
 
   152     NodeIt source(const EdgeIt& e) const {
 
   153       return NodeIt(*this, e.idx);
 
   157     /* Iterator classes */
 
   160      * \brief Iterator class to iterate on the edges of the paths
 
   162      * This class is used to iterate on the edges of the paths
 
   164      * Of course it converts to Graph::Edge
 
   168       friend class DirPath;
 
   173       /// Default constructor
 
   175       /// Invalid constructor
 
   176       EdgeIt(Invalid) : idx(-1), p(0) {}
 
   177       /// Constructor with starting point
 
   178       EdgeIt(const DirPath &_p, int _idx = 0) :
 
   179 	idx(_idx), p(&_p) { validate(); }
 
   182       bool valid() const { return idx!=-1; }
 
   184       ///Conversion to Graph::Edge
 
   185       operator GraphEdge () const {
 
   186 	return valid() ? p->edges[idx] : INVALID;
 
   190       EdgeIt& operator++() { ++idx; validate(); return *this; }
 
   192       /// Comparison operator
 
   193       bool operator==(const EdgeIt& e) const { return idx==e.idx; }
 
   194       /// Comparison operator
 
   195       bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
 
   196       /// Comparison operator
 
   197       bool operator<(const EdgeIt& e) const { return idx<e.idx; }
 
   200       void validate() { if(idx >= p->length() ) idx=-1; }
 
   204      * \brief Iterator class to iterate on the nodes of the paths
 
   206      * This class is used to iterate on the nodes of the paths
 
   208      * Of course it converts to Graph::Node
 
   212       friend class DirPath;
 
   217       /// Default constructor
 
   219       /// Invalid constructor
 
   220       NodeIt(Invalid) : idx(-1), p(0) {}
 
   221       /// Constructor with starting point
 
   222       NodeIt(const DirPath &_p, int _idx = 0) :
 
   223 	idx(_idx), p(&_p) { validate(); }
 
   226       bool valid() const { return idx!=-1; }
 
   228       ///Conversion to Graph::Node
 
   229       operator const GraphNode& () const {
 
   230 	if(idx >= p->length())
 
   233 	  return p->gr->source(p->edges[idx]);
 
   238       NodeIt& operator++() { ++idx; validate(); return *this; }
 
   240       /// Comparison operator
 
   241       bool operator==(const NodeIt& e) const { return idx==e.idx; }
 
   242       /// Comparison operator
 
   243       bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
 
   244       /// Comparison operator
 
   245       bool operator<(const NodeIt& e) const { return idx<e.idx; }
 
   248       void validate() { if(idx > p->length() ) idx=-1; }
 
   251     friend class Builder;
 
   254      * \brief Class to build paths
 
   256      * This class is used to fill a path with edges.
 
   258      * You can push new edges to the front and to the back of the path in
 
   259      * arbitrary order then you should commit these changes to the graph.
 
   261      * Fundamentally, for most "Paths" (classes fulfilling the
 
   262      * PathConcept) while the builder is active (after the first modifying
 
   263      * operation and until the commit()) the original Path is in a
 
   264      * "transitional" state (operations on it have undefined result). But
 
   265      * in the case of DirPath the original path remains unchanged until the
 
   266      * commit. However we don't recomend that you use this feature.
 
   270       Container front, back;
 
   273       ///\param _p the path you want to fill in.
 
   275       Builder(DirPath &_p) : P(_p) {}
 
   277       /// Sets the starting node of the path.
 
   279       /// Sets the starting node of the path. Edge added to the path
 
   280       /// afterwards have to be incident to this node.
 
   281       /// It should be called if and only if
 
   282       /// the path is empty and before any call to
 
   283       /// \ref pushFront() or \ref pushBack()
 
   284       void setStartNode(const GraphNode &) {}
 
   286       ///Push a new edge to the front of the path
 
   288       ///Push a new edge to the front of the path.
 
   290       void pushFront(const GraphEdge& e) {
 
   294       ///Push a new edge to the back of the path
 
   296       ///Push a new edge to the back of the path.
 
   298       void pushBack(const GraphEdge& e) {
 
   302       ///Commit the changes to the path.
 
   304 	if( !front.empty() || !back.empty() ) {
 
   306 	  tmp.reserve(front.size()+back.size()+P.length());
 
   307 	  tmp.insert(tmp.end(), front.rbegin(), front.rend());
 
   308 	  tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
 
   309 	  tmp.insert(tmp.end(), back.begin(), back.end());
 
   316       ///Reserve storage for the builder in advance.
 
   318       ///If you know a reasonable upper bound of the number of the edges
 
   319       ///to add to the front, using this function you can speed up the building.
 
   321       void reserveFront(size_t r) {front.reserve(r);}
 
   323       ///Reserve storage for the builder in advance.
 
   325       ///If you know a reasonable upper bound of the number of the edges
 
   326       ///to add to the back, using this function you can speed up the building.
 
   328       void reserveBack(size_t r) {back.reserve(r);}
 
   332 	return front.empty() && back.empty() && P.empty();
 
   335       GraphNode source() const {
 
   336 	if( ! front.empty() )
 
   337 	  return P.gr->source(front[front.size()-1]);
 
   338 	else if( ! P.empty() )
 
   339 	  return P.gr->source(P.edges[0]);
 
   340 	else if( ! back.empty() )
 
   341 	  return P.gr->source(back[0]);
 
   345       GraphNode target() const {
 
   347 	  return P.gr->target(back[back.size()-1]);
 
   348 	else if( ! P.empty() )
 
   349 	  return P.gr->target(P.edges[P.length()-1]);
 
   350 	else if( ! front.empty() )
 
   351 	  return P.gr->target(front[0]);
 
   369   /**********************************************************************/
 
   372   //! \brief A structure for representing undirected path in a graph.
 
   374   //! A structure for representing undirected path in a graph. Ie. this is
 
   375   //! a path in a \e directed graph but the edges should not be directed
 
   378   //! \param Graph The graph type in which the path is.
 
   379   //! \param DM DebugMode, defaults to DefaultDebugMode.
 
   381   //! In a sense, the path can be treated as a graph, for is has \c NodeIt
 
   382   //! and \c EdgeIt with the same usage. These types converts to the \c Node
 
   383   //! and \c Edge of the original graph.
 
   385   //! \todo Thoroughfully check all the range and consistency tests.
 
   386   template<typename Graph>
 
   389     /// Edge type of the underlying graph.
 
   390     typedef typename Graph::Edge GraphEdge;
 
   391      /// Node type of the underlying graph.
 
   392    typedef typename Graph::Node GraphNode;
 
   398     typedef std::vector<GraphEdge> Container;
 
   403     /// \param _G The graph in which the path is.
 
   405     UndirPath(const Graph &_G) : gr(&_G) {}
 
   407     /// \brief Subpath constructor.
 
   409     /// Subpath defined by two nodes.
 
   410     /// \warning It is an error if the two edges are not in order!
 
   411     UndirPath(const UndirPath &P, const NodeIt &a, const NodeIt &b) {
 
   413       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
 
   416     /// \brief Subpath constructor.
 
   418     /// Subpath defined by two edges. Contains edges in [a,b)
 
   419     /// \warning It is an error if the two edges are not in order!
 
   420     UndirPath(const UndirPath &P, const EdgeIt &a, const EdgeIt &b) {
 
   422       edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
 
   425     /// Length of the path.
 
   426     size_t length() const { return edges.size(); }
 
   427     /// Returns whether the path is empty.
 
   428     bool empty() const { return edges.empty(); }
 
   430     /// Resets the path to an empty path.
 
   431     void clear() { edges.clear(); }
 
   433     /// \brief Starting point of the path.
 
   435     /// Starting point of the path.
 
   436     /// Returns INVALID if the path is empty.
 
   437     GraphNode source() const {
 
   438       return empty() ? INVALID : gr->source(edges[0]);
 
   440     /// \brief End point of the path.
 
   442     /// End point of the path.
 
   443     /// Returns INVALID if the path is empty.
 
   444     GraphNode target() const {
 
   445       return empty() ? INVALID : gr->target(edges[length()-1]);
 
   448     /// \brief Initializes node or edge iterator to point to the first
 
   452     template<typename It>
 
   453     It& first(It &i) const { return i=It(*this); }
 
   455     /// \brief Initializes node iterator to point to the node of a given index.
 
   456     NodeIt& nth(NodeIt &i, int n) const {
 
   457       return i=NodeIt(*this, n);
 
   460     /// \brief Initializes edge iterator to point to the edge of a given index.
 
   461     EdgeIt& nth(EdgeIt &i, int n) const {
 
   462       return i=EdgeIt(*this, n);
 
   465     /// Checks validity of a node or edge iterator.
 
   466     template<typename It>
 
   468     bool valid(const It &i) { return i.valid(); }
 
   470     /// Steps the given node or edge iterator.
 
   471     template<typename It>
 
   477     /// \brief Returns node iterator pointing to the target node of the
 
   478     /// given edge iterator.
 
   479     NodeIt target(const EdgeIt& e) const {
 
   480       return NodeIt(*this, e.idx+1);
 
   483     /// \brief Returns node iterator pointing to the source node of the
 
   484     /// given edge iterator.
 
   485     NodeIt source(const EdgeIt& e) const {
 
   486       return NodeIt(*this, e.idx);
 
   492      * \brief Iterator class to iterate on the edges of the paths
 
   494      * This class is used to iterate on the edges of the paths
 
   496      * Of course it converts to Graph::Edge
 
   498      * \todo Its interface differs from the standard edge iterator.
 
   502       friend class UndirPath;
 
   507       /// Default constructor
 
   509       /// Invalid constructor
 
   510       EdgeIt(Invalid) : idx(-1), p(0) {}
 
   511       /// Constructor with starting point
 
   512       EdgeIt(const UndirPath &_p, int _idx = 0) :
 
   513 	idx(_idx), p(&_p) { validate(); }
 
   516       bool valid() const { return idx!=-1; }
 
   518       ///Conversion to Graph::Edge
 
   519       operator GraphEdge () const {
 
   520 	return valid() ? p->edges[idx] : INVALID;
 
   523      EdgeIt& operator++() { ++idx; validate(); return *this; }
 
   525       /// Comparison operator
 
   526       bool operator==(const EdgeIt& e) const { return idx==e.idx; }
 
   527       /// Comparison operator
 
   528       bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
 
   529       /// Comparison operator
 
   530       bool operator<(const EdgeIt& e) const { return idx<e.idx; }
 
   533       // FIXME: comparison between signed and unsigned...
 
   534       // Jo ez igy? Vagy esetleg legyen a length() int?
 
   535       void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
 
   539      * \brief Iterator class to iterate on the nodes of the paths
 
   541      * This class is used to iterate on the nodes of the paths
 
   543      * Of course it converts to Graph::Node
 
   545      * \todo Its interface differs from the standard node iterator.
 
   549       friend class UndirPath;
 
   554       /// Default constructor
 
   556       /// Invalid constructor
 
   557       NodeIt(Invalid) : idx(-1), p(0) {}
 
   558       /// Constructor with starting point
 
   559       NodeIt(const UndirPath &_p, int _idx = 0) :
 
   560 	idx(_idx), p(&_p) { validate(); }
 
   563       bool valid() const { return idx!=-1; }
 
   565       ///Conversion to Graph::Node
 
   566       operator const GraphNode& () const {
 
   567 	if(idx >= p->length())
 
   570 	  return p->gr->source(p->edges[idx]);
 
   575       NodeIt& operator++() { ++idx; validate(); return *this; }
 
   577       /// Comparison operator
 
   578       bool operator==(const NodeIt& e) const { return idx==e.idx; }
 
   579       /// Comparison operator
 
   580       bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
 
   581        /// Comparison operator
 
   582      bool operator<(const NodeIt& e) const { return idx<e.idx; }
 
   585       void validate() { if( size_t(idx) > p->length() ) idx=-1; }
 
   588     friend class Builder;
 
   591      * \brief Class to build paths
 
   593      * This class is used to fill a path with edges.
 
   595      * You can push new edges to the front and to the back of the path in
 
   596      * arbitrary order then you should commit these changes to the graph.
 
   598      * Fundamentally, for most "Paths" (classes fulfilling the
 
   599      * PathConcept) while the builder is active (after the first modifying
 
   600      * operation and until the commit()) the original Path is in a
 
   601      * "transitional" state (operations ot it have undefined result). But
 
   602      * in the case of UndirPath the original path is unchanged until the
 
   603      * commit. However we don't recomend that you use this feature.
 
   607       Container front, back;
 
   610       ///\param _p the path you want to fill in.
 
   612       Builder(UndirPath &_p) : P(_p) {}
 
   614       /// Sets the starting node of the path.
 
   616       /// Sets the starting node of the path. Edge added to the path
 
   617       /// afterwards have to be incident to this node.
 
   618       /// It should be called if and only if
 
   619       /// the path is empty and before any call to
 
   620       /// \ref pushFront() or \ref pushBack()
 
   621       void setStartNode(const GraphNode &) {}
 
   623       ///Push a new edge to the front of the path
 
   625       ///Push a new edge to the front of the path.
 
   627       void pushFront(const GraphEdge& e) {
 
   631       ///Push a new edge to the back of the path
 
   633       ///Push a new edge to the back of the path.
 
   635       void pushBack(const GraphEdge& e) {
 
   639       ///Commit the changes to the path.
 
   641 	if( !(front.empty() && back.empty()) ) {
 
   643 	  tmp.reserve(front.size()+back.size()+P.length());
 
   644 	  tmp.insert(tmp.end(), front.rbegin(), front.rend());
 
   645 	  tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
 
   646 	  tmp.insert(tmp.end(), back.begin(), back.end());
 
   654       ///Reserve storage for the builder in advance.
 
   656       ///If you know a reasonable upper bound of the number of the edges
 
   657       ///to add to the front, using this function you can speed up the building.
 
   659       void reserveFront(size_t r) {front.reserve(r);}
 
   661       ///Reserve storage for the builder in advance.
 
   663       ///If you know a reasonable upper bound of the number of the edges
 
   664       ///to add to the back, using this function you can speed up the building.
 
   666       void reserveBack(size_t r) {back.reserve(r);}
 
   670 	return front.empty() && back.empty() && P.empty();
 
   673       GraphNode source() const {
 
   674 	if( ! front.empty() )
 
   675 	  return P.gr->source(front[front.size()-1]);
 
   676 	else if( ! P.empty() )
 
   677 	  return P.gr->source(P.edges[0]);
 
   678 	else if( ! back.empty() )
 
   679 	  return P.gr->source(back[0]);
 
   683       GraphNode target() const {
 
   685 	  return P.gr->target(back[back.size()-1]);
 
   686 	else if( ! P.empty() )
 
   687 	  return P.gr->target(P.edges[P.length()-1]);
 
   688 	else if( ! front.empty() )
 
   689 	  return P.gr->target(front[0]);
 
   703 #endif // LEMON_PATH_H