1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
3 * This file is a part of LEMON, a generic C++ optimization library.
5 * Copyright (C) 2003-2010
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/core.h>
32 #include <lemon/concepts/path.h>
40 /// \brief A structure for representing directed paths in a digraph.
42 /// A structure for representing directed path in a digraph.
43 /// \tparam GR The digraph type in which the path is.
45 /// In a sense, the path can be treated as a list of arcs. The
46 /// lemon path type stores just this list. As a consequence, it
47 /// cannot enumerate the nodes of the path and the source node of
48 /// a zero length path is undefined.
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 erase is done in O(1) (amortized) time. The
53 /// implementation uses two vectors for storing the front and back
55 template <typename GR>
60 typedef typename Digraph::Arc Arc;
62 /// \brief Default constructor
64 /// Default constructor
67 /// \brief Copy constructor
69 Path(const Path& cpath) {
70 pathCopy(cpath, *this);
73 /// \brief Template copy constructor
75 /// This constuctor initializes the path from any other path type.
76 /// It simply makes a copy of the given path.
77 template <typename CPath>
78 Path(const CPath& cpath) {
79 pathCopy(cpath, *this);
82 /// \brief Copy assignment
84 Path& operator=(const Path& cpath) {
85 pathCopy(cpath, *this);
89 /// \brief Template copy assignment
91 /// This operator makes a copy of a path of any other type.
92 template <typename CPath>
93 Path& operator=(const CPath& cpath) {
94 pathCopy(cpath, *this);
98 /// \brief LEMON style iterator for path arcs
100 /// This class is used to iterate on the arcs of the paths.
104 /// \brief Default constructor
106 /// \brief Invalid constructor
107 ArcIt(Invalid) : path(0), idx(-1) {}
108 /// \brief Initializate the iterator to the first arc of path
109 ArcIt(const Path &_path)
110 : path(&_path), idx(_path.empty() ? -1 : 0) {}
114 ArcIt(const Path &_path, int _idx)
115 : path(&_path), idx(_idx) {}
119 /// \brief Conversion to Arc
120 operator const Arc&() const {
121 return path->nth(idx);
125 ArcIt& operator++() {
127 if (idx >= path->length()) idx = -1;
131 /// \brief Comparison operator
132 bool operator==(const ArcIt& e) const { return idx==e.idx; }
133 /// \brief Comparison operator
134 bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
135 /// \brief Comparison operator
136 bool operator<(const ArcIt& e) const { return idx<e.idx; }
143 /// \brief Length of the path.
144 int length() const { return head.size() + tail.size(); }
145 /// \brief Return whether the path is empty.
146 bool empty() const { return head.empty() && tail.empty(); }
148 /// \brief Reset the path to an empty one.
149 void clear() { head.clear(); tail.clear(); }
151 /// \brief The nth arc.
153 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
154 const Arc& nth(int n) const {
155 return n < int(head.size()) ? *(head.rbegin() + n) :
156 *(tail.begin() + (n - head.size()));
159 /// \brief Initialize arc iterator to point to the nth arc
161 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
162 ArcIt nthIt(int n) const {
163 return ArcIt(*this, n);
166 /// \brief The first arc of the path
167 const Arc& front() const {
168 return head.empty() ? tail.front() : head.back();
171 /// \brief Add a new arc before the current path
172 void addFront(const Arc& arc) {
176 /// \brief Erase the first arc of the path
182 int halfsize = tail.size() / 2;
183 head.resize(halfsize);
184 std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
186 std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
187 tail.resize(tail.size() - halfsize - 1);
191 /// \brief The last arc of the path
192 const Arc& back() const {
193 return tail.empty() ? head.front() : tail.back();
196 /// \brief Add a new arc behind the current path
197 void addBack(const Arc& arc) {
201 /// \brief Erase the last arc of the path
206 int halfsize = head.size() / 2;
207 tail.resize(halfsize);
208 std::copy(head.begin() + 1, head.begin() + halfsize + 1,
210 std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
211 head.resize(head.size() - halfsize - 1);
215 typedef True BuildTag;
217 template <typename CPath>
218 void build(const CPath& path) {
219 int len = path.length();
221 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
226 template <typename CPath>
227 void buildRev(const CPath& path) {
228 int len = path.length();
230 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
236 typedef std::vector<Arc> Container;
237 Container head, tail;
241 /// \brief A structure for representing directed paths in a digraph.
243 /// A structure for representing directed path in a digraph.
244 /// \tparam GR The digraph type in which the path is.
246 /// In a sense, the path can be treated as a list of arcs. The
247 /// lemon path type stores just this list. As a consequence it
248 /// cannot enumerate the nodes in the path and the zero length paths
249 /// cannot store the source.
251 /// This implementation is a just back insertable and erasable path
252 /// type. It can be indexed in O(1) time. The back insertion and
253 /// erasure is amortized O(1) time. This implementation is faster
254 /// then the \c Path type because it use just one vector for the
256 template <typename GR>
261 typedef typename Digraph::Arc Arc;
263 /// \brief Default constructor
265 /// Default constructor
268 /// \brief Copy constructor
270 SimplePath(const SimplePath& cpath) {
271 pathCopy(cpath, *this);
274 /// \brief Template copy constructor
276 /// This path can be initialized with any other path type. It just
277 /// makes a copy of the given path.
278 template <typename CPath>
279 SimplePath(const CPath& cpath) {
280 pathCopy(cpath, *this);
283 /// \brief Copy assignment
285 SimplePath& operator=(const SimplePath& cpath) {
286 pathCopy(cpath, *this);
290 /// \brief Template copy assignment
292 /// This path can be initialized with any other path type. It just
293 /// makes a copy of the given path.
294 template <typename CPath>
295 SimplePath& operator=(const CPath& cpath) {
296 pathCopy(cpath, *this);
300 /// \brief Iterator class to iterate on the arcs of the paths
302 /// This class is used to iterate on the arcs of the paths
304 /// Of course it converts to Digraph::Arc
306 friend class SimplePath;
308 /// Default constructor
310 /// Invalid constructor
311 ArcIt(Invalid) : path(0), idx(-1) {}
312 /// \brief Initializate the constructor to the first arc of path
313 ArcIt(const SimplePath &_path)
314 : path(&_path), idx(_path.empty() ? -1 : 0) {}
318 /// Constructor with starting point
319 ArcIt(const SimplePath &_path, int _idx)
320 : idx(_idx), path(&_path) {}
324 ///Conversion to Digraph::Arc
325 operator const Arc&() const {
326 return path->nth(idx);
330 ArcIt& operator++() {
332 if (idx >= path->length()) idx = -1;
336 /// Comparison operator
337 bool operator==(const ArcIt& e) const { return idx==e.idx; }
338 /// Comparison operator
339 bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
340 /// Comparison operator
341 bool operator<(const ArcIt& e) const { return idx<e.idx; }
344 const SimplePath *path;
348 /// \brief Length of the path.
349 int length() const { return data.size(); }
350 /// \brief Return true if the path is empty.
351 bool empty() const { return data.empty(); }
353 /// \brief Reset the path to an empty one.
354 void clear() { data.clear(); }
356 /// \brief The nth arc.
358 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
359 const Arc& nth(int n) const {
363 /// \brief Initializes arc iterator to point to the nth arc.
364 ArcIt nthIt(int n) const {
365 return ArcIt(*this, n);
368 /// \brief The first arc of the path.
369 const Arc& front() const {
373 /// \brief The last arc of the path.
374 const Arc& back() const {
378 /// \brief Add a new arc behind the current path.
379 void addBack(const Arc& arc) {
383 /// \brief Erase the last arc of the path
388 typedef True BuildTag;
390 template <typename CPath>
391 void build(const CPath& path) {
392 int len = path.length();
395 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
401 template <typename CPath>
402 void buildRev(const CPath& path) {
403 int len = path.length();
406 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
413 typedef std::vector<Arc> Container;
418 /// \brief A structure for representing directed paths in a digraph.
420 /// A structure for representing directed path in a digraph.
421 /// \tparam GR The digraph type in which the path is.
423 /// In a sense, the path can be treated as a list of arcs. The
424 /// lemon path type stores just this list. As a consequence it
425 /// cannot enumerate the nodes in the path and the zero length paths
426 /// cannot store the source.
428 /// This implementation is a back and front insertable and erasable
429 /// path type. It can be indexed in O(k) time, where k is the rank
430 /// of the arc in the path. The length can be computed in O(n)
431 /// time. The front and back insertion and erasure is O(1) time
432 /// and it can be splited and spliced in O(1) time.
433 template <typename GR>
438 typedef typename Digraph::Arc Arc;
442 // the std::list<> is incompatible
443 // hard to create invalid iterator
451 std::allocator<Node> alloc;
455 /// \brief Default constructor
457 /// Default constructor
458 ListPath() : first(0), last(0) {}
460 /// \brief Copy constructor
462 ListPath(const ListPath& cpath) : first(0), last(0) {
463 pathCopy(cpath, *this);
466 /// \brief Template copy constructor
468 /// This path can be initialized with any other path type. It just
469 /// makes a copy of the given path.
470 template <typename CPath>
471 ListPath(const CPath& cpath) : first(0), last(0) {
472 pathCopy(cpath, *this);
475 /// \brief Destructor of the path
477 /// Destructor of the path
482 /// \brief Copy assignment
484 ListPath& operator=(const ListPath& cpath) {
485 pathCopy(cpath, *this);
489 /// \brief Template copy assignment
491 /// This path can be initialized with any other path type. It just
492 /// makes a copy of the given path.
493 template <typename CPath>
494 ListPath& operator=(const CPath& cpath) {
495 pathCopy(cpath, *this);
499 /// \brief Iterator class to iterate on the arcs of the paths
501 /// This class is used to iterate on the arcs of the paths
503 /// Of course it converts to Digraph::Arc
505 friend class ListPath;
507 /// Default constructor
509 /// Invalid constructor
510 ArcIt(Invalid) : path(0), node(0) {}
511 /// \brief Initializate the constructor to the first arc of path
512 ArcIt(const ListPath &_path)
513 : path(&_path), node(_path.first) {}
517 ArcIt(const ListPath &_path, Node *_node)
518 : path(&_path), node(_node) {}
523 ///Conversion to Digraph::Arc
524 operator const Arc&() const {
529 ArcIt& operator++() {
534 /// Comparison operator
535 bool operator==(const ArcIt& e) const { return node==e.node; }
536 /// Comparison operator
537 bool operator!=(const ArcIt& e) const { return node!=e.node; }
538 /// Comparison operator
539 bool operator<(const ArcIt& e) const { return node<e.node; }
542 const ListPath *path;
546 /// \brief The nth arc.
548 /// This function looks for the nth arc in O(n) time.
549 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
550 const Arc& nth(int n) const {
552 for (int i = 0; i < n; ++i) {
558 /// \brief Initializes arc iterator to point to the nth arc.
559 ArcIt nthIt(int n) const {
561 for (int i = 0; i < n; ++i) {
564 return ArcIt(*this, node);
567 /// \brief Length of the path.
578 /// \brief Return true if the path is empty.
579 bool empty() const { return first == 0; }
581 /// \brief Reset the path to an empty one.
585 alloc.destroy(first);
586 alloc.deallocate(first, 1);
591 /// \brief The first arc of the path
592 const Arc& front() const {
596 /// \brief Add a new arc before the current path
597 void addFront(const Arc& arc) {
598 Node *node = alloc.allocate(1);
599 alloc.construct(node, Node());
611 /// \brief Erase the first arc of the path
621 alloc.deallocate(node, 1);
624 /// \brief The last arc of the path.
625 const Arc& back() const {
629 /// \brief Add a new arc behind the current path.
630 void addBack(const Arc& arc) {
631 Node *node = alloc.allocate(1);
632 alloc.construct(node, Node());
644 /// \brief Erase the last arc of the path
654 alloc.deallocate(node, 1);
657 /// \brief Splice a path to the back of the current path.
659 /// It splices \c tpath to the back of the current path and \c
660 /// tpath becomes empty. The time complexity of this function is
662 void spliceBack(ListPath& tpath) {
665 last->next = tpath.first;
666 tpath.first->prev = last;
673 tpath.first = tpath.last = 0;
676 /// \brief Splice a path to the front of the current path.
678 /// It splices \c tpath before the current path and \c tpath
679 /// becomes empty. The time complexity of this function
681 void spliceFront(ListPath& tpath) {
684 first->prev = tpath.last;
685 tpath.last->next = first;
692 tpath.first = tpath.last = 0;
695 /// \brief Splice a path into the current path.
697 /// It splices the \c tpath into the current path before the
698 /// position of \c it iterator and \c tpath becomes empty. The
699 /// time complexity of this function is O(1). If the \c it is
700 /// \c INVALID then it will splice behind the current path.
701 void splice(ArcIt it, ListPath& tpath) {
704 tpath.first->prev = it.node->prev;
706 it.node->prev->next = tpath.first;
710 it.node->prev = tpath.last;
711 tpath.last->next = it.node;
716 last->next = tpath.first;
717 tpath.first->prev = last;
725 tpath.first = tpath.last = 0;
728 /// \brief Split the current path.
730 /// It splits the current path into two parts. The part before
731 /// the iterator \c it will remain in the current path and the part
733 /// \c it will put into \c tpath. If \c tpath have arcs
734 /// before the operation they are removed first. The time
735 /// complexity of this function is O(1) plus the the time of emtying
736 /// \c tpath. If \c it is \c INVALID then it just clears \c tpath
737 void split(ArcIt it, ListPath& tpath) {
740 tpath.first = it.node;
743 last = it.node->prev;
753 typedef True BuildTag;
755 template <typename CPath>
756 void build(const CPath& path) {
757 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
762 template <typename CPath>
763 void buildRev(const CPath& path) {
764 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
771 /// \brief A structure for representing directed paths in a digraph.
773 /// A structure for representing directed path in a digraph.
774 /// \tparam GR The digraph type in which the path is.
776 /// In a sense, the path can be treated as a list of arcs. The
777 /// lemon path type stores just this list. As a consequence it
778 /// cannot enumerate the nodes in the path and the source node of
779 /// a zero length path is undefined.
781 /// This implementation is completly static, i.e. it can be copy constucted
782 /// or copy assigned from another path, but otherwise it cannot be
785 /// Being the the most memory efficient path type in LEMON,
786 /// it is intented to be
787 /// used when you want to store a large number of paths.
788 template <typename GR>
793 typedef typename Digraph::Arc Arc;
795 /// \brief Default constructor
797 /// Default constructor
798 StaticPath() : len(0), arcs(0) {}
800 /// \brief Copy constructor
802 StaticPath(const StaticPath& cpath) : arcs(0) {
803 pathCopy(cpath, *this);
806 /// \brief Template copy constructor
808 /// This path can be initialized from any other path type.
809 template <typename CPath>
810 StaticPath(const CPath& cpath) : arcs(0) {
811 pathCopy(cpath, *this);
814 /// \brief Destructor of the path
816 /// Destructor of the path
818 if (arcs) delete[] arcs;
821 /// \brief Copy assignment
823 StaticPath& operator=(const StaticPath& cpath) {
824 pathCopy(cpath, *this);
828 /// \brief Template copy assignment
830 /// This path can be made equal to any other path type. It simply
831 /// makes a copy of the given path.
832 template <typename CPath>
833 StaticPath& operator=(const CPath& cpath) {
834 pathCopy(cpath, *this);
838 /// \brief Iterator class to iterate on the arcs of the paths
840 /// This class is used to iterate on the arcs of the paths
842 /// Of course it converts to Digraph::Arc
844 friend class StaticPath;
846 /// Default constructor
848 /// Invalid constructor
849 ArcIt(Invalid) : path(0), idx(-1) {}
850 /// Initializate the constructor to the first arc of path
851 ArcIt(const StaticPath &_path)
852 : path(&_path), idx(_path.empty() ? -1 : 0) {}
856 /// Constructor with starting point
857 ArcIt(const StaticPath &_path, int _idx)
858 : idx(_idx), path(&_path) {}
862 ///Conversion to Digraph::Arc
863 operator const Arc&() const {
864 return path->nth(idx);
868 ArcIt& operator++() {
870 if (idx >= path->length()) idx = -1;
874 /// Comparison operator
875 bool operator==(const ArcIt& e) const { return idx==e.idx; }
876 /// Comparison operator
877 bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
878 /// Comparison operator
879 bool operator<(const ArcIt& e) const { return idx<e.idx; }
882 const StaticPath *path;
886 /// \brief The nth arc.
888 /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
889 const Arc& nth(int n) const {
893 /// \brief The arc iterator pointing to the nth arc.
894 ArcIt nthIt(int n) const {
895 return ArcIt(*this, n);
898 /// \brief The length of the path.
899 int length() const { return len; }
901 /// \brief Return true when the path is empty.
902 int empty() const { return len == 0; }
904 /// \brief Erase all arcs in the digraph.
907 if (arcs) delete[] arcs;
911 /// \brief The first arc of the path.
912 const Arc& front() const {
916 /// \brief The last arc of the path.
917 const Arc& back() const {
918 return arcs[len - 1];
922 typedef True BuildTag;
924 template <typename CPath>
925 void build(const CPath& path) {
929 for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
935 template <typename CPath>
936 void buildRev(const CPath& path) {
940 for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
951 ///////////////////////////////////////////////////////////////////////
952 // Additional utilities
953 ///////////////////////////////////////////////////////////////////////
955 namespace _path_bits {
957 template <typename Path, typename Enable = void>
958 struct RevPathTagIndicator {
959 static const bool value = false;
962 template <typename Path>
963 struct RevPathTagIndicator<
965 typename enable_if<typename Path::RevPathTag, void>::type
967 static const bool value = true;
970 template <typename Path, typename Enable = void>
971 struct BuildTagIndicator {
972 static const bool value = false;
975 template <typename Path>
976 struct BuildTagIndicator<
978 typename enable_if<typename Path::BuildTag, void>::type
980 static const bool value = true;
983 template <typename From, typename To,
984 bool buildEnable = BuildTagIndicator<To>::value>
985 struct PathCopySelectorForward {
986 static void copy(const From& from, To& to) {
988 for (typename From::ArcIt it(from); it != INVALID; ++it) {
994 template <typename From, typename To>
995 struct PathCopySelectorForward<From, To, true> {
996 static void copy(const From& from, To& to) {
1002 template <typename From, typename To,
1003 bool buildEnable = BuildTagIndicator<To>::value>
1004 struct PathCopySelectorBackward {
1005 static void copy(const From& from, To& to) {
1007 for (typename From::RevArcIt it(from); it != INVALID; ++it) {
1013 template <typename From, typename To>
1014 struct PathCopySelectorBackward<From, To, true> {
1015 static void copy(const From& from, To& to) {
1022 template <typename From, typename To,
1023 bool revEnable = RevPathTagIndicator<From>::value>
1024 struct PathCopySelector {
1025 static void copy(const From& from, To& to) {
1026 PathCopySelectorForward<From, To>::copy(from, to);
1030 template <typename From, typename To>
1031 struct PathCopySelector<From, To, true> {
1032 static void copy(const From& from, To& to) {
1033 PathCopySelectorBackward<From, To>::copy(from, to);
1040 /// \brief Make a copy of a path.
1042 /// This function makes a copy of a path.
1043 template <typename From, typename To>
1044 void pathCopy(const From& from, To& to) {
1045 checkConcept<concepts::PathDumper<typename From::Digraph>, From>();
1046 _path_bits::PathCopySelector<From, To>::copy(from, to);
1049 /// \brief Deprecated version of \ref pathCopy().
1051 /// Deprecated version of \ref pathCopy() (only for reverse compatibility).
1052 template <typename To, typename From>
1053 void copyPath(To& to, const From& from) {
1057 /// \brief Check the consistency of a path.
1059 /// This function checks that the target of each arc is the same
1060 /// as the source of the next one.
1062 template <typename Digraph, typename Path>
1063 bool checkPath(const Digraph& digraph, const Path& path) {
1064 typename Path::ArcIt it(path);
1065 if (it == INVALID) return true;
1066 typename Digraph::Node node = digraph.target(it);
1068 while (it != INVALID) {
1069 if (digraph.source(it) != node) return false;
1070 node = digraph.target(it);
1076 /// \brief The source of a path
1078 /// This function returns the source node of the given path.
1079 /// If the path is empty, then it returns \c INVALID.
1080 template <typename Digraph, typename Path>
1081 typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
1082 return path.empty() ? INVALID : digraph.source(path.front());
1085 /// \brief The target of a path
1087 /// This function returns the target node of the given path.
1088 /// If the path is empty, then it returns \c INVALID.
1089 template <typename Digraph, typename Path>
1090 typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1091 return path.empty() ? INVALID : digraph.target(path.back());
1094 /// \brief Class which helps to iterate through the nodes of a path
1096 /// In a sense, the path can be treated as a list of arcs. The
1097 /// lemon path type stores only this list. As a consequence, it
1098 /// cannot enumerate the nodes in the path and the zero length paths
1099 /// cannot have a source node.
1101 /// This class implements the node iterator of a path structure. To
1102 /// provide this feature, the underlying digraph should be passed to
1103 /// the constructor of the iterator.
1104 template <typename Path>
1107 const typename Path::Digraph *_digraph;
1108 typename Path::ArcIt _it;
1109 typename Path::Digraph::Node _nd;
1113 typedef typename Path::Digraph Digraph;
1114 typedef typename Digraph::Node Node;
1116 /// Default constructor
1118 /// Invalid constructor
1120 : _digraph(0), _it(INVALID), _nd(INVALID) {}
1122 PathNodeIt(const Digraph& digraph, const Path& path)
1123 : _digraph(&digraph), _it(path) {
1124 _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1127 PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
1128 : _digraph(&digraph), _it(path), _nd(src) {}
1130 ///Conversion to Digraph::Node
1131 operator Node() const {
1136 PathNodeIt& operator++() {
1137 if (_it == INVALID) _nd = INVALID;
1139 _nd = _digraph->target(_it);
1145 /// Comparison operator
1146 bool operator==(const PathNodeIt& n) const {
1147 return _it == n._it && _nd == n._nd;
1149 /// Comparison operator
1150 bool operator!=(const PathNodeIt& n) const {
1151 return _it != n._it || _nd != n._nd;
1153 /// Comparison operator
1154 bool operator<(const PathNodeIt& n) const {
1155 return (_it < n._it && _nd != INVALID);
1162 } // namespace lemon
1164 #endif // LEMON_PATH_H