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 6144 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
namespace lemon {
20 20

	
21 21
/**
22 22
@defgroup datas Data Structures
23 23
This group contains the several data structures implemented in LEMON.
24 24
*/
25 25

	
26 26
/**
27 27
@defgroup graphs Graph Structures
28 28
@ingroup datas
29 29
\brief Graph structures implemented in LEMON.
30 30

	
31 31
The implementation of combinatorial algorithms heavily relies on
32 32
efficient graph implementations. LEMON offers data structures which are
33 33
planned to be easily used in an experimental phase of implementation studies,
34 34
and thereafter the program code can be made efficient by small modifications.
35 35

	
36 36
The most efficient implementation of diverse applications require the
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.
442 463
- \ref MinCostMaxBipartiteMatching
443 464
  Successive shortest path algorithm for calculating minimum cost maximum
444 465
  matching in bipartite graphs.
445 466
- \ref MaxMatching Edmond's blossom shrinking algorithm for calculating
446 467
  maximum cardinality matching in general graphs.
447 468
- \ref MaxWeightedMatching Edmond's blossom shrinking algorithm for calculating
448 469
  maximum weighted matching in general graphs.
449 470
- \ref MaxWeightedPerfectMatching
450 471
  Edmond's blossom shrinking algorithm for calculating maximum weighted
451 472
  perfect matching in general graphs.
452 473

	
453 474
\image html bipartite_matching.png
454 475
\image latex bipartite_matching.eps "Bipartite Matching" width=\textwidth
455 476
*/
456 477

	
457 478
/**
458 479
@defgroup spantree Minimum Spanning Tree Algorithms
459 480
@ingroup algs
460 481
\brief Algorithms for finding minimum cost spanning trees and arborescences.
461 482

	
462 483
This group contains the algorithms for finding minimum cost spanning
463 484
trees and arborescences.
464 485
*/
465 486

	
466 487
/**
467 488
@defgroup auxalg Auxiliary Algorithms
468 489
@ingroup algs
469 490
\brief Auxiliary algorithms implemented in LEMON.
470 491

	
471 492
This group contains some algorithms implemented in LEMON
472 493
in order to make it easier to implement complex algorithms.
473 494
*/
474 495

	
475 496
/**
476 497
@defgroup approx Approximation Algorithms
477 498
@ingroup algs
478 499
\brief Approximation algorithms.
479 500

	
480 501
This group contains the approximation and heuristic algorithms
481 502
implemented in LEMON.
482 503
*/
483 504

	
484 505
/**
485 506
@defgroup gen_opt_group General Optimization Tools
486 507
\brief This group contains some general optimization frameworks
487 508
implemented in LEMON.
488 509

	
489 510
This group contains some general optimization frameworks
490 511
implemented in LEMON.
491 512
*/
492 513

	
493 514
/**
494 515
@defgroup lp_group Lp and Mip Solvers
495 516
@ingroup gen_opt_group
496 517
\brief Lp and Mip solver interfaces for LEMON.
497 518

	
498 519
This group contains Lp and Mip solver interfaces for LEMON. The
499 520
various LP solvers could be used in the same manner with this
500 521
interface.
501 522
*/
502 523

	
503 524
/**
504 525
@defgroup lp_utils Tools for Lp and Mip Solvers
505 526
@ingroup lp_group
506 527
\brief Helper tools to the Lp and Mip solvers.
507 528

	
508 529
This group adds some helper tools to general optimization framework
509 530
implemented in LEMON.
510 531
*/
511 532

	
512 533
/**
513 534
@defgroup metah Metaheuristics
514 535
@ingroup gen_opt_group
515 536
\brief Metaheuristics for LEMON library.
516 537

	
517 538
This group contains some metaheuristic optimization tools.
518 539
*/
519 540

	
520 541
/**
521 542
@defgroup utils Tools and Utilities
522 543
\brief Tools and utilities for programming in LEMON
523 544

	
524 545
Tools and utilities for programming in LEMON.
525 546
*/
526 547

	
527 548
/**
528 549
@defgroup gutils Basic Graph Utilities
529 550
@ingroup utils
530 551
\brief Simple basic graph utilities.
531 552

	
532 553
This group contains some simple basic graph utilities.
533 554
*/
534 555

	
535 556
/**
536 557
@defgroup misc Miscellaneous Tools
537 558
@ingroup utils
538 559
\brief Tools for development, debugging and testing.
539 560

	
540 561
This group contains several useful tools for development,
541 562
debugging and testing.
542 563
*/
543 564

	
544 565
/**
545 566
@defgroup timecount Time Measuring and Counting
546 567
@ingroup misc
547 568
\brief Simple tools for measuring the performance of algorithms.
548 569

	
549 570
This group contains simple tools for measuring the performance
550 571
of algorithms.
551 572
*/
552 573

	
553 574
/**
554 575
@defgroup exceptions Exceptions
555 576
@ingroup utils
556 577
\brief Exceptions defined in LEMON.
557 578

	
558 579
This group contains the exceptions defined in LEMON.
559 580
*/
560 581

	
561 582
/**
562 583
@defgroup io_group Input-Output
563 584
\brief Graph Input-Output methods
564 585

	
565 586
This group contains the tools for importing and exporting graphs
566 587
and graph related data. Now it supports the \ref lgf-format
567 588
"LEMON Graph Format", the \c DIMACS format and the encapsulated
568 589
postscript (EPS) format.
569 590
*/
570 591

	
571 592
/**
572 593
@defgroup lemon_io LEMON Graph Format
573 594
@ingroup io_group
574 595
\brief Reading and writing LEMON Graph Format.
575 596

	
576 597
This group contains methods for reading and writing
577 598
\ref lgf-format "LEMON Graph Format".
578 599
*/
579 600

	
580 601
/**
581 602
@defgroup eps_io Postscript Exporting
582 603
@ingroup io_group
583 604
\brief General \c EPS drawer and graph exporter
584 605

	
585 606
This group contains general \c EPS drawing methods and special
586 607
graph exporting tools.
587 608
*/
588 609

	
589 610
/**
590 611
@defgroup dimacs_group DIMACS format
591 612
@ingroup io_group
592 613
\brief Read and write files in DIMACS format
593 614

	
594 615
Tools to read a digraph from or write it to a file in DIMACS format data.
595 616
*/
596 617

	
597 618
/**
598 619
@defgroup nauty_group NAUTY Format
599 620
@ingroup io_group
600 621
\brief Read \e Nauty format
601 622

	
602 623
Tool to read graphs from \e Nauty format data.
603 624
*/
604 625

	
605 626
/**
606 627
@defgroup concept Concepts
607 628
\brief Skeleton classes and concept checking classes
608 629

	
609 630
This group contains the data/algorithm skeletons and concept checking
610 631
classes implemented in LEMON.
611 632

	
612 633
The purpose of the classes in this group is fourfold.
613 634

	
614 635
- These classes contain the documentations of the %concepts. In order
615 636
  to avoid document multiplications, an implementation of a concept
616 637
  simply refers to the corresponding concept class.
617 638

	
618 639
- These classes declare every functions, <tt>typedef</tt>s etc. an
619 640
  implementation of the %concepts should provide, however completely
620 641
  without implementations and real data structures behind the
621 642
  interface. On the other hand they should provide nothing else. All
622 643
  the algorithms working on a data structure meeting a certain concept
623 644
  should compile with these classes. (Though it will not run properly,
624 645
  of course.) In this way it is easily to check if an algorithm
625 646
  doesn't use any extra feature of a certain implementation.
626 647

	
627 648
- The concept descriptor classes also provide a <em>checker class</em>
628 649
  that makes it possible to check whether a certain implementation of a
629 650
  concept indeed provides all the required features.
630 651

	
631 652
- Finally, They can serve as a skeleton of a new implementation of a concept.
632 653
*/
633 654

	
634 655
/**
635 656
@defgroup graph_concepts Graph Structure Concepts
636 657
@ingroup concept
637 658
\brief Skeleton and concept checking classes for graph structures
638 659

	
639 660
This group contains the skeletons and concept checking classes of LEMON's
640 661
graph structures and helper classes used to implement these.
641 662
*/
642 663

	
643 664
/**
644 665
@defgroup map_concepts Map Concepts
645 666
@ingroup concept
646 667
\brief Skeleton and concept checking classes for maps
647 668

	
648 669
This group contains the skeletons and concept checking classes of maps.
649 670
*/
650 671

	
651 672
/**
652 673
\anchor demoprograms
653 674

	
654 675
@defgroup demos Demo Programs
655 676

	
656 677
Some demo programs are listed here. Their full source codes can be found in
657 678
the \c demo subdirectory of the source tree.
658 679

	
659 680
In order to compile them, use the <tt>make demo</tt> or the
660 681
<tt>make check</tt> commands.
661 682
*/
662 683

	
663 684
/**
664 685
@defgroup tools Standalone Utility Applications
665 686

	
666 687
Some utility applications are listed here.
667 688

	
668 689
The standard compilation procedure (<tt>./configure;make</tt>) will compile
669 690
them, as well.
670 691
*/
671 692

	
672 693
}
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_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
225 225
    /// already stored.
