lemongraph 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +8 -0
  3. data/LICENSE +674 -0
  4. data/README.md +6 -0
  5. data/ext/lemon-1.3.1/AUTHORS +26 -0
  6. data/ext/lemon-1.3.1/CMakeLists.txt +371 -0
  7. data/ext/lemon-1.3.1/INSTALL +167 -0
  8. data/ext/lemon-1.3.1/LICENSE +32 -0
  9. data/ext/lemon-1.3.1/NEWS +337 -0
  10. data/ext/lemon-1.3.1/README +50 -0
  11. data/ext/lemon-1.3.1/cmake/FindCOIN.cmake +110 -0
  12. data/ext/lemon-1.3.1/cmake/FindGLPK.cmake +55 -0
  13. data/ext/lemon-1.3.1/cmake/FindGhostscript.cmake +10 -0
  14. data/ext/lemon-1.3.1/cmake/FindILOG.cmake +102 -0
  15. data/ext/lemon-1.3.1/cmake/FindSOPLEX.cmake +23 -0
  16. data/ext/lemon-1.3.1/cmake/LEMONConfig.cmake.in +13 -0
  17. data/ext/lemon-1.3.1/cmake/nsis/lemon.ico +0 -0
  18. data/ext/lemon-1.3.1/cmake/nsis/uninstall.ico +0 -0
  19. data/ext/lemon-1.3.1/cmake/version.cmake +1 -0
  20. data/ext/lemon-1.3.1/cmake/version.cmake.in +1 -0
  21. data/ext/lemon-1.3.1/contrib/CMakeLists.txt +19 -0
  22. data/ext/lemon-1.3.1/lemon/CMakeLists.txt +91 -0
  23. data/ext/lemon-1.3.1/lemon/adaptors.h +3638 -0
  24. data/ext/lemon-1.3.1/lemon/arg_parser.cc +474 -0
  25. data/ext/lemon-1.3.1/lemon/arg_parser.h +440 -0
  26. data/ext/lemon-1.3.1/lemon/assert.h +214 -0
  27. data/ext/lemon-1.3.1/lemon/base.cc +37 -0
  28. data/ext/lemon-1.3.1/lemon/bellman_ford.h +1116 -0
  29. data/ext/lemon-1.3.1/lemon/bfs.h +1754 -0
  30. data/ext/lemon-1.3.1/lemon/bin_heap.h +347 -0
  31. data/ext/lemon-1.3.1/lemon/binomial_heap.h +445 -0
  32. data/ext/lemon-1.3.1/lemon/bits/alteration_notifier.h +472 -0
  33. data/ext/lemon-1.3.1/lemon/bits/array_map.h +351 -0
  34. data/ext/lemon-1.3.1/lemon/bits/bezier.h +174 -0
  35. data/ext/lemon-1.3.1/lemon/bits/default_map.h +182 -0
  36. data/ext/lemon-1.3.1/lemon/bits/edge_set_extender.h +627 -0
  37. data/ext/lemon-1.3.1/lemon/bits/enable_if.h +131 -0
  38. data/ext/lemon-1.3.1/lemon/bits/graph_adaptor_extender.h +401 -0
  39. data/ext/lemon-1.3.1/lemon/bits/graph_extender.h +1332 -0
  40. data/ext/lemon-1.3.1/lemon/bits/lock.h +65 -0
  41. data/ext/lemon-1.3.1/lemon/bits/map_extender.h +332 -0
  42. data/ext/lemon-1.3.1/lemon/bits/path_dump.h +177 -0
  43. data/ext/lemon-1.3.1/lemon/bits/solver_bits.h +194 -0
  44. data/ext/lemon-1.3.1/lemon/bits/traits.h +388 -0
  45. data/ext/lemon-1.3.1/lemon/bits/variant.h +494 -0
  46. data/ext/lemon-1.3.1/lemon/bits/vector_map.h +244 -0
  47. data/ext/lemon-1.3.1/lemon/bits/windows.cc +166 -0
  48. data/ext/lemon-1.3.1/lemon/bits/windows.h +44 -0
  49. data/ext/lemon-1.3.1/lemon/bucket_heap.h +594 -0
  50. data/ext/lemon-1.3.1/lemon/capacity_scaling.h +1014 -0
  51. data/ext/lemon-1.3.1/lemon/cbc.cc +460 -0
  52. data/ext/lemon-1.3.1/lemon/cbc.h +129 -0
  53. data/ext/lemon-1.3.1/lemon/christofides_tsp.h +254 -0
  54. data/ext/lemon-1.3.1/lemon/circulation.h +807 -0
  55. data/ext/lemon-1.3.1/lemon/clp.cc +464 -0
  56. data/ext/lemon-1.3.1/lemon/clp.h +164 -0
  57. data/ext/lemon-1.3.1/lemon/color.cc +44 -0
  58. data/ext/lemon-1.3.1/lemon/color.h +204 -0
  59. data/ext/lemon-1.3.1/lemon/concept_check.h +77 -0
  60. data/ext/lemon-1.3.1/lemon/concepts/bpgraph.h +1029 -0
  61. data/ext/lemon-1.3.1/lemon/concepts/digraph.h +491 -0
  62. data/ext/lemon-1.3.1/lemon/concepts/graph.h +788 -0
  63. data/ext/lemon-1.3.1/lemon/concepts/graph_components.h +2134 -0
  64. data/ext/lemon-1.3.1/lemon/concepts/heap.h +324 -0
  65. data/ext/lemon-1.3.1/lemon/concepts/maps.h +223 -0
  66. data/ext/lemon-1.3.1/lemon/concepts/path.h +312 -0
  67. data/ext/lemon-1.3.1/lemon/config.h.in +22 -0
  68. data/ext/lemon-1.3.1/lemon/connectivity.h +1688 -0
  69. data/ext/lemon-1.3.1/lemon/core.h +2506 -0
  70. data/ext/lemon-1.3.1/lemon/cost_scaling.h +1607 -0
  71. data/ext/lemon-1.3.1/lemon/counter.h +249 -0
  72. data/ext/lemon-1.3.1/lemon/cplex.cc +994 -0
  73. data/ext/lemon-1.3.1/lemon/cplex.h +292 -0
  74. data/ext/lemon-1.3.1/lemon/cycle_canceling.h +1230 -0
  75. data/ext/lemon-1.3.1/lemon/dfs.h +1637 -0
  76. data/ext/lemon-1.3.1/lemon/dheap.h +352 -0
  77. data/ext/lemon-1.3.1/lemon/dijkstra.h +1303 -0
  78. data/ext/lemon-1.3.1/lemon/dim2.h +726 -0
  79. data/ext/lemon-1.3.1/lemon/dimacs.h +448 -0
  80. data/ext/lemon-1.3.1/lemon/edge_set.h +1420 -0
  81. data/ext/lemon-1.3.1/lemon/edmonds_karp.h +556 -0
  82. data/ext/lemon-1.3.1/lemon/elevator.h +982 -0
  83. data/ext/lemon-1.3.1/lemon/error.h +276 -0
  84. data/ext/lemon-1.3.1/lemon/euler.h +287 -0
  85. data/ext/lemon-1.3.1/lemon/fib_heap.h +475 -0
  86. data/ext/lemon-1.3.1/lemon/fractional_matching.h +2139 -0
  87. data/ext/lemon-1.3.1/lemon/full_graph.h +1082 -0
  88. data/ext/lemon-1.3.1/lemon/glpk.cc +1012 -0
  89. data/ext/lemon-1.3.1/lemon/glpk.h +263 -0
  90. data/ext/lemon-1.3.1/lemon/gomory_hu.h +568 -0
  91. data/ext/lemon-1.3.1/lemon/graph_to_eps.h +1186 -0
  92. data/ext/lemon-1.3.1/lemon/greedy_tsp.h +251 -0
  93. data/ext/lemon-1.3.1/lemon/grid_graph.h +699 -0
  94. data/ext/lemon-1.3.1/lemon/grosso_locatelli_pullan_mc.h +840 -0
  95. data/ext/lemon-1.3.1/lemon/hao_orlin.h +1015 -0
  96. data/ext/lemon-1.3.1/lemon/hartmann_orlin_mmc.h +654 -0
  97. data/ext/lemon-1.3.1/lemon/howard_mmc.h +651 -0
  98. data/ext/lemon-1.3.1/lemon/hypercube_graph.h +459 -0
  99. data/ext/lemon-1.3.1/lemon/insertion_tsp.h +533 -0
  100. data/ext/lemon-1.3.1/lemon/karp_mmc.h +590 -0
  101. data/ext/lemon-1.3.1/lemon/kruskal.h +324 -0
  102. data/ext/lemon-1.3.1/lemon/lemon.pc.in +10 -0
  103. data/ext/lemon-1.3.1/lemon/lgf_reader.h +3854 -0
  104. data/ext/lemon-1.3.1/lemon/lgf_writer.h +2687 -0
  105. data/ext/lemon-1.3.1/lemon/list_graph.h +2510 -0
  106. data/ext/lemon-1.3.1/lemon/lp.h +95 -0
  107. data/ext/lemon-1.3.1/lemon/lp_base.cc +30 -0
  108. data/ext/lemon-1.3.1/lemon/lp_base.h +2147 -0
  109. data/ext/lemon-1.3.1/lemon/lp_skeleton.cc +143 -0
  110. data/ext/lemon-1.3.1/lemon/lp_skeleton.h +234 -0
  111. data/ext/lemon-1.3.1/lemon/maps.h +4057 -0
  112. data/ext/lemon-1.3.1/lemon/matching.h +3505 -0
  113. data/ext/lemon-1.3.1/lemon/math.h +77 -0
  114. data/ext/lemon-1.3.1/lemon/max_cardinality_search.h +794 -0
  115. data/ext/lemon-1.3.1/lemon/min_cost_arborescence.h +808 -0
  116. data/ext/lemon-1.3.1/lemon/nagamochi_ibaraki.h +702 -0
  117. data/ext/lemon-1.3.1/lemon/nauty_reader.h +113 -0
  118. data/ext/lemon-1.3.1/lemon/nearest_neighbor_tsp.h +238 -0
  119. data/ext/lemon-1.3.1/lemon/network_simplex.h +1659 -0
  120. data/ext/lemon-1.3.1/lemon/opt2_tsp.h +367 -0
  121. data/ext/lemon-1.3.1/lemon/pairing_heap.h +474 -0
  122. data/ext/lemon-1.3.1/lemon/path.h +1164 -0
  123. data/ext/lemon-1.3.1/lemon/planarity.h +2754 -0
  124. data/ext/lemon-1.3.1/lemon/preflow.h +985 -0
  125. data/ext/lemon-1.3.1/lemon/quad_heap.h +343 -0
  126. data/ext/lemon-1.3.1/lemon/radix_heap.h +438 -0
  127. data/ext/lemon-1.3.1/lemon/radix_sort.h +487 -0
  128. data/ext/lemon-1.3.1/lemon/random.cc +29 -0
  129. data/ext/lemon-1.3.1/lemon/random.h +1005 -0
  130. data/ext/lemon-1.3.1/lemon/smart_graph.h +1344 -0
  131. data/ext/lemon-1.3.1/lemon/soplex.cc +465 -0
  132. data/ext/lemon-1.3.1/lemon/soplex.h +158 -0
  133. data/ext/lemon-1.3.1/lemon/static_graph.h +476 -0
  134. data/ext/lemon-1.3.1/lemon/suurballe.h +776 -0
  135. data/ext/lemon-1.3.1/lemon/time_measure.h +610 -0
  136. data/ext/lemon-1.3.1/lemon/tolerance.h +242 -0
  137. data/ext/lemon-1.3.1/lemon/unionfind.h +1824 -0
  138. data/ext/lemon-1.3.1/scripts/unify-sources.sh +390 -0
  139. data/ext/lemon-1.3.1/scripts/valgrind-wrapper.sh +22 -0
  140. data/ext/lemongraph/arc_map.cc +1007 -0
  141. data/ext/lemongraph/digraph.cc +282 -0
  142. data/ext/lemongraph/digraph_arc.cc +153 -0
  143. data/ext/lemongraph/digraph_node.cc +277 -0
  144. data/ext/lemongraph/edge_map.cc +770 -0
  145. data/ext/lemongraph/extconf.rb +53 -0
  146. data/ext/lemongraph/graph.cc +351 -0
  147. data/ext/lemongraph/graph_arc.cc +95 -0
  148. data/ext/lemongraph/graph_edge.cc +153 -0
  149. data/ext/lemongraph/graph_item.cc +76 -0
  150. data/ext/lemongraph/graph_node.cc +321 -0
  151. data/ext/lemongraph/lemongraph.cc +260 -0
  152. data/ext/lemongraph/lemongraph.hh +295 -0
  153. data/ext/lemongraph/lemongraph.map +6 -0
  154. data/ext/lemongraph/lemongraph_export.hh +31 -0
  155. data/ext/lemongraph/node_map.cc +1011 -0
  156. data/lemongraph.gemspec +176 -0
  157. data/lib/lemongraph/graphviz.rb +240 -0
  158. data/lib/lemongraph/version.rb +4 -0
  159. data/lib/lemongraph.rb +21 -0
  160. data/samples/lemondeps.rb +38 -0
  161. metadata +202 -0
