lemon/concepts/path.h
changeset 2335 27aa03cd3121
parent 2260 4274224f8a7d
child 2357 5365600a7a5c
equal deleted inserted replaced
0:7ab7452a8e7f 1:158c142651c8
    24 
    24 
    25 #ifndef LEMON_CONCEPT_PATH_H
    25 #ifndef LEMON_CONCEPT_PATH_H
    26 #define LEMON_CONCEPT_PATH_H
    26 #define LEMON_CONCEPT_PATH_H
    27 
    27 
    28 #include <lemon/bits/invalid.h>
    28 #include <lemon/bits/invalid.h>
       
    29 #include <lemon/bits/utility.h>
    29 #include <lemon/concept_check.h>
    30 #include <lemon/concept_check.h>
    30 
    31 
    31 namespace lemon {
    32 namespace lemon {
    32   namespace concepts {
    33   namespace concepts {
       
    34 
    33     /// \addtogroup concept
    35     /// \addtogroup concept
    34     /// @{
    36     /// @{
    35 
    37 
    36 
    38     /// \brief A skeleton structure for representing directed paths in
    37     //! \brief A skeleton structure for representing directed paths in a graph.
    39     /// a graph.
    38     //!
    40     ///
    39     //! A skeleton structure for representing directed paths in a graph.
    41     /// A skeleton structure for representing directed paths in a
    40     //! \param _Graph The graph type in which the path is.
    42     /// graph.  
    41     //!
    43     /// \param _Graph The graph type in which the path is.
    42     //! In a sense, the path can be treated as a graph, for it has \c NodeIt
    44     ///
    43     //! and \c EdgeIt with the same usage. These types converts to the \c Node
    45     /// In a sense, the path can be treated as a list of edges. The
    44     //! and \c Edge of the original graph.
    46     /// lemon path type stores just this list. As a consequence it
    45     template<typename _Graph>
    47     /// cannot enumerate the nodes in the path and the zero length
       
    48     /// paths cannot store the source.
       
    49     ///
       
    50     template <typename _Graph>
    46     class Path {
    51     class Path {
    47     public:
    52     public:
    48 
    53 
    49       /// Type of the underlying graph.
    54       /// Type of the underlying graph.
    50       typedef _Graph Graph;
    55       typedef _Graph Graph;
    51       /// Edge type of the underlying graph.
    56       /// Edge type of the underlying graph.
    52       typedef typename Graph::Edge Edge;
    57       typedef typename Graph::Edge Edge;
    53       /// Node type of the underlying graph.
    58 
    54       typedef typename Graph::Node Node;
       
    55 
       
    56       class NodeIt;
       
    57       class EdgeIt;
    59       class EdgeIt;
    58 
    60 
    59       /// \param _g The graph in which the path is.
    61       /// \brief Default constructor
    60       ///
    62       Path() {}
    61       Path(const Graph &_g) {
    63 
    62 	ignore_unused_variable_warning(_g);
    64       /// \brief Template constructor
    63       }
    65       template <typename CPath>
       
    66       Path(const CPath& cpath) {}
       
    67 
       
    68       /// \brief Template assigment
       
    69       template <typename CPath>
       
    70       Path& operator=(const CPath& cpath) {}
    64 
    71 
    65       /// Length of the path ie. the number of edges in the path.
    72       /// Length of the path ie. the number of edges in the path.
    66       int length() const {return 0;}
    73       int length() const { return 0;}
    67 
    74 
    68       /// Returns whether the path is empty.
    75       /// Returns whether the path is empty.
    69       bool empty() const { return true;}
    76       bool empty() const { return true;}
    70 
    77 
    71       /// Resets the path to an empty path.
    78       /// Resets the path to an empty path.
    72       void clear() {}
    79       void clear() {}
    73 
    80 
    74       /// \brief Starting point of the path.
    81       /// \brief Lemon style iterator for path edges
    75       ///
    82       ///
    76       /// Starting point of the path.
    83       /// This class is used to iterate on the edges of the paths.
    77       /// Returns INVALID if the path is empty.
       
    78       Node target() const {return INVALID;}
       
    79       /// \brief End point of the path.
       
    80       ///
       
    81       /// End point of the path.
       
    82       /// Returns INVALID if the path is empty.
       
    83       Node source() const {return INVALID;}
       
    84 
       
    85       /// \brief The target of an edge.
       
    86       ///
       
    87       /// Returns node iterator pointing to the target node of the
       
    88       /// given edge iterator.
       
    89       NodeIt target(const EdgeIt&) const {return INVALID;}
       
    90 
       
    91       /// \brief The source of an edge.
       
    92       ///
       
    93       /// Returns node iterator pointing to the source node of the
       
    94       /// given edge iterator.
       
    95       NodeIt source(const EdgeIt&) const {return INVALID;}
       
    96 
       
    97       /// \brief Iterator class to iterate on the nodes of the paths
       
    98       ///
       
    99       /// This class is used to iterate on the nodes of the paths
       
   100       ///
       
   101       /// Of course it converts to Graph::Node.
       
   102       class NodeIt {
       
   103       public:
       
   104 	/// Default constructor
       
   105 	NodeIt() {}
       
   106 	/// Invalid constructor
       
   107 	NodeIt(Invalid) {}
       
   108 	/// Constructor with starting point
       
   109 	NodeIt(const Path &) {}
       
   110 
       
   111 	///Conversion to Graph::Node
       
   112 	operator Node() const { return INVALID; }
       
   113 	/// Next node
       
   114 	NodeIt& operator++() {return *this;}
       
   115 
       
   116 	/// Comparison operator
       
   117 	bool operator==(const NodeIt&) const {return true;}
       
   118 	/// Comparison operator
       
   119 	bool operator!=(const NodeIt&) const {return true;}
       
   120  	/// Comparison operator
       
   121  	bool operator<(const NodeIt&) const {return false;}
       
   122 
       
   123       };
       
   124 
       
   125       /// \brief Iterator class to iterate on the edges of the paths
       
   126       ///
       
   127       /// This class is used to iterate on the edges of the paths
       
   128       ///
       
   129       /// Of course it converts to Graph::Edge
       
   130       class EdgeIt {
    84       class EdgeIt {
   131       public:
    85       public:
   132 	/// Default constructor
    86 	/// Default constructor
   133 	EdgeIt() {}
    87 	EdgeIt() {}
   134 	/// Invalid constructor
    88 	/// Invalid constructor
   135 	EdgeIt(Invalid) {}
    89 	EdgeIt(Invalid) {}
   136 	/// Constructor with starting point
    90 	/// Constructor for first edge
   137 	EdgeIt(const Path &) {}
    91 	EdgeIt(const Path &) {}
   138 
    92 
       
    93         /// Conversion to Edge
   139 	operator Edge() const { return INVALID; }
    94 	operator Edge() const { return INVALID; }
   140 
    95 
   141 	/// Next edge
    96 	/// Next edge
   142 	EdgeIt& operator++() {return *this;}
    97 	EdgeIt& operator++() {return *this;}
   143 
    98 
   148  	/// Comparison operator
   103  	/// Comparison operator
   149  	bool operator<(const EdgeIt&) const {return false;}
   104  	bool operator<(const EdgeIt&) const {return false;}
   150 
   105 
   151       };
   106       };
   152 
   107 
   153 
       
   154       friend class Builder;
       
   155 
       
   156       /// \brief Class to build paths
       
   157       ///
       
   158       /// This class is used to fill a path with edges.
       
   159       ///
       
   160       /// You can push new edges to the front and to the back of the path in
       
   161       /// arbitrary order then you should commit these changes to the graph.
       
   162       ///
       
   163       /// While the builder is active (after the first modifying
       
   164       /// operation and until the call of \ref commit()) the
       
   165       /// underlining Path is in a "transitional" state (operations on
       
   166       /// it have undefined result).
       
   167       class Builder {
       
   168       public:
       
   169 
       
   170         /// Constructor
       
   171 
       
   172         /// Constructor
       
   173 	/// \param _path the path you want to fill in.
       
   174 	///
       
   175 
       
   176 	Builder(Path &_path) { ignore_unused_variable_warning(_path); }
       
   177 
       
   178 	/// Sets the starting node of the path.
       
   179 
       
   180 	/// Sets the starting node of the path. Edge added to the path
       
   181 	/// afterwards have to be incident to this node.
       
   182 	/// You \em must start building an empty path with these functions.
       
   183 	/// (And you \em must \em not use it later).
       
   184 	/// \sa pushFront()
       
   185 	/// \sa pushBack()
       
   186 	void setStartNode(const Node &) {}
       
   187 
       
   188 	///Push a new edge to the front of the path
       
   189 
       
   190 	///Push a new edge to the front of the path.
       
   191 	///If the path is empty, you \em must call \ref setStartNode() before
       
   192 	///the first use of \ref pushFront().
       
   193 	void pushFront(const Edge&) {}
       
   194 
       
   195 	///Push a new edge to the back of the path
       
   196 
       
   197 	///Push a new edge to the back of the path.
       
   198 	///If the path is empty, you \em must call \ref setStartNode() before
       
   199 	///the first use of \ref pushBack().
       
   200 	void pushBack(const Edge&) {}
       
   201 
       
   202 	///Commit the changes to the path.
       
   203 
       
   204 	///Commit the changes to the path.
       
   205         ///
       
   206 	void commit() {}
       
   207 
       
   208 	///Reserve (front) storage for the builder in advance.
       
   209 
       
   210 	///If you know a reasonable upper bound on the number of the edges
       
   211 	///to add to the front of the path,
       
   212 	///using this function you may speed up the building.
       
   213 	void reserveFront(size_t) {}
       
   214 	///Reserve (back) storage for the builder in advance.
       
   215 
       
   216 	///If you know a reasonable upper bound on the number of the edges
       
   217 	///to add to the back of the path,
       
   218 	///using this function you may speed up the building.
       
   219 	void reserveBack(size_t) {}
       
   220       };
       
   221 
       
   222       template <typename _Path>
   108       template <typename _Path>
   223       struct Constraints {
   109       struct Constraints {
   224 	void constraints() {
   110         void constraints() {
   225           typedef typename _Path::Node Node;
   111           Path<Graph> pc;
   226           typedef typename _Path::NodeIt NodeIt;
   112           _Path p, pp(pc);
   227           typedef typename Graph::Node GraphNode;
   113           int l = p.length();
   228 
   114           int e = p.empty();
   229           typedef typename _Path::Edge Edge;
   115           p.clear();
   230           typedef typename _Path::EdgeIt EdgeIt;
   116 
   231           typedef typename Graph::Edge GraphEdge;
   117           p = pc;
   232 
   118 
   233           typedef typename _Path::Builder Builder;
   119           typename _Path::EdgeIt id, ii(INVALID), i(p);
   234 
   120 
   235           path = _Path(graph);
   121           ++i;
   236 
   122           typename Graph::Edge ed = i;
   237           bool b = cpath.empty();
   123 
   238           int l = cpath.length();
   124           e = (i == ii);
   239 
   125           e = (i != ii);
   240           Node gn;
   126           e = (i < ii);
   241           Edge ge;
   127 
   242           gn = cpath.source();
       
   243           gn = cpath.target();
       
   244 
       
   245           NodeIt nit;
       
   246           EdgeIt eit(INVALID);
       
   247           nit = path.source(eit);
       
   248           nit = path.target(eit);
       
   249           
       
   250           nit = NodeIt();
       
   251           nit = NodeIt(cpath);
       
   252           nit = INVALID;
       
   253           gn = nit;
       
   254           ++nit;
       
   255           b = nit == nit;
       
   256           b = nit != nit;
       
   257           b = nit < nit;
       
   258 
       
   259           eit = EdgeIt();
       
   260           eit = EdgeIt(cpath);
       
   261           eit = INVALID;
       
   262           ge = eit;
       
   263           ++eit;
       
   264           b = eit == eit;
       
   265           b = eit != eit;
       
   266           b = eit < eit;
       
   267 
       
   268           size_t st = 0;
       
   269 
       
   270           Builder builder(path); 
       
   271           builder.setStartNode(gn);
       
   272           builder.pushFront(ge);
       
   273           builder.pushBack(ge);
       
   274           builder.commit();
       
   275           builder.reserveFront(st);
       
   276           builder.reserveBack(st);
       
   277           
       
   278           ignore_unused_variable_warning(l);
   128           ignore_unused_variable_warning(l);
   279           ignore_unused_variable_warning(b);
   129           ignore_unused_variable_warning(pp);
   280 	}
   130           ignore_unused_variable_warning(e);
   281 
   131           ignore_unused_variable_warning(id);
   282         const Graph& graph;
   132           ignore_unused_variable_warning(ii);
   283         const _Path& cpath;
   133           ignore_unused_variable_warning(ed);
   284         _Path& path;
   134         }
   285       };
   135       };
   286 
   136 
   287     };
   137     };
   288 
   138 
   289   ///@}
   139     namespace _path_bits {
       
   140       
       
   141       template <typename _Graph, typename _Path, typename RevPathTag = void>
       
   142       struct PathDumperConstraints {
       
   143         void constraints() {
       
   144           int l = p.length();
       
   145           int e = p.empty();
       
   146 
       
   147           typename _Path::EdgeIt id, ii(INVALID), i(p);
       
   148 
       
   149           ++i;
       
   150           typename _Graph::Edge ed = i;
       
   151 
       
   152           e = (i == ii);
       
   153           e = (i != ii);
       
   154           e = (i < ii);
       
   155 
       
   156           ignore_unused_variable_warning(l);
       
   157           ignore_unused_variable_warning(e);
       
   158           ignore_unused_variable_warning(id);
       
   159           ignore_unused_variable_warning(ii);
       
   160           ignore_unused_variable_warning(ed);
       
   161         }
       
   162         _Path& p;
       
   163       };
       
   164 
       
   165       template <typename _Graph, typename _Path>
       
   166       struct PathDumperConstraints<
       
   167         _Graph, _Path, 
       
   168         typename enable_if<typename _Path::RevPathTag, void>::type
       
   169       > {
       
   170         void constraints() {
       
   171           int l = p.length();
       
   172           int e = p.empty();
       
   173 
       
   174           typename _Path::RevIt id, ii(INVALID), i(p);
       
   175 
       
   176           ++i;
       
   177           typename _Graph::Edge ed = i;
       
   178 
       
   179           e = (i == ii);
       
   180           e = (i != ii);
       
   181           e = (i < ii);
       
   182 
       
   183           ignore_unused_variable_warning(l);
       
   184           ignore_unused_variable_warning(e);
       
   185           ignore_unused_variable_warning(id);
       
   186           ignore_unused_variable_warning(ii);
       
   187           ignore_unused_variable_warning(ed);
       
   188         }
       
   189         _Path& p;
       
   190       };
       
   191     
       
   192     }
       
   193 
       
   194 
       
   195     /// \brief A skeleton structure for path dumpers.
       
   196     ///
       
   197     /// A skeleton structure for path dumpers. The path dumpers are
       
   198     /// the generalization of the paths. The path dumpers can
       
   199     /// enumerate the edges of the path wheter in forward or in
       
   200     /// backward order.  In most time these classes are not used
       
   201     /// directly rather it used to assign a dumped class to a real
       
   202     /// path type.
       
   203     ///
       
   204     /// The main purpose of this concept is that the shortest path
       
   205     /// algorithms can enumerate easily the edges in reverse order.
       
   206     /// If we would like to give back a real path from these
       
   207     /// algorithms then we should create a temporarly path object. In
       
   208     /// Lemon such algorithms gives back a path dumper what can
       
   209     /// assigned to a real path and the dumpers can be implemented as
       
   210     /// an adaptor class to the predecessor map.
       
   211 
       
   212     /// \param _Graph  The graph type in which the path is.
       
   213     ///
       
   214     /// The paths can be constructed from any path type by a
       
   215     /// template constructor or a template assignment operator.
       
   216     /// 
       
   217     template <typename _Graph>
       
   218     class PathDumper {
       
   219     public:
       
   220 
       
   221       /// Type of the underlying graph.
       
   222       typedef _Graph Graph;
       
   223       /// Edge type of the underlying graph.
       
   224       typedef typename Graph::Edge Edge;
       
   225 
       
   226       /// Length of the path ie. the number of edges in the path.
       
   227       int length() const { return 0;}
       
   228 
       
   229       /// Returns whether the path is empty.
       
   230       bool empty() const { return true;}
       
   231 
       
   232       /// \brief Forward or reverse dumping
       
   233       ///
       
   234       /// If the RevPathTag is defined and true then reverse dumping
       
   235       /// is provided in the path proxy. In this case instead of the
       
   236       /// EdgeIt the RevIt iterator should be implemented in the
       
   237       /// proxy.
       
   238       typedef False RevPathTag;
       
   239 
       
   240       /// \brief Lemon style iterator for path edges
       
   241       ///
       
   242       /// This class is used to iterate on the edges of the paths.
       
   243       class EdgeIt {
       
   244       public:
       
   245 	/// Default constructor
       
   246 	EdgeIt() {}
       
   247 	/// Invalid constructor
       
   248 	EdgeIt(Invalid) {}
       
   249 	/// Constructor for first edge
       
   250 	EdgeIt(const PathDumper&) {}
       
   251 
       
   252         /// Conversion to Edge
       
   253 	operator Edge() const { return INVALID; }
       
   254 
       
   255 	/// Next edge
       
   256 	EdgeIt& operator++() {return *this;}
       
   257 
       
   258 	/// Comparison operator
       
   259 	bool operator==(const EdgeIt&) const {return true;}
       
   260 	/// Comparison operator
       
   261 	bool operator!=(const EdgeIt&) const {return true;}
       
   262  	/// Comparison operator
       
   263  	bool operator<(const EdgeIt&) const {return false;}
       
   264 
       
   265       };
       
   266 
       
   267       /// \brief Lemon style iterator for path edges
       
   268       ///
       
   269       /// This class is used to iterate on the edges of the paths in
       
   270       /// reverse direction.
       
   271       class RevIt {
       
   272       public:
       
   273 	/// Default constructor
       
   274 	RevIt() {}
       
   275 	/// Invalid constructor
       
   276 	RevIt(Invalid) {}
       
   277 	/// Constructor for first edge
       
   278 	RevIt(const PathDumper &) {}
       
   279 
       
   280         /// Conversion to Edge
       
   281 	operator Edge() const { return INVALID; }
       
   282 
       
   283 	/// Next edge
       
   284 	RevIt& operator++() {return *this;}
       
   285 
       
   286 	/// Comparison operator
       
   287 	bool operator==(const RevIt&) const {return true;}
       
   288 	/// Comparison operator
       
   289 	bool operator!=(const RevIt&) const {return true;}
       
   290  	/// Comparison operator
       
   291  	bool operator<(const RevIt&) const {return false;}
       
   292 
       
   293       };
       
   294 
       
   295       template <typename _Path>
       
   296       struct Constraints {
       
   297         void constraints() {
       
   298           function_requires<_path_bits::
       
   299             PathDumperConstraints<Graph, _Path> >();
       
   300         }
       
   301       };
       
   302 
       
   303     };
       
   304 
       
   305 
       
   306     ///@}
   290   }
   307   }
   291 
   308 
   292 } // namespace lemon
   309 } // namespace lemon
   293 
   310 
   294 #endif // LEMON_CONCEPT_PATH_H
   311 #endif // LEMON_CONCEPT_PATH_H