226 226
    /// \param i The item to delete.
227 227
    /// \pre \e i must be in the heap.
228 228
    void erase(const Item &i) {
229 229
      int h = _iim[i];
230 230
      int n = _data.size()-1;
231 231
      _iim.set(_data[h].first, POST_HEAP);
232 232
      if( h < n ) {
233 233
        if ( bubble_up(h, _data[n]) == h) {
234 234
          bubble_down(h, _data[n], n);
235 235
        }
236 236
      }
237 237
      _data.pop_back();
238 238
    }
239 239

	
240 240
    /// \brief The priority of the given item.
241 241
    ///
242 242
    /// This function returns the priority of the given item.
243 243
    /// \param i The item.
244 244
    /// \pre \e i must be in the heap.
245 245
    Prio operator[](const Item &i) const {
246 246
      int idx = _iim[i];
247 247
      return _data[idx].second;
248 248
    }
249 249

	
250 250
    /// \brief Set the priority of an item or insert it, if it is
251 251
    /// not stored in the heap.
252 252
    ///
253 253
    /// This method sets the priority of the given item if it is
254 254
    /// already stored in the heap. Otherwise it inserts the given
255 255
    /// item into the heap with the given priority.
256 256
    /// \param i The item.
257 257
    /// \param p The priority.
