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.
31 #include <lemon/path_utils.h>
32 #include <lemon/error.h>
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.
46 /// In a sense, the path can be treated as a list of edges. The
47 /// lemon path type stores just this list. As a consequence it
48 /// cannot enumerate the nodes in the path and the zero length paths
49 /// cannot store the source.
51 /// This implementation is a back and front insertable and erasable
52 /// path type. It can be indexed in O(1) time. The front and back
53 /// insertion and erasure is amortized O(1) time. The
54 /// impelementation is based on two opposite organized vectors.
55 template <typename _Graph>
60 typedef typename Graph::Edge Edge;
62 /// \brief Default constructor
64 /// Default constructor
67 /// \brief Template copy constructor
69 /// This path can be initialized with any other path type. It just
70 /// makes a copy of the given path.
71 template <typename CPath>
72 Path(const CPath& cpath) {
73 copyPath(*this, cpath);
76 /// \brief Template copy assignment
78 /// This path can be initialized with any other path type. It just
79 /// makes a copy of the given path.
80 template <typename CPath>
81 Path& operator=(const CPath& cpath) {
82 copyPath(*this, cpath);
86 /// \brief Lemon style iterator for path edges
88 /// This class is used to iterate on the edges of the paths.
92 /// \brief Default constructor
94 /// \brief Invalid constructor
95 EdgeIt(Invalid) : path(0), idx(-1) {}
96 /// \brief Initializate the constructor to the first edge of path
97 EdgeIt(const Path &_path)
98 : path(&_path), idx(_path.empty() ? -1 : 0) {}
102 EdgeIt(const Path &_path, int _idx)
103 : idx(_idx), path(&_path) {}
107 /// \brief Conversion to Edge
108 operator const Edge&() const {
109 return path->nth(idx);
113 EdgeIt& operator++() {
115 if (idx >= path->length()) idx = -1;
119 /// \brief Comparison operator
120 bool operator==(const EdgeIt& e) const { return idx==e.idx; }
121 /// \brief Comparison operator
122 bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
123 /// \brief Comparison operator
124 bool operator<(const EdgeIt& e) const { return idx<e.idx; }
131 /// \brief Length of the path.
132 int length() const { return head.size() + tail.size(); }
133 /// \brief Returns whether the path is empty.
134 bool empty() const { return head.empty() && tail.empty(); }
136 /// \brief Resets the path to an empty path.
137 void clear() { head.clear(); tail.clear(); }
139 /// \brief Gives back the nth edge.
141 /// \pre n is in the [0..length() - 1] range
142 const Edge& nth(int n) const {
143 return n < (int)head.size() ? *(head.rbegin() + n) :
144 *(tail.begin() + (n - head.size()));
147 /// \brief Initializes edge iterator to point to the nth edge
149 /// \pre n is in the [0..length() - 1] range
150 EdgeIt nthIt(int n) const {
151 return EdgeIt(*this, n);
154 /// \brief Gives back the first edge of the path
155 const Edge& front() const {
156 return head.empty() ? tail.front() : head.back();
159 /// \brief Add a new edge before the current path
160 void addFront(const Edge& edge) {
161 head.push_back(edge);
164 /// \brief Erase the first edge of the path
170 int halfsize = tail.size() / 2;
171 head.resize(halfsize);
172 std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
174 std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
175 tail.resize(tail.size() - halfsize - 1);
179 /// \brief Gives back the last edge of the path
180 const Edge& back() const {
181 return tail.empty() ? head.front() : tail.back();
184 /// \brief Add a new edge behind the current path
185 void addBack(const Edge& edge) {
186 tail.push_back(edge);
189 /// \brief Erase the last edge of the path
194 int halfsize = head.size() / 2;
195 tail.resize(halfsize);
196 std::copy(head.begin() + 1, head.begin() + halfsize + 1,
198 std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
199 head.resize(head.size() - halfsize - 1);
205 typedef True BuildTag;
207 template <typename CPath>
208 void build(const CPath& path) {
209 int len = path.length();
211 for (typename CPath::EdgeIt it(path); it != INVALID; ++it) {
216 template <typename CPath>
217 void buildRev(const CPath& path) {
218 int len = path.length();
220 for (typename CPath::RevEdgeIt it(path); it != INVALID; ++it) {
226 typedef std::vector<Edge> Container;
227 Container head, tail;
231 /// \brief A structure for representing directed paths in a graph.
233 /// A structure for representing directed path in a graph.
234 /// \param Graph The graph type in which the path is.
236 /// In a sense, the path can be treated as a list of edges. The
237 /// lemon path type stores just this list. As a consequence it
238 /// cannot enumerate the nodes in the path and the zero length paths
239 /// cannot store the source.
241 /// This implementation is a just back insertable and erasable path
242 /// type. It can be indexed in O(1) time. The back insertion and
243 /// erasure is amortized O(1) time. This implementation is faster
244 /// then the \c Path type because it use just one vector for the
246 template <typename _Graph>
250 typedef _Graph Graph;
251 typedef typename Graph::Edge Edge;
253 /// \brief Default constructor
255 /// Default constructor
258 /// \brief Template copy constructor
260 /// This path can be initialized with any other path type. It just
261 /// makes a copy of the given path.
262 template <typename CPath>
263 SimplePath(const CPath& cpath) {
264 copyPath(*this, cpath);
267 /// \brief Template copy assignment
269 /// This path can be initialized with any other path type. It just
270 /// makes a copy of the given path.
271 template <typename CPath>
272 SimplePath& operator=(const CPath& cpath) {
273 copyPath(*this, cpath);
277 /// \brief Iterator class to iterate on the edges of the paths
279 /// This class is used to iterate on the edges of the paths
281 /// Of course it converts to Graph::Edge
283 friend class SimplePath;
285 /// Default constructor
287 /// Invalid constructor
288 EdgeIt(Invalid) : path(0), idx(-1) {}
289 /// \brief Initializate the constructor to the first edge of path
290 EdgeIt(const SimplePath &_path)
291 : path(&_path), idx(_path.empty() ? -1 : 0) {}
295 /// Constructor with starting point
296 EdgeIt(const SimplePath &_path, int _idx)
297 : idx(_idx), path(&_path) {}
301 ///Conversion to Graph::Edge
302 operator const Edge&() const {
303 return path->nth(idx);
307 EdgeIt& operator++() {
309 if (idx >= path->length()) idx = -1;
313 /// Comparison operator
314 bool operator==(const EdgeIt& e) const { return idx==e.idx; }
315 /// Comparison operator
316 bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
317 /// Comparison operator
318 bool operator<(const EdgeIt& e) const { return idx<e.idx; }
321 const SimplePath *path;
325 /// \brief Length of the path.
326 int length() const { return data.size(); }
327 /// \brief Returns whether the path is empty.
328 bool empty() const { return data.empty(); }
330 /// \brief Resets the path to an empty path.
331 void clear() { data.clear(); }
333 /// \brief Gives back the nth edge.
335 /// \pre n is in the [0..length() - 1] range
336 const Edge& nth(int n) const {
340 /// \brief Initializes edge iterator to point to the nth edge.
341 EdgeIt nthIt(int n) const {
342 return EdgeIt(*this, n);
345 /// \brief Gives back the last edge of the path.
346 const Edge& back() const {
350 /// \brief Add a new edge behind the current path.
351 void addBack(const Edge& edge) {
352 data.push_back(edge);
355 /// \brief Erase the last edge of the path
360 typedef True BuildTag;
362 template <typename CPath>
363 void build(const CPath& path) {
364 int len = path.length();
367 for (typename CPath::EdgeIt it(path); it != INVALID; ++it) {
373 template <typename CPath>
374 void buildRev(const CPath& path) {
375 int len = path.length();
378 for (typename CPath::RevEdgeIt it(path); it != INVALID; ++it) {
385 typedef std::vector<Edge> Container;
390 /// \brief A structure for representing directed paths in a graph.
392 /// A structure for representing directed path in a graph.
393 /// \param Graph The graph type in which the path is.
395 /// In a sense, the path can be treated as a list of edges. The
396 /// lemon path type stores just this list. As a consequence it
397 /// cannot enumerate the nodes in the path and the zero length paths
398 /// cannot store the source.
400 /// This implementation is a back and front insertable and erasable
401 /// path type. It can be indexed in O(k) time, where k is the rank
402 /// of the edge in the path. The length can be computed in O(n)
403 /// time. The front and back insertion and erasure is O(1) time
404 /// and it can be splited and spliced in O(1) time.
405 template <typename _Graph>
409 typedef _Graph Graph;
410 typedef typename Graph::Edge Edge;
414 // the std::list<> is incompatible
415 // hard to create invalid iterator
423 std::allocator<Node> alloc;
427 /// \brief Default constructor
429 /// Default constructor
430 ListPath() : first(0), last(0) {}
432 /// \brief Template copy constructor
434 /// This path can be initialized with any other path type. It just
435 /// makes a copy of the given path.
436 template <typename CPath>
437 ListPath(const CPath& cpath) : first(0), last(0) {
438 copyPath(*this, cpath);
441 /// \brief Destructor of the path
443 /// Destructor of the path
448 /// \brief Template copy assignment
450 /// This path can be initialized with any other path type. It just
451 /// makes a copy of the given path.
452 template <typename CPath>
453 ListPath& operator=(const CPath& cpath) {
454 copyPath(*this, cpath);
458 /// \brief Iterator class to iterate on the edges of the paths
460 /// This class is used to iterate on the edges of the paths
462 /// Of course it converts to Graph::Edge
464 friend class ListPath;
466 /// Default constructor
468 /// Invalid constructor
469 EdgeIt(Invalid) : path(0), node(0) {}
470 /// \brief Initializate the constructor to the first edge of path
471 EdgeIt(const ListPath &_path)
472 : path(&_path), node(_path.first) {}
476 EdgeIt(const ListPath &_path, Node *_node)
477 : path(&_path), node(_node) {}
482 ///Conversion to Graph::Edge
483 operator const Edge&() const {
488 EdgeIt& operator++() {
493 /// Comparison operator
494 bool operator==(const EdgeIt& e) const { return node==e.node; }
495 /// Comparison operator
496 bool operator!=(const EdgeIt& e) const { return node!=e.node; }
497 /// Comparison operator
498 bool operator<(const EdgeIt& e) const { return node<e.node; }
501 const ListPath *path;
505 /// \brief Gives back the nth edge.
507 /// Gives back the nth edge in O(n) time.
508 /// \pre n is in the [0..length() - 1] range
509 const Edge& nth(int n) const {
511 for (int i = 0; i < n; ++i) {
517 /// \brief Initializes edge iterator to point to the nth edge.
518 EdgeIt nthIt(int n) const {
520 for (int i = 0; i < n; ++i) {
523 return EdgeIt(*this, node);
526 /// \brief Length of the path.
537 /// \brief Returns whether the path is empty.
538 bool empty() const { return first == 0; }
540 /// \brief Resets the path to an empty path.
544 alloc.destroy(first);
545 alloc.deallocate(first, 1);
550 /// \brief Gives back the first edge of the path
551 const Edge& front() const {
555 /// \brief Add a new edge before the current path
556 void addFront(const Edge& edge) {
557 Node *node = alloc.allocate(1);
558 alloc.construct(node, Node());
570 /// \brief Erase the first edge of the path
580 alloc.deallocate(node, 1);
583 /// \brief Gives back the last edge of the path.
584 const Edge& back() const {
588 /// \brief Add a new edge behind the current path.
589 void addBack(const Edge& edge) {
590 Node *node = alloc.allocate(1);
591 alloc.construct(node, Node());
603 /// \brief Erase the last edge of the path
613 alloc.deallocate(node, 1);
616 /// \brief Splicing the given path to the current path.
618 /// It splices the \c tpath to the back of the current path and \c
619 /// tpath becomes empty. The time complexity of this function is
621 void spliceBack(ListPath& tpath) {
624 last->next = tpath.first;
625 tpath.first->prev = last;
632 tpath.first = tpath.last = 0;
635 /// \brief Splicing the given path to the current path.
637 /// It splices the \c tpath before the current path and \c tpath
638 /// becomes empty. The time complexity of this function
640 void spliceFront(ListPath& tpath) {
643 first->prev = tpath.last;
644 tpath.last->next = first;
651 tpath.first = tpath.last = 0;
654 /// \brief Splicing the given path into the current path.
656 /// It splices the \c tpath into the current path before the
657 /// position of \c it iterator and \c tpath becomes empty. The
658 /// time complexity of this function is O(1). If the \c it is \c
659 /// INVALID then it will splice behind the current path.
660 void splice(EdgeIt it, ListPath& tpath) {
663 tpath.first->prev = it.node->prev;
665 it.node->prev->next = tpath.first;
669 it.node->prev = tpath.last;
670 tpath.last->next = it.node;
675 last->next = tpath.first;
676 tpath.first->prev = last;
684 tpath.first = tpath.last = 0;
687 /// \brief Spliting the current path.
689 /// It splits the current path into two parts. The part before \c
690 /// it iterator will remain in the current path and the part from
691 /// the it will put into the \c tpath. If the \c tpath had edges
692 /// before the operation they will be removed first. The time
693 /// complexity of this function is O(1) plus the clearing of \c
694 /// tpath. If the \c it is \c INVALID then it just clears \c
696 void split(EdgeIt it, ListPath& tpath) {
699 tpath.first = it.node;
702 last = it.node->prev;
712 typedef True BuildTag;
714 template <typename CPath>
715 void build(const CPath& path) {
716 for (typename CPath::EdgeIt it(path); it != INVALID; ++it) {
721 template <typename CPath>
722 void buildRev(const CPath& path) {
723 for (typename CPath::RevEdgeIt it(path); it != INVALID; ++it) {
730 /// \brief A structure for representing directed paths in a graph.
732 /// A structure for representing directed path in a graph.
733 /// \param Graph The graph type in which the path is.
735 /// In a sense, the path can be treated as a list of edges. The
736 /// lemon path type stores just this list. As a consequence it
737 /// cannot enumerate the nodes in the path and the zero length paths
738 /// cannot store the source.
740 /// This implementation is completly static, so it cannot be
741 /// modified exclude the assign an other path. It is intented to be
742 /// used when you want to store a large number of paths because it is
743 /// the most memory efficient path type in the lemon.
744 template <typename _Graph>
748 typedef _Graph Graph;
749 typedef typename Graph::Edge Edge;
751 /// \brief Default constructor
753 /// Default constructor
754 StaticPath() : len(0), edges(0) {}
756 /// \brief Template copy constructor
758 /// This path can be initialized with any other path type. It just
759 /// makes a copy of the given path.
760 template <typename CPath>
761 StaticPath(const CPath& cpath) : edges(0) {
762 copyPath(*this, cpath);
765 /// \brief Destructor of the path
767 /// Destructor of the path
769 if (edges) delete[] edges;
772 /// \brief Template copy assignment
774 /// This path can be initialized with any other path type. It just
775 /// makes a copy of the given path.
776 template <typename CPath>
777 StaticPath& operator=(const CPath& cpath) {
778 copyPath(*this, cpath);
782 /// \brief Iterator class to iterate on the edges of the paths
784 /// This class is used to iterate on the edges of the paths
786 /// Of course it converts to Graph::Edge
788 friend class StaticPath;
790 /// Default constructor
792 /// Invalid constructor
793 EdgeIt(Invalid) : path(0), idx(-1) {}
794 /// Initializate the constructor to the first edge of path
795 EdgeIt(const StaticPath &_path)
796 : path(&_path), idx(_path.empty() ? -1 : 0) {}
800 /// Constructor with starting point
801 EdgeIt(const StaticPath &_path, int _idx)
802 : idx(_idx), path(&_path) {}
806 ///Conversion to Graph::Edge
807 operator const Edge&() const {
808 return path->nth(idx);
812 EdgeIt& operator++() {
814 if (idx >= path->length()) idx = -1;
818 /// Comparison operator
819 bool operator==(const EdgeIt& e) const { return idx==e.idx; }
820 /// Comparison operator
821 bool operator!=(const EdgeIt& e) const { return idx!=e.idx; }
822 /// Comparison operator
823 bool operator<(const EdgeIt& e) const { return idx<e.idx; }
826 const StaticPath *path;
830 /// \brief Gives back the nth edge.
832 /// \pre n is in the [0..length() - 1] range
833 const Edge& nth(int n) const {
837 /// \brief Initializes edge iterator to point to the nth edge.
838 EdgeIt nthIt(int n) const {
839 return EdgeIt(*this, n);
842 /// \brief Gives back the length of the path.
843 int length() const { return len; }
845 /// \brief Returns true when the path is empty.
846 int empty() const { return len == 0; }
848 /// \break Erase all edge in the graph.
851 if (edges) delete[] edges;
855 /// \brief Gives back the first edge of the path.
856 const Edge& front() const {
860 /// \brief Gives back the last edge of the path.
861 const Edge& back() const {
862 return edges[len - 1];
866 typedef True BuildTag;
868 template <typename CPath>
869 void build(const CPath& path) {
871 edges = new Edge[len];
873 for (typename CPath::EdgeIt it(path); it != INVALID; ++it) {
879 template <typename CPath>
880 void buildRev(const CPath& path) {
882 edges = new Edge[len];
884 for (typename CPath::RevEdgeIt it(path); it != INVALID; ++it) {
899 #endif // LEMON_PATH_H