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,982 @@
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-2009
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
+ #ifndef LEMON_ELEVATOR_H
20
+ #define LEMON_ELEVATOR_H
21
+
22
+ ///\ingroup auxdat
23
+ ///\file
24
+ ///\brief Elevator class
25
+ ///
26
+ ///Elevator class implements an efficient data structure
27
+ ///for labeling items in push-relabel type algorithms.
28
+ ///
29
+
30
+ #include <lemon/core.h>
31
+ #include <lemon/bits/traits.h>
32
+
33
+ namespace lemon {
34
+
35
+ ///Class for handling "labels" in push-relabel type algorithms.
36
+
37
+ ///A class for handling "labels" in push-relabel type algorithms.
38
+ ///
39
+ ///\ingroup auxdat
40
+ ///Using this class you can assign "labels" (nonnegative integer numbers)
41
+ ///to the edges or nodes of a graph, manipulate and query them through
42
+ ///operations typically arising in "push-relabel" type algorithms.
43
+ ///
44
+ ///Each item is either \em active or not, and you can also choose a
45
+ ///highest level active item.
46
+ ///
47
+ ///\sa LinkedElevator
48
+ ///
49
+ ///\param GR Type of the underlying graph.
50
+ ///\param Item Type of the items the data is assigned to (\c GR::Node,
51
+ ///\c GR::Arc or \c GR::Edge).
52
+ template<class GR, class Item>
53
+ class Elevator
54
+ {
55
+ public:
56
+
57
+ typedef Item Key;
58
+ typedef int Value;
59
+
60
+ private:
61
+
62
+ typedef Item *Vit;
63
+ typedef typename ItemSetTraits<GR,Item>::template Map<Vit>::Type VitMap;
64
+ typedef typename ItemSetTraits<GR,Item>::template Map<int>::Type IntMap;
65
+
66
+ const GR &_g;
67
+ int _max_level;
68
+ int _item_num;
69
+ VitMap _where;
70
+ IntMap _level;
71
+ std::vector<Item> _items;
72
+ std::vector<Vit> _first;
73
+ std::vector<Vit> _last_active;
74
+
75
+ int _highest_active;
76
+
77
+ void copy(Item i, Vit p)
78
+ {
79
+ _where[*p=i] = p;
80
+ }
81
+ void copy(Vit s, Vit p)
82
+ {
83
+ if(s!=p)
84
+ {
85
+ Item i=*s;
86
+ *p=i;
87
+ _where[i] = p;
88
+ }
89
+ }
90
+ void swap(Vit i, Vit j)
91
+ {
92
+ Item ti=*i;
93
+ Vit ct = _where[ti];
94
+ _where[ti] = _where[*i=*j];
95
+ _where[*j] = ct;
96
+ *j=ti;
97
+ }
98
+
99
+ public:
100
+
101
+ ///Constructor with given maximum level.
102
+
103
+ ///Constructor with given maximum level.
104
+ ///
105
+ ///\param graph The underlying graph.
106
+ ///\param max_level The maximum allowed level.
107
+ ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
108
+ Elevator(const GR &graph,int max_level) :
109
+ _g(graph),
110
+ _max_level(max_level),
111
+ _item_num(_max_level),
112
+ _where(graph),
113
+ _level(graph,0),
114
+ _items(_max_level),
115
+ _first(_max_level+2),
116
+ _last_active(_max_level+2),
117
+ _highest_active(-1) {}
118
+ ///Constructor.
119
+
120
+ ///Constructor.
121
+ ///
122
+ ///\param graph The underlying graph.
123
+ ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
124
+ ///where \c max_level is equal to the number of labeled items in the graph.
125
+ Elevator(const GR &graph) :
126
+ _g(graph),
127
+ _max_level(countItems<GR, Item>(graph)),
128
+ _item_num(_max_level),
129
+ _where(graph),
130
+ _level(graph,0),
131
+ _items(_max_level),
132
+ _first(_max_level+2),
133
+ _last_active(_max_level+2),
134
+ _highest_active(-1)
135
+ {
136
+ }
137
+
138
+ ///Activate item \c i.
139
+
140
+ ///Activate item \c i.
141
+ ///\pre Item \c i shouldn't be active before.
142
+ void activate(Item i)
143
+ {
144
+ const int l=_level[i];
145
+ swap(_where[i],++_last_active[l]);
146
+ if(l>_highest_active) _highest_active=l;
147
+ }
148
+
149
+ ///Deactivate item \c i.
150
+
151
+ ///Deactivate item \c i.
152
+ ///\pre Item \c i must be active before.
153
+ void deactivate(Item i)
154
+ {
155
+ swap(_where[i],_last_active[_level[i]]--);
156
+ while(_highest_active>=0 &&
157
+ _last_active[_highest_active]<_first[_highest_active])
158
+ _highest_active--;
159
+ }
160
+
161
+ ///Query whether item \c i is active
162
+ bool active(Item i) const { return _where[i]<=_last_active[_level[i]]; }
163
+
164
+ ///Return the level of item \c i.
165
+ int operator[](Item i) const { return _level[i]; }
166
+
167
+ ///Return the number of items on level \c l.
168
+ int onLevel(int l) const
169
+ {
170
+ return _first[l+1]-_first[l];
171
+ }
172
+ ///Return true if level \c l is empty.
173
+ bool emptyLevel(int l) const
174
+ {
175
+ return _first[l+1]-_first[l]==0;
176
+ }
177
+ ///Return the number of items above level \c l.
178
+ int aboveLevel(int l) const
179
+ {
180
+ return _first[_max_level+1]-_first[l+1];
181
+ }
182
+ ///Return the number of active items on level \c l.
183
+ int activesOnLevel(int l) const
184
+ {
185
+ return _last_active[l]-_first[l]+1;
186
+ }
187
+ ///Return true if there is no active item on level \c l.
188
+ bool activeFree(int l) const
189
+ {
190
+ return _last_active[l]<_first[l];
191
+ }
192
+ ///Return the maximum allowed level.
193
+ int maxLevel() const
194
+ {
195
+ return _max_level;
196
+ }
197
+
198
+ ///\name Highest Active Item
199
+ ///Functions for working with the highest level
200
+ ///active item.
201
+
202
+ ///@{
203
+
204
+ ///Return a highest level active item.
205
+
206
+ ///Return a highest level active item or INVALID if there is no active
207
+ ///item.
208
+ Item highestActive() const
209
+ {
210
+ return _highest_active>=0?*_last_active[_highest_active]:INVALID;
211
+ }
212
+
213
+ ///Return the highest active level.
214
+
215
+ ///Return the level of the highest active item or -1 if there is no active
216
+ ///item.
217
+ int highestActiveLevel() const
218
+ {
219
+ return _highest_active;
220
+ }
221
+
222
+ ///Lift the highest active item by one.
223
+
224
+ ///Lift the item returned by highestActive() by one.
225
+ ///
226
+ void liftHighestActive()
227
+ {
228
+ Item it = *_last_active[_highest_active];
229
+ ++_level[it];
230
+ swap(_last_active[_highest_active]--,_last_active[_highest_active+1]);
231
+ --_first[++_highest_active];
232
+ }
233
+
234
+ ///Lift the highest active item to the given level.
235
+
236
+ ///Lift the item returned by highestActive() to level \c new_level.
237
+ ///
238
+ ///\warning \c new_level must be strictly higher
239
+ ///than the current level.
240
+ ///
241
+ void liftHighestActive(int new_level)
242
+ {
243
+ const Item li = *_last_active[_highest_active];
244
+
245
+ copy(--_first[_highest_active+1],_last_active[_highest_active]--);
246
+ for(int l=_highest_active+1;l<new_level;l++)
247
+ {
248
+ copy(--_first[l+1],_first[l]);
249
+ --_last_active[l];
250
+ }
251
+ copy(li,_first[new_level]);
252
+ _level[li] = new_level;
253
+ _highest_active=new_level;
254
+ }
255
+
256
+ ///Lift the highest active item to the top level.
257
+
258
+ ///Lift the item returned by highestActive() to the top level and
259
+ ///deactivate it.
260
+ void liftHighestActiveToTop()
261
+ {
262
+ const Item li = *_last_active[_highest_active];
263
+
264
+ copy(--_first[_highest_active+1],_last_active[_highest_active]--);
265
+ for(int l=_highest_active+1;l<_max_level;l++)
266
+ {
267
+ copy(--_first[l+1],_first[l]);
268
+ --_last_active[l];
269
+ }
270
+ copy(li,_first[_max_level]);
271
+ --_last_active[_max_level];
272
+ _level[li] = _max_level;
273
+
274
+ while(_highest_active>=0 &&
275
+ _last_active[_highest_active]<_first[_highest_active])
276
+ _highest_active--;
277
+ }
278
+
279
+ ///@}
280
+
281
+ ///\name Active Item on Certain Level
282
+ ///Functions for working with the active items.
283
+
284
+ ///@{
285
+
286
+ ///Return an active item on level \c l.
287
+
288
+ ///Return an active item on level \c l or \ref INVALID if there is no such
289
+ ///an item. (\c l must be from the range [0...\c max_level].
290
+ Item activeOn(int l) const
291
+ {
292
+ return _last_active[l]>=_first[l]?*_last_active[l]:INVALID;
293
+ }
294
+
295
+ ///Lift the active item returned by \c activeOn(level) by one.
296
+
297
+ ///Lift the active item returned by \ref activeOn() "activeOn(level)"
298
+ ///by one.
299
+ Item liftActiveOn(int level)
300
+ {
301
+ Item it =*_last_active[level];
302
+ ++_level[it];
303
+ swap(_last_active[level]--, --_first[level+1]);
304
+ if (level+1>_highest_active) ++_highest_active;
305
+ }
306
+
307
+ ///Lift the active item returned by \c activeOn(level) to the given level.
308
+
309
+ ///Lift the active item returned by \ref activeOn() "activeOn(level)"
310
+ ///to the given level.
311
+ void liftActiveOn(int level, int new_level)
312
+ {
313
+ const Item ai = *_last_active[level];
314
+
315
+ copy(--_first[level+1], _last_active[level]--);
316
+ for(int l=level+1;l<new_level;l++)
317
+ {
318
+ copy(_last_active[l],_first[l]);
319
+ copy(--_first[l+1], _last_active[l]--);
320
+ }
321
+ copy(ai,_first[new_level]);
322
+ _level[ai] = new_level;
323
+ if (new_level>_highest_active) _highest_active=new_level;
324
+ }
325
+
326
+ ///Lift the active item returned by \c activeOn(level) to the top level.
327
+
328
+ ///Lift the active item returned by \ref activeOn() "activeOn(level)"
329
+ ///to the top level and deactivate it.
330
+ void liftActiveToTop(int level)
331
+ {
332
+ const Item ai = *_last_active[level];
333
+
334
+ copy(--_first[level+1],_last_active[level]--);
335
+ for(int l=level+1;l<_max_level;l++)
336
+ {
337
+ copy(_last_active[l],_first[l]);
338
+ copy(--_first[l+1], _last_active[l]--);
339
+ }
340
+ copy(ai,_first[_max_level]);
341
+ --_last_active[_max_level];
342
+ _level[ai] = _max_level;
343
+
344
+ if (_highest_active==level) {
345
+ while(_highest_active>=0 &&
346
+ _last_active[_highest_active]<_first[_highest_active])
347
+ _highest_active--;
348
+ }
349
+ }
350
+
351
+ ///@}
352
+
353
+ ///Lift an active item to a higher level.
354
+
355
+ ///Lift an active item to a higher level.
356
+ ///\param i The item to be lifted. It must be active.
357
+ ///\param new_level The new level of \c i. It must be strictly higher
358
+ ///than the current level.
359
+ ///
360
+ void lift(Item i, int new_level)
361
+ {
362
+ const int lo = _level[i];
363
+ const Vit w = _where[i];
364
+
365
+ copy(_last_active[lo],w);
366
+ copy(--_first[lo+1],_last_active[lo]--);
367
+ for(int l=lo+1;l<new_level;l++)
368
+ {
369
+ copy(_last_active[l],_first[l]);
370
+ copy(--_first[l+1],_last_active[l]--);
371
+ }
372
+ copy(i,_first[new_level]);
373
+ _level[i] = new_level;
374
+ if(new_level>_highest_active) _highest_active=new_level;
375
+ }
376
+
377
+ ///Move an inactive item to the top but one level (in a dirty way).
378
+
379
+ ///This function moves an inactive item from the top level to the top
380
+ ///but one level (in a dirty way).
381
+ ///\warning It makes the underlying datastructure corrupt, so use it
382
+ ///only if you really know what it is for.
383
+ ///\pre The item is on the top level.
384
+ void dirtyTopButOne(Item i) {
385
+ _level[i] = _max_level - 1;
386
+ }
387
+
388
+ ///Lift all items on and above the given level to the top level.
389
+
390
+ ///This function lifts all items on and above level \c l to the top
391
+ ///level and deactivates them.
392
+ void liftToTop(int l)
393
+ {
394
+ const Vit f=_first[l];
395
+ const Vit tl=_first[_max_level];
396
+ for(Vit i=f;i!=tl;++i)
397
+ _level[*i] = _max_level;
398
+ for(int i=l;i<=_max_level;i++)
399
+ {
400
+ _first[i]=f;
401
+ _last_active[i]=f-1;
402
+ }
403
+ for(_highest_active=l-1;
404
+ _highest_active>=0 &&
405
+ _last_active[_highest_active]<_first[_highest_active];
406
+ _highest_active--) ;
407
+ }
408
+
409
+ private:
410
+ int _init_lev;
411
+ Vit _init_num;
412
+
413
+ public:
414
+
415
+ ///\name Initialization
416
+ ///Using these functions you can initialize the levels of the items.
417
+ ///\n
418
+ ///The initialization must be started with calling \c initStart().
419
+ ///Then the items should be listed level by level starting with the
420
+ ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
421
+ ///Finally \c initFinish() must be called.
422
+ ///The items not listed are put on the highest level.
423
+ ///@{
424
+
425
+ ///Start the initialization process.
426
+ void initStart()
427
+ {
428
+ _init_lev=0;
429
+ _init_num=&_items[0];
430
+ _first[0]=&_items[0];
431
+ _last_active[0]=&_items[0]-1;
432
+ Vit n=&_items[0];
433
+ for(typename ItemSetTraits<GR,Item>::ItemIt i(_g);i!=INVALID;++i)
434
+ {
435
+ *n=i;
436
+ _where[i] = n;
437
+ _level[i] = _max_level;
438
+ ++n;
439
+ }
440
+ }
441
+
442
+ ///Add an item to the current level.
443
+ void initAddItem(Item i)
444
+ {
445
+ swap(_where[i],_init_num);
446
+ _level[i] = _init_lev;
447
+ ++_init_num;
448
+ }
449
+
450
+ ///Start a new level.
451
+
452
+ ///Start a new level.
453
+ ///It shouldn't be used before the items on level 0 are listed.
454
+ void initNewLevel()
455
+ {
456
+ _init_lev++;
457
+ _first[_init_lev]=_init_num;
458
+ _last_active[_init_lev]=_init_num-1;
459
+ }
460
+
461
+ ///Finalize the initialization process.
462
+ void initFinish()
463
+ {
464
+ for(_init_lev++;_init_lev<=_max_level;_init_lev++)
465
+ {
466
+ _first[_init_lev]=_init_num;
467
+ _last_active[_init_lev]=_init_num-1;
468
+ }
469
+ _first[_max_level+1]=&_items[0]+_item_num;
470
+ _last_active[_max_level+1]=&_items[0]+_item_num-1;
471
+ _highest_active = -1;
472
+ }
473
+
474
+ ///@}
475
+
476
+ };
477
+
478
+ ///Class for handling "labels" in push-relabel type algorithms.
479
+
480
+ ///A class for handling "labels" in push-relabel type algorithms.
481
+ ///
482
+ ///\ingroup auxdat
483
+ ///Using this class you can assign "labels" (nonnegative integer numbers)
484
+ ///to the edges or nodes of a graph, manipulate and query them through
485
+ ///operations typically arising in "push-relabel" type algorithms.
486
+ ///
487
+ ///Each item is either \em active or not, and you can also choose a
488
+ ///highest level active item.
489
+ ///
490
+ ///\sa Elevator
491
+ ///
492
+ ///\param GR Type of the underlying graph.
493
+ ///\param Item Type of the items the data is assigned to (\c GR::Node,
494
+ ///\c GR::Arc or \c GR::Edge).
495
+ template <class GR, class Item>
496
+ class LinkedElevator {
497
+ public:
498
+
499
+ typedef Item Key;
500
+ typedef int Value;
501
+
502
+ private:
503
+
504
+ typedef typename ItemSetTraits<GR,Item>::
505
+ template Map<Item>::Type ItemMap;
506
+ typedef typename ItemSetTraits<GR,Item>::
507
+ template Map<int>::Type IntMap;
508
+ typedef typename ItemSetTraits<GR,Item>::
509
+ template Map<bool>::Type BoolMap;
510
+
511
+ const GR &_graph;
512
+ int _max_level;
513
+ int _item_num;
514
+ std::vector<Item> _first, _last;
515
+ ItemMap _prev, _next;
516
+ int _highest_active;
517
+ IntMap _level;
518
+ BoolMap _active;
519
+
520
+ public:
521
+ ///Constructor with given maximum level.
522
+
523
+ ///Constructor with given maximum level.
524
+ ///
525
+ ///\param graph The underlying graph.
526
+ ///\param max_level The maximum allowed level.
527
+ ///Set the range of the possible labels to <tt>[0..max_level]</tt>.
528
+ LinkedElevator(const GR& graph, int max_level)
529
+ : _graph(graph), _max_level(max_level), _item_num(_max_level),
530
+ _first(_max_level + 1), _last(_max_level + 1),
531
+ _prev(graph), _next(graph),
532
+ _highest_active(-1), _level(graph), _active(graph) {}
533
+
534
+ ///Constructor.
535
+
536
+ ///Constructor.
537
+ ///
538
+ ///\param graph The underlying graph.
539
+ ///Set the range of the possible labels to <tt>[0..max_level]</tt>,
540
+ ///where \c max_level is equal to the number of labeled items in the graph.
541
+ LinkedElevator(const GR& graph)
542
+ : _graph(graph), _max_level(countItems<GR, Item>(graph)),
543
+ _item_num(_max_level),
544
+ _first(_max_level + 1), _last(_max_level + 1),
545
+ _prev(graph, INVALID), _next(graph, INVALID),
546
+ _highest_active(-1), _level(graph), _active(graph) {}
547
+
548
+
549
+ ///Activate item \c i.
550
+
551
+ ///Activate item \c i.
552
+ ///\pre Item \c i shouldn't be active before.
553
+ void activate(Item i) {
554
+ _active[i] = true;
555
+
556
+ int level = _level[i];
557
+ if (level > _highest_active) {
558
+ _highest_active = level;
559
+ }
560
+
561
+ if (_prev[i] == INVALID || _active[_prev[i]]) return;
562
+ //unlace
563
+ _next[_prev[i]] = _next[i];
564
+ if (_next[i] != INVALID) {
565
+ _prev[_next[i]] = _prev[i];
566
+ } else {
567
+ _last[level] = _prev[i];
568
+ }
569
+ //lace
570
+ _next[i] = _first[level];
571
+ _prev[_first[level]] = i;
572
+ _prev[i] = INVALID;
573
+ _first[level] = i;
574
+
575
+ }
576
+
577
+ ///Deactivate item \c i.
578
+
579
+ ///Deactivate item \c i.
580
+ ///\pre Item \c i must be active before.
581
+ void deactivate(Item i) {
582
+ _active[i] = false;
583
+ int level = _level[i];
584
+
585
+ if (_next[i] == INVALID || !_active[_next[i]])
586
+ goto find_highest_level;
587
+
588
+ //unlace
589
+ _prev[_next[i]] = _prev[i];
590
+ if (_prev[i] != INVALID) {
591
+ _next[_prev[i]] = _next[i];
592
+ } else {
593
+ _first[_level[i]] = _next[i];
594
+ }
595
+ //lace
596
+ _prev[i] = _last[level];
597
+ _next[_last[level]] = i;
598
+ _next[i] = INVALID;
599
+ _last[level] = i;
600
+
601
+ find_highest_level:
602
+ if (level == _highest_active) {
603
+ while (_highest_active >= 0 && activeFree(_highest_active))
604
+ --_highest_active;
605
+ }
606
+ }
607
+
608
+ ///Query whether item \c i is active
609
+ bool active(Item i) const { return _active[i]; }
610
+
611
+ ///Return the level of item \c i.
612
+ int operator[](Item i) const { return _level[i]; }
613
+
614
+ ///Return the number of items on level \c l.
615
+ int onLevel(int l) const {
616
+ int num = 0;
617
+ Item n = _first[l];
618
+ while (n != INVALID) {
619
+ ++num;
620
+ n = _next[n];
621
+ }
622
+ return num;
623
+ }
624
+
625
+ ///Return true if the level is empty.
626
+ bool emptyLevel(int l) const {
627
+ return _first[l] == INVALID;
628
+ }
629
+
630
+ ///Return the number of items above level \c l.
631
+ int aboveLevel(int l) const {
632
+ int num = 0;
633
+ for (int level = l + 1; level < _max_level; ++level)
634
+ num += onLevel(level);
635
+ return num;
636
+ }
637
+
638
+ ///Return the number of active items on level \c l.
639
+ int activesOnLevel(int l) const {
640
+ int num = 0;
641
+ Item n = _first[l];
642
+ while (n != INVALID && _active[n]) {
643
+ ++num;
644
+ n = _next[n];
645
+ }
646
+ return num;
647
+ }
648
+
649
+ ///Return true if there is no active item on level \c l.
650
+ bool activeFree(int l) const {
651
+ return _first[l] == INVALID || !_active[_first[l]];
652
+ }
653
+
654
+ ///Return the maximum allowed level.
655
+ int maxLevel() const {
656
+ return _max_level;
657
+ }
658
+
659
+ ///\name Highest Active Item
660
+ ///Functions for working with the highest level
661
+ ///active item.
662
+
663
+ ///@{
664
+
665
+ ///Return a highest level active item.
666
+
667
+ ///Return a highest level active item or INVALID if there is no active
668
+ ///item.
669
+ Item highestActive() const {
670
+ return _highest_active >= 0 ? _first[_highest_active] : INVALID;
671
+ }
672
+
673
+ ///Return the highest active level.
674
+
675
+ ///Return the level of the highest active item or -1 if there is no active
676
+ ///item.
677
+ int highestActiveLevel() const {
678
+ return _highest_active;
679
+ }
680
+
681
+ ///Lift the highest active item by one.
682
+
683
+ ///Lift the item returned by highestActive() by one.
684
+ ///
685
+ void liftHighestActive() {
686
+ Item i = _first[_highest_active];
687
+ if (_next[i] != INVALID) {
688
+ _prev[_next[i]] = INVALID;
689
+ _first[_highest_active] = _next[i];
690
+ } else {
691
+ _first[_highest_active] = INVALID;
692
+ _last[_highest_active] = INVALID;
693
+ }
694
+ _level[i] = ++_highest_active;
695
+ if (_first[_highest_active] == INVALID) {
696
+ _first[_highest_active] = i;
697
+ _last[_highest_active] = i;
698
+ _prev[i] = INVALID;
699
+ _next[i] = INVALID;
700
+ } else {
701
+ _prev[_first[_highest_active]] = i;
702
+ _next[i] = _first[_highest_active];
703
+ _first[_highest_active] = i;
704
+ }
705
+ }
706
+
707
+ ///Lift the highest active item to the given level.
708
+
709
+ ///Lift the item returned by highestActive() to level \c new_level.
710
+ ///
711
+ ///\warning \c new_level must be strictly higher
712
+ ///than the current level.
713
+ ///
714
+ void liftHighestActive(int new_level) {
715
+ Item i = _first[_highest_active];
716
+ if (_next[i] != INVALID) {
717
+ _prev[_next[i]] = INVALID;
718
+ _first[_highest_active] = _next[i];
719
+ } else {
720
+ _first[_highest_active] = INVALID;
721
+ _last[_highest_active] = INVALID;
722
+ }
723
+ _level[i] = _highest_active = new_level;
724
+ if (_first[_highest_active] == INVALID) {
725
+ _first[_highest_active] = _last[_highest_active] = i;
726
+ _prev[i] = INVALID;
727
+ _next[i] = INVALID;
728
+ } else {
729
+ _prev[_first[_highest_active]] = i;
730
+ _next[i] = _first[_highest_active];
731
+ _first[_highest_active] = i;
732
+ }
733
+ }
734
+
735
+ ///Lift the highest active item to the top level.
736
+
737
+ ///Lift the item returned by highestActive() to the top level and
738
+ ///deactivate it.
739
+ void liftHighestActiveToTop() {
740
+ Item i = _first[_highest_active];
741
+ _level[i] = _max_level;
742
+ if (_next[i] != INVALID) {
743
+ _prev[_next[i]] = INVALID;
744
+ _first[_highest_active] = _next[i];
745
+ } else {
746
+ _first[_highest_active] = INVALID;
747
+ _last[_highest_active] = INVALID;
748
+ }
749
+ while (_highest_active >= 0 && activeFree(_highest_active))
750
+ --_highest_active;
751
+ }
752
+
753
+ ///@}
754
+
755
+ ///\name Active Item on Certain Level
756
+ ///Functions for working with the active items.
757
+
758
+ ///@{
759
+
760
+ ///Return an active item on level \c l.
761
+
762
+ ///Return an active item on level \c l or \ref INVALID if there is no such
763
+ ///an item. (\c l must be from the range [0...\c max_level].
764
+ Item activeOn(int l) const
765
+ {
766
+ return _active[_first[l]] ? _first[l] : INVALID;
767
+ }
768
+
769
+ ///Lift the active item returned by \c activeOn(l) by one.
770
+
771
+ ///Lift the active item returned by \ref activeOn() "activeOn(l)"
772
+ ///by one.
773
+ Item liftActiveOn(int l)
774
+ {
775
+ Item i = _first[l];
776
+ if (_next[i] != INVALID) {
777
+ _prev[_next[i]] = INVALID;
778
+ _first[l] = _next[i];
779
+ } else {
780
+ _first[l] = INVALID;
781
+ _last[l] = INVALID;
782
+ }
783
+ _level[i] = ++l;
784
+ if (_first[l] == INVALID) {
785
+ _first[l] = _last[l] = i;
786
+ _prev[i] = INVALID;
787
+ _next[i] = INVALID;
788
+ } else {
789
+ _prev[_first[l]] = i;
790
+ _next[i] = _first[l];
791
+ _first[l] = i;
792
+ }
793
+ if (_highest_active < l) {
794
+ _highest_active = l;
795
+ }
796
+ }
797
+
798
+ ///Lift the active item returned by \c activeOn(l) to the given level.
799
+
800
+ ///Lift the active item returned by \ref activeOn() "activeOn(l)"
801
+ ///to the given level.
802
+ void liftActiveOn(int l, int new_level)
803
+ {
804
+ Item i = _first[l];
805
+ if (_next[i] != INVALID) {
806
+ _prev[_next[i]] = INVALID;
807
+ _first[l] = _next[i];
808
+ } else {
809
+ _first[l] = INVALID;
810
+ _last[l] = INVALID;
811
+ }
812
+ _level[i] = l = new_level;
813
+ if (_first[l] == INVALID) {
814
+ _first[l] = _last[l] = i;
815
+ _prev[i] = INVALID;
816
+ _next[i] = INVALID;
817
+ } else {
818
+ _prev[_first[l]] = i;
819
+ _next[i] = _first[l];
820
+ _first[l] = i;
821
+ }
822
+ if (_highest_active < l) {
823
+ _highest_active = l;
824
+ }
825
+ }
826
+
827
+ ///Lift the active item returned by \c activeOn(l) to the top level.
828
+
829
+ ///Lift the active item returned by \ref activeOn() "activeOn(l)"
830
+ ///to the top level and deactivate it.
831
+ void liftActiveToTop(int l)
832
+ {
833
+ Item i = _first[l];
834
+ if (_next[i] != INVALID) {
835
+ _prev[_next[i]] = INVALID;
836
+ _first[l] = _next[i];
837
+ } else {
838
+ _first[l] = INVALID;
839
+ _last[l] = INVALID;
840
+ }
841
+ _level[i] = _max_level;
842
+ if (l == _highest_active) {
843
+ while (_highest_active >= 0 && activeFree(_highest_active))
844
+ --_highest_active;
845
+ }
846
+ }
847
+
848
+ ///@}
849
+
850
+ /// \brief Lift an active item to a higher level.
851
+ ///
852
+ /// Lift an active item to a higher level.
853
+ /// \param i The item to be lifted. It must be active.
854
+ /// \param new_level The new level of \c i. It must be strictly higher
855
+ /// than the current level.
856
+ ///
857
+ void lift(Item i, int new_level) {
858
+ if (_next[i] != INVALID) {
859
+ _prev[_next[i]] = _prev[i];
860
+ } else {
861
+ _last[new_level] = _prev[i];
862
+ }
863
+ if (_prev[i] != INVALID) {
864
+ _next[_prev[i]] = _next[i];
865
+ } else {
866
+ _first[new_level] = _next[i];
867
+ }
868
+ _level[i] = new_level;
869
+ if (_first[new_level] == INVALID) {
870
+ _first[new_level] = _last[new_level] = i;
871
+ _prev[i] = INVALID;
872
+ _next[i] = INVALID;
873
+ } else {
874
+ _prev[_first[new_level]] = i;
875
+ _next[i] = _first[new_level];
876
+ _first[new_level] = i;
877
+ }
878
+ if (_highest_active < new_level) {
879
+ _highest_active = new_level;
880
+ }
881
+ }
882
+
883
+ ///Move an inactive item to the top but one level (in a dirty way).
884
+
885
+ ///This function moves an inactive item from the top level to the top
886
+ ///but one level (in a dirty way).
887
+ ///\warning It makes the underlying datastructure corrupt, so use it
888
+ ///only if you really know what it is for.
889
+ ///\pre The item is on the top level.
890
+ void dirtyTopButOne(Item i) {
891
+ _level[i] = _max_level - 1;
892
+ }
893
+
894
+ ///Lift all items on and above the given level to the top level.
895
+
896
+ ///This function lifts all items on and above level \c l to the top
897
+ ///level and deactivates them.
898
+ void liftToTop(int l) {
899
+ for (int i = l + 1; _first[i] != INVALID; ++i) {
900
+ Item n = _first[i];
901
+ while (n != INVALID) {
902
+ _level[n] = _max_level;
903
+ n = _next[n];
904
+ }
905
+ _first[i] = INVALID;
906
+ _last[i] = INVALID;
907
+ }
908
+ if (_highest_active > l - 1) {
909
+ _highest_active = l - 1;
910
+ while (_highest_active >= 0 && activeFree(_highest_active))
911
+ --_highest_active;
912
+ }
913
+ }
914
+
915
+ private:
916
+
917
+ int _init_level;
918
+
919
+ public:
920
+
921
+ ///\name Initialization
922
+ ///Using these functions you can initialize the levels of the items.
923
+ ///\n
924
+ ///The initialization must be started with calling \c initStart().
925
+ ///Then the items should be listed level by level starting with the
926
+ ///lowest one (level 0) using \c initAddItem() and \c initNewLevel().
927
+ ///Finally \c initFinish() must be called.
928
+ ///The items not listed are put on the highest level.
929
+ ///@{
930
+
931
+ ///Start the initialization process.
932
+ void initStart() {
933
+
934
+ for (int i = 0; i <= _max_level; ++i) {
935
+ _first[i] = _last[i] = INVALID;
936
+ }
937
+ _init_level = 0;
938
+ for(typename ItemSetTraits<GR,Item>::ItemIt i(_graph);
939
+ i != INVALID; ++i) {
940
+ _level[i] = _max_level;
941
+ _active[i] = false;
942
+ }
943
+ }
944
+
945
+ ///Add an item to the current level.
946
+ void initAddItem(Item i) {
947
+ _level[i] = _init_level;
948
+ if (_last[_init_level] == INVALID) {
949
+ _first[_init_level] = i;
950
+ _last[_init_level] = i;
951
+ _prev[i] = INVALID;
952
+ _next[i] = INVALID;
953
+ } else {
954
+ _prev[i] = _last[_init_level];
955
+ _next[i] = INVALID;
956
+ _next[_last[_init_level]] = i;
957
+ _last[_init_level] = i;
958
+ }
959
+ }
960
+
961
+ ///Start a new level.
962
+
963
+ ///Start a new level.
964
+ ///It shouldn't be used before the items on level 0 are listed.
965
+ void initNewLevel() {
966
+ ++_init_level;
967
+ }
968
+
969
+ ///Finalize the initialization process.
970
+ void initFinish() {
971
+ _highest_active = -1;
972
+ }
973
+
974
+ ///@}
975
+
976
+ };
977
+
978
+
979
+ } //END OF NAMESPACE LEMON
980
+
981
+ #endif
982
+