258 258
    void set(const Item &i, const Prio &p) {
259 259
      int idx = _iim[i];
260 260
      if( idx < 0 ) {
261 261
        push(i,p);
262 262
      }
263 263
      else if( _comp(p, _data[idx].second) ) {
264 264
        bubble_up(idx, Pair(i,p));
265 265
      }
266 266
      else {
267 267
        bubble_down(idx, Pair(i,p), _data.size());
268 268
      }
269 269
    }
270 270

	
271 271
    /// \brief Decrease the priority of an item to the given value.
272 272
    ///
273 273
    /// This function decreases the priority of an item to the given value.
274 274
    /// \param i The item.
275 275
    /// \param p The priority.
276 276
    /// \pre \e i must be stored in the heap with priority at least \e p.
277 277
    void decrease(const Item &i, const Prio &p) {
278 278
      int idx = _iim[i];
279 279
      bubble_up(idx, Pair(i,p));
280 280
    }
281 281

	
282 282
    /// \brief Increase the priority of an item to the given value.
283 283
    ///
284 284
    /// This function increases the priority of an item to the given value.
285 285
    /// \param i The item.
286 286
    /// \param p The priority.
287 287
    /// \pre \e i must be stored in the heap with priority at most \e p.
288 288
    void increase(const Item &i, const Prio &p) {
289 289
      int idx = _iim[i];
290 290
      bubble_down(idx, Pair(i,p), _data.size());
291 291
    }
292 292

	
293 293
    /// \brief Return the state of an item.
294 294
    ///
295 295
    /// This method returns \c PRE_HEAP if the given item has never
296 296
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
297 297
    /// and \c POST_HEAP otherwise.
298 298
    /// In the latter case it is possible that the item will get back
299 299
    /// to the heap again.
300 300
    /// \param i The item.
301 301
    State state(const Item &i) const {
302 302
      int s = _iim[i];
303 303
      if( s>=0 )
304 304
        s=0;
305 305
      return State(s);
306 306
    }
307 307

	
308 308
    /// \brief Set the state of an item in the heap.
309 309
    ///
310 310
    /// This function sets the state of the given item in the heap.
311 311
    /// It can be used to manually clear the heap when it is important
312 312
    /// to achive better time complexity.
313 313
    /// \param i The item.
