3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
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 digraphs.
30 #include <lemon/error.h>
31 #include <lemon/bits/invalid.h>
39 /// \brief A structure for representing directed paths in a digraph.
41 /// A structure for representing directed path in a digraph.
42 /// \param Digraph The digraph type in which the path is.
44 /// In a sense, the path can be treated as a list of arcs. The
45 /// lemon path type stores just this list. As a consequence, it
46 /// cannot enumerate the nodes of the path and the source node of
47 /// a zero length path is undefined.
49 /// This implementation is a back and front insertable and erasable
50 /// path type. It can be indexed in O(1) time. The front and back
51 /// insertion and erase is done in O(1) (amortized) time. The
52 /// implementation uses two vectors for storing the front and back
54 template <typename _Digraph>
58 typedef _Digraph Digraph;
59 typedef typename Digraph::Arc Arc;
61 /// \brief Default constructor
63 /// Default constructor
66 /// \brief Template copy constructor
68 /// This constuctor initializes the path from any other path type.
69 /// It simply 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 operator makes a copy of a path of any other type.
78 template <typename CPath>
79 Path& operator=(const CPath& cpath) {
80 copyPath(*this, cpath);
84 /// \brief Lemon style iterator for path arcs
86 /// This class is used to iterate on the arcs of the paths.
90 /// \brief Default constructor
92 /// \brief Invalid constructor
93 ArcIt(Invalid) : path(0), idx(-1) {}
94 /// \brief Initializate the iterator to the first arc of path
95 ArcIt(const Path &_path)
96 : path(&_path), idx(_path.empty() ? -1 : 0) {}
100 ArcIt(const Path &_path, int _idx)
101 : path(&_path), idx(_idx) {}
105 /// \brief Conversion to Arc
106 operator const Arc&() const {
107 return path->nth(idx);
111 ArcIt& operator++() {
113 if (idx >= path->length()) idx = -1;
117 /// \brief Comparison operator
118 bool operator==(const ArcIt& e) const { return idx==e.idx; }
119 /// \brief Comparison operator
120 bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
121 /// \brief Comparison operator
122 bool operator<(const ArcIt& e) const { return idx<e.idx; }
129 /// \brief Length of the path.
130 int length() const { return head.size() + tail.size(); }
131 /// \brief Return whether the path is empty.
132 bool empty() const { return head.empty() && tail.empty(); }
134 /// \brief Reset the path to an empty one.
135 void clear() { head.clear(); tail.clear(); }
137 /// \brief The nth arc.
139 /// \pre n is in the [0..length() - 1] range
140 const Arc& nth(int n) const {
141 return n < int(head.size()) ? *(head.rbegin() + n) :
142 *(tail.begin() + (n - head.size()));
145 /// \brief Initialize arc iterator to point to the nth arc
147 /// \pre n is in the [0..length() - 1] range
148 ArcIt nthIt(int n) const {
149 return ArcIt(*this, n);
152 /// \brief The first arc of the path
153 const Arc& front() const {
154 return head.empty() ? tail.front() : head.back();
157 /// \brief Add a new arc before the current path
158 void addFront(const Arc& arc) {
162 /// \brief Erase the first arc of the path
168 int halfsize = tail.size() / 2;
169 head.resize(halfsize);
170 std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
172 std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
173 tail.resize(tail.size() - halfsize - 1);
177 /// \brief The last arc of the path
178 const Arc& back() const {
179 return tail.empty() ? head.front() : tail.back();
182 /// \brief Add a new arc behind the current path
183 void addBack(const Arc& arc) {
187 /// \brief Erase the last arc of the path
192 int halfsize = head.size() / 2;
193 tail.resize(halfsize);
194 std::copy(head.begin() + 1, head.begin() + halfsize + 1,
196 std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
197 head.resize(head.size() - halfsize - 1);
201 typedef True BuildTag;
203 template <typename CPath>
204 void build(const CPath& path) {
205 int len = path.length();
207 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
212 template <typename CPath>
213 void buildRev(const CPath& path) {
214 int len = path.length();
216 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
222 typedef std::vector<Arc> Container;
223 Container head, tail;
227 /// \brief A structure for representing directed paths in a digraph.
229 /// A structure for representing directed path in a digraph.
230 /// \param Digraph The digraph type in which the path is.
232 /// In a sense, the path can be treated as a list of arcs. The
233 /// lemon path type stores just this list. As a consequence it
234 /// cannot enumerate the nodes in the path and the zero length paths
235 /// cannot store the source.
237 /// This implementation is a just back insertable and erasable path
238 /// type. It can be indexed in O(1) time. The back insertion and
239 /// erasure is amortized O(1) time. This implementation is faster
240 /// then the \c Path type because it use just one vector for the
242 template <typename _Digraph>
246 typedef _Digraph Digraph;
247 typedef typename Digraph::Arc Arc;
249 /// \brief Default constructor
251 /// Default constructor
254 /// \brief Template copy constructor
256 /// This path can be initialized with any other path type. It just
257 /// makes a copy of the given path.
258 template <typename CPath>
259 SimplePath(const CPath& cpath) {
260 copyPath(*this, cpath);
263 /// \brief Template copy assignment
265 /// This path can be initialized with any other path type. It just
266 /// makes a copy of the given path.
267 template <typename CPath>
268 SimplePath& operator=(const CPath& cpath) {
269 copyPath(*this, cpath);
273 /// \brief Iterator class to iterate on the arcs of the paths
275 /// This class is used to iterate on the arcs of the paths
277 /// Of course it converts to Digraph::Arc
279 friend class SimplePath;
281 /// Default constructor
283 /// Invalid constructor
284 ArcIt(Invalid) : path(0), idx(-1) {}
285 /// \brief Initializate the constructor to the first arc of path
286 ArcIt(const SimplePath &_path)
287 : path(&_path), idx(_path.empty() ? -1 : 0) {}
291 /// Constructor with starting point
292 ArcIt(const SimplePath &_path, int _idx)
293 : idx(_idx), path(&_path) {}
297 ///Conversion to Digraph::Arc
298 operator const Arc&() const {
299 return path->nth(idx);
303 ArcIt& operator++() {
305 if (idx >= path->length()) idx = -1;
309 /// Comparison operator
310 bool operator==(const ArcIt& e) const { return idx==e.idx; }
311 /// Comparison operator
312 bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
313 /// Comparison operator
314 bool operator<(const ArcIt& e) const { return idx<e.idx; }
317 const SimplePath *path;
321 /// \brief Length of the path.
322 int length() const { return data.size(); }
323 /// \brief Return true if the path is empty.
324 bool empty() const { return data.empty(); }
326 /// \brief Reset the path to an empty one.
327 void clear() { data.clear(); }
329 /// \brief The nth arc.
331 /// \pre n is in the [0..length() - 1] range
332 const Arc& nth(int n) const {
336 /// \brief Initializes arc iterator to point to the nth arc.
337 ArcIt nthIt(int n) const {
338 return ArcIt(*this, n);
341 /// \brief The first arc of the path.
342 const Arc& front() const {
346 /// \brief The last arc of the path.
347 const Arc& back() const {
351 /// \brief Add a new arc behind the current path.
352 void addBack(const Arc& arc) {
356 /// \brief Erase the last arc of the path
361 typedef True BuildTag;
363 template <typename CPath>
364 void build(const CPath& path) {
365 int len = path.length();
368 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
374 template <typename CPath>
375 void buildRev(const CPath& path) {
376 int len = path.length();
379 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
386 typedef std::vector<Arc> Container;
391 /// \brief A structure for representing directed paths in a digraph.
393 /// A structure for representing directed path in a digraph.
394 /// \param Digraph The digraph type in which the path is.
396 /// In a sense, the path can be treated as a list of arcs. The
397 /// lemon path type stores just this list. As a consequence it
398 /// cannot enumerate the nodes in the path and the zero length paths
399 /// cannot store the source.
401 /// This implementation is a back and front insertable and erasable
402 /// path type. It can be indexed in O(k) time, where k is the rank
403 /// of the arc in the path. The length can be computed in O(n)
404 /// time. The front and back insertion and erasure is O(1) time
405 /// and it can be splited and spliced in O(1) time.
406 template <typename _Digraph>
410 typedef _Digraph Digraph;
411 typedef typename Digraph::Arc Arc;
415 // the std::list<> is incompatible
416 // hard to create invalid iterator
424 std::allocator<Node> alloc;
428 /// \brief Default constructor
430 /// Default constructor
431 ListPath() : first(0), last(0) {}
433 /// \brief Template copy constructor
435 /// This path can be initialized with any other path type. It just
436 /// makes a copy of the given path.
437 template <typename CPath>
438 ListPath(const CPath& cpath) : first(0), last(0) {
439 copyPath(*this, cpath);
442 /// \brief Destructor of the path
444 /// Destructor of the path
449 /// \brief Template copy assignment
451 /// This path can be initialized with any other path type. It just
452 /// makes a copy of the given path.
453 template <typename CPath>
454 ListPath& operator=(const CPath& cpath) {
455 copyPath(*this, cpath);
459 /// \brief Iterator class to iterate on the arcs of the paths
461 /// This class is used to iterate on the arcs of the paths
463 /// Of course it converts to Digraph::Arc
465 friend class ListPath;
467 /// Default constructor
469 /// Invalid constructor
470 ArcIt(Invalid) : path(0), node(0) {}
471 /// \brief Initializate the constructor to the first arc of path
472 ArcIt(const ListPath &_path)
473 : path(&_path), node(_path.first) {}
477 ArcIt(const ListPath &_path, Node *_node)
478 : path(&_path), node(_node) {}
483 ///Conversion to Digraph::Arc
484 operator const Arc&() const {
489 ArcIt& operator++() {
494 /// Comparison operator
495 bool operator==(const ArcIt& e) const { return node==e.node; }
496 /// Comparison operator
497 bool operator!=(const ArcIt& e) const { return node!=e.node; }
498 /// Comparison operator
499 bool operator<(const ArcIt& e) const { return node<e.node; }
502 const ListPath *path;
506 /// \brief The nth arc.
508 /// This function looks for the nth arc in O(n) time.
509 /// \pre n is in the [0..length() - 1] range
510 const Arc& nth(int n) const {
512 for (int i = 0; i < n; ++i) {
518 /// \brief Initializes arc iterator to point to the nth arc.
519 ArcIt nthIt(int n) const {
521 for (int i = 0; i < n; ++i) {
524 return ArcIt(*this, node);
527 /// \brief Length of the path.
538 /// \brief Return true if the path is empty.
539 bool empty() const { return first == 0; }
541 /// \brief Reset the path to an empty one.
545 alloc.destroy(first);
546 alloc.deallocate(first, 1);
551 /// \brief The first arc of the path
552 const Arc& front() const {
556 /// \brief Add a new arc before the current path
557 void addFront(const Arc& arc) {
558 Node *node = alloc.allocate(1);
559 alloc.construct(node, Node());
571 /// \brief Erase the first arc of the path
581 alloc.deallocate(node, 1);
584 /// \brief The last arc of the path.
585 const Arc& back() const {
589 /// \brief Add a new arc behind the current path.
590 void addBack(const Arc& arc) {
591 Node *node = alloc.allocate(1);
592 alloc.construct(node, Node());
604 /// \brief Erase the last arc of the path
614 alloc.deallocate(node, 1);
617 /// \brief Splice a path to the back of the current path.
619 /// It splices \c tpath to the back of the current path and \c
620 /// tpath becomes empty. The time complexity of this function is
622 void spliceBack(ListPath& tpath) {
625 last->next = tpath.first;
626 tpath.first->prev = last;
633 tpath.first = tpath.last = 0;
636 /// \brief Splice a path to the front of the current path.
638 /// It splices \c tpath before the current path and \c tpath
639 /// becomes empty. The time complexity of this function
641 void spliceFront(ListPath& tpath) {
644 first->prev = tpath.last;
645 tpath.last->next = first;
652 tpath.first = tpath.last = 0;
655 /// \brief Splice a path into the current path.
657 /// It splices the \c tpath into the current path before the
658 /// position of \c it iterator and \c tpath becomes empty. The
659 /// time complexity of this function is O(1). If the \c it is
660 /// \c INVALID then it will splice behind the current path.
661 void splice(ArcIt it, ListPath& tpath) {
664 tpath.first->prev = it.node->prev;
666 it.node->prev->next = tpath.first;
670 it.node->prev = tpath.last;
671 tpath.last->next = it.node;
676 last->next = tpath.first;
677 tpath.first->prev = last;
685 tpath.first = tpath.last = 0;
688 /// \brief Split the current path.
690 /// It splits the current path into two parts. The part before
691 /// the iterator \c it will remain in the current path and the part
693 /// \c it will put into \c tpath. If \c tpath have arcs
694 /// before the operation they are removed first. The time
695 /// complexity of this function is O(1) plus the the time of emtying
696 /// \c tpath. If \c it is \c INVALID then it just clears \c tpath
697 void split(ArcIt it, ListPath& tpath) {
700 tpath.first = it.node;
703 last = it.node->prev;
713 typedef True BuildTag;
715 template <typename CPath>
716 void build(const CPath& path) {
717 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
722 template <typename CPath>
723 void buildRev(const CPath& path) {
724 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
731 /// \brief A structure for representing directed paths in a digraph.
733 /// A structure for representing directed path in a digraph.
734 /// \param Digraph The digraph type in which the path is.
736 /// In a sense, the path can be treated as a list of arcs. The
737 /// lemon path type stores just this list. As a consequence it
738 /// cannot enumerate the nodes in the path and the source node of
739 /// a zero length path is undefined.
741 /// This implementation is completly static, i.e. it can be copy constucted
742 /// or copy assigned from another path, but otherwise it cannot be
745 /// Being the the most memory efficient path type in LEMON,
746 /// it is intented to be
747 /// used when you want to store a large number of paths.
748 template <typename _Digraph>
752 typedef _Digraph Digraph;
753 typedef typename Digraph::Arc Arc;
755 /// \brief Default constructor
757 /// Default constructor
758 StaticPath() : len(0), arcs(0) {}
760 /// \brief Template copy constructor
762 /// This path can be initialized from any other path type.
763 template <typename CPath>
764 StaticPath(const CPath& cpath) : arcs(0) {
765 copyPath(*this, cpath);
768 /// \brief Destructor of the path
770 /// Destructor of the path
772 if (arcs) delete[] arcs;
775 /// \brief Template copy assignment
777 /// This path can be made equal to any other path type. It simply
778 /// makes a copy of the given path.
779 template <typename CPath>
780 StaticPath& operator=(const CPath& cpath) {
781 copyPath(*this, cpath);
785 /// \brief Iterator class to iterate on the arcs of the paths
787 /// This class is used to iterate on the arcs of the paths
789 /// Of course it converts to Digraph::Arc
791 friend class StaticPath;
793 /// Default constructor
795 /// Invalid constructor
796 ArcIt(Invalid) : path(0), idx(-1) {}
797 /// Initializate the constructor to the first arc of path
798 ArcIt(const StaticPath &_path)
799 : path(&_path), idx(_path.empty() ? -1 : 0) {}
803 /// Constructor with starting point
804 ArcIt(const StaticPath &_path, int _idx)
805 : idx(_idx), path(&_path) {}
809 ///Conversion to Digraph::Arc
810 operator const Arc&() const {
811 return path->nth(idx);
815 ArcIt& operator++() {
817 if (idx >= path->length()) idx = -1;
821 /// Comparison operator
822 bool operator==(const ArcIt& e) const { return idx==e.idx; }
823 /// Comparison operator
824 bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
825 /// Comparison operator
826 bool operator<(const ArcIt& e) const { return idx<e.idx; }
829 const StaticPath *path;
833 /// \brief The nth arc.
835 /// \pre n is in the [0..length() - 1] range
836 const Arc& nth(int n) const {
840 /// \brief The arc iterator pointing to the nth arc.
841 ArcIt nthIt(int n) const {
842 return ArcIt(*this, n);
845 /// \brief The length of the path.
846 int length() const { return len; }
848 /// \brief Return true when the path is empty.
849 int empty() const { return len == 0; }
851 /// \break Erase all arcs in the digraph.
854 if (arcs) delete[] arcs;
858 /// \brief The first arc of the path.
859 const Arc& front() const {
863 /// \brief The last arc of the path.
864 const Arc& back() const {
865 return arcs[len - 1];
869 typedef True BuildTag;
871 template <typename CPath>
872 void build(const CPath& path) {
876 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
882 template <typename CPath>
883 void buildRev(const CPath& path) {
887 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
898 ///////////////////////////////////////////////////////////////////////
899 // Additional utilities
900 ///////////////////////////////////////////////////////////////////////
902 namespace _path_bits {
904 template <typename Path, typename Enable = void>
905 struct RevTagIndicator {
906 static const bool value = false;
909 template <typename Digraph>
910 struct RevTagIndicator<
912 typename enable_if<typename Digraph::RevTag, void>::type
914 static const bool value = true;
917 template <typename Target, typename Source,
918 typename BuildEnable = void, typename RevEnable = void>
919 struct PathCopySelector {
920 static void copy(Target& target, const Source& source) {
922 for (typename Source::ArcIt it(source); it != INVALID; ++it) {
928 template <typename Target, typename Source, typename BuildEnable>
929 struct PathCopySelector<
930 Target, Source, BuildEnable,
931 typename enable_if<typename Source::RevPathTag, void>::type> {
932 static void copy(Target& target, const Source& source) {
934 for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
940 template <typename Target, typename Source, typename RevEnable>
941 struct PathCopySelector<
943 typename enable_if<typename Target::BuildTag, void>::type, RevEnable> {
944 static void copy(Target& target, const Source& source) {
946 target.build(source);
950 template <typename Target, typename Source>
951 struct PathCopySelector<
953 typename enable_if<typename Target::BuildTag, void>::type,
954 typename enable_if<typename Source::RevPathTag, void>::type> {
955 static void copy(Target& target, const Source& source) {
957 target.buildRev(source);
964 /// \brief Make a copy of a path.
966 /// This function makes a copy of a path.
967 template <typename Target, typename Source>
968 void copyPath(Target& target, const Source& source) {
969 checkConcept<concepts::PathDumper<typename Source::Digraph>, Source>();
970 _path_bits::PathCopySelector<Target, Source>::copy(target, source);
973 /// \brief Check the consistency of a path.
975 /// This function checks that the target of each arc is the same
976 /// as the source of the next one.
978 template <typename Digraph, typename Path>
979 bool checkPath(const Digraph& digraph, const Path& path) {
980 typename Path::ArcIt it(path);
981 if (it == INVALID) return true;
982 typename Digraph::Node node = digraph.target(it);
984 while (it != INVALID) {
985 if (digraph.source(it) != node) return false;
986 node = digraph.target(it);
992 /// \brief The source of a path
994 /// This function returns the source of the given path.
995 template <typename Digraph, typename Path>
996 typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
997 return digraph.source(path.front());
1000 /// \brief The target of a path
1002 /// This function returns the target of the given path.
1003 template <typename Digraph, typename Path>
1004 typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1005 return digraph.target(path.back());
1008 /// \brief Class which helps to iterate through the nodes of a path
1010 /// In a sense, the path can be treated as a list of arcs. The
1011 /// lemon path type stores only this list. As a consequence, it
1012 /// cannot enumerate the nodes in the path and the zero length paths
1013 /// cannot have a source node.
1015 /// This class implements the node iterator of a path structure. To
1016 /// provide this feature, the underlying digraph should be passed to
1017 /// the constructor of the iterator.
1018 template <typename Path>
1021 const typename Path::Digraph *_digraph;
1022 typename Path::ArcIt _it;
1023 typename Path::Digraph::Node _nd;
1027 typedef typename Path::Digraph Digraph;
1028 typedef typename Digraph::Node Node;
1030 /// Default constructor
1032 /// Invalid constructor
1034 : _digraph(0), _it(INVALID), _nd(INVALID) {}
1036 PathNodeIt(const Digraph& digraph, const Path& path)
1037 : _digraph(&digraph), _it(path) {
1038 _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1041 PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
1042 : _digraph(&digraph), _it(path), _nd(src) {}
1044 ///Conversion to Digraph::Node
1045 operator Node() const {
1050 PathNodeIt& operator++() {
1051 if (_it == INVALID) _nd = INVALID;
1053 _nd = _digraph->target(_it);
1059 /// Comparison operator
1060 bool operator==(const PathNodeIt& n) const {
1061 return _it == n._it && _nd == n._nd;
1063 /// Comparison operator
1064 bool operator!=(const PathNodeIt& n) const {
1065 return _it != n._it || _nd != n._nd;
1067 /// Comparison operator
1068 bool operator<(const PathNodeIt& n) const {
1069 return (_it < n._it && _nd != INVALID);
1076 } // namespace lemon
1078 #endif // LEMON_PATH_H