@@ -0,0 +1,1164 @@
1
+ /* -*- mode: C++; indent-tabs-mode: nil; -*-
2
+ *
3
+ * This file is a part of LEMON, a generic C++ optimization library.
4
+ *
5
+ * Copyright (C) 2003-2013
6
+ * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7
+ * (Egervary Research Group on Combinatorial Optimization, EGRES).
8
+ *
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.
12
+ *
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
15
+ * purpose.
16
+ *
17
+ */
18
+
19
+ ///\ingroup paths
20
+ ///\file
21
+ ///\brief Classes for representing paths in digraphs.
22
+ ///
23
+
24
+ #ifndef LEMON_PATH_H
25
+ #define LEMON_PATH_H
26
+
27
+ #include <vector>
28
+ #include <algorithm>
29
+
30
+ #include <lemon/error.h>
31
+ #include <lemon/core.h>
32
+ #include <lemon/concepts/path.h>
33
+
34
+ namespace lemon {
35
+
36
+ /// \addtogroup paths
37
+ /// @{
38
+
39
+
40
+ /// \brief A structure for representing directed paths in a digraph.
41
+ ///
42
+ /// A structure for representing directed path in a digraph.
43
+ /// \tparam GR The digraph type in which the path is.
44
+ ///
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.
49
+ ///
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
54
+ /// insertions.
55
+ template <typename GR>
56
+ class Path {
57
+ public:
58
+
59
+ typedef GR Digraph;
60
+ typedef typename Digraph::Arc Arc;
61
+
62
+ /// \brief Default constructor
63
+ ///
64
+ /// Default constructor
65
+ Path() {}
66
+
67
+ /// \brief Copy constructor
68
+ ///
69
+ Path(const Path& cpath) {
70
+ pathCopy(cpath, *this);
71
+ }
72
+
73
+ /// \brief Template copy constructor
74
+ ///
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);
80
+ }
81
+
82
+ /// \brief Copy assignment
83
+ ///
84
+ Path& operator=(const Path& cpath) {
85
+ pathCopy(cpath, *this);
86
+ return *this;
87
+ }
88
+
89
+ /// \brief Template copy assignment
90
+ ///
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);
95
+ return *this;
96
+ }
97
+
98
+ /// \brief LEMON style iterator for path arcs
99
+ ///
100
+ /// This class is used to iterate on the arcs of the paths.
101
+ class ArcIt {
102
+ friend class Path;
103
+ public:
104
+ /// \brief Default constructor
105
+ ArcIt() {}
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) {}
111
+
112
+ private:
113
+
114
+ ArcIt(const Path &_path, int _idx)
115
+ : path(&_path), idx(_idx) {}
116
+
117
+ public:
118
+
119
+ /// \brief Conversion to Arc
120
+ operator const Arc&() const {
121
+ return path->nth(idx);
122
+ }
123
+
124
+ /// \brief Next arc
125
+ ArcIt& operator++() {
126
+ ++idx;
127
+ if (idx >= path->length()) idx = -1;
128
+ return *this;
129
+ }
130
+
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; }
137
+
138
+ private:
139
+ const Path *path;
140
+ int idx;
141
+ };
142
+
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(); }
147
+
148
+ /// \brief Reset the path to an empty one.
149
+ void clear() { head.clear(); tail.clear(); }
150
+
151
+ /// \brief The n-th arc.
152
+ ///
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()));
157
+ }
158
+
159
+ /// \brief Initialize arc iterator to point to the n-th arc
160
+ ///
161
+ /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
162
+ ArcIt nthIt(int n) const {
163
+ return ArcIt(*this, n);
164
+ }
165
+
166
+ /// \brief The first arc of the path
167
+ const Arc& front() const {
168
+ return head.empty() ? tail.front() : head.back();
169
+ }
170
+
171
+ /// \brief Add a new arc before the current path
172
+ void addFront(const Arc& arc) {
173
+ head.push_back(arc);
174
+ }
175
+
176
+ /// \brief Erase the first arc of the path
177
+ void eraseFront() {
178
+ if (!head.empty()) {
179
+ head.pop_back();
180
+ } else {
181
+ head.clear();
182
+ int halfsize = tail.size() / 2;
183
+ head.resize(halfsize);
184
+ std::copy(tail.begin() + 1, tail.begin() + halfsize + 1,
185
+ head.rbegin());
186
+ std::copy(tail.begin() + halfsize + 1, tail.end(), tail.begin());
187
+ tail.resize(tail.size() - halfsize - 1);
188
+ }
189
+ }
190
+
191
+ /// \brief The last arc of the path
192
+ const Arc& back() const {
193
+ return tail.empty() ? head.front() : tail.back();
194
+ }
195
+
196
+ /// \brief Add a new arc behind the current path
197
+ void addBack(const Arc& arc) {
198
+ tail.push_back(arc);
199
+ }
200
+
201
+ /// \brief Erase the last arc of the path
202
+ void eraseBack() {
203
+ if (!tail.empty()) {
204
+ tail.pop_back();
205
+ } else {
206
+ int halfsize = head.size() / 2;
207
+ tail.resize(halfsize);
208
+ std::copy(head.begin() + 1, head.begin() + halfsize + 1,
209
+ tail.rbegin());
210
+ std::copy(head.begin() + halfsize + 1, head.end(), head.begin());
211
+ head.resize(head.size() - halfsize - 1);
212
+ }
213
+ }
214
+
215
+ typedef True BuildTag;
216
+
217
+ template <typename CPath>
218
+ void build(const CPath& path) {
219
+ int len = path.length();
220
+ tail.reserve(len);
221
+ for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
222
+ tail.push_back(it);
223
+ }
224
+ }
225
+
226
+ template <typename CPath>
227
+ void buildRev(const CPath& path) {
228
+ int len = path.length();
229
+ head.reserve(len);
230
+ for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
231
+ head.push_back(it);
232
+ }
233
+ }
234
+
235
+ protected:
236
+ typedef std::vector<Arc> Container;
237
+ Container head, tail;
238
+
239
+ };
240
+
241
+ /// \brief A structure for representing directed paths in a digraph.
242
+ ///
243
+ /// A structure for representing directed path in a digraph.
244
+ /// \tparam GR The digraph type in which the path is.
245
+ ///
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.
250
+ ///
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
255
+ /// arcs.
256
+ template <typename GR>
257
+ class SimplePath {
258
+ public:
259
+
260
+ typedef GR Digraph;
261
+ typedef typename Digraph::Arc Arc;
262
+
263
+ /// \brief Default constructor
264
+ ///
265
+ /// Default constructor
266
+ SimplePath() {}
267
+
268
+ /// \brief Copy constructor
269
+ ///
270
+ SimplePath(const SimplePath& cpath) {
271
+ pathCopy(cpath, *this);
272
+ }
273
+
274
+ /// \brief Template copy constructor
275
+ ///
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);
281
+ }
282
+
283
+ /// \brief Copy assignment
284
+ ///
285
+ SimplePath& operator=(const SimplePath& cpath) {
286
+ pathCopy(cpath, *this);
287
+ return *this;
288
+ }
289
+
290
+ /// \brief Template copy assignment
291
+ ///
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);
297
+ return *this;
298
+ }
299
+
300
+ /// \brief Iterator class to iterate on the arcs of the paths
301
+ ///
302
+ /// This class is used to iterate on the arcs of the paths
303
+ ///
304
+ /// Of course it converts to Digraph::Arc
305
+ class ArcIt {
306
+ friend class SimplePath;
307
+ public:
308
+ /// Default constructor
309
+ ArcIt() {}
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) {}
315
+
316
+ private:
317
+
318
+ /// Constructor with starting point
319
+ ArcIt(const SimplePath &_path, int _idx)
320
+ : path(&_path), idx(_idx) {}
321
+
322
+ public:
323
+
324
+ ///Conversion to Digraph::Arc
325
+ operator const Arc&() const {
326
+ return path->nth(idx);
327
+ }
328
+
329
+ /// Next arc
330
+ ArcIt& operator++() {
331
+ ++idx;
332
+ if (idx >= path->length()) idx = -1;
333
+ return *this;
334
+ }
335
+
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; }
342
+
343
+ private:
344
+ const SimplePath *path;
345
+ int idx;
346
+ };
347
+
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(); }
352
+
353
+ /// \brief Reset the path to an empty one.
354
+ void clear() { data.clear(); }
355
+
356
+ /// \brief The n-th arc.
357
+ ///
358
+ /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
359
+ const Arc& nth(int n) const {
360
+ return data[n];
361
+ }
362
+
363
+ /// \brief Initializes arc iterator to point to the n-th arc.
364
+ ArcIt nthIt(int n) const {
365
+ return ArcIt(*this, n);
366
+ }
367
+
368
+ /// \brief The first arc of the path.
369
+ const Arc& front() const {
370
+ return data.front();
371
+ }
372
+
373
+ /// \brief The last arc of the path.
374
+ const Arc& back() const {
375
+ return data.back();
376
+ }
377
+
378
+ /// \brief Add a new arc behind the current path.
379
+ void addBack(const Arc& arc) {
380
+ data.push_back(arc);
381
+ }
382
+
383
+ /// \brief Erase the last arc of the path
384
+ void eraseBack() {
385
+ data.pop_back();
386
+ }
387
+
388
+ typedef True BuildTag;
389
+
390
+ template <typename CPath>
391
+ void build(const CPath& path) {
392
+ int len = path.length();
393
+ data.resize(len);
394
+ int index = 0;
395
+ for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
396
+ data[index] = it;;
397
+ ++index;
398
+ }
399
+ }
400
+
401
+ template <typename CPath>
402
+ void buildRev(const CPath& path) {
403
+ int len = path.length();
404
+ data.resize(len);
405
+ int index = len;
406
+ for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
407
+ --index;
408
+ data[index] = it;;
409
+ }
410
+ }
411
+
412
+ protected:
413
+ typedef std::vector<Arc> Container;
414
+ Container data;
415
+
416
+ };
417
+
418
+ /// \brief A structure for representing directed paths in a digraph.
419
+ ///
420
+ /// A structure for representing directed path in a digraph.
421
+ /// \tparam GR The digraph type in which the path is.
422
+ ///
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.
427
+ ///
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>
434
+ class ListPath {
435
+ public:
436
+
437
+ typedef GR Digraph;
438
+ typedef typename Digraph::Arc Arc;
439
+
440
+ protected:
441
+
442
+ // the std::list<> is incompatible
443
+ // hard to create invalid iterator
444
+ struct Node {
445
+ Arc arc;
446
+ Node *next, *prev;
447
+ };
448
+
449
+ Node *first, *last;
450
+
451
+ std::allocator<Node> alloc;
452
+
453
+ public:
454
+
455
+ /// \brief Default constructor
456
+ ///
457
+ /// Default constructor
458
+ ListPath() : first(0), last(0) {}
459
+
460
+ /// \brief Copy constructor
461
+ ///
462
+ ListPath(const ListPath& cpath) : first(0), last(0) {
463
+ pathCopy(cpath, *this);
464
+ }
465
+
466
+ /// \brief Template copy constructor
467
+ ///
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);
473
+ }
474
+
475
+ /// \brief Destructor of the path
476
+ ///
477
+ /// Destructor of the path
478
+ ~ListPath() {
479
+ clear();
480
+ }
481
+
482
+ /// \brief Copy assignment
483
+ ///
484
+ ListPath& operator=(const ListPath& cpath) {
485
+ pathCopy(cpath, *this);
486
+ return *this;
487
+ }
488
+
489
+ /// \brief Template copy assignment
490
+ ///
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);
496
+ return *this;
497
+ }
498
+
499
+ /// \brief Iterator class to iterate on the arcs of the paths
500
+ ///
501
+ /// This class is used to iterate on the arcs of the paths
502
+ ///
503
+ /// Of course it converts to Digraph::Arc
504
+ class ArcIt {
505
+ friend class ListPath;
506
+ public:
507
+ /// Default constructor
508
+ ArcIt() {}
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) {}
514
+
515
+ protected:
516
+
517
+ ArcIt(const ListPath &_path, Node *_node)
518
+ : path(&_path), node(_node) {}
519
+
520
+
521
+ public:
522
+
523
+ ///Conversion to Digraph::Arc
524
+ operator const Arc&() const {
525
+ return node->arc;
526
+ }
527
+
528
+ /// Next arc
529
+ ArcIt& operator++() {
530
+ node = node->next;
531
+ return *this;
532
+ }
533
+
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; }
540
+
541
+ private:
542
+ const ListPath *path;
543
+ Node *node;
544
+ };
545
+
546
+ /// \brief The n-th arc.
547
+ ///
548
+ /// This function looks for the n-th 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 {
551
+ Node *node = first;
552
+ for (int i = 0; i < n; ++i) {
553
+ node = node->next;
554
+ }
555
+ return node->arc;
556
+ }
557
+
558
+ /// \brief Initializes arc iterator to point to the n-th arc.
559
+ ArcIt nthIt(int n) const {
560
+ Node *node = first;
561
+ for (int i = 0; i < n; ++i) {
562
+ node = node->next;
563
+ }
564
+ return ArcIt(*this, node);
565
+ }
566
+
567
+ /// \brief Length of the path.
568
+ int length() const {
569
+ int len = 0;
570
+ Node *node = first;
571
+ while (node != 0) {
572
+ node = node->next;
573
+ ++len;
574
+ }
575
+ return len;
576
+ }
577
+
578
+ /// \brief Return true if the path is empty.
579
+ bool empty() const { return first == 0; }
580
+
581
+ /// \brief Reset the path to an empty one.
582
+ void clear() {
583
+ while (first != 0) {
584
+ last = first->next;
585
+ alloc.destroy(first);
586
+ alloc.deallocate(first, 1);
587
+ first = last;
588
+ }
589
+ }
590
+
591
+ /// \brief The first arc of the path
592
+ const Arc& front() const {
593
+ return first->arc;
594
+ }
595
+
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());
600
+ node->prev = 0;
601
+ node->next = first;
602
+ node->arc = arc;
603
+ if (first) {
604
+ first->prev = node;
605
+ first = node;
606
+ } else {
607
+ first = last = node;
608
+ }
609
+ }
610
+
611
+ /// \brief Erase the first arc of the path
612
+ void eraseFront() {
613
+ Node *node = first;
614
+ first = first->next;
615
+ if (first) {
616
+ first->prev = 0;
617
+ } else {
618
+ last = 0;
619
+ }
620
+ alloc.destroy(node);
621
+ alloc.deallocate(node, 1);
622
+ }
623
+
624
+ /// \brief The last arc of the path.
625
+ const Arc& back() const {
626
+ return last->arc;
627
+ }
628
+
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());
633
+ node->next = 0;
634
+ node->prev = last;
635
+ node->arc = arc;
636
+ if (last) {
637
+ last->next = node;
638
+ last = node;
639
+ } else {
640
+ last = first = node;
641
+ }
642
+ }
643
+
644
+ /// \brief Erase the last arc of the path
645
+ void eraseBack() {
646
+ Node *node = last;
647
+ last = last->prev;
648
+ if (last) {
649
+ last->next = 0;
650
+ } else {
651
+ first = 0;
652
+ }
653
+ alloc.destroy(node);
654
+ alloc.deallocate(node, 1);
655
+ }
656
+
657
+ /// \brief Splice a path to the back of the current path.
658
+ ///
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
661
+ /// O(1).
662
+ void spliceBack(ListPath& tpath) {
663
+ if (first) {
664
+ if (tpath.first) {
665
+ last->next = tpath.first;
666
+ tpath.first->prev = last;
667
+ last = tpath.last;
668
+ }
669
+ } else {
670
+ first = tpath.first;
671
+ last = tpath.last;
672
+ }
673
+ tpath.first = tpath.last = 0;
674
+ }
675
+
676
+ /// \brief Splice a path to the front of the current path.
677
+ ///
678
+ /// It splices \c tpath before the current path and \c tpath
679
+ /// becomes empty. The time complexity of this function
680
+ /// is O(1).
681
+ void spliceFront(ListPath& tpath) {
682
+ if (first) {
683
+ if (tpath.first) {
684
+ first->prev = tpath.last;
685
+ tpath.last->next = first;
686
+ first = tpath.first;
687
+ }
688
+ } else {
689
+ first = tpath.first;
690
+ last = tpath.last;
691
+ }
692
+ tpath.first = tpath.last = 0;
693
+ }
694
+
695
+ /// \brief Splice a path into the current path.
696
+ ///
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) {
702
+ if (it.node) {
703
+ if (tpath.first) {
704
+ tpath.first->prev = it.node->prev;
705
+ if (it.node->prev) {
706
+ it.node->prev->next = tpath.first;
707
+ } else {
708
+ first = tpath.first;
709
+ }
710
+ it.node->prev = tpath.last;
711
+ tpath.last->next = it.node;
712
+ }
713
+ } else {
714
+ if (first) {
715
+ if (tpath.first) {
716
+ last->next = tpath.first;
717
+ tpath.first->prev = last;
718
+ last = tpath.last;
719
+ }
720
+ } else {
721
+ first = tpath.first;
722
+ last = tpath.last;
723
+ }
724
+ }
725
+ tpath.first = tpath.last = 0;
726
+ }
727
+
728
+ /// \brief Split the current path.
729
+ ///
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
732
+ /// starting with
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) {
738
+ tpath.clear();
739
+ if (it.node) {
740
+ tpath.first = it.node;
741
+ tpath.last = last;
742
+ if (it.node->prev) {
743
+ last = it.node->prev;
744
+ last->next = 0;
745
+ } else {
746
+ first = last = 0;
747
+ }
748
+ it.node->prev = 0;
749
+ }
750
+ }
751
+
752
+
753
+ typedef True BuildTag;
754
+
755
+ template <typename CPath>
756
+ void build(const CPath& path) {
757
+ for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
758
+ addBack(it);
759
+ }
760
+ }
761
+
762
+ template <typename CPath>
763
+ void buildRev(const CPath& path) {
764
+ for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
765
+ addFront(it);
766
+ }
767
+ }
768
+
769
+ };
770
+
771
+ /// \brief A structure for representing directed paths in a digraph.
772
+ ///
773
+ /// A structure for representing directed path in a digraph.
774
+ /// \tparam GR The digraph type in which the path is.
775
+ ///
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.
780
+ ///
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
783
+ /// modified.
784
+ ///
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>
789
+ class StaticPath {
790
+ public:
791
+
792
+ typedef GR Digraph;
793
+ typedef typename Digraph::Arc Arc;
794
+
795
+ /// \brief Default constructor
796
+ ///
797
+ /// Default constructor
798
+ StaticPath() : len(0), arcs(0) {}
799
+
800
+ /// \brief Copy constructor
801
+ ///
802
+ StaticPath(const StaticPath& cpath) : arcs(0) {
803
+ pathCopy(cpath, *this);
804
+ }
805
+
806
+ /// \brief Template copy constructor
807
+ ///
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);
812
+ }
813
+
814
+ /// \brief Destructor of the path
815
+ ///
816
+ /// Destructor of the path
817
+ ~StaticPath() {
818
+ if (arcs) delete[] arcs;
819
+ }
820
+
821
+ /// \brief Copy assignment
822
+ ///
823
+ StaticPath& operator=(const StaticPath& cpath) {
824
+ pathCopy(cpath, *this);
825
+ return *this;
826
+ }
827
+
828
+ /// \brief Template copy assignment
829
+ ///
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);
835
+ return *this;
836
+ }
837
+
838
+ /// \brief Iterator class to iterate on the arcs of the paths
839
+ ///
840
+ /// This class is used to iterate on the arcs of the paths
841
+ ///
842
+ /// Of course it converts to Digraph::Arc
843
+ class ArcIt {
844
+ friend class StaticPath;
845
+ public:
846
+ /// Default constructor
847
+ ArcIt() {}
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) {}
853
+
854
+ private:
855
+
856
+ /// Constructor with starting point
857
+ ArcIt(const StaticPath &_path, int _idx)
858
+ : idx(_idx), path(&_path) {}
859
+
860
+ public:
861
+
862
+ ///Conversion to Digraph::Arc
863
+ operator const Arc&() const {
864
+ return path->nth(idx);
865
+ }
866
+
867
+ /// Next arc
868
+ ArcIt& operator++() {
869
+ ++idx;
870
+ if (idx >= path->length()) idx = -1;
871
+ return *this;
872
+ }
873
+
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; }
880
+
881
+ private:
882
+ const StaticPath *path;
883
+ int idx;
884
+ };
885
+
886
+ /// \brief The n-th arc.
887
+ ///
888
+ /// \pre \c n is in the <tt>[0..length() - 1]</tt> range.
889
+ const Arc& nth(int n) const {
890
+ return arcs[n];
891
+ }
892
+
893
+ /// \brief The arc iterator pointing to the n-th arc.
894
+ ArcIt nthIt(int n) const {
895
+ return ArcIt(*this, n);
896
+ }
897
+
898
+ /// \brief The length of the path.
899
+ int length() const { return len; }
900
+
901
+ /// \brief Return true when the path is empty.
902
+ int empty() const { return len == 0; }
903
+
904
+ /// \brief Erase all arcs in the digraph.
905
+ void clear() {
906
+ len = 0;
907
+ if (arcs) delete[] arcs;
908
+ arcs = 0;
909
+ }
910
+
911
+ /// \brief The first arc of the path.
912
+ const Arc& front() const {
913
+ return arcs[0];
914
+ }
915
+
916
+ /// \brief The last arc of the path.
917
+ const Arc& back() const {
918
+ return arcs[len - 1];
919
+ }
920
+
921
+
922
+ typedef True BuildTag;
923
+
924
+ template <typename CPath>
925
+ void build(const CPath& path) {
926
+ len = path.length();
927
+ arcs = new Arc[len];
928
+ int index = 0;
929
+ for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
930
+ arcs[index] = it;
931
+ ++index;
932
+ }
933
+ }
934
+
935
+ template <typename CPath>
936
+ void buildRev(const CPath& path) {
937
+ len = path.length();
938
+ arcs = new Arc[len];
939
+ int index = len;
940
+ for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
941
+ --index;
942
+ arcs[index] = it;
943
+ }
944
+ }
945
+
946
+ private:
947
+ int len;
948
+ Arc* arcs;
949
+ };
950
+
951
+ ///////////////////////////////////////////////////////////////////////
952
+ // Additional utilities
953
+ ///////////////////////////////////////////////////////////////////////
954
+
955
+ namespace _path_bits {
956
+
957
+ template <typename Path, typename Enable = void>
958
+ struct RevPathTagIndicator {
959
+ static const bool value = false;
960
+ };
961
+
962
+ template <typename Path>
963
+ struct RevPathTagIndicator<
964
+ Path,
965
+ typename enable_if<typename Path::RevPathTag, void>::type
966
+ > {
967
+ static const bool value = true;
968
+ };
969
+
970
+ template <typename Path, typename Enable = void>
971
+ struct BuildTagIndicator {
972
+ static const bool value = false;
973
+ };
974
+
975
+ template <typename Path>
976
+ struct BuildTagIndicator<
977
+ Path,
978
+ typename enable_if<typename Path::BuildTag, void>::type
979
+ > {
980
+ static const bool value = true;
981
+ };
982
+
983
+ template <typename From, typename To,
984
+ bool buildEnable = BuildTagIndicator<To>::value>
985
+ struct PathCopySelectorForward {
986
+ static void copy(const From& from, To& to) {
987
+ to.clear();
988
+ for (typename From::ArcIt it(from); it != INVALID; ++it) {
989
+ to.addBack(it);
990
+ }
991
+ }
992
+ };
993
+
994
+ template <typename From, typename To>
995
+ struct PathCopySelectorForward<From, To, true> {
996
+ static void copy(const From& from, To& to) {
997
+ to.clear();
998
+ to.build(from);
999
+ }
1000
+ };
1001
+
1002
+ template <typename From, typename To,
1003
+ bool buildEnable = BuildTagIndicator<To>::value>
1004
+ struct PathCopySelectorBackward {
1005
+ static void copy(const From& from, To& to) {
1006
+ to.clear();
1007
+ for (typename From::RevArcIt it(from); it != INVALID; ++it) {
1008
+ to.addFront(it);
1009
+ }
1010
+ }
1011
+ };
1012
+
1013
+ template <typename From, typename To>
1014
+ struct PathCopySelectorBackward<From, To, true> {
1015
+ static void copy(const From& from, To& to) {
1016
+ to.clear();
1017
+ to.buildRev(from);
1018
+ }
1019
+ };
1020
+
1021
+
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);
1027
+ }
1028
+ };
1029
+
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);
1034
+ }
1035
+ };
1036
+
1037
+ }
1038
+
1039
+
1040
+ /// \brief Make a copy of a path.
1041
+ ///
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);
1047
+ }
1048
+
1049
+ /// \brief Deprecated version of \ref pathCopy().
1050
+ ///
1051
+ /// Deprecated version of \ref pathCopy() (only for reverse compatibility).
1052
+ template <typename To, typename From>
1053
+ void copyPath(To& to, const From& from) {
1054
+ pathCopy(from, to);
1055
+ }
1056
+
1057
+ /// \brief Check the consistency of a path.
1058
+ ///
1059
+ /// This function checks that the target of each arc is the same
1060
+ /// as the source of the next one.
1061
+ ///
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);
1067
+ ++it;
1068
+ while (it != INVALID) {
1069
+ if (digraph.source(it) != node) return false;
1070
+ node = digraph.target(it);
1071
+ ++it;
1072
+ }
1073
+ return true;
1074
+ }
1075
+
1076
+ /// \brief The source of a path
1077
+ ///
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());
1083
+ }
1084
+
1085
+ /// \brief The target of a path
1086
+ ///
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());
1092
+ }
1093
+
1094
+ /// \brief Class which helps to iterate through the nodes of a path
1095
+ ///
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.
1100
+ ///
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>
1105
+ class PathNodeIt {
1106
+ private:
1107
+ const typename Path::Digraph *_digraph;
1108
+ typename Path::ArcIt _it;
1109
+ typename Path::Digraph::Node _nd;
1110
+
1111
+ public:
1112
+
1113
+ typedef typename Path::Digraph Digraph;
1114
+ typedef typename Digraph::Node Node;
1115
+
1116
+ /// Default constructor
1117
+ PathNodeIt() {}
1118
+ /// Invalid constructor
1119
+ PathNodeIt(Invalid)
1120
+ : _digraph(0), _it(INVALID), _nd(INVALID) {}
1121
+ /// Constructor
1122
+ PathNodeIt(const Digraph& digraph, const Path& path)
1123
+ : _digraph(&digraph), _it(path) {
1124
+ _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1125
+ }
1126
+ /// Constructor
1127
+ PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
1128
+ : _digraph(&digraph), _it(path), _nd(src) {}
1129
+
1130
+ ///Conversion to Digraph::Node
1131
+ operator Node() const {
1132
+ return _nd;
1133
+ }
1134
+
1135
+ /// Next node
1136
+ PathNodeIt& operator++() {
1137
+ if (_it == INVALID) _nd = INVALID;
1138
+ else {
1139
+ _nd = _digraph->target(_it);
1140
+ ++_it;
1141
+ }
1142
+ return *this;
1143
+ }
1144
+
1145
+ /// Comparison operator
1146
+ bool operator==(const PathNodeIt& n) const {
1147
+ return _it == n._it && _nd == n._nd;
1148
+ }
1149
+ /// Comparison operator
1150
+ bool operator!=(const PathNodeIt& n) const {
1151
+ return _it != n._it || _nd != n._nd;
1152
+ }
1153
+ /// Comparison operator
1154
+ bool operator<(const PathNodeIt& n) const {
1155
+ return (_it < n._it && _nd != INVALID);
1156
+ }
1157
+
1158
+ };
1159
+
1160
+ ///@}
1161
+
1162
+ } // namespace lemon
1163
+
1164
+ #endif // LEMON_PATH_H