314 314
    /// \param st The state. It should not be \c IN_HEAP.
315 315
    void state(const Item& i, State st) {
316 316
      switch (st) {
317 317
      case POST_HEAP:
318 318
      case PRE_HEAP:
319 319
        if (state(i) == IN_HEAP) {
320 320
          erase(i);
321 321
        }
322 322
        _iim[i] = st;
323 323
        break;
324 324
      case IN_HEAP:
325 325
        break;
326 326
      }
327 327
    }
328 328

	
329 329
    /// \brief Replace an item in the heap.
330 330
    ///
331 331
    /// This function replaces item \c i with item \c j.
332 332
    /// Item \c i must be in the heap, while \c j must be out of the heap.
333 333
    /// After calling this method, item \c i will be out of the
334 334
    /// heap and \c j will be in the heap with the same prioriority
335 335
    /// as item \c i had before.
336 336
    void replace(const Item& i, const Item& j) {
337 337
      int idx = _iim[i];
338 338
      _iim.set(i, _iim[j]);
339 339
      _iim.set(j, idx);
340 340
      _data[idx].first = j;
341 341
    }
342 342

	
343 343
  }; // class BinHeap
344 344

	
345 345
} // namespace lemon
346 346

	
347 347
#endif // LEMON_BIN_HEAP_H
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.
567 567
    /// \param i The item.
568 568
    State state(const Item &i) const {
569 569
      int idx = _iim[i];
570 570
      if (idx >= 0) idx = 0;
571 571
      return State(idx);
572 572
    }
573 573

	
574 574
  private:
575 575

	
576 576
    struct BucketItem {
577 577
      BucketItem(const Item& _item)
578 578
        : item(_item) {}
579 579

	
580 580
      Item item;
581 581
      int next;
582 582
    };
583 583

	
584 584
    ItemIntMap& _iim;
585 585
    std::vector<int> _first;
586 586
    std::vector<BucketItem> _data;
587 587
    int _free, _num;
588 588
    mutable int _minimum;
589 589

	
590 590
  }; // class SimpleBucketHeap
591 591

	
592 592
}
593 593

	
594 594
#endif
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);
232 232
          ignore_unused_variable_warning(own_prio);
233 233
          ignore_unused_variable_warning(own_state);
234 234

	
235 235
          _Heap heap1(map);
236 236
          _Heap heap2 = heap1;
237 237
          ignore_unused_variable_warning(heap1);
238 238
          ignore_unused_variable_warning(heap2);
239 239

	
240 240
          int s = heap.size();
241 241
          ignore_unused_variable_warning(s);
242 242
          bool e = heap.empty();
243 243
          ignore_unused_variable_warning(e);
244 244

	
245 245
          prio = heap.prio();
246 246
          item = heap.top();
247 247
          prio = heap[item];
248 248
          own_prio = heap.prio();
249 249
          own_item = heap.top();
250 250
          own_prio = heap[own_item];
251 251

	
252 252
          heap.push(item, prio);
253 253
          heap.push(own_item, own_prio);
254 254
          heap.pop();
255 255

	
256 256
          heap.set(item, prio);
257 257
          heap.decrease(item, prio);
258 258
          heap.increase(item, prio);
259 259
          heap.set(own_item, own_prio);
260 260
          heap.decrease(own_item, own_prio);
261 261
          heap.increase(own_item, own_prio);
262 262

	
263 263
          heap.erase(item);
264 264
          heap.erase(own_item);
265 265
          heap.clear();
266 266

	
267 267
          own_state = heap.state(own_item);
268 268
          heap.state(own_item, own_state);
269 269

	
270 270
          own_state = _Heap::PRE_HEAP;
271 271
          own_state = _Heap::IN_HEAP;
272 272
          own_state = _Heap::POST_HEAP;
273 273
        }
274 274

	
275 275
        _Heap& heap;
276 276
        ItemIntMap& map;
277 277
      };
278 278
    };
279 279

	
280 280
    /// @}
281 281
  } // namespace lemon
282 282
}
283 283
#endif
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

	
226 226
      if ( i >= 0 && _data[i].in ) {
227 227
        if ( _data[i].parent!=-1 ) {
228 228
          int p=_data[i].parent;
229 229
          cut(i,p);
230 230
          cascade(p);
231 231
        }
232 232
        _minimum=i;     //As if its prio would be -infinity
233 233
        pop();
234 234
      }
