gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Move the heaps to a separate group (#299)
0 6 0
default
6 files changed with 40 insertions and 19 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -37,405 +37,426 @@
37 37
usage of different physical graph implementations. These differences
38 38
appear in the size of graph we require to handle, memory or time usage
39 39
limitations or in the set of operations through which the graph can be
40 40
accessed.  LEMON provides several physical graph structures to meet
41 41
the diverging requirements of the possible users.  In order to save on
42 42
running time or on memory usage, some structures may fail to provide
43 43
some graph features like arc/edge or node deletion.
44 44

	
45 45
Alteration of standard containers need a very limited number of
46 46
operations, these together satisfy the everyday requirements.
47 47
In the case of graph structures, different operations are needed which do
48 48
not alter the physical graph, but gives another view. If some nodes or
49 49
arcs have to be hidden or the reverse oriented graph have to be used, then
50 50
this is the case. It also may happen that in a flow implementation
51 51
the residual graph can be accessed by another algorithm, or a node-set
52 52
is to be shrunk for another algorithm.
53 53
LEMON also provides a variety of graphs for these requirements called
54 54
\ref graph_adaptors "graph adaptors". Adaptors cannot be used alone but only
55 55
in conjunction with other graph representations.
56 56

	
57 57
You are free to use the graph structure that fit your requirements
58 58
the best, most graph algorithms and auxiliary data structures can be used
59 59
with any graph structure.
60 60

	
61 61
<b>See also:</b> \ref graph_concepts "Graph Structure Concepts".
62 62
*/
63 63

	
64 64
/**
65 65
@defgroup graph_adaptors Adaptor Classes for Graphs
66 66
@ingroup graphs
67 67
\brief Adaptor classes for digraphs and graphs
68 68

	
69 69
This group contains several useful adaptor classes for digraphs and graphs.
70 70

	
71 71
The main parts of LEMON are the different graph structures, generic
72 72
graph algorithms, graph concepts, which couple them, and graph
73 73
adaptors. While the previous notions are more or less clear, the
74 74
latter one needs further explanation. Graph adaptors are graph classes
75 75
which serve for considering graph structures in different ways.
76 76

	
77 77
A short example makes this much clearer.  Suppose that we have an
78 78
instance \c g of a directed graph type, say ListDigraph and an algorithm
79 79
\code
80 80
template <typename Digraph>
81 81
int algorithm(const Digraph&);
82 82
\endcode
83 83
is needed to run on the reverse oriented graph.  It may be expensive
84 84
(in time or in memory usage) to copy \c g with the reversed
85 85
arcs.  In this case, an adaptor class is used, which (according
86 86
to LEMON \ref concepts::Digraph "digraph concepts") works as a digraph.
87 87
The adaptor uses the original digraph structure and digraph operations when
88 88
methods of the reversed oriented graph are called.  This means that the adaptor
89 89
have minor memory usage, and do not perform sophisticated algorithmic
90 90
actions.  The purpose of it is to give a tool for the cases when a
91 91
graph have to be used in a specific alteration.  If this alteration is
92 92
obtained by a usual construction like filtering the node or the arc set or
93 93
considering a new orientation, then an adaptor is worthwhile to use.
94 94
To come back to the reverse oriented graph, in this situation
95 95
\code
96 96
template<typename Digraph> class ReverseDigraph;
97 97
\endcode
98 98
template class can be used. The code looks as follows
99 99
\code
100 100
ListDigraph g;
101 101
ReverseDigraph<ListDigraph> rg(g);
102 102
int result = algorithm(rg);
103 103
\endcode
104 104
During running the algorithm, the original digraph \c g is untouched.
105 105
This techniques give rise to an elegant code, and based on stable
106 106
graph adaptors, complex algorithms can be implemented easily.
107 107

	
108 108
In flow, circulation and matching problems, the residual
109 109
graph is of particular importance. Combining an adaptor implementing
110 110
this with shortest path algorithms or minimum mean cycle algorithms,
111 111
a range of weighted and cardinality optimization algorithms can be
112 112
obtained. For other examples, the interested user is referred to the
113 113
detailed documentation of particular adaptors.
114 114

	
115 115
The behavior of graph adaptors can be very different. Some of them keep
116 116
capabilities of the original graph while in other cases this would be
117 117
meaningless. This means that the concepts that they meet depend
118 118
on the graph adaptor, and the wrapped graph.
119 119
For example, if an arc of a reversed digraph is deleted, this is carried
120 120
out by deleting the corresponding arc of the original digraph, thus the
121 121
adaptor modifies the original digraph.
122 122
However in case of a residual digraph, this operation has no sense.
123 123

	
124 124
Let us stand one more example here to simplify your work.
125 125
ReverseDigraph has constructor
126 126
\code
127 127
ReverseDigraph(Digraph& digraph);
128 128
\endcode
129 129
This means that in a situation, when a <tt>const %ListDigraph&</tt>
130 130
reference to a graph is given, then it have to be instantiated with
131 131
<tt>Digraph=const %ListDigraph</tt>.
132 132
\code
133 133
int algorithm1(const ListDigraph& g) {
134 134
  ReverseDigraph<const ListDigraph> rg(g);
135 135
  return algorithm2(rg);
136 136
}
137 137
\endcode
138 138
*/
139 139

	
140 140
/**
141 141
@defgroup maps Maps
142 142
@ingroup datas
143 143
\brief Map structures implemented in LEMON.
144 144

	
145 145
This group contains the map structures implemented in LEMON.
146 146

	
147 147
LEMON provides several special purpose maps and map adaptors that e.g. combine
148 148
new maps from existing ones.
149 149

	
150 150
<b>See also:</b> \ref map_concepts "Map Concepts".
151 151
*/
152 152

	
153 153
/**
154 154
@defgroup graph_maps Graph Maps
155 155
@ingroup maps
156 156
\brief Special graph-related maps.
157 157

	
158 158
This group contains maps that are specifically designed to assign
159 159
values to the nodes and arcs/edges of graphs.
160 160

	
161 161
If you are looking for the standard graph maps (\c NodeMap, \c ArcMap,
162 162
\c EdgeMap), see the \ref graph_concepts "Graph Structure Concepts".
163 163
*/
164 164

	
165 165
/**
166 166
\defgroup map_adaptors Map Adaptors
167 167
\ingroup maps
168 168
\brief Tools to create new maps from existing ones
169 169

	
170 170
This group contains map adaptors that are used to create "implicit"
171 171
maps from other maps.
172 172

	
173 173
Most of them are \ref concepts::ReadMap "read-only maps".
174 174
They can make arithmetic and logical operations between one or two maps
175 175
(negation, shifting, addition, multiplication, logical 'and', 'or',
176 176
'not' etc.) or e.g. convert a map to another one of different Value type.
177 177

	
178 178
The typical usage of this classes is passing implicit maps to
179 179
algorithms.  If a function type algorithm is called then the function
180 180
type map adaptors can be used comfortable. For example let's see the
181 181
usage of map adaptors with the \c graphToEps() function.
182 182
\code
183 183
  Color nodeColor(int deg) {
184 184
    if (deg >= 2) {
185 185
      return Color(0.5, 0.0, 0.5);
186 186
    } else if (deg == 1) {
187 187
      return Color(1.0, 0.5, 1.0);
188 188
    } else {
189 189
      return Color(0.0, 0.0, 0.0);
190 190
    }
191 191
  }
192 192

	
193 193
  Digraph::NodeMap<int> degree_map(graph);
194 194

	
195 195
  graphToEps(graph, "graph.eps")
196 196
    .coords(coords).scaleToA4().undirected()
197 197
    .nodeColors(composeMap(functorToMap(nodeColor), degree_map))
198 198
    .run();
199 199
\endcode
200 200
The \c functorToMap() function makes an \c int to \c Color map from the
201 201
\c nodeColor() function. The \c composeMap() compose the \c degree_map
202 202
and the previously created map. The composed map is a proper function to
203 203
get the color of each node.
204 204

	
205 205
The usage with class type algorithms is little bit harder. In this
206 206
case the function type map adaptors can not be used, because the
207 207
function map adaptors give back temporary objects.
208 208
\code
209 209
  Digraph graph;
210 210

	
211 211
  typedef Digraph::ArcMap<double> DoubleArcMap;
212 212
  DoubleArcMap length(graph);
213 213
  DoubleArcMap speed(graph);
214 214

	
215 215
  typedef DivMap<DoubleArcMap, DoubleArcMap> TimeMap;
216 216
  TimeMap time(length, speed);
217 217

	
218 218
  Dijkstra<Digraph, TimeMap> dijkstra(graph, time);
219 219
  dijkstra.run(source, target);
220 220
\endcode
221 221
We have a length map and a maximum speed map on the arcs of a digraph.
222 222
The minimum time to pass the arc can be calculated as the division of
223 223
the two maps which can be done implicitly with the \c DivMap template
224 224
class. We use the implicit minimum time map as the length map of the
225 225
\c Dijkstra algorithm.
226 226
*/
227 227

	
228 228
/**
229
@defgroup matrices Matrices
230
@ingroup datas
231
\brief Two dimensional data storages implemented in LEMON.
232

	
233
This group contains two dimensional data storages implemented in LEMON.
234
*/
235

	
236
/**
237 229
@defgroup paths Path Structures
238 230
@ingroup datas
239 231
\brief %Path structures implemented in LEMON.
240 232

	
241 233
This group contains the path structures implemented in LEMON.
242 234

	
243 235
LEMON provides flexible data structures to work with paths.
244 236
All of them have similar interfaces and they can be copied easily with
245 237
assignment operators and copy constructors. This makes it easy and
246 238
efficient to have e.g. the Dijkstra algorithm to store its result in
247 239
any kind of path structure.
248 240

	
249
\sa lemon::concepts::Path
241
\sa \ref concepts::Path "Path concept"
242
*/
243

	
244
/**
245
@defgroup heaps Heap Structures
246
@ingroup datas
247
\brief %Heap structures implemented in LEMON.
248

	
249
This group contains the heap structures implemented in LEMON.
250

	
251
LEMON provides several heap classes. They are efficient implementations
252
of the abstract data type \e priority \e queue. They store items with
253
specified values called \e priorities in such a way that finding and
254
removing the item with minimum priority are efficient.
255
The basic operations are adding and erasing items, changing the priority
256
of an item, etc.
257

	
258
Heaps are crucial in several algorithms, such as Dijkstra and Prim.
259
The heap implementations have the same interface, thus any of them can be
260
used easily in such algorithms.
261

	
262
\sa \ref concepts::Heap "Heap concept"
263
*/
264

	
265
/**
266
@defgroup matrices Matrices
267
@ingroup datas
268
\brief Two dimensional data storages implemented in LEMON.
269

	
270
This group contains two dimensional data storages implemented in LEMON.
250 271
*/
251 272

	
252 273
/**
253 274
@defgroup auxdat Auxiliary Data Structures
254 275
@ingroup datas
255 276
\brief Auxiliary data structures implemented in LEMON.
256 277

	
257 278
This group contains some data structures implemented in LEMON in
258 279
order to make it easier to implement combinatorial algorithms.
259 280
*/
260 281

	
261 282
/**
262 283
@defgroup algs Algorithms
263 284
\brief This group contains the several algorithms
264 285
implemented in LEMON.
265 286

	
266 287
This group contains the several algorithms
267 288
implemented in LEMON.
268 289
*/
269 290

	
270 291
/**
271 292
@defgroup search Graph Search
272 293
@ingroup algs
273 294
\brief Common graph search algorithms.
274 295

	
275 296
This group contains the common graph search algorithms, namely
276 297
\e breadth-first \e search (BFS) and \e depth-first \e search (DFS).
277 298
*/
278 299

	
279 300
/**
280 301
@defgroup shortest_path Shortest Path Algorithms
281 302
@ingroup algs
282 303
\brief Algorithms for finding shortest paths.
283 304

	
284 305
This group contains the algorithms for finding shortest paths in digraphs.
285 306

	
286 307
 - \ref Dijkstra algorithm for finding shortest paths from a source node
287 308
   when all arc lengths are non-negative.
288 309
 - \ref BellmanFord "Bellman-Ford" algorithm for finding shortest paths
289 310
   from a source node when arc lenghts can be either positive or negative,
290 311
   but the digraph should not contain directed cycles with negative total
291 312
   length.
292 313
 - \ref FloydWarshall "Floyd-Warshall" and \ref Johnson "Johnson" algorithms
293 314
   for solving the \e all-pairs \e shortest \e paths \e problem when arc
294 315
   lenghts can be either positive or negative, but the digraph should
295 316
   not contain directed cycles with negative total length.
296 317
 - \ref Suurballe A successive shortest path algorithm for finding
297 318
   arc-disjoint paths between two nodes having minimum total length.
298 319
*/
299 320

	
300 321
/**
301 322
@defgroup max_flow Maximum Flow Algorithms
302 323
@ingroup algs
303 324
\brief Algorithms for finding maximum flows.
304 325

	
305 326
This group contains the algorithms for finding maximum flows and
306 327
feasible circulations.
307 328

	
308 329
The \e maximum \e flow \e problem is to find a flow of maximum value between
309 330
a single source and a single target. Formally, there is a \f$G=(V,A)\f$
310 331
digraph, a \f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function and
311 332
\f$s, t \in V\f$ source and target nodes.
312 333
A maximum flow is an \f$f: A\rightarrow\mathbf{R}^+_0\f$ solution of the
313 334
following optimization problem.
314 335

	
315 336
\f[ \max\sum_{sv\in A} f(sv) - \sum_{vs\in A} f(vs) \f]
316 337
\f[ \sum_{uv\in A} f(uv) = \sum_{vu\in A} f(vu)
317 338
    \quad \forall u\in V\setminus\{s,t\} \f]
318 339
\f[ 0 \leq f(uv) \leq cap(uv) \quad \forall uv\in A \f]
319 340

	
320 341
LEMON contains several algorithms for solving maximum flow problems:
321 342
- \ref EdmondsKarp Edmonds-Karp algorithm.
322 343
- \ref Preflow Goldberg-Tarjan's preflow push-relabel algorithm.
323 344
- \ref DinitzSleatorTarjan Dinitz's blocking flow algorithm with dynamic trees.
324 345
- \ref GoldbergTarjan Preflow push-relabel algorithm with dynamic trees.
325 346

	
326 347
In most cases the \ref Preflow "Preflow" algorithm provides the
327 348
fastest method for computing a maximum flow. All implementations
328 349
also provide functions to query the minimum cut, which is the dual
329 350
problem of maximum flow.
330 351

	
331 352
\ref Circulation is a preflow push-relabel algorithm implemented directly 
332 353
for finding feasible circulations, which is a somewhat different problem,
333 354
but it is strongly related to maximum flow.
334 355
For more information, see \ref Circulation.
335 356
*/
336 357

	
337 358
/**
338 359
@defgroup min_cost_flow_algs Minimum Cost Flow Algorithms
339 360
@ingroup algs
340 361

	
341 362
\brief Algorithms for finding minimum cost flows and circulations.
342 363

	
343 364
This group contains the algorithms for finding minimum cost flows and
344 365
circulations. For more information about this problem and its dual
345 366
solution see \ref min_cost_flow "Minimum Cost Flow Problem".
346 367

	
347 368
LEMON contains several algorithms for this problem.
348 369
 - \ref NetworkSimplex Primal Network Simplex algorithm with various
349 370
   pivot strategies.
350 371
 - \ref CostScaling Push-Relabel and Augment-Relabel algorithms based on
351 372
   cost scaling.
352 373
 - \ref CapacityScaling Successive Shortest %Path algorithm with optional
353 374
   capacity scaling.
354 375
 - \ref CancelAndTighten The Cancel and Tighten algorithm.
355 376
 - \ref CycleCanceling Cycle-Canceling algorithms.
356 377

	
357 378
In general NetworkSimplex is the most efficient implementation,
358 379
but in special cases other algorithms could be faster.
359 380
For example, if the total supply and/or capacities are rather small,
360 381
CapacityScaling is usually the fastest algorithm (without effective scaling).
361 382
*/
362 383

	
363 384
/**
364 385
@defgroup min_cut Minimum Cut Algorithms
365 386
@ingroup algs
366 387

	
367 388
\brief Algorithms for finding minimum cut in graphs.
368 389

	
369 390
This group contains the algorithms for finding minimum cut in graphs.
370 391

	
371 392
The \e minimum \e cut \e problem is to find a non-empty and non-complete
372 393
\f$X\f$ subset of the nodes with minimum overall capacity on
373 394
outgoing arcs. Formally, there is a \f$G=(V,A)\f$ digraph, a
374 395
\f$cap: A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
375 396
cut is the \f$X\f$ solution of the next optimization problem:
376 397

	
377 398
\f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}
378 399
    \sum_{uv\in A, u\in X, v\not\in X}cap(uv) \f]
379 400

	
380 401
LEMON contains several algorithms related to minimum cut problems:
381 402

	
382 403
- \ref HaoOrlin "Hao-Orlin algorithm" for calculating minimum cut
383 404
  in directed graphs.
384 405
- \ref NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
385 406
  calculating minimum cut in undirected graphs.
386 407
- \ref GomoryHu "Gomory-Hu tree computation" for calculating
387 408
  all-pairs minimum cut in undirected graphs.
388 409

	
389 410
If you want to find minimum cut just between two distinict nodes,
390 411
see the \ref max_flow "maximum flow problem".
391 412
*/
392 413

	
393 414
/**
394 415
@defgroup graph_properties Connectivity and Other Graph Properties
395 416
@ingroup algs
396 417
\brief Algorithms for discovering the graph properties
397 418

	
398 419
This group contains the algorithms for discovering the graph properties
399 420
like connectivity, bipartiteness, euler property, simplicity etc.
400 421

	
401 422
\image html edge_biconnected_components.png
402 423
\image latex edge_biconnected_components.eps "bi-edge-connected components" width=\textwidth
403 424
*/
404 425

	
405 426
/**
406 427
@defgroup planar Planarity Embedding and Drawing
407 428
@ingroup algs
408 429
\brief Algorithms for planarity checking, embedding and drawing
409 430

	
410 431
This group contains the algorithms for planarity checking,
411 432
embedding and drawing.
412 433

	
413 434
\image html planar.png
414 435
\image latex planar.eps "Plane graph" width=\textwidth
415 436
*/
416 437

	
417 438
/**
418 439
@defgroup matching Matching Algorithms
419 440
@ingroup algs
420 441
\brief Algorithms for finding matchings in graphs and bipartite graphs.
421 442

	
422 443
This group contains the algorithms for calculating
423 444
matchings in graphs and bipartite graphs. The general matching problem is
424 445
finding a subset of the edges for which each node has at most one incident
425 446
edge.
426 447

	
427 448
There are several different algorithms for calculate matchings in
428 449
graphs.  The matching problems in bipartite graphs are generally
429 450
easier than in general graphs. The goal of the matching optimization
430 451
can be finding maximum cardinality, maximum weight or minimum cost
431 452
matching. The search can be constrained to find perfect or
432 453
maximum cardinality matching.
433 454

	
434 455
The matching algorithms implemented in LEMON:
435 456
- \ref MaxBipartiteMatching Hopcroft-Karp augmenting path algorithm
436 457
  for calculating maximum cardinality matching in bipartite graphs.
437 458
- \ref PrBipartiteMatching Push-relabel algorithm
438 459
  for calculating maximum cardinality matching in bipartite graphs.
439 460
- \ref MaxWeightedBipartiteMatching
440 461
  Successive shortest path algorithm for calculating maximum weighted
441 462
  matching and maximum weighted bipartite matching in bipartite graphs.
Ignore white space 384 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_BIN_HEAP_H
20 20
#define LEMON_BIN_HEAP_H
21 21

	
22
///\ingroup auxdat
22
///\ingroup heaps
23 23
///\file
24 24
///\brief Binary heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <utility>
28 28
#include <functional>
29 29

	
30 30
namespace lemon {
31 31

	
32
  /// \ingroup auxdat
32
  /// \ingroup heaps
33 33
  ///
34 34
  /// \brief Binary heap data structure.
35 35
  ///
36 36
  /// This class implements the \e binary \e heap data structure.
37 37
  /// It fully conforms to the \ref concepts::Heap "heap concept".
38 38
  ///
39 39
  /// \tparam PR Type of the priorities of the items.
40 40
  /// \tparam IM A read-writable item map with \c int values, used
41 41
  /// internally to handle the cross references.
42 42
  /// \tparam CMP A functor class for comparing the priorities.
43 43
  /// The default is \c std::less<PR>.
44 44
#ifdef DOXYGEN
45 45
  template <typename PR, typename IM, typename CMP>
46 46
#else
47 47
  template <typename PR, typename IM, typename CMP = std::less<PR> >
48 48
#endif
49 49
  class BinHeap {
50 50
  public:
51 51

	
52 52
    /// Type of the item-int map.
53 53
    typedef IM ItemIntMap;
54 54
    /// Type of the priorities.
55 55
    typedef PR Prio;
56 56
    /// Type of the items stored in the heap.
57 57
    typedef typename ItemIntMap::Key Item;
58 58
    /// Type of the item-priority pairs.
59 59
    typedef std::pair<Item,Prio> Pair;
60 60
    /// Functor type for comparing the priorities.
61 61
    typedef CMP Compare;
62 62

	
63 63
    /// \brief Type to represent the states of the items.
64 64
    ///
65 65
    /// Each item has a state associated to it. It can be "in heap",
66 66
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
67 67
    /// heap's point of view, but may be useful to the user.
68 68
    ///
69 69
    /// The item-int map must be initialized in such way that it assigns
70 70
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
71 71
    enum State {
72 72
      IN_HEAP = 0,    ///< = 0.
73 73
      PRE_HEAP = -1,  ///< = -1.
74 74
      POST_HEAP = -2  ///< = -2.
75 75
    };
76 76

	
77 77
  private:
78 78
    std::vector<Pair> _data;
79 79
    Compare _comp;
80 80
    ItemIntMap &_iim;
81 81

	
82 82
  public:
83 83

	
84 84
    /// \brief Constructor.
85 85
    ///
86 86
    /// Constructor.
87 87
    /// \param map A map that assigns \c int values to the items.
88 88
    /// It is used internally to handle the cross references.
89 89
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
90 90
    explicit BinHeap(ItemIntMap &map) : _iim(map) {}
91 91

	
92 92
    /// \brief Constructor.
93 93
    ///
94 94
    /// Constructor.
95 95
    /// \param map A map that assigns \c int values to the items.
96 96
    /// It is used internally to handle the cross references.
97 97
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
98 98
    /// \param comp The function object used for comparing the priorities.
99 99
    BinHeap(ItemIntMap &map, const Compare &comp)
100 100
      : _iim(map), _comp(comp) {}
101 101

	
102 102

	
103 103
    /// \brief The number of items stored in the heap.
104 104
    ///
105 105
    /// This function returns the number of items stored in the heap.
106 106
    int size() const { return _data.size(); }
107 107

	
108 108
    /// \brief Check if the heap is empty.
109 109
    ///
110 110
    /// This function returns \c true if the heap is empty.
111 111
    bool empty() const { return _data.empty(); }
112 112

	
113 113
    /// \brief Make the heap empty.
114 114
    ///
115 115
    /// This functon makes the heap empty.
116 116
    /// It does not change the cross reference map. If you want to reuse
117 117
    /// a heap that is not surely empty, you should first clear it and
118 118
    /// then you should set the cross reference map to \c PRE_HEAP
119 119
    /// for each item.
120 120
    void clear() {
121 121
      _data.clear();
122 122
    }
123 123

	
124 124
  private:
125 125
    static int parent(int i) { return (i-1)/2; }
126 126

	
127 127
    static int second_child(int i) { return 2*i+2; }
128 128
    bool less(const Pair &p1, const Pair &p2) const {
129 129
      return _comp(p1.second, p2.second);
130 130
    }
131 131

	
132 132
    int bubble_up(int hole, Pair p) {
133 133
      int par = parent(hole);
134 134
      while( hole>0 && less(p,_data[par]) ) {
135 135
        move(_data[par],hole);
136 136
        hole = par;
137 137
        par = parent(hole);
138 138
      }
139 139
      move(p, hole);
140 140
      return hole;
141 141
    }
142 142

	
143 143
    int bubble_down(int hole, Pair p, int length) {
144 144
      int child = second_child(hole);
145 145
      while(child < length) {
146 146
        if( less(_data[child-1], _data[child]) ) {
147 147
          --child;
148 148
        }
149 149
        if( !less(_data[child], p) )
150 150
          goto ok;
151 151
        move(_data[child], hole);
152 152
        hole = child;
153 153
        child = second_child(hole);
154 154
      }
155 155
      child--;
156 156
      if( child<length && less(_data[child], p) ) {
157 157
        move(_data[child], hole);
158 158
        hole=child;
159 159
      }
160 160
    ok:
161 161
      move(p, hole);
162 162
      return hole;
163 163
    }
164 164

	
165 165
    void move(const Pair &p, int i) {
166 166
      _data[i] = p;
167 167
      _iim.set(p.first, i);
168 168
    }
169 169

	
170 170
  public:
171 171

	
172 172
    /// \brief Insert a pair of item and priority into the heap.
173 173
    ///
174 174
    /// This function inserts \c p.first to the heap with priority
175 175
    /// \c p.second.
176 176
    /// \param p The pair to insert.
177 177
    /// \pre \c p.first must not be stored in the heap.
178 178
    void push(const Pair &p) {
179 179
      int n = _data.size();
180 180
      _data.resize(n+1);
181 181
      bubble_up(n, p);
182 182
    }
183 183

	
184 184
    /// \brief Insert an item into the heap with the given priority.
185 185
    ///
186 186
    /// This function inserts the given item into the heap with the
187 187
    /// given priority.
188 188
    /// \param i The item to insert.
189 189
    /// \param p The priority of the item.
190 190
    /// \pre \e i must not be stored in the heap.
191 191
    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
192 192

	
193 193
    /// \brief Return the item having minimum priority.
194 194
    ///
195 195
    /// This function returns the item having minimum priority.
196 196
    /// \pre The heap must be non-empty.
197 197
    Item top() const {
198 198
      return _data[0].first;
199 199
    }
200 200

	
201 201
    /// \brief The minimum priority.
202 202
    ///
203 203
    /// This function returns the minimum priority.
204 204
    /// \pre The heap must be non-empty.
205 205
    Prio prio() const {
206 206
      return _data[0].second;
207 207
    }
208 208

	
209 209
    /// \brief Remove the item having minimum priority.
210 210
    ///
211 211
    /// This function removes the item having minimum priority.
212 212
    /// \pre The heap must be non-empty.
213 213
    void pop() {
214 214
      int n = _data.size()-1;
215 215
      _iim.set(_data[0].first, POST_HEAP);
216 216
      if (n > 0) {
217 217
        bubble_down(0, _data[n], n);
218 218
      }
219 219
      _data.pop_back();
220 220
    }
221 221

	
222 222
    /// \brief Remove the given item from the heap.
223 223
    ///
224 224
    /// This function removes the given item from the heap if it is
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_BUCKET_HEAP_H
20 20
#define LEMON_BUCKET_HEAP_H
21 21

	
22
///\ingroup auxdat
22
///\ingroup heaps
23 23
///\file
24 24
///\brief Bucket heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <utility>
28 28
#include <functional>
29 29

	
30 30
namespace lemon {
31 31

	
32 32
  namespace _bucket_heap_bits {
33 33

	
34 34
    template <bool MIN>
35 35
    struct DirectionTraits {
36 36
      static bool less(int left, int right) {
37 37
        return left < right;
38 38
      }
39 39
      static void increase(int& value) {
40 40
        ++value;
41 41
      }
42 42
    };
43 43

	
44 44
    template <>
45 45
    struct DirectionTraits<false> {
46 46
      static bool less(int left, int right) {
47 47
        return left > right;
48 48
      }
49 49
      static void increase(int& value) {
50 50
        --value;
51 51
      }
52 52
    };
53 53

	
54 54
  }
55 55

	
56
  /// \ingroup auxdat
56
  /// \ingroup heaps
57 57
  ///
58 58
  /// \brief Bucket heap data structure.
59 59
  ///
60 60
  /// This class implements the \e bucket \e heap data structure.
61 61
  /// It practically conforms to the \ref concepts::Heap "heap concept",
62 62
  /// but it has some limitations.
63 63
  ///
64 64
  /// The bucket heap is a very simple structure. It can store only
65 65
  /// \c int priorities and it maintains a list of items for each priority
66 66
  /// in the range <tt>[0..C)</tt>. So it should only be used when the
67 67
  /// priorities are small. It is not intended to use as a Dijkstra heap.
68 68
  ///
69 69
  /// \tparam IM A read-writable item map with \c int values, used
70 70
  /// internally to handle the cross references.
71 71
  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
72 72
  /// The default is \e min-heap. If this parameter is set to \c false,
73 73
  /// then the comparison is reversed, so the top(), prio() and pop()
74 74
  /// functions deal with the item having maximum priority instead of the
75 75
  /// minimum.
76 76
  ///
77 77
  /// \sa SimpleBucketHeap
78 78
  template <typename IM, bool MIN = true>
79 79
  class BucketHeap {
80 80

	
81 81
  public:
82 82

	
83 83
    /// Type of the item-int map.
84 84
    typedef IM ItemIntMap;
85 85
    /// Type of the priorities.
86 86
    typedef int Prio;
87 87
    /// Type of the items stored in the heap.
88 88
    typedef typename ItemIntMap::Key Item;
89 89
    /// Type of the item-priority pairs.
90 90
    typedef std::pair<Item,Prio> Pair;
91 91

	
92 92
  private:
93 93

	
94 94
    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
95 95

	
96 96
  public:
97 97

	
98 98
    /// \brief Type to represent the states of the items.
99 99
    ///
100 100
    /// Each item has a state associated to it. It can be "in heap",
101 101
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
102 102
    /// heap's point of view, but may be useful to the user.
103 103
    ///
104 104
    /// The item-int map must be initialized in such way that it assigns
105 105
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
106 106
    enum State {
107 107
      IN_HEAP = 0,    ///< = 0.
108 108
      PRE_HEAP = -1,  ///< = -1.
109 109
      POST_HEAP = -2  ///< = -2.
110 110
    };
111 111

	
112 112
  public:
113 113

	
114 114
    /// \brief Constructor.
115 115
    ///
116 116
    /// Constructor.
117 117
    /// \param map A map that assigns \c int values to the items.
118 118
    /// It is used internally to handle the cross references.
119 119
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
120 120
    explicit BucketHeap(ItemIntMap &map) : _iim(map), _minimum(0) {}
121 121

	
122 122
    /// \brief The number of items stored in the heap.
123 123
    ///
124 124
    /// This function returns the number of items stored in the heap.
125 125
    int size() const { return _data.size(); }
126 126

	
127 127
    /// \brief Check if the heap is empty.
128 128
    ///
129 129
    /// This function returns \c true if the heap is empty.
130 130
    bool empty() const { return _data.empty(); }
131 131

	
132 132
    /// \brief Make the heap empty.
133 133
    ///
134 134
    /// This functon makes the heap empty.
135 135
    /// It does not change the cross reference map. If you want to reuse
136 136
    /// a heap that is not surely empty, you should first clear it and
137 137
    /// then you should set the cross reference map to \c PRE_HEAP
138 138
    /// for each item.
139 139
    void clear() {
140 140
      _data.clear(); _first.clear(); _minimum = 0;
141 141
    }
142 142

	
143 143
  private:
144 144

	
145 145
    void relocate_last(int idx) {
146 146
      if (idx + 1 < int(_data.size())) {
147 147
        _data[idx] = _data.back();
148 148
        if (_data[idx].prev != -1) {
149 149
          _data[_data[idx].prev].next = idx;
150 150
        } else {
151 151
          _first[_data[idx].value] = idx;
152 152
        }
153 153
        if (_data[idx].next != -1) {
154 154
          _data[_data[idx].next].prev = idx;
155 155
        }
156 156
        _iim[_data[idx].item] = idx;
157 157
      }
158 158
      _data.pop_back();
159 159
    }
160 160

	
161 161
    void unlace(int idx) {
162 162
      if (_data[idx].prev != -1) {
163 163
        _data[_data[idx].prev].next = _data[idx].next;
164 164
      } else {
165 165
        _first[_data[idx].value] = _data[idx].next;
166 166
      }
167 167
      if (_data[idx].next != -1) {
168 168
        _data[_data[idx].next].prev = _data[idx].prev;
169 169
      }
170 170
    }
171 171

	
172 172
    void lace(int idx) {
173 173
      if (int(_first.size()) <= _data[idx].value) {
174 174
        _first.resize(_data[idx].value + 1, -1);
175 175
      }
176 176
      _data[idx].next = _first[_data[idx].value];
177 177
      if (_data[idx].next != -1) {
178 178
        _data[_data[idx].next].prev = idx;
179 179
      }
180 180
      _first[_data[idx].value] = idx;
181 181
      _data[idx].prev = -1;
182 182
    }
183 183

	
184 184
  public:
185 185

	
186 186
    /// \brief Insert a pair of item and priority into the heap.
187 187
    ///
188 188
    /// This function inserts \c p.first to the heap with priority
189 189
    /// \c p.second.
190 190
    /// \param p The pair to insert.
191 191
    /// \pre \c p.first must not be stored in the heap.
192 192
    void push(const Pair& p) {
193 193
      push(p.first, p.second);
194 194
    }
195 195

	
196 196
    /// \brief Insert an item into the heap with the given priority.
197 197
    ///
198 198
    /// This function inserts the given item into the heap with the
199 199
    /// given priority.
200 200
    /// \param i The item to insert.
201 201
    /// \param p The priority of the item.
202 202
    /// \pre \e i must not be stored in the heap.
203 203
    void push(const Item &i, const Prio &p) {
204 204
      int idx = _data.size();
205 205
      _iim[i] = idx;
206 206
      _data.push_back(BucketItem(i, p));
207 207
      lace(idx);
208 208
      if (Direction::less(p, _minimum)) {
209 209
        _minimum = p;
210 210
      }
211 211
    }
212 212

	
213 213
    /// \brief Return the item having minimum priority.
214 214
    ///
215 215
    /// This function returns the item having minimum priority.
216 216
    /// \pre The heap must be non-empty.
217 217
    Item top() const {
218 218
      while (_first[_minimum] == -1) {
219 219
        Direction::increase(_minimum);
220 220
      }
221 221
      return _data[_first[_minimum]].item;
222 222
    }
223 223

	
224 224
    /// \brief The minimum priority.
225 225
    ///
226 226
    /// This function returns the minimum priority.
227 227
    /// \pre The heap must be non-empty.
228 228
    Prio prio() const {
229 229
      while (_first[_minimum] == -1) {
230 230
        Direction::increase(_minimum);
231 231
      }
232 232
      return _minimum;
233 233
    }
234 234

	
235 235
    /// \brief Remove the item having minimum priority.
236 236
    ///
237 237
    /// This function removes the item having minimum priority.
238 238
    /// \pre The heap must be non-empty.
239 239
    void pop() {
240 240
      while (_first[_minimum] == -1) {
241 241
        Direction::increase(_minimum);
242 242
      }
243 243
      int idx = _first[_minimum];
244 244
      _iim[_data[idx].item] = -2;
245 245
      unlace(idx);
246 246
      relocate_last(idx);
247 247
    }
248 248

	
249 249
    /// \brief Remove the given item from the heap.
250 250
    ///
251 251
    /// This function removes the given item from the heap if it is
252 252
    /// already stored.
253 253
    /// \param i The item to delete.
254 254
    /// \pre \e i must be in the heap.
255 255
    void erase(const Item &i) {
256 256
      int idx = _iim[i];
257 257
      _iim[_data[idx].item] = -2;
258 258
      unlace(idx);
259 259
      relocate_last(idx);
260 260
    }
261 261

	
262 262
    /// \brief The priority of the given item.
263 263
    ///
264 264
    /// This function returns the priority of the given item.
265 265
    /// \param i The item.
266 266
    /// \pre \e i must be in the heap.
267 267
    Prio operator[](const Item &i) const {
268 268
      int idx = _iim[i];
269 269
      return _data[idx].value;
270 270
    }
271 271

	
272 272
    /// \brief Set the priority of an item or insert it, if it is
273 273
    /// not stored in the heap.
274 274
    ///
275 275
    /// This method sets the priority of the given item if it is
276 276
    /// already stored in the heap. Otherwise it inserts the given
277 277
    /// item into the heap with the given priority.
278 278
    /// \param i The item.
279 279
    /// \param p The priority.
280 280
    void set(const Item &i, const Prio &p) {
281 281
      int idx = _iim[i];
282 282
      if (idx < 0) {
283 283
        push(i, p);
284 284
      } else if (Direction::less(p, _data[idx].value)) {
285 285
        decrease(i, p);
286 286
      } else {
287 287
        increase(i, p);
288 288
      }
289 289
    }
290 290

	
291 291
    /// \brief Decrease the priority of an item to the given value.
292 292
    ///
293 293
    /// This function decreases the priority of an item to the given value.
294 294
    /// \param i The item.
295 295
    /// \param p The priority.
296 296
    /// \pre \e i must be stored in the heap with priority at least \e p.
297 297
    void decrease(const Item &i, const Prio &p) {
298 298
      int idx = _iim[i];
299 299
      unlace(idx);
300 300
      _data[idx].value = p;
301 301
      if (Direction::less(p, _minimum)) {
302 302
        _minimum = p;
303 303
      }
304 304
      lace(idx);
305 305
    }
306 306

	
307 307
    /// \brief Increase the priority of an item to the given value.
308 308
    ///
309 309
    /// This function increases the priority of an item to the given value.
310 310
    /// \param i The item.
311 311
    /// \param p The priority.
312 312
    /// \pre \e i must be stored in the heap with priority at most \e p.
313 313
    void increase(const Item &i, const Prio &p) {
314 314
      int idx = _iim[i];
315 315
      unlace(idx);
316 316
      _data[idx].value = p;
317 317
      lace(idx);
318 318
    }
319 319

	
320 320
    /// \brief Return the state of an item.
321 321
    ///
322 322
    /// This method returns \c PRE_HEAP if the given item has never
323 323
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
324 324
    /// and \c POST_HEAP otherwise.
325 325
    /// In the latter case it is possible that the item will get back
326 326
    /// to the heap again.
327 327
    /// \param i The item.
328 328
    State state(const Item &i) const {
329 329
      int idx = _iim[i];
330 330
      if (idx >= 0) idx = 0;
331 331
      return State(idx);
332 332
    }
333 333

	
334 334
    /// \brief Set the state of an item in the heap.
335 335
    ///
336 336
    /// This function sets the state of the given item in the heap.
337 337
    /// It can be used to manually clear the heap when it is important
338 338
    /// to achive better time complexity.
339 339
    /// \param i The item.
340 340
    /// \param st The state. It should not be \c IN_HEAP.
341 341
    void state(const Item& i, State st) {
342 342
      switch (st) {
343 343
      case POST_HEAP:
344 344
      case PRE_HEAP:
345 345
        if (state(i) == IN_HEAP) {
346 346
          erase(i);
347 347
        }
348 348
        _iim[i] = st;
349 349
        break;
350 350
      case IN_HEAP:
351 351
        break;
352 352
      }
353 353
    }
354 354

	
355 355
  private:
356 356

	
357 357
    struct BucketItem {
358 358
      BucketItem(const Item& _item, int _value)
359 359
        : item(_item), value(_value) {}
360 360

	
361 361
      Item item;
362 362
      int value;
363 363

	
364 364
      int prev, next;
365 365
    };
366 366

	
367 367
    ItemIntMap& _iim;
368 368
    std::vector<int> _first;
369 369
    std::vector<BucketItem> _data;
370 370
    mutable int _minimum;
371 371

	
372 372
  }; // class BucketHeap
373 373

	
374
  /// \ingroup auxdat
374
  /// \ingroup heaps
375 375
  ///
376 376
  /// \brief Simplified bucket heap data structure.
377 377
  ///
378 378
  /// This class implements a simplified \e bucket \e heap data
379 379
  /// structure. It does not provide some functionality, but it is
380 380
  /// faster and simpler than BucketHeap. The main difference is
381 381
  /// that BucketHeap stores a doubly-linked list for each key while
382 382
  /// this class stores only simply-linked lists. It supports erasing
383 383
  /// only for the item having minimum priority and it does not support
384 384
  /// key increasing and decreasing.
385 385
  ///
386 386
  /// Note that this implementation does not conform to the
387 387
  /// \ref concepts::Heap "heap concept" due to the lack of some 
388 388
  /// functionality.
389 389
  ///
390 390
  /// \tparam IM A read-writable item map with \c int values, used
391 391
  /// internally to handle the cross references.
392 392
  /// \tparam MIN Indicate if the heap is a \e min-heap or a \e max-heap.
393 393
  /// The default is \e min-heap. If this parameter is set to \c false,
394 394
  /// then the comparison is reversed, so the top(), prio() and pop()
395 395
  /// functions deal with the item having maximum priority instead of the
396 396
  /// minimum.
397 397
  ///
398 398
  /// \sa BucketHeap
399 399
  template <typename IM, bool MIN = true >
400 400
  class SimpleBucketHeap {
401 401

	
402 402
  public:
403 403

	
404 404
    /// Type of the item-int map.
405 405
    typedef IM ItemIntMap;
406 406
    /// Type of the priorities.
407 407
    typedef int Prio;
408 408
    /// Type of the items stored in the heap.
409 409
    typedef typename ItemIntMap::Key Item;
410 410
    /// Type of the item-priority pairs.
411 411
    typedef std::pair<Item,Prio> Pair;
412 412

	
413 413
  private:
414 414

	
415 415
    typedef _bucket_heap_bits::DirectionTraits<MIN> Direction;
416 416

	
417 417
  public:
418 418

	
419 419
    /// \brief Type to represent the states of the items.
420 420
    ///
421 421
    /// Each item has a state associated to it. It can be "in heap",
422 422
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
423 423
    /// heap's point of view, but may be useful to the user.
424 424
    ///
425 425
    /// The item-int map must be initialized in such way that it assigns
426 426
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
427 427
    enum State {
428 428
      IN_HEAP = 0,    ///< = 0.
429 429
      PRE_HEAP = -1,  ///< = -1.
430 430
      POST_HEAP = -2  ///< = -2.
431 431
    };
432 432

	
433 433
  public:
434 434

	
435 435
    /// \brief Constructor.
436 436
    ///
437 437
    /// Constructor.
438 438
    /// \param map A map that assigns \c int values to the items.
439 439
    /// It is used internally to handle the cross references.
440 440
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
441 441
    explicit SimpleBucketHeap(ItemIntMap &map)
442 442
      : _iim(map), _free(-1), _num(0), _minimum(0) {}
443 443

	
444 444
    /// \brief The number of items stored in the heap.
445 445
    ///
446 446
    /// This function returns the number of items stored in the heap.
447 447
    int size() const { return _num; }
448 448

	
449 449
    /// \brief Check if the heap is empty.
450 450
    ///
451 451
    /// This function returns \c true if the heap is empty.
452 452
    bool empty() const { return _num == 0; }
453 453

	
454 454
    /// \brief Make the heap empty.
455 455
    ///
456 456
    /// This functon makes the heap empty.
457 457
    /// It does not change the cross reference map. If you want to reuse
458 458
    /// a heap that is not surely empty, you should first clear it and
459 459
    /// then you should set the cross reference map to \c PRE_HEAP
460 460
    /// for each item.
461 461
    void clear() {
462 462
      _data.clear(); _first.clear(); _free = -1; _num = 0; _minimum = 0;
463 463
    }
464 464

	
465 465
    /// \brief Insert a pair of item and priority into the heap.
466 466
    ///
467 467
    /// This function inserts \c p.first to the heap with priority
468 468
    /// \c p.second.
469 469
    /// \param p The pair to insert.
470 470
    /// \pre \c p.first must not be stored in the heap.
471 471
    void push(const Pair& p) {
472 472
      push(p.first, p.second);
473 473
    }
474 474

	
475 475
    /// \brief Insert an item into the heap with the given priority.
476 476
    ///
477 477
    /// This function inserts the given item into the heap with the
478 478
    /// given priority.
479 479
    /// \param i The item to insert.
480 480
    /// \param p The priority of the item.
481 481
    /// \pre \e i must not be stored in the heap.
482 482
    void push(const Item &i, const Prio &p) {
483 483
      int idx;
484 484
      if (_free == -1) {
485 485
        idx = _data.size();
486 486
        _data.push_back(BucketItem(i));
487 487
      } else {
488 488
        idx = _free;
489 489
        _free = _data[idx].next;
490 490
        _data[idx].item = i;
491 491
      }
492 492
      _iim[i] = idx;
493 493
      if (p >= int(_first.size())) _first.resize(p + 1, -1);
494 494
      _data[idx].next = _first[p];
495 495
      _first[p] = idx;
496 496
      if (Direction::less(p, _minimum)) {
497 497
        _minimum = p;
498 498
      }
499 499
      ++_num;
500 500
    }
501 501

	
502 502
    /// \brief Return the item having minimum priority.
503 503
    ///
504 504
    /// This function returns the item having minimum priority.
505 505
    /// \pre The heap must be non-empty.
506 506
    Item top() const {
507 507
      while (_first[_minimum] == -1) {
508 508
        Direction::increase(_minimum);
509 509
      }
510 510
      return _data[_first[_minimum]].item;
511 511
    }
512 512

	
513 513
    /// \brief The minimum priority.
514 514
    ///
515 515
    /// This function returns the minimum priority.
516 516
    /// \pre The heap must be non-empty.
517 517
    Prio prio() const {
518 518
      while (_first[_minimum] == -1) {
519 519
        Direction::increase(_minimum);
520 520
      }
521 521
      return _minimum;
522 522
    }
523 523

	
524 524
    /// \brief Remove the item having minimum priority.
525 525
    ///
526 526
    /// This function removes the item having minimum priority.
527 527
    /// \pre The heap must be non-empty.
528 528
    void pop() {
529 529
      while (_first[_minimum] == -1) {
530 530
        Direction::increase(_minimum);
531 531
      }
532 532
      int idx = _first[_minimum];
533 533
      _iim[_data[idx].item] = -2;
534 534
      _first[_minimum] = _data[idx].next;
535 535
      _data[idx].next = _free;
536 536
      _free = idx;
537 537
      --_num;
538 538
    }
539 539

	
540 540
    /// \brief The priority of the given item.
541 541
    ///
542 542
    /// This function returns the priority of the given item.
543 543
    /// \param i The item.
544 544
    /// \pre \e i must be in the heap.
545 545
    /// \warning This operator is not a constant time function because
546 546
    /// it scans the whole data structure to find the proper value.
547 547
    Prio operator[](const Item &i) const {
548 548
      for (int k = 0; k < int(_first.size()); ++k) {
549 549
        int idx = _first[k];
550 550
        while (idx != -1) {
551 551
          if (_data[idx].item == i) {
552 552
            return k;
553 553
          }
554 554
          idx = _data[idx].next;
555 555
        }
556 556
      }
557 557
      return -1;
558 558
    }
559 559

	
560 560
    /// \brief Return the state of an item.
561 561
    ///
562 562
    /// This method returns \c PRE_HEAP if the given item has never
563 563
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
564 564
    /// and \c POST_HEAP otherwise.
565 565
    /// In the latter case it is possible that the item will get back
566 566
    /// to the heap again.
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_CONCEPTS_HEAP_H
20 20
#define LEMON_CONCEPTS_HEAP_H
21 21

	
22 22
///\ingroup concept
23 23
///\file
24 24
///\brief The concept of heaps.
25 25

	
26 26
#include <lemon/core.h>
27 27
#include <lemon/concept_check.h>
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  namespace concepts {
32 32

	
33 33
    /// \addtogroup concept
34 34
    /// @{
35 35

	
36 36
    /// \brief The heap concept.
37 37
    ///
38 38
    /// This concept class describes the main interface of heaps.
39
    /// The various heap structures are efficient
39
    /// The various \ref heaps "heap structures" are efficient
40 40
    /// implementations of the abstract data type \e priority \e queue.
41 41
    /// They store items with specified values called \e priorities
42 42
    /// in such a way that finding and removing the item with minimum
43 43
    /// priority are efficient. The basic operations are adding and
44 44
    /// erasing items, changing the priority of an item, etc.
45 45
    ///
46 46
    /// Heaps are crucial in several algorithms, such as Dijkstra and Prim.
47 47
    /// Any class that conforms to this concept can be used easily in such
48 48
    /// algorithms.
49 49
    ///
50 50
    /// \tparam PR Type of the priorities of the items.
51 51
    /// \tparam IM A read-writable item map with \c int values, used
52 52
    /// internally to handle the cross references.
53 53
    /// \tparam CMP A functor class for comparing the priorities.
54 54
    /// The default is \c std::less<PR>.
55 55
#ifdef DOXYGEN
56 56
    template <typename PR, typename IM, typename CMP>
57 57
#else
58 58
    template <typename PR, typename IM, typename CMP = std::less<PR> >
59 59
#endif
60 60
    class Heap {
61 61
    public:
62 62

	
63 63
      /// Type of the item-int map.
64 64
      typedef IM ItemIntMap;
65 65
      /// Type of the priorities.
66 66
      typedef PR Prio;
67 67
      /// Type of the items stored in the heap.
68 68
      typedef typename ItemIntMap::Key Item;
69 69

	
70 70
      /// \brief Type to represent the states of the items.
71 71
      ///
72 72
      /// Each item has a state associated to it. It can be "in heap",
73 73
      /// "pre-heap" or "post-heap". The latter two are indifferent from the
74 74
      /// heap's point of view, but may be useful to the user.
75 75
      ///
76 76
      /// The item-int map must be initialized in such way that it assigns
77 77
      /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
78 78
      enum State {
79 79
        IN_HEAP = 0,    ///< = 0. The "in heap" state constant.
80 80
        PRE_HEAP = -1,  ///< = -1. The "pre-heap" state constant.
81 81
        POST_HEAP = -2  ///< = -2. The "post-heap" state constant.
82 82
      };
83 83

	
84 84
      /// \brief Constructor.
85 85
      ///
86 86
      /// Constructor.
87 87
      /// \param map A map that assigns \c int values to keys of type
88 88
      /// \c Item. It is used internally by the heap implementations to
89 89
      /// handle the cross references. The assigned value must be
90 90
      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
91 91
      explicit Heap(ItemIntMap &map) {}
92 92

	
93 93
      /// \brief Constructor.
94 94
      ///
95 95
      /// Constructor.
96 96
      /// \param map A map that assigns \c int values to keys of type
97 97
      /// \c Item. It is used internally by the heap implementations to
98 98
      /// handle the cross references. The assigned value must be
99 99
      /// \c PRE_HEAP (<tt>-1</tt>) for each item.
100 100
      /// \param comp The function object used for comparing the priorities.
101 101
      explicit Heap(ItemIntMap &map, const CMP &comp) {}
102 102

	
103 103
      /// \brief The number of items stored in the heap.
104 104
      ///
105 105
      /// This function returns the number of items stored in the heap.
106 106
      int size() const { return 0; }
107 107

	
108 108
      /// \brief Check if the heap is empty.
109 109
      ///
110 110
      /// This function returns \c true if the heap is empty.
111 111
      bool empty() const { return false; }
112 112

	
113 113
      /// \brief Make the heap empty.
114 114
      ///
115 115
      /// This functon makes the heap empty.
116 116
      /// It does not change the cross reference map. If you want to reuse
117 117
      /// a heap that is not surely empty, you should first clear it and
118 118
      /// then you should set the cross reference map to \c PRE_HEAP
119 119
      /// for each item.
120 120
      void clear() {}
121 121

	
122 122
      /// \brief Insert an item into the heap with the given priority.
123 123
      ///
124 124
      /// This function inserts the given item into the heap with the
125 125
      /// given priority.
126 126
      /// \param i The item to insert.
127 127
      /// \param p The priority of the item.
128 128
      /// \pre \e i must not be stored in the heap.
129 129
      void push(const Item &i, const Prio &p) {}
130 130

	
131 131
      /// \brief Return the item having minimum priority.
132 132
      ///
133 133
      /// This function returns the item having minimum priority.
134 134
      /// \pre The heap must be non-empty.
135 135
      Item top() const {}
136 136

	
137 137
      /// \brief The minimum priority.
138 138
      ///
139 139
      /// This function returns the minimum priority.
140 140
      /// \pre The heap must be non-empty.
141 141
      Prio prio() const {}
142 142

	
143 143
      /// \brief Remove the item having minimum priority.
144 144
      ///
145 145
      /// This function removes the item having minimum priority.
146 146
      /// \pre The heap must be non-empty.
147 147
      void pop() {}
148 148

	
149 149
      /// \brief Remove the given item from the heap.
150 150
      ///
151 151
      /// This function removes the given item from the heap if it is
152 152
      /// already stored.
153 153
      /// \param i The item to delete.
154 154
      /// \pre \e i must be in the heap.
155 155
      void erase(const Item &i) {}
156 156

	
157 157
      /// \brief The priority of the given item.
158 158
      ///
159 159
      /// This function returns the priority of the given item.
160 160
      /// \param i The item.
161 161
      /// \pre \e i must be in the heap.
162 162
      Prio operator[](const Item &i) const {}
163 163

	
164 164
      /// \brief Set the priority of an item or insert it, if it is
165 165
      /// not stored in the heap.
166 166
      ///
167 167
      /// This method sets the priority of the given item if it is
168 168
      /// already stored in the heap. Otherwise it inserts the given
169 169
      /// item into the heap with the given priority.
170 170
      ///
171 171
      /// \param i The item.
172 172
      /// \param p The priority.
173 173
      void set(const Item &i, const Prio &p) {}
174 174

	
175 175
      /// \brief Decrease the priority of an item to the given value.
176 176
      ///
177 177
      /// This function decreases the priority of an item to the given value.
178 178
      /// \param i The item.
179 179
      /// \param p The priority.
180 180
      /// \pre \e i must be stored in the heap with priority at least \e p.
181 181
      void decrease(const Item &i, const Prio &p) {}
182 182

	
183 183
      /// \brief Increase the priority of an item to the given value.
184 184
      ///
185 185
      /// This function increases the priority of an item to the given value.
186 186
      /// \param i The item.
187 187
      /// \param p The priority.
188 188
      /// \pre \e i must be stored in the heap with priority at most \e p.
189 189
      void increase(const Item &i, const Prio &p) {}
190 190

	
191 191
      /// \brief Return the state of an item.
192 192
      ///
193 193
      /// This method returns \c PRE_HEAP if the given item has never
194 194
      /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
195 195
      /// and \c POST_HEAP otherwise.
196 196
      /// In the latter case it is possible that the item will get back
197 197
      /// to the heap again.
198 198
      /// \param i The item.
199 199
      State state(const Item &i) const {}
200 200

	
201 201
      /// \brief Set the state of an item in the heap.
202 202
      ///
203 203
      /// This function sets the state of the given item in the heap.
204 204
      /// It can be used to manually clear the heap when it is important
205 205
      /// to achive better time complexity.
206 206
      /// \param i The item.
207 207
      /// \param st The state. It should not be \c IN_HEAP.
208 208
      void state(const Item& i, State st) {}
209 209

	
210 210

	
211 211
      template <typename _Heap>
212 212
      struct Constraints {
213 213
      public:
214 214
        void constraints() {
215 215
          typedef typename _Heap::Item OwnItem;
216 216
          typedef typename _Heap::Prio OwnPrio;
217 217
          typedef typename _Heap::State OwnState;
218 218

	
219 219
          Item item;
220 220
          Prio prio;
221 221
          item=Item();
222 222
          prio=Prio();
223 223
          ignore_unused_variable_warning(item);
224 224
          ignore_unused_variable_warning(prio);
225 225

	
226 226
          OwnItem own_item;
227 227
          OwnPrio own_prio;
228 228
          OwnState own_state;
229 229
          own_item=Item();
230 230
          own_prio=Prio();
231 231
          ignore_unused_variable_warning(own_item);
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_FIB_HEAP_H
20 20
#define LEMON_FIB_HEAP_H
21 21

	
22 22
///\file
23
///\ingroup auxdat
23
///\ingroup heaps
24 24
///\brief Fibonacci heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <utility>
28 28
#include <functional>
29 29
#include <lemon/math.h>
30 30

	
31 31
namespace lemon {
32 32

	
33
  /// \ingroup auxdat
33
  /// \ingroup heaps
34 34
  ///
35 35
  /// \brief Fibonacci heap data structure.
36 36
  ///
37 37
  /// This class implements the \e Fibonacci \e heap data structure.
38 38
  /// It fully conforms to the \ref concepts::Heap "heap concept".
39 39
  ///
40 40
  /// The methods \ref increase() and \ref erase() are not efficient in a
41 41
  /// Fibonacci heap. In case of many calls of these operations, it is
42 42
  /// better to use other heap structure, e.g. \ref BinHeap "binary heap".
43 43
  ///
44 44
  /// \tparam PR Type of the priorities of the items.
45 45
  /// \tparam IM A read-writable item map with \c int values, used
46 46
  /// internally to handle the cross references.
47 47
  /// \tparam CMP A functor class for comparing the priorities.
48 48
  /// The default is \c std::less<PR>.
49 49
#ifdef DOXYGEN
50 50
  template <typename PR, typename IM, typename CMP>
51 51
#else
52 52
  template <typename PR, typename IM, typename CMP = std::less<PR> >
53 53
#endif
54 54
  class FibHeap {
55 55
  public:
56 56

	
57 57
    /// Type of the item-int map.
58 58
    typedef IM ItemIntMap;
59 59
    /// Type of the priorities.
60 60
    typedef PR Prio;
61 61
    /// Type of the items stored in the heap.
62 62
    typedef typename ItemIntMap::Key Item;
63 63
    /// Type of the item-priority pairs.
64 64
    typedef std::pair<Item,Prio> Pair;
65 65
    /// Functor type for comparing the priorities.
66 66
    typedef CMP Compare;
67 67

	
68 68
  private:
69 69
    class Store;
70 70

	
71 71
    std::vector<Store> _data;
72 72
    int _minimum;
73 73
    ItemIntMap &_iim;
74 74
    Compare _comp;
75 75
    int _num;
76 76

	
77 77
  public:
78 78

	
79 79
    /// \brief Type to represent the states of the items.
80 80
    ///
81 81
    /// Each item has a state associated to it. It can be "in heap",
82 82
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
83 83
    /// heap's point of view, but may be useful to the user.
84 84
    ///
85 85
    /// The item-int map must be initialized in such way that it assigns
86 86
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
87 87
    enum State {
88 88
      IN_HEAP = 0,    ///< = 0.
89 89
      PRE_HEAP = -1,  ///< = -1.
90 90
      POST_HEAP = -2  ///< = -2.
91 91
    };
92 92

	
93 93
    /// \brief Constructor.
94 94
    ///
95 95
    /// Constructor.
96 96
    /// \param map A map that assigns \c int values to the items.
97 97
    /// It is used internally to handle the cross references.
98 98
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
99 99
    explicit FibHeap(ItemIntMap &map)
100 100
      : _minimum(0), _iim(map), _num() {}
101 101

	
102 102
    /// \brief Constructor.
103 103
    ///
104 104
    /// Constructor.
105 105
    /// \param map A map that assigns \c int values to the items.
106 106
    /// It is used internally to handle the cross references.
107 107
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
108 108
    /// \param comp The function object used for comparing the priorities.
109 109
    FibHeap(ItemIntMap &map, const Compare &comp)
110 110
      : _minimum(0), _iim(map), _comp(comp), _num() {}
111 111

	
112 112
    /// \brief The number of items stored in the heap.
113 113
    ///
114 114
    /// This function returns the number of items stored in the heap.
115 115
    int size() const { return _num; }
116 116

	
117 117
    /// \brief Check if the heap is empty.
118 118
    ///
119 119
    /// This function returns \c true if the heap is empty.
120 120
    bool empty() const { return _num==0; }
121 121

	
122 122
    /// \brief Make the heap empty.
123 123
    ///
124 124
    /// This functon makes the heap empty.
125 125
    /// It does not change the cross reference map. If you want to reuse
126 126
    /// a heap that is not surely empty, you should first clear it and
127 127
    /// then you should set the cross reference map to \c PRE_HEAP
128 128
    /// for each item.
129 129
    void clear() {
130 130
      _data.clear(); _minimum = 0; _num = 0;
131 131
    }
132 132

	
133 133
    /// \brief Insert an item into the heap with the given priority.
134 134
    ///
135 135
    /// This function inserts the given item into the heap with the
136 136
    /// given priority.
137 137
    /// \param item The item to insert.
138 138
    /// \param prio The priority of the item.
139 139
    /// \pre \e item must not be stored in the heap.
140 140
    void push (const Item& item, const Prio& prio) {
141 141
      int i=_iim[item];
142 142
      if ( i < 0 ) {
143 143
        int s=_data.size();
144 144
        _iim.set( item, s );
145 145
        Store st;
146 146
        st.name=item;
147 147
        _data.push_back(st);
148 148
        i=s;
149 149
      } else {
150 150
        _data[i].parent=_data[i].child=-1;
151 151
        _data[i].degree=0;
152 152
        _data[i].in=true;
153 153
        _data[i].marked=false;
154 154
      }
155 155

	
156 156
      if ( _num ) {
157 157
        _data[_data[_minimum].right_neighbor].left_neighbor=i;
158 158
        _data[i].right_neighbor=_data[_minimum].right_neighbor;
159 159
        _data[_minimum].right_neighbor=i;
160 160
        _data[i].left_neighbor=_minimum;
161 161
        if ( _comp( prio, _data[_minimum].prio) ) _minimum=i;
162 162
      } else {
163 163
        _data[i].right_neighbor=_data[i].left_neighbor=i;
164 164
        _minimum=i;
165 165
      }
166 166
      _data[i].prio=prio;
167 167
      ++_num;
168 168
    }
169 169

	
170 170
    /// \brief Return the item having minimum priority.
171 171
    ///
172 172
    /// This function returns the item having minimum priority.
173 173
    /// \pre The heap must be non-empty.
174 174
    Item top() const { return _data[_minimum].name; }
175 175

	
176 176
    /// \brief The minimum priority.
177 177
    ///
178 178
    /// This function returns the minimum priority.
179 179
    /// \pre The heap must be non-empty.
180 180
    Prio prio() const { return _data[_minimum].prio; }
181 181

	
182 182
    /// \brief Remove the item having minimum priority.
183 183
    ///
184 184
    /// This function removes the item having minimum priority.
185 185
    /// \pre The heap must be non-empty.
186 186
    void pop() {
187 187
      /*The first case is that there are only one root.*/
188 188
      if ( _data[_minimum].left_neighbor==_minimum ) {
189 189
        _data[_minimum].in=false;
190 190
        if ( _data[_minimum].degree!=0 ) {
191 191
          makeroot(_data[_minimum].child);
192 192
          _minimum=_data[_minimum].child;
193 193
          balance();
194 194
        }
195 195
      } else {
196 196
        int right=_data[_minimum].right_neighbor;
197 197
        unlace(_minimum);
198 198
        _data[_minimum].in=false;
199 199
        if ( _data[_minimum].degree > 0 ) {
200 200
          int left=_data[_minimum].left_neighbor;
201 201
          int child=_data[_minimum].child;
202 202
          int last_child=_data[child].left_neighbor;
203 203

	
204 204
          makeroot(child);
205 205

	
206 206
          _data[left].right_neighbor=child;
207 207
          _data[child].left_neighbor=left;
208 208
          _data[right].left_neighbor=last_child;
209 209
          _data[last_child].right_neighbor=right;
210 210
        }
211 211
        _minimum=right;
212 212
        balance();
213 213
      } // the case where there are more roots
214 214
      --_num;
215 215
    }
