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 |