235 235
    }
236 236

	
237 237
    /// \brief The priority of the given item.
238 238
    ///
239 239
    /// This function returns the priority of the given item.
240 240
    /// \param item The item.
241 241
    /// \pre \e item must be in the heap.
242 242
    Prio operator[](const Item& item) const {
243 243
      return _data[_iim[item]].prio;
244 244
    }
245 245

	
246 246
    /// \brief Set the priority of an item or insert it, if it is
247 247
    /// not stored in the heap.
248 248
    ///
249 249
    /// This method sets the priority of the given item if it is
250 250
    /// already stored in the heap. Otherwise it inserts the given
251 251
    /// item into the heap with the given priority.
252 252
    /// \param item The item.
253 253
    /// \param prio The priority.
254 254
    void set (const Item& item, const Prio& prio) {
255 255
      int i=_iim[item];
256 256
      if ( i >= 0 && _data[i].in ) {
257 257
        if ( _comp(prio, _data[i].prio) ) decrease(item, prio);
258 258
        if ( _comp(_data[i].prio, prio) ) increase(item, prio);
259 259
      } else push(item, prio);
260 260
    }
261 261

	
262 262
    /// \brief Decrease the priority of an item to the given value.
263 263
    ///
264 264
    /// This function decreases the priority of an item to the given value.
265 265
    /// \param item The item.
266 266
    /// \param prio The priority.
267 267
    /// \pre \e item must be stored in the heap with priority at least \e prio.
268 268
    void decrease (const Item& item, const Prio& prio) {
269 269
      int i=_iim[item];
270 270
      _data[i].prio=prio;
271 271
      int p=_data[i].parent;
272 272

	
273 273
      if ( p!=-1 && _comp(prio, _data[p].prio) ) {
274 274
        cut(i,p);
275 275
        cascade(p);
276 276
      }
277 277
      if ( _comp(prio, _data[_minimum].prio) ) _minimum=i;
278 278
    }
279 279

	
280 280
    /// \brief Increase the priority of an item to the given value.
281 281
    ///
282 282
    /// This function increases the priority of an item to the given value.
283 283
    /// \param item The item.
284 284
    /// \param prio The priority.
285 285
    /// \pre \e item must be stored in the heap with priority at most \e prio.
286 286
    void increase (const Item& item, const Prio& prio) {
287 287
      erase(item);
288 288
      push(item, prio);
289 289
    }
290 290

	
291 291
    /// \brief Return the state of an item.
292 292
    ///
293 293
    /// This method returns \c PRE_HEAP if the given item has never
294 294
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
295 295
    /// and \c POST_HEAP otherwise.
296 296
    /// In the latter case it is possible that the item will get back
297 297
    /// to the heap again.
298 298
    /// \param item The item.
299 299
    State state(const Item &item) const {
300 300
      int i=_iim[item];
301 301
      if( i>=0 ) {
302 302
        if ( _data[i].in ) i=0;
303 303
        else i=-2;
304 304
      }
305 305
      return State(i);
306 306
    }
307 307

	
308 308
    /// \brief Set the state of an item in the heap.
309 309
    ///
310 310
    /// This function sets the state of the given item in the heap.
311 311
    /// It can be used to manually clear the heap when it is important
312 312
    /// to achive better time complexity.
313 313
    /// \param i The item.
314 314
    /// \param st The state. It should not be \c IN_HEAP.
315 315
    void state(const Item& i, State st) {
316 316
      switch (st) {
317 317
      case POST_HEAP:
318 318
      case PRE_HEAP:
319 319
        if (state(i) == IN_HEAP) {
320 320
          erase(i);
321 321
        }
322 322
        _iim[i] = st;
323 323
        break;
324 324
      case IN_HEAP:
325 325
        break;
326 326
      }
327 327
    }
328 328

	
329 329
  private:
