Minor changes.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
22 ///\brief Classes for representing paths in graphs.
24 ///\todo Iterators have obsolete style
33 #include <lemon/bits/invalid.h>
41 //! \brief A structure for representing directed paths in a graph.
43 //! A structure for representing directed path in a graph.
44 //! \param Graph The graph type in which the path is.
45 //! \param DM DebugMode, defaults to DefaultDebugMode.
47 //! In a sense, the path can be treated as a graph, for is has \c NodeIt
48 //! and \c EdgeIt with the same usage. These types converts to the \c Node
49 //! and \c Edge of the original graph.
51 //! \todo Thoroughfully check all the range and consistency tests.
52 template<typename Graph>
55 /// Edge type of the underlying graph.
56 typedef typename Graph::Edge GraphEdge;
57 /// Node type of the underlying graph.
58 typedef typename Graph::Node GraphNode;
64 typedef std::vector<GraphEdge> Container;
69 /// \param _G The graph in which the path is.
71 DirPath(const Graph &_G) : gr(&_G) {}
73 /// \brief Subpath constructor.
75 /// Subpath defined by two nodes.
76 /// \warning It is an error if the two edges are not in order!
77 DirPath(const DirPath &P, const NodeIt &a, const NodeIt &b) {
79 edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
82 /// \brief Subpath constructor.
84 /// Subpath defined by two edges. Contains edges in [a,b)
85 /// \warning It is an error if the two edges are not in order!
86 DirPath(const DirPath &P, const EdgeIt &a, const EdgeIt &b) {
88 edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
91 /// Length of the path.
92 int length() const { return edges.size(); }
93 /// Returns whether the path is empty.
94 bool empty() const { return edges.empty(); }
96 /// Resets the path to an empty path.
97 void clear() { edges.clear(); }
99 /// \brief Starting point of the path.
101 /// Starting point of the path.
102 /// Returns INVALID if the path is empty.
103 GraphNode source() const {
104 return empty() ? INVALID : gr->source(edges[0]);
106 /// \brief End point of the path.
108 /// End point of the path.
109 /// Returns INVALID if the path is empty.
110 GraphNode target() const {
111 return empty() ? INVALID : gr->target(edges[length()-1]);
114 /// \brief Initializes node or edge iterator to point to the first
118 template<typename It>
119 It& first(It &i) const { return i=It(*this); }
121 /// \brief Initializes node iterator to point to the node of a given index.
122 NodeIt& nth(NodeIt &i, int n) const {
123 return i=NodeIt(*this, n);
126 /// \brief Initializes edge iterator to point to the edge of a given index.
127 EdgeIt& nth(EdgeIt &i, int n) const {
128 return i=EdgeIt(*this, n);
131 /// \brief Returns node iterator pointing to the target node of the
132 /// given edge iterator.
133 NodeIt target(const EdgeIt& e) const {
134 return NodeIt(*this, e.idx+1);
137 /// \brief Returns node iterator pointing to the source node of the
138 /// given edge iterator.
139 NodeIt source(const EdgeIt& e) const {
140 return NodeIt(*this, e.idx);
144 /* Iterator classes */
147 * \brief Iterator class to iterate on the edges of the paths
149 * This class is used to iterate on the edges of the paths
151 * Of course it converts to Graph::Edge
155 friend class DirPath;
160 /// Default constructor
162 /// Invalid constructor
163 EdgeIt(Invalid) : idx(-1), p(0) {}
164 /// Constructor with starting point
165 EdgeIt(const DirPath &_p, int _idx = 0) :
166 idx(_idx), p(&_p) { validate(); }
169 bool valid() const { return idx!=-1; }
171 ///Conversion to Graph::Edge
172 operator GraphEdge () const {
173 return valid() ? p->edges[idx] : INVALID;
177 EdgeIt& operator++() { ++idx; validate(); return *this; }
179 /// Comparison operator
180 bool operator==(const EdgeIt& e) const { return idx==e.idx; }
181 /// Comparison operator
182 bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
183 /// Comparison operator
184 bool operator<(const EdgeIt& e) const { return idx<e.idx; }
187 void validate() { if(idx >= p->length() ) idx=-1; }
191 * \brief Iterator class to iterate on the nodes of the paths
193 * This class is used to iterate on the nodes of the paths
195 * Of course it converts to Graph::Node
199 friend class DirPath;
204 /// Default constructor
206 /// Invalid constructor
207 NodeIt(Invalid) : idx(-1), p(0) {}
208 /// Constructor with starting point
209 NodeIt(const DirPath &_p, int _idx = 0) :
210 idx(_idx), p(&_p) { validate(); }
213 bool valid() const { return idx!=-1; }
215 ///Conversion to Graph::Node
216 operator GraphNode () const {
217 if(idx >= p->length())
220 return p->gr->source(p->edges[idx]);
225 NodeIt& operator++() { ++idx; validate(); return *this; }
227 /// Comparison operator
228 bool operator==(const NodeIt& e) const { return idx==e.idx; }
229 /// Comparison operator
230 bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
231 /// Comparison operator
232 bool operator<(const NodeIt& e) const { return idx<e.idx; }
235 void validate() { if(idx > p->length() ) idx=-1; }
238 friend class Builder;
241 * \brief Class to build paths
243 * This class is used to fill a path with edges.
245 * You can push new edges to the front and to the back of the path in
246 * arbitrary order then you should commit these changes to the graph.
248 * Fundamentally, for most "Paths" (classes fulfilling the
249 * PathConcept) while the builder is active (after the first modifying
250 * operation and until the commit()) the original Path is in a
251 * "transitional" state (operations on it have undefined result). But
252 * in the case of DirPath the original path remains unchanged until the
253 * commit. However we don't recomend that you use this feature.
257 Container front, back;
260 ///\param _p the path you want to fill in.
262 Builder(DirPath &_p) : P(_p) {}
264 /// Sets the starting node of the path.
266 /// Sets the starting node of the path. Edge added to the path
267 /// afterwards have to be incident to this node.
268 /// It should be called if and only if
269 /// the path is empty and before any call to
270 /// \ref pushFront() or \ref pushBack()
271 void setStartNode(const GraphNode &) {}
273 ///Push a new edge to the front of the path
275 ///Push a new edge to the front of the path.
277 void pushFront(const GraphEdge& e) {
281 ///Push a new edge to the back of the path
283 ///Push a new edge to the back of the path.
285 void pushBack(const GraphEdge& e) {
289 ///Commit the changes to the path.
291 if( !front.empty() || !back.empty() ) {
293 tmp.reserve(front.size()+back.size()+P.length());
294 tmp.insert(tmp.end(), front.rbegin(), front.rend());
295 tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
296 tmp.insert(tmp.end(), back.begin(), back.end());
303 ///Reserve storage for the builder in advance.
305 ///If you know a reasonable upper bound of the number of the edges
306 ///to add to the front, using this function you can speed up the building.
308 void reserveFront(size_t r) {front.reserve(r);}
310 ///Reserve storage for the builder in advance.
312 ///If you know a reasonable upper bound of the number of the edges
313 ///to add to the back, using this function you can speed up the building.
315 void reserveBack(size_t r) {back.reserve(r);}
319 return front.empty() && back.empty() && P.empty();
322 GraphNode source() const {
323 if( ! front.empty() )
324 return P.gr->source(front[front.size()-1]);
325 else if( ! P.empty() )
326 return P.gr->source(P.edges[0]);
327 else if( ! back.empty() )
328 return P.gr->source(back[0]);
332 GraphNode target() const {
334 return P.gr->target(back[back.size()-1]);
335 else if( ! P.empty() )
336 return P.gr->target(P.edges[P.length()-1]);
337 else if( ! front.empty() )
338 return P.gr->target(front[0]);
356 /**********************************************************************/
359 //! \brief A structure for representing undirected path in a graph.
361 //! A structure for representing undirected path in a graph. Ie. this is
362 //! a path in a \e directed graph but the edges should not be directed
365 //! \param Graph The graph type in which the path is.
366 //! \param DM DebugMode, defaults to DefaultDebugMode.
368 //! In a sense, the path can be treated as a graph, for is has \c NodeIt
369 //! and \c EdgeIt with the same usage. These types converts to the \c Node
370 //! and \c Edge of the original graph.
372 //! \todo Thoroughfully check all the range and consistency tests.
373 /// \todo May we need just path for undirected graph instead of this.
374 template<typename Graph>
377 /// Edge type of the underlying graph.
378 typedef typename Graph::Edge GraphEdge;
379 /// Node type of the underlying graph.
380 typedef typename Graph::Node GraphNode;
386 typedef std::vector<GraphEdge> Container;
391 /// \param _G The graph in which the path is.
393 UPath(const Graph &_G) : gr(&_G) {}
395 /// \brief Subpath constructor.
397 /// Subpath defined by two nodes.
398 /// \warning It is an error if the two edges are not in order!
399 UPath(const UPath &P, const NodeIt &a, const NodeIt &b) {
401 edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
404 /// \brief Subpath constructor.
406 /// Subpath defined by two edges. Contains edges in [a,b)
407 /// \warning It is an error if the two edges are not in order!
408 UPath(const UPath &P, const EdgeIt &a, const EdgeIt &b) {
410 edges.insert(edges.end(), P.edges.begin()+a.idx, P.edges.begin()+b.idx);
413 /// Length of the path.
414 size_t length() const { return edges.size(); }
415 /// Returns whether the path is empty.
416 bool empty() const { return edges.empty(); }
418 /// Resets the path to an empty path.
419 void clear() { edges.clear(); }
421 /// \brief Starting point of the path.
423 /// Starting point of the path.
424 /// Returns INVALID if the path is empty.
425 GraphNode source() const {
426 return empty() ? INVALID : gr->source(edges[0]);
428 /// \brief End point of the path.
430 /// End point of the path.
431 /// Returns INVALID if the path is empty.
432 GraphNode target() const {
433 return empty() ? INVALID : gr->target(edges[length()-1]);
436 /// \brief Initializes node or edge iterator to point to the first
440 template<typename It>
441 It& first(It &i) const { return i=It(*this); }
443 /// \brief Initializes node iterator to point to the node of a given index.
444 NodeIt& nth(NodeIt &i, int n) const {
445 return i=NodeIt(*this, n);
448 /// \brief Initializes edge iterator to point to the edge of a given index.
449 EdgeIt& nth(EdgeIt &i, int n) const {
450 return i=EdgeIt(*this, n);
453 /// Checks validity of a node or edge iterator.
454 template<typename It>
456 bool valid(const It &i) { return i.valid(); }
458 /// Steps the given node or edge iterator.
459 template<typename It>
465 /// \brief Returns node iterator pointing to the target node of the
466 /// given edge iterator.
467 NodeIt target(const EdgeIt& e) const {
468 return NodeIt(*this, e.idx+1);
471 /// \brief Returns node iterator pointing to the source node of the
472 /// given edge iterator.
473 NodeIt source(const EdgeIt& e) const {
474 return NodeIt(*this, e.idx);
480 * \brief Iterator class to iterate on the edges of the paths
482 * This class is used to iterate on the edges of the paths
484 * Of course it converts to Graph::Edge
486 * \todo Its interface differs from the standard edge iterator.
495 /// Default constructor
497 /// Invalid constructor
498 EdgeIt(Invalid) : idx(-1), p(0) {}
499 /// Constructor with starting point
500 EdgeIt(const UPath &_p, int _idx = 0) :
501 idx(_idx), p(&_p) { validate(); }
504 bool valid() const { return idx!=-1; }
506 ///Conversion to Graph::Edge
507 operator GraphEdge () const {
508 return valid() ? p->edges[idx] : INVALID;
511 EdgeIt& operator++() { ++idx; validate(); return *this; }
513 /// Comparison operator
514 bool operator==(const EdgeIt& e) const { return idx==e.idx; }
515 /// Comparison operator
516 bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
517 /// Comparison operator
518 bool operator<(const EdgeIt& e) const { return idx<e.idx; }
521 // FIXME: comparison between signed and unsigned...
522 // Jo ez igy? Vagy esetleg legyen a length() int?
523 void validate() { if( size_t(idx) >= p->length() ) idx=-1; }
527 * \brief Iterator class to iterate on the nodes of the paths
529 * This class is used to iterate on the nodes of the paths
531 * Of course it converts to Graph::Node
533 * \todo Its interface differs from the standard node iterator.
542 /// Default constructor
544 /// Invalid constructor
545 NodeIt(Invalid) : idx(-1), p(0) {}
546 /// Constructor with starting point
547 NodeIt(const UPath &_p, int _idx = 0) :
548 idx(_idx), p(&_p) { validate(); }
551 bool valid() const { return idx!=-1; }
553 ///Conversion to Graph::Node
554 operator const GraphNode& () const {
555 if(idx >= p->length())
558 return p->gr->source(p->edges[idx]);
563 NodeIt& operator++() { ++idx; validate(); return *this; }
565 /// Comparison operator
566 bool operator==(const NodeIt& e) const { return idx==e.idx; }
567 /// Comparison operator
568 bool operator!=(const NodeIt& e) const { return idx!=e.idx; }
569 /// Comparison operator
570 bool operator<(const NodeIt& e) const { return idx<e.idx; }
573 void validate() { if( size_t(idx) > p->length() ) idx=-1; }
576 friend class Builder;
579 * \brief Class to build paths
581 * This class is used to fill a path with edges.
583 * You can push new edges to the front and to the back of the path in
584 * arbitrary order then you should commit these changes to the graph.
586 * Fundamentally, for most "Paths" (classes fulfilling the
587 * PathConcept) while the builder is active (after the first modifying
588 * operation and until the commit()) the original Path is in a
589 * "transitional" state (operations ot it have undefined result). But
590 * in the case of UPath the original path is unchanged until the
591 * commit. However we don't recomend that you use this feature.
595 Container front, back;
598 ///\param _p the path you want to fill in.
600 Builder(UPath &_p) : P(_p) {}
602 /// Sets the starting node of the path.
604 /// Sets the starting node of the path. Edge added to the path
605 /// afterwards have to be incident to this node.
606 /// It should be called if and only if
607 /// the path is empty and before any call to
608 /// \ref pushFront() or \ref pushBack()
609 void setStartNode(const GraphNode &) {}
611 ///Push a new edge to the front of the path
613 ///Push a new edge to the front of the path.
615 void pushFront(const GraphEdge& e) {
619 ///Push a new edge to the back of the path
621 ///Push a new edge to the back of the path.
623 void pushBack(const GraphEdge& e) {
627 ///Commit the changes to the path.
629 if( !(front.empty() && back.empty()) ) {
631 tmp.reserve(front.size()+back.size()+P.length());
632 tmp.insert(tmp.end(), front.rbegin(), front.rend());
633 tmp.insert(tmp.end(), P.edges.begin(), P.edges.end());
634 tmp.insert(tmp.end(), back.begin(), back.end());
642 ///Reserve storage for the builder in advance.
644 ///If you know a reasonable upper bound of the number of the edges
645 ///to add to the front, using this function you can speed up the building.
647 void reserveFront(size_t r) {front.reserve(r);}
649 ///Reserve storage for the builder in advance.
651 ///If you know a reasonable upper bound of the number of the edges
652 ///to add to the back, using this function you can speed up the building.
654 void reserveBack(size_t r) {back.reserve(r);}
658 return front.empty() && back.empty() && P.empty();
661 GraphNode source() const {
662 if( ! front.empty() )
663 return P.gr->source(front[front.size()-1]);
664 else if( ! P.empty() )
665 return P.gr->source(P.edges[0]);
666 else if( ! back.empty() )
667 return P.gr->source(back[0]);
671 GraphNode target() const {
673 return P.gr->target(back[back.size()-1]);
674 else if( ! P.empty() )
675 return P.gr->target(P.edges[P.length()-1]);
676 else if( ! front.empty() )
677 return P.gr->target(front[0]);
691 #endif // LEMON_PATH_H