216 216

	
217 217
    /// \brief Remove the given item from the heap.
218 218
    ///
219 219
    /// This function removes the given item from the heap if it is
220 220
    /// already stored.
221 221
    /// \param item The item to delete.
222 222
    /// \pre \e item must be in the heap.
223 223
    void erase (const Item& item) {
224 224
      int i=_iim[item];
225 225

	
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_RADIX_HEAP_H
20 20
#define LEMON_RADIX_HEAP_H
21 21

	
22
///\ingroup auxdat
22
///\ingroup heaps
23 23
///\file
24 24
///\brief Radix heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <lemon/error.h>
28 28

	
29 29
namespace lemon {
30 30

	
31 31

	
32
  /// \ingroup auxdat
32
  /// \ingroup heaps
33 33
  ///
34 34
  /// \brief Radix heap data structure.
35 35
  ///
36 36
  /// This class implements the \e radix \e heap data structure.
37 37
  /// It practically conforms to the \ref concepts::Heap "heap concept",
38 38
  /// but it has some limitations due its special implementation.
39 39
  /// The type of the priorities must be \c int and the priority of an
40 40
  /// item cannot be decreased under the priority of the last removed item.
41 41
  ///
42 42
  /// \tparam IM A read-writable item map with \c int values, used
43 43
  /// internally to handle the cross references.
44 44
  template <typename IM>
45 45
  class RadixHeap {
46 46

	
47 47
  public:
48 48

	
49 49
    /// Type of the item-int map.
50 50
    typedef IM ItemIntMap;
51 51
    /// Type of the priorities.
52 52
    typedef int Prio;
53 53
    /// Type of the items stored in the heap.
54 54
    typedef typename ItemIntMap::Key Item;
55 55

	
56 56
    /// \brief Exception thrown by RadixHeap.
57 57
    ///
58 58
    /// This exception is thrown when an item is inserted into a
59 59
    /// RadixHeap with a priority smaller than the last erased one.
60 60
    /// \see RadixHeap
61 61
    class UnderFlowPriorityError : public Exception {
62 62
    public:
63 63
      virtual const char* what() const throw() {
64 64
        return "lemon::RadixHeap::UnderFlowPriorityError";
65 65
      }
66 66
    };
67 67

	
68 68
    /// \brief Type to represent the states of the items.
69 69
    ///
70 70
    /// Each item has a state associated to it. It can be "in heap",
71 71
    /// "pre-heap" or "post-heap". The latter two are indifferent from the
72 72
    /// heap's point of view, but may be useful to the user.
73 73
    ///
74 74
    /// The item-int map must be initialized in such way that it assigns
75 75
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
76 76
    enum State {
77 77
      IN_HEAP = 0,    ///< = 0.
78 78
      PRE_HEAP = -1,  ///< = -1.
79 79
      POST_HEAP = -2  ///< = -2.
80 80
    };
81 81

	
82 82
  private:
83 83

	
84 84
    struct RadixItem {
85 85
      int prev, next, box;
86 86
      Item item;
87 87
      int prio;
88 88
      RadixItem(Item _item, int _prio) : item(_item), prio(_prio) {}
89 89
    };
90 90

	
91 91
    struct RadixBox {
92 92
      int first;
93 93
      int min, size;
94 94
      RadixBox(int _min, int _size) : first(-1), min(_min), size(_size) {}
95 95
    };
96 96

	
97 97
    std::vector<RadixItem> data;
98 98
    std::vector<RadixBox> boxes;
99 99

	
100 100
    ItemIntMap &_iim;
101 101

	
102 102
  public:
103 103

	
104 104
    /// \brief Constructor.
105 105
    ///
106 106
    /// Constructor.
107 107
    /// \param map A map that assigns \c int values to the items.
108 108
    /// It is used internally to handle the cross references.
109 109
    /// The assigned value must be \c PRE_HEAP (<tt>-1</tt>) for each item.
110 110
    /// \param minimum The initial minimum value of the heap.
111 111
    /// \param capacity The initial capacity of the heap.
112 112
    RadixHeap(ItemIntMap &map, int minimum = 0, int capacity = 0)
113 113
      : _iim(map)
114 114
    {
115 115
      boxes.push_back(RadixBox(minimum, 1));
116 116
      boxes.push_back(RadixBox(minimum + 1, 1));
117 117
      while (lower(boxes.size() - 1, capacity + minimum - 1)) {
118 118
        extend();
119 119
      }
120 120
    }
121 121

	
122 122
    /// \brief The number of items stored in the heap.
123 123
    ///
124 124
    /// This function returns the number of items stored in the heap.
125 125
    int size() const { return data.size(); }
126 126

	
127 127
    /// \brief Check if the heap is empty.
128 128
    ///
129 129
    /// This function returns \c true if the heap is empty.
130 130
    bool empty() const { return data.empty(); }
131 131

	
132 132
    /// \brief Make the heap empty.
133 133
    ///
134 134
    /// This functon makes the heap empty.
135 135
    /// It does not change the cross reference map. If you want to reuse
136 136
    /// a heap that is not surely empty, you should first clear it and
137 137
    /// then you should set the cross reference map to \c PRE_HEAP
138 138
    /// for each item.
139 139
    /// \param minimum The minimum value of the heap.
140 140
    /// \param capacity The capacity of the heap.
141 141
    void clear(int minimum = 0, int capacity = 0) {
142 142
      data.clear(); boxes.clear();
143 143
      boxes.push_back(RadixBox(minimum, 1));
144 144
      boxes.push_back(RadixBox(minimum + 1, 1));
145 145
      while (lower(boxes.size() - 1, capacity + minimum - 1)) {
146 146
        extend();
147 147
      }
148 148
    }
149 149

	
150 150
  private:
151 151

	
152 152
    bool upper(int box, Prio pr) {
153 153
      return pr < boxes[box].min;
154 154
    }
155 155

	
156 156
    bool lower(int box, Prio pr) {
157 157
      return pr >= boxes[box].min + boxes[box].size;
158 158
    }
159 159

	
160 160
    // Remove item from the box list
161 161
    void remove(int index) {
162 162
      if (data[index].prev >= 0) {
163 163
        data[data[index].prev].next = data[index].next;
164 164
      } else {
165 165
        boxes[data[index].box].first = data[index].next;
166 166
      }
167 167
      if (data[index].next >= 0) {
168 168
        data[data[index].next].prev = data[index].prev;
169 169
      }
170 170
    }
171 171

	
172 172
    // Insert item into the box list
173 173
    void insert(int box, int index) {
174 174
      if (boxes[box].first == -1) {
175 175
        boxes[box].first = index;
176 176
        data[index].next = data[index].prev = -1;
177 177
      } else {
178 178
        data[index].next = boxes[box].first;
179 179
        data[boxes[box].first].prev = index;
180 180
        data[index].prev = -1;
181 181
        boxes[box].first = index;
182 182
      }
183 183
      data[index].box = box;
184 184
    }
185 185

	
186 186
    // Add a new box to the box list
187 187
    void extend() {
188 188
      int min = boxes.back().min + boxes.back().size;
189 189
      int bs = 2 * boxes.back().size;
190 190
      boxes.push_back(RadixBox(min, bs));
191 191
    }
192 192

	
193 193
    // Move an item up into the proper box.
194 194
    void bubble_up(int index) {
195 195
      if (!lower(data[index].box, data[index].prio)) return;
196 196
      remove(index);
197 197
      int box = findUp(data[index].box, data[index].prio);
198 198
      insert(box, index);
199 199
    }
200 200

	
201 201
    // Find up the proper box for the item with the given priority
202 202
    int findUp(int start, int pr) {
203 203
      while (lower(start, pr)) {
204 204
        if (++start == int(boxes.size())) {
205 205
          extend();
206 206
        }
207 207
      }
208 208
      return start;
209 209
    }
210 210

	
211 211
    // Move an item down into the proper box
212 212
    void bubble_down(int index) {
213 213
      if (!upper(data[index].box, data[index].prio)) return;
214 214
      remove(index);
215 215
      int box = findDown(data[index].box, data[index].prio);
216 216
      insert(box, index);
217 217
    }
218 218

	
219 219
    // Find down the proper box for the item with the given priority
220 220
    int findDown(int start, int pr) {
221 221
      while (upper(start, pr)) {
222 222
        if (--start < 0) throw UnderFlowPriorityError();
223 223
      }
224 224
      return start;
0 comments (0 inline)