330 330

	
331 331
    void balance() {
332 332

	
333 333
      int maxdeg=int( std::floor( 2.08*log(double(_data.size()))))+1;
334 334

	
335 335
      std::vector<int> A(maxdeg,-1);
336 336

	
337 337
      /*
338 338
       *Recall that now minimum does not point to the minimum prio element.
339 339
       *We set minimum to this during balance().
340 340
       */
341 341
      int anchor=_data[_minimum].left_neighbor;
342 342
      int next=_minimum;
343 343
      bool end=false;
344 344

	
345 345
      do {
346 346
        int active=next;
347 347
        if ( anchor==active ) end=true;
348 348
        int d=_data[active].degree;
349 349
        next=_data[active].right_neighbor;
350 350

	
351 351
        while (A[d]!=-1) {
352 352
          if( _comp(_data[active].prio, _data[A[d]].prio) ) {
353 353
            fuse(active,A[d]);
354 354
          } else {
355 355
            fuse(A[d],active);
356 356
            active=A[d];
357 357
          }
358 358
          A[d]=-1;
359 359
          ++d;
360 360
        }
361 361
        A[d]=active;
362 362
      } while ( !end );
363 363

	
364 364

	
365 365
      while ( _data[_minimum].parent >=0 )
366 366
        _minimum=_data[_minimum].parent;
367 367
      int s=_minimum;
368 368
      int m=_minimum;
369 369
      do {
370 370
        if ( _comp(_data[s].prio, _data[_minimum].prio) ) _minimum=s;
371 371
        s=_data[s].right_neighbor;
372 372
      } while ( s != m );
373 373
    }
374 374

	
375 375
    void makeroot(int c) {
376 376
      int s=c;
377 377
      do {
378 378
        _data[s].parent=-1;
379 379
        s=_data[s].right_neighbor;
380 380
      } while ( s != c );
381 381
    }
382 382

	
383 383
    void cut(int a, int b) {
384 384
      /*
385 385
       *Replacing a from the children of b.
386 386
       */
387 387
      --_data[b].degree;
388 388

	
389 389
      if ( _data[b].degree !=0 ) {
390 390
        int child=_data[b].child;
391 391
        if ( child==a )
392 392
          _data[b].child=_data[child].right_neighbor;
393 393
        unlace(a);
394 394
      }
395 395

	
396 396

	
397 397
      /*Lacing a to the roots.*/
398 398
      int right=_data[_minimum].right_neighbor;
399 399
      _data[_minimum].right_neighbor=a;
400 400
      _data[a].left_neighbor=_minimum;
401 401
      _data[a].right_neighbor=right;
402 402
      _data[right].left_neighbor=a;
403 403

	
404 404
      _data[a].parent=-1;
405 405
      _data[a].marked=false;
406 406
    }
407 407

	
408 408
    void cascade(int a) {
409 409
      if ( _data[a].parent!=-1 ) {
410 410
        int p=_data[a].parent;
411 411

	
412 412
        if ( _data[a].marked==false ) _data[a].marked=true;
413 413
        else {
414 414
          cut(a,p);
415 415
          cascade(p);
416 416
        }
417 417
      }
418 418
    }
419 419

	
420 420
    void fuse(int a, int b) {
421 421
      unlace(b);
422 422

	
423 423
      /*Lacing b under a.*/
424 424
      _data[b].parent=a;
425 425

	
426 426
      if (_data[a].degree==0) {
427 427
        _data[b].left_neighbor=b;
428 428
        _data[b].right_neighbor=b;
429 429
        _data[a].child=b;
430 430
      } else {
431 431
        int child=_data[a].child;
432 432
        int last_child=_data[child].left_neighbor;
433 433
        _data[child].left_neighbor=b;
434 434
        _data[b].right_neighbor=child;
435 435
        _data[last_child].right_neighbor=b;
436 436
        _data[b].left_neighbor=last_child;
437 437
      }
438 438

	
439 439
      ++_data[a].degree;
440 440

	
441 441
      _data[b].marked=false;
442 442
    }
443 443

	
444 444
    /*
445 445
     *It is invoked only if a has siblings.
446 446
     */
447 447
    void unlace(int a) {
448 448
      int leftn=_data[a].left_neighbor;
449 449
      int rightn=_data[a].right_neighbor;
450 450
      _data[leftn].right_neighbor=rightn;
451 451
      _data[rightn].left_neighbor=leftn;
452 452
    }
453 453

	
454 454

	
455 455
    class Store {
456 456
      friend class FibHeap;
457 457

	
458 458
      Item name;
459 459
      int parent;
460 460
      int left_neighbor;
461 461
      int right_neighbor;
462 462
      int child;
463 463
      int degree;
464 464
      bool marked;
465 465
      bool in;
466 466
      Prio prio;
467 467

	
468 468
      Store() : parent(-1), child(-1), degree(), marked(false), in(true) {}
469 469
    };
