Append the svn revision number to the version string automatically.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2007
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
21 ///\brief Classes for representing paths in graphs.
30 #include <lemon/path_utils.h>
31 #include <lemon/error.h>
32 #include <lemon/bits/invalid.h>
40 /// \brief A structure for representing directed paths in a graph.
42 /// A structure for representing directed path in a graph.
43 /// \param Graph The graph type in which the path is.
45 /// In a sense, the path can be treated as a list of edges. The
46 /// lemon path type stores just this list. As a consequence it
47 /// cannot enumerate the nodes in the path and the zero length paths
48 /// cannot store the source.
50 /// This implementation is a back and front insertable and erasable
51 /// path type. It can be indexed in O(1) time. The front and back
52 /// insertion and erasure is amortized O(1) time. The
53 /// impelementation is based on two opposite organized vectors.
54 template <typename _Graph>
59 typedef typename Graph::Edge Edge;
61 /// \brief Default constructor
63 /// Default constructor
66 /// \brief Template copy constructor
68 /// This path can be initialized with any other path type. It just
69 /// makes a copy of the given path.
70 template <typename CPath>
71 Path(const CPath& cpath) {
72 copyPath(*this, cpath);
75 /// \brief Template copy assignment
77 /// This path can be initialized with any other path type. It just
78 /// makes a copy of the given path.
79 template <typename CPath>
80 Path& operator=(const CPath& cpath) {
81 copyPath(*this, cpath);
85 /// \brief Lemon style iterator for path edges
87 /// This class is used to iterate on the edges of the paths.
91 /// \brief Default constructor
93 /// \brief Invalid constructor
94 EdgeIt(Invalid) : path(0), idx(-1) {}
95 /// \brief Initializate the constructor to the first edge of path
96 EdgeIt(const Path &_path)
97 : path(&_path), idx(_path.empty() ? -1 : 0) {}
101 EdgeIt(const Path &_path, int _idx)
102 : idx(_idx), path(&_path) {}
106 /// \brief Conversion to Edge
107 operator const Edge&() const {
108 return path->nth(idx);
112 EdgeIt& operator++() {
114 if (idx >= path->length()) idx = -1;
118 /// \brief Comparison operator
119 bool operator==(const EdgeIt& e) const { return idx==e.idx; }
120 /// \brief Comparison operator
121 bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
122 /// \brief Comparison operator
123 bool operator<(const EdgeIt& e) const { return idx<e.idx; }
130 /// \brief Length of the path.
131 int length() const { return head.size() + tail.size(); }
132 /// \brief Returns whether the path is empty.
133 bool empty() const { return head.empty() && tail.empty(); }
135 /// \brief Resets the path to an empty path.
136 void clear() { head.clear(); tail.clear(); }
138 /// \brief Gives back the nth edge.
140 /// \pre n is in the [0..length() - 1] range
141 const Edge& nth(int n) const {
142 return n < int(head.size()) ? *(head.rbegin() + n) :
143 *(tail.begin() + (n - head.size()));
146 /// \brief Initializes edge iterator to point to the nth edge
148 /// \pre n is in the [0..length() - 1] range
149 EdgeIt nthIt(int n) const {
150 return EdgeIt(*this, n);
153 /// \brief Gives back the first edge of the path
154 const Edge& front() const {
155 return head.empty() ? tail.front() : head.back();
158 /// \brief Add a new edge before the current path
159 void addFront(const Edge& edge) {
160 head.push_back(edge);
163 /// \brief Erase the first edge of the path
169 int halfsize = tail.size() / 2;
170 head.resize(halfsize);
171 std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
173 std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
174 tail.resize(tail.size() - halfsize - 1);
178 /// \brief Gives back the last edge of the path
179 const Edge& back() const {
180 return tail.empty() ? head.front() : tail.back();
183 /// \brief Add a new edge behind the current path
184 void addBack(const Edge& edge) {
185 tail.push_back(edge);
188 /// \brief Erase the last edge of the path
193 int halfsize = head.size() / 2;
194 tail.resize(halfsize);
195 std::copy(head.begin() + 1, head.begin() + halfsize + 1,
197 std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
198 head.resize(head.size() - halfsize - 1);
204 typedef True BuildTag;
206 template <typename CPath>
207 void build(const CPath& path) {
208 int len = path.length();
210 for (typename CPath::EdgeIt it(path); it != INVALID; ++it) {
215 template <typename CPath>
216 void buildRev(const CPath& path) {
217 int len = path.length();
219 for (typename CPath::RevEdgeIt it(path); it != INVALID; ++it) {
225 typedef std::vector<Edge> Container;
226 Container head, tail;
230 /// \brief A structure for representing directed paths in a graph.
232 /// A structure for representing directed path in a graph.
233 /// \param Graph The graph type in which the path is.
235 /// In a sense, the path can be treated as a list of edges. The
236 /// lemon path type stores just this list. As a consequence it
237 /// cannot enumerate the nodes in the path and the zero length paths
238 /// cannot store the source.
240 /// This implementation is a just back insertable and erasable path
241 /// type. It can be indexed in O(1) time. The back insertion and
242 /// erasure is amortized O(1) time. This implementation is faster
243 /// then the \c Path type because it use just one vector for the
245 template <typename _Graph>
249 typedef _Graph Graph;
250 typedef typename Graph::Edge Edge;
252 /// \brief Default constructor
254 /// Default constructor
257 /// \brief Template copy constructor
259 /// This path can be initialized with any other path type. It just
260 /// makes a copy of the given path.
261 template <typename CPath>
262 SimplePath(const CPath& cpath) {
263 copyPath(*this, cpath);
266 /// \brief Template copy assignment
268 /// This path can be initialized with any other path type. It just
269 /// makes a copy of the given path.
270 template <typename CPath>
271 SimplePath& operator=(const CPath& cpath) {
272 copyPath(*this, cpath);
276 /// \brief Iterator class to iterate on the edges of the paths
278 /// This class is used to iterate on the edges of the paths
280 /// Of course it converts to Graph::Edge
282 friend class SimplePath;
284 /// Default constructor
286 /// Invalid constructor
287 EdgeIt(Invalid) : path(0), idx(-1) {}
288 /// \brief Initializate the constructor to the first edge of path
289 EdgeIt(const SimplePath &_path)
290 : path(&_path), idx(_path.empty() ? -1 : 0) {}
294 /// Constructor with starting point
295 EdgeIt(const SimplePath &_path, int _idx)
296 : idx(_idx), path(&_path) {}
300 ///Conversion to Graph::Edge
301 operator const Edge&() const {
302 return path->nth(idx);
306 EdgeIt& operator++() {
308 if (idx >= path->length()) idx = -1;
312 /// Comparison operator
313 bool operator==(const EdgeIt& e) const { return idx==e.idx; }
314 /// Comparison operator
315 bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
316 /// Comparison operator
317 bool operator<(const EdgeIt& e) const { return idx<e.idx; }
320 const SimplePath *path;
324 /// \brief Length of the path.
325 int length() const { return data.size(); }
326 /// \brief Returns whether the path is empty.
327 bool empty() const { return data.empty(); }
329 /// \brief Resets the path to an empty path.
330 void clear() { data.clear(); }
332 /// \brief Gives back the nth edge.
334 /// \pre n is in the [0..length() - 1] range
335 const Edge& nth(int n) const {
339 /// \brief Initializes edge iterator to point to the nth edge.
340 EdgeIt nthIt(int n) const {
341 return EdgeIt(*this, n);
344 /// \brief Gives back the last edge of the path.
345 const Edge& back() const {
349 /// \brief Add a new edge behind the current path.
350 void addBack(const Edge& edge) {
351 data.push_back(edge);
354 /// \brief Erase the last edge of the path
359 typedef True BuildTag;
361 template <typename CPath>
362 void build(const CPath& path) {
363 int len = path.length();
366 for (typename CPath::EdgeIt it(path); it != INVALID; ++it) {
372 template <typename CPath>
373 void buildRev(const CPath& path) {
374 int len = path.length();
377 for (typename CPath::RevEdgeIt it(path); it != INVALID; ++it) {
384 typedef std::vector<Edge> Container;
389 /// \brief A structure for representing directed paths in a graph.
391 /// A structure for representing directed path in a graph.
392 /// \param Graph The graph type in which the path is.
394 /// In a sense, the path can be treated as a list of edges. The
395 /// lemon path type stores just this list. As a consequence it
396 /// cannot enumerate the nodes in the path and the zero length paths
397 /// cannot store the source.
399 /// This implementation is a back and front insertable and erasable
400 /// path type. It can be indexed in O(k) time, where k is the rank
401 /// of the edge in the path. The length can be computed in O(n)
402 /// time. The front and back insertion and erasure is O(1) time
403 /// and it can be splited and spliced in O(1) time.
404 template <typename _Graph>
408 typedef _Graph Graph;
409 typedef typename Graph::Edge Edge;
413 // the std::list<> is incompatible
414 // hard to create invalid iterator
422 std::allocator<Node> alloc;
426 /// \brief Default constructor
428 /// Default constructor
429 ListPath() : first(0), last(0) {}
431 /// \brief Template copy constructor
433 /// This path can be initialized with any other path type. It just
434 /// makes a copy of the given path.
435 template <typename CPath>
436 ListPath(const CPath& cpath) : first(0), last(0) {
437 copyPath(*this, cpath);
440 /// \brief Destructor of the path
442 /// Destructor of the path
447 /// \brief Template copy assignment
449 /// This path can be initialized with any other path type. It just
450 /// makes a copy of the given path.
451 template <typename CPath>
452 ListPath& operator=(const CPath& cpath) {
453 copyPath(*this, cpath);
457 /// \brief Iterator class to iterate on the edges of the paths
459 /// This class is used to iterate on the edges of the paths
461 /// Of course it converts to Graph::Edge
463 friend class ListPath;
465 /// Default constructor
467 /// Invalid constructor
468 EdgeIt(Invalid) : path(0), node(0) {}
469 /// \brief Initializate the constructor to the first edge of path
470 EdgeIt(const ListPath &_path)
471 : path(&_path), node(_path.first) {}
475 EdgeIt(const ListPath &_path, Node *_node)
476 : path(&_path), node(_node) {}
481 ///Conversion to Graph::Edge
482 operator const Edge&() const {
487 EdgeIt& operator++() {
492 /// Comparison operator
493 bool operator==(const EdgeIt& e) const { return node==e.node; }
494 /// Comparison operator
495 bool operator!=(const EdgeIt& e) const { return node!=e.node; }
496 /// Comparison operator
497 bool operator<(const EdgeIt& e) const { return node<e.node; }
500 const ListPath *path;
504 /// \brief Gives back the nth edge.
506 /// Gives back the nth edge in O(n) time.
507 /// \pre n is in the [0..length() - 1] range
508 const Edge& nth(int n) const {
510 for (int i = 0; i < n; ++i) {
516 /// \brief Initializes edge iterator to point to the nth edge.
517 EdgeIt nthIt(int n) const {
519 for (int i = 0; i < n; ++i) {
522 return EdgeIt(*this, node);
525 /// \brief Length of the path.
536 /// \brief Returns whether the path is empty.
537 bool empty() const { return first == 0; }
539 /// \brief Resets the path to an empty path.
543 alloc.destroy(first);
544 alloc.deallocate(first, 1);
549 /// \brief Gives back the first edge of the path
550 const Edge& front() const {
554 /// \brief Add a new edge before the current path
555 void addFront(const Edge& edge) {
556 Node *node = alloc.allocate(1);
557 alloc.construct(node, Node());
569 /// \brief Erase the first edge of the path
579 alloc.deallocate(node, 1);
582 /// \brief Gives back the last edge of the path.
583 const Edge& back() const {
587 /// \brief Add a new edge behind the current path.
588 void addBack(const Edge& edge) {
589 Node *node = alloc.allocate(1);
590 alloc.construct(node, Node());
602 /// \brief Erase the last edge of the path
612 alloc.deallocate(node, 1);
615 /// \brief Splicing the given path to the current path.
617 /// It splices the \c tpath to the back of the current path and \c
618 /// tpath becomes empty. The time complexity of this function is
620 void spliceBack(ListPath& tpath) {
623 last->next = tpath.first;
624 tpath.first->prev = last;
631 tpath.first = tpath.last = 0;
634 /// \brief Splicing the given path to the current path.
636 /// It splices the \c tpath before the current path and \c tpath
637 /// becomes empty. The time complexity of this function
639 void spliceFront(ListPath& tpath) {
642 first->prev = tpath.last;
643 tpath.last->next = first;
650 tpath.first = tpath.last = 0;
653 /// \brief Splicing the given path into the current path.
655 /// It splices the \c tpath into the current path before the
656 /// position of \c it iterator and \c tpath becomes empty. The
657 /// time complexity of this function is O(1). If the \c it is \c
658 /// INVALID then it will splice behind the current path.
659 void splice(EdgeIt it, ListPath& tpath) {
662 tpath.first->prev = it.node->prev;
664 it.node->prev->next = tpath.first;
668 it.node->prev = tpath.last;
669 tpath.last->next = it.node;
674 last->next = tpath.first;
675 tpath.first->prev = last;
683 tpath.first = tpath.last = 0;
686 /// \brief Spliting the current path.
688 /// It splits the current path into two parts. The part before \c
689 /// it iterator will remain in the current path and the part from
690 /// the it will put into the \c tpath. If the \c tpath had edges
691 /// before the operation they will be removed first. The time
692 /// complexity of this function is O(1) plus the clearing of \c
693 /// tpath. If the \c it is \c INVALID then it just clears \c
695 void split(EdgeIt it, ListPath& tpath) {
698 tpath.first = it.node;
701 last = it.node->prev;
711 typedef True BuildTag;
713 template <typename CPath>
714 void build(const CPath& path) {
715 for (typename CPath::EdgeIt it(path); it != INVALID; ++it) {
720 template <typename CPath>
721 void buildRev(const CPath& path) {
722 for (typename CPath::RevEdgeIt it(path); it != INVALID; ++it) {
729 /// \brief A structure for representing directed paths in a graph.
731 /// A structure for representing directed path in a graph.
732 /// \param Graph The graph type in which the path is.
734 /// In a sense, the path can be treated as a list of edges. The
735 /// lemon path type stores just this list. As a consequence it
736 /// cannot enumerate the nodes in the path and the zero length paths
737 /// cannot store the source.
739 /// This implementation is completly static, so it cannot be
740 /// modified exclude the assign an other path. It is intented to be
741 /// used when you want to store a large number of paths because it is
742 /// the most memory efficient path type in the lemon.
743 template <typename _Graph>
747 typedef _Graph Graph;
748 typedef typename Graph::Edge Edge;
750 /// \brief Default constructor
752 /// Default constructor
753 StaticPath() : len(0), edges(0) {}
755 /// \brief Template copy constructor
757 /// This path can be initialized with any other path type. It just
758 /// makes a copy of the given path.
759 template <typename CPath>
760 StaticPath(const CPath& cpath) : edges(0) {
761 copyPath(*this, cpath);
764 /// \brief Destructor of the path
766 /// Destructor of the path
768 if (edges) delete[] edges;
771 /// \brief Template copy assignment
773 /// This path can be initialized with any other path type. It just
774 /// makes a copy of the given path.
775 template <typename CPath>
776 StaticPath& operator=(const CPath& cpath) {
777 copyPath(*this, cpath);
781 /// \brief Iterator class to iterate on the edges of the paths
783 /// This class is used to iterate on the edges of the paths
785 /// Of course it converts to Graph::Edge
787 friend class StaticPath;
789 /// Default constructor
791 /// Invalid constructor
792 EdgeIt(Invalid) : path(0), idx(-1) {}
793 /// Initializate the constructor to the first edge of path
794 EdgeIt(const StaticPath &_path)
795 : path(&_path), idx(_path.empty() ? -1 : 0) {}
799 /// Constructor with starting point
800 EdgeIt(const StaticPath &_path, int _idx)
801 : idx(_idx), path(&_path) {}
805 ///Conversion to Graph::Edge
806 operator const Edge&() const {
807 return path->nth(idx);
811 EdgeIt& operator++() {
813 if (idx >= path->length()) idx = -1;
817 /// Comparison operator
818 bool operator==(const EdgeIt& e) const { return idx==e.idx; }
819 /// Comparison operator
820 bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
821 /// Comparison operator
822 bool operator<(const EdgeIt& e) const { return idx<e.idx; }
825 const StaticPath *path;
829 /// \brief Gives back the nth edge.
831 /// \pre n is in the [0..length() - 1] range
832 const Edge& nth(int n) const {
836 /// \brief Initializes edge iterator to point to the nth edge.
837 EdgeIt nthIt(int n) const {
838 return EdgeIt(*this, n);
841 /// \brief Gives back the length of the path.
842 int length() const { return len; }
844 /// \brief Returns true when the path is empty.
845 int empty() const { return len == 0; }
847 /// \break Erase all edge in the graph.
850 if (edges) delete[] edges;
854 /// \brief Gives back the first edge of the path.
855 const Edge& front() const {
859 /// \brief Gives back the last edge of the path.
860 const Edge& back() const {
861 return edges[len - 1];
865 typedef True BuildTag;
867 template <typename CPath>
868 void build(const CPath& path) {
870 edges = new Edge[len];
872 for (typename CPath::EdgeIt it(path); it != INVALID; ++it) {
878 template <typename CPath>
879 void buildRev(const CPath& path) {
881 edges = new Edge[len];
883 for (typename CPath::RevEdgeIt it(path); it != INVALID; ++it) {
898 #endif // LEMON_PATH_H