470 470
  };
471 471

	
472 472
} //namespace lemon
473 473

	
474 474
#endif //LEMON_FIB_HEAP_H
475 475

	
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;
225 225
    }
226 226

	
227 227
    // Find the first non-empty box
228 228
    int findFirst() {
229 229
      int first = 0;
230 230
      while (boxes[first].first == -1) ++first;
231 231
      return first;
232 232
    }
233 233

	
234 234
    // Gives back the minimum priority of the given box
235 235
    int minValue(int box) {
236 236
      int min = data[boxes[box].first].prio;
237 237
      for (int k = boxes[box].first; k != -1; k = data[k].next) {
238 238
        if (data[k].prio < min) min = data[k].prio;
239 239
      }
240 240
      return min;
241 241
    }
242 242

	
243 243
    // Rearrange the items of the heap and make the first box non-empty
244 244
    void moveDown() {
245 245
      int box = findFirst();
246 246
      if (box == 0) return;
247 247
      int min = minValue(box);
248 248
      for (int i = 0; i <= box; ++i) {
249 249
        boxes[i].min = min;
250 250
        min += boxes[i].size;
251 251
      }
252 252
      int curr = boxes[box].first, next;
253 253
      while (curr != -1) {
254 254
        next = data[curr].next;
255 255
        bubble_down(curr);
256 256
        curr = next;
257 257
      }
258 258
    }
259 259

	
260 260
    void relocate_last(int index) {
261 261
      if (index != int(data.size()) - 1) {
262 262
        data[index] = data.back();
263 263
        if (data[index].prev != -1) {
264 264
          data[data[index].prev].next = index;
265 265
        } else {
266 266
          boxes[data[index].box].first = index;
267 267
        }
268 268
        if (data[index].next != -1) {
269 269
          data[data[index].next].prev = index;
270 270
        }
271 271
        _iim[data[index].item] = index;
272 272
      }
273 273
      data.pop_back();
274 274
    }
275 275

	
276 276
  public:
277 277

	
278 278
    /// \brief Insert an item into the heap with the given priority.
279 279
    ///
280 280
    /// This function inserts the given item into the heap with the
281 281
    /// given priority.
282 282
    /// \param i The item to insert.
283 283
    /// \param p The priority of the item.
284 284
    /// \pre \e i must not be stored in the heap.
285 285
    /// \warning This method may throw an \c UnderFlowPriorityException.
286 286
    void push(const Item &i, const Prio &p) {
287 287
      int n = data.size();
288 288
      _iim.set(i, n);
289 289
      data.push_back(RadixItem(i, p));
290 290
      while (lower(boxes.size() - 1, p)) {
291 291
        extend();
292 292
      }
293 293
      int box = findDown(boxes.size() - 1, p);
294 294
      insert(box, n);
295 295
    }
296 296

	
297 297
    /// \brief Return the item having minimum priority.
298 298
    ///
299 299
    /// This function returns the item having minimum priority.
300 300
    /// \pre The heap must be non-empty.
301 301
    Item top() const {
302 302
      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
303 303
      return data[boxes[0].first].item;
304 304
    }
305 305

	
306 306
    /// \brief The minimum priority.
307 307
    ///
308 308
    /// This function returns the minimum priority.
309 309
    /// \pre The heap must be non-empty.
310 310
    Prio prio() const {
311 311
      const_cast<RadixHeap<ItemIntMap>&>(*this).moveDown();
312 312
      return data[boxes[0].first].prio;
313 313
     }
314 314

	
315 315
    /// \brief Remove the item having minimum priority.
316 316
    ///
317 317
    /// This function removes the item having minimum priority.
318 318
    /// \pre The heap must be non-empty.
319 319
    void pop() {
320 320
      moveDown();
321 321
      int index = boxes[0].first;
322 322
      _iim[data[index].item] = POST_HEAP;
323 323
      remove(index);
324 324
      relocate_last(index);
325 325
    }
326 326

	
327 327
    /// \brief Remove the given item from the heap.
328 328
    ///
329 329
    /// This function removes the given item from the heap if it is
330 330
    /// already stored.
331 331
    /// \param i The item to delete.
332 332
    /// \pre \e i must be in the heap.
333 333
    void erase(const Item &i) {
334 334
      int index = _iim[i];
335 335
      _iim[i] = POST_HEAP;
336 336
      remove(index);
337 337
      relocate_last(index);
338 338
   }
339 339

	
340 340
    /// \brief The priority of the given item.
341 341
    ///
342 342
    /// This function returns the priority of the given item.
343 343
    /// \param i The item.
344 344
    /// \pre \e i must be in the heap.
345 345
    Prio operator[](const Item &i) const {
346 346
      int idx = _iim[i];
347 347
      return data[idx].prio;
348 348
    }
349 349

	
350 350
    /// \brief Set the priority of an item or insert it, if it is
351 351
    /// not stored in the heap.
352 352
    ///
353 353
    /// This method sets the priority of the given item if it is
354 354
    /// already stored in the heap. Otherwise it inserts the given
355 355
    /// item into the heap with the given priority.
356 356
    /// \param i The item.
357 357
    /// \param p The priority.
358 358
    /// \pre \e i must be in the heap.
359 359
    /// \warning This method may throw an \c UnderFlowPriorityException.
360 360
    void set(const Item &i, const Prio &p) {
361 361
      int idx = _iim[i];
362 362
      if( idx < 0 ) {
363 363
        push(i, p);
364 364
      }
365 365
      else if( p >= data[idx].prio ) {
366 366
        data[idx].prio = p;
367 367
        bubble_up(idx);
368 368
      } else {
369 369
        data[idx].prio = p;
370 370
        bubble_down(idx);
371 371
      }
372 372
    }
373 373

	
374 374
    /// \brief Decrease the priority of an item to the given value.
375 375
    ///
376 376
    /// This function decreases the priority of an item to the given value.
377 377
    /// \param i The item.
378 378
    /// \param p The priority.
379 379
    /// \pre \e i must be stored in the heap with priority at least \e p.
380 380
    /// \warning This method may throw an \c UnderFlowPriorityException.
381 381
    void decrease(const Item &i, const Prio &p) {
382 382
      int idx = _iim[i];
383 383
      data[idx].prio = p;
384 384
      bubble_down(idx);
385 385
    }
386 386

	
387 387
    /// \brief Increase the priority of an item to the given value.
388 388
    ///
389 389
    /// This function increases the priority of an item to the given value.
390 390
    /// \param i The item.
391 391
    /// \param p The priority.
392 392
    /// \pre \e i must be stored in the heap with priority at most \e p.
393 393
    void increase(const Item &i, const Prio &p) {
394 394
      int idx = _iim[i];
395 395
      data[idx].prio = p;
396 396
      bubble_up(idx);
397 397
    }
398 398

	
399 399
    /// \brief Return the state of an item.
400 400
    ///
401 401
    /// This method returns \c PRE_HEAP if the given item has never
402 402
    /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
403 403
    /// and \c POST_HEAP otherwise.
404 404
    /// In the latter case it is possible that the item will get back
405 405
    /// to the heap again.
406 406
    /// \param i The item.
407 407
    State state(const Item &i) const {
408 408
      int s = _iim[i];
409 409
      if( s >= 0 ) s = 0;
410 410
      return State(s);
411 411
    }
412 412

	
413 413
    /// \brief Set the state of an item in the heap.
414 414
    ///
415 415
    /// This function sets the state of the given item in the heap.
416 416
    /// It can be used to manually clear the heap when it is important
417 417
    /// to achive better time complexity.
418 418
    /// \param i The item.
419 419
    /// \param st The state. It should not be \c IN_HEAP.
420 420
    void state(const Item& i, State st) {
421 421
      switch (st) {
422 422
      case POST_HEAP:
423 423
      case PRE_HEAP:
424 424
        if (state(i) == IN_HEAP) {
425 425
          erase(i);
426 426
        }
427 427
        _iim[i] = st;
428 428
        break;
429 429
      case IN_HEAP:
430 430
        break;
431 431
      }
432 432
    }
433 433

	
434 434
  }; // class RadixHeap
435 435

	
436 436
} // namespace lemon
437 437

	
438 438
#endif // LEMON_RADIX_HEAP_H
0 comments (0 inline)