gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 2 0
merge default
0 files changed with 1 insertions and 24 deletions:
↑ Collapse diff ↑
Show white space 1536 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-2008
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_DIJKSTRA_H
20 20
#define LEMON_DIJKSTRA_H
21 21

	
22 22
///\ingroup shortest_path
23 23
///\file
24 24
///\brief Dijkstra algorithm.
25 25

	
26 26
#include <limits>
27 27
#include <lemon/list_graph.h>
28 28
#include <lemon/bin_heap.h>
29 29
#include <lemon/bits/path_dump.h>
30 30
#include <lemon/core.h>
31 31
#include <lemon/error.h>
32 32
#include <lemon/maps.h>
33 33
#include <lemon/path.h>
34 34

	
35 35
namespace lemon {
36 36

	
37 37
  /// \brief Default operation traits for the Dijkstra algorithm class.
38 38
  ///
39 39
  /// This operation traits class defines all computational operations and
40 40
  /// constants which are used in the Dijkstra algorithm.
41 41
  template <typename Value>
42 42
  struct DijkstraDefaultOperationTraits {
43 43
    /// \brief Gives back the zero value of the type.
44 44
    static Value zero() {
45 45
      return static_cast<Value>(0);
46 46
    }
47 47
    /// \brief Gives back the sum of the given two elements.
48 48
    static Value plus(const Value& left, const Value& right) {
49 49
      return left + right;
50 50
    }
51 51
    /// \brief Gives back true only if the first value is less than the second.
52 52
    static bool less(const Value& left, const Value& right) {
53 53
      return left < right;
54 54
    }
55 55
  };
56 56

	
57
  /// \brief Widest path operation traits for the Dijkstra algorithm class.
58
  ///
59
  /// This operation traits class defines all computational operations and
60
  /// constants which are used in the Dijkstra algorithm for widest path
61
  /// computation.
62
  ///
63
  /// \see DijkstraDefaultOperationTraits
64
  template <typename Value>
65
  struct DijkstraWidestPathOperationTraits {
66
    /// \brief Gives back the maximum value of the type.
67
    static Value zero() {
68
      return std::numeric_limits<Value>::max();
69
    }
70
    /// \brief Gives back the minimum of the given two elements.
71
    static Value plus(const Value& left, const Value& right) {
72
      return std::min(left, right);
73
    }
74
    /// \brief Gives back true only if the first value is less than the second.
75
    static bool less(const Value& left, const Value& right) {
76
      return left < right;
77
    }
78
  };
79

	
80 57
  ///Default traits class of Dijkstra class.
81 58

	
82 59
  ///Default traits class of Dijkstra class.
83 60
  ///\tparam GR The type of the digraph.
84 61
  ///\tparam LM The type of the length map.
85 62
  template<class GR, class LM>
86 63
  struct DijkstraDefaultTraits
87 64
  {
88 65
    ///The type of the digraph the algorithm runs on.
89 66
    typedef GR Digraph;
90 67

	
91 68
    ///The type of the map that stores the arc lengths.
92 69

	
93 70
    ///The type of the map that stores the arc lengths.
94 71
    ///It must meet the \ref concepts::ReadMap "ReadMap" concept.
95 72
    typedef LM LengthMap;
96 73
    ///The type of the length of the arcs.
97 74
    typedef typename LM::Value Value;
98 75

	
99 76
    /// Operation traits for Dijkstra algorithm.
100 77

	
101 78
    /// This class defines the operations that are used in the algorithm.
102 79
    /// \see DijkstraDefaultOperationTraits
103 80
    typedef DijkstraDefaultOperationTraits<Value> OperationTraits;
104 81

	
105 82
    /// The cross reference type used by the heap.
106 83

	
107 84
    /// The cross reference type used by the heap.
108 85
    /// Usually it is \c Digraph::NodeMap<int>.
109 86
    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
110 87
    ///Instantiates a \ref HeapCrossRef.
111 88

	
112 89
    ///This function instantiates a \ref HeapCrossRef.
113 90
    /// \param g is the digraph, to which we would like to define the
114 91
    /// \ref HeapCrossRef.
115 92
    static HeapCrossRef *createHeapCrossRef(const Digraph &g)
116 93
    {
117 94
      return new HeapCrossRef(g);
118 95
    }
119 96

	
120 97
    ///The heap type used by the Dijkstra algorithm.
121 98

	
122 99
    ///The heap type used by the Dijkstra algorithm.
123 100
    ///
124 101
    ///\sa BinHeap
125 102
    ///\sa Dijkstra
126 103
    typedef BinHeap<typename LM::Value, HeapCrossRef, std::less<Value> > Heap;
127 104
    ///Instantiates a \ref Heap.
128 105

	
129 106
    ///This function instantiates a \ref Heap.
130 107
    static Heap *createHeap(HeapCrossRef& r)
131 108
    {
132 109
      return new Heap(r);
133 110
    }
134 111

	
135 112
    ///\brief The type of the map that stores the predecessor
136 113
    ///arcs of the shortest paths.
137 114
    ///
138 115
    ///The type of the map that stores the predecessor
139 116
    ///arcs of the shortest paths.
140 117
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
141 118
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
142 119
    ///Instantiates a PredMap.
143 120

	
144 121
    ///This function instantiates a PredMap.
145 122
    ///\param g is the digraph, to which we would like to define the
146 123
    ///PredMap.
147 124
    static PredMap *createPredMap(const Digraph &g)
148 125
    {
149 126
      return new PredMap(g);
150 127
    }
151 128

	
152 129
    ///The type of the map that indicates which nodes are processed.
153 130

	
154 131
    ///The type of the map that indicates which nodes are processed.
155 132
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
156 133
    ///By default it is a NullMap.
157 134
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
158 135
    ///Instantiates a ProcessedMap.
159 136

	
160 137
    ///This function instantiates a ProcessedMap.
161 138
    ///\param g is the digraph, to which
162 139
    ///we would like to define the ProcessedMap
163 140
#ifdef DOXYGEN
164 141
    static ProcessedMap *createProcessedMap(const Digraph &g)
165 142
#else
166 143
    static ProcessedMap *createProcessedMap(const Digraph &)
167 144
#endif
168 145
    {
169 146
      return new ProcessedMap();
170 147
    }
171 148

	
172 149
    ///The type of the map that stores the distances of the nodes.
173 150

	
174 151
    ///The type of the map that stores the distances of the nodes.
175 152
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
176 153
    typedef typename Digraph::template NodeMap<typename LM::Value> DistMap;
177 154
    ///Instantiates a DistMap.
178 155

	
179 156
    ///This function instantiates a DistMap.
180 157
    ///\param g is the digraph, to which we would like to define
181 158
    ///the DistMap
182 159
    static DistMap *createDistMap(const Digraph &g)
183 160
    {
184 161
      return new DistMap(g);
185 162
    }
186 163
  };
187 164

	
188 165
  ///%Dijkstra algorithm class.
189 166

	
190 167
  /// \ingroup shortest_path
191 168
  ///This class provides an efficient implementation of the %Dijkstra algorithm.
192 169
  ///
193 170
  ///The arc lengths are passed to the algorithm using a
194 171
  ///\ref concepts::ReadMap "ReadMap",
195 172
  ///so it is easy to change it to any kind of length.
196 173
  ///The type of the length is determined by the
197 174
  ///\ref concepts::ReadMap::Value "Value" of the length map.
198 175
  ///It is also possible to change the underlying priority heap.
199 176
  ///
200 177
  ///There is also a \ref dijkstra() "function-type interface" for the
201 178
  ///%Dijkstra algorithm, which is convenient in the simplier cases and
202 179
  ///it can be used easier.
203 180
  ///
204 181
  ///\tparam GR The type of the digraph the algorithm runs on.
205 182
  ///The default value is \ref ListDigraph.
206 183
  ///The value of GR is not used directly by \ref Dijkstra, it is only
207 184
  ///passed to \ref DijkstraDefaultTraits.
208 185
  ///\tparam LM A readable arc map that determines the lengths of the
209 186
  ///arcs. It is read once for each arc, so the map may involve in
210 187
  ///relatively time consuming process to compute the arc lengths if
211 188
  ///it is necessary. The default map type is \ref
212 189
  ///concepts::Digraph::ArcMap "Digraph::ArcMap<int>".
213 190
  ///The value of LM is not used directly by \ref Dijkstra, it is only
214 191
  ///passed to \ref DijkstraDefaultTraits.
215 192
  ///\tparam TR Traits class to set various data types used by the algorithm.
216 193
  ///The default traits class is \ref DijkstraDefaultTraits
217 194
  ///"DijkstraDefaultTraits<GR,LM>". See \ref DijkstraDefaultTraits
218 195
  ///for the documentation of a Dijkstra traits class.
219 196
#ifdef DOXYGEN
220 197
  template <typename GR, typename LM, typename TR>
221 198
#else
222 199
  template <typename GR=ListDigraph,
223 200
            typename LM=typename GR::template ArcMap<int>,
224 201
            typename TR=DijkstraDefaultTraits<GR,LM> >
225 202
#endif
226 203
  class Dijkstra {
227 204
  public:
228 205

	
229 206
    ///The type of the digraph the algorithm runs on.
230 207
    typedef typename TR::Digraph Digraph;
231 208

	
232 209
    ///The type of the length of the arcs.
233 210
    typedef typename TR::LengthMap::Value Value;
234 211
    ///The type of the map that stores the arc lengths.
235 212
    typedef typename TR::LengthMap LengthMap;
236 213
    ///\brief The type of the map that stores the predecessor arcs of the
237 214
    ///shortest paths.
238 215
    typedef typename TR::PredMap PredMap;
239 216
    ///The type of the map that stores the distances of the nodes.
240 217
    typedef typename TR::DistMap DistMap;
241 218
    ///The type of the map that indicates which nodes are processed.
242 219
    typedef typename TR::ProcessedMap ProcessedMap;
243 220
    ///The type of the paths.
244 221
    typedef PredMapPath<Digraph, PredMap> Path;
245 222
    ///The cross reference type used for the current heap.
246 223
    typedef typename TR::HeapCrossRef HeapCrossRef;
247 224
    ///The heap type used by the algorithm.
248 225
    typedef typename TR::Heap Heap;
249 226
    ///The operation traits class.
250 227
    typedef typename TR::OperationTraits OperationTraits;
251 228

	
252 229
    ///The traits class.
253 230
    typedef TR Traits;
254 231

	
255 232
  private:
256 233

	
257 234
    typedef typename Digraph::Node Node;
258 235
    typedef typename Digraph::NodeIt NodeIt;
259 236
    typedef typename Digraph::Arc Arc;
260 237
    typedef typename Digraph::OutArcIt OutArcIt;
261 238

	
262 239
    //Pointer to the underlying digraph.
263 240
    const Digraph *G;
264 241
    //Pointer to the length map.
265 242
    const LengthMap *length;
266 243
    //Pointer to the map of predecessors arcs.
267 244
    PredMap *_pred;
268 245
    //Indicates if _pred is locally allocated (true) or not.
269 246
    bool local_pred;
270 247
    //Pointer to the map of distances.
271 248
    DistMap *_dist;
272 249
    //Indicates if _dist is locally allocated (true) or not.
273 250
    bool local_dist;
274 251
    //Pointer to the map of processed status of the nodes.
275 252
    ProcessedMap *_processed;
276 253
    //Indicates if _processed is locally allocated (true) or not.
277 254
    bool local_processed;
278 255
    //Pointer to the heap cross references.
279 256
    HeapCrossRef *_heap_cross_ref;
280 257
    //Indicates if _heap_cross_ref is locally allocated (true) or not.
281 258
    bool local_heap_cross_ref;
282 259
    //Pointer to the heap.
283 260
    Heap *_heap;
284 261
    //Indicates if _heap is locally allocated (true) or not.
285 262
    bool local_heap;
286 263

	
287 264
    //Creates the maps if necessary.
288 265
    void create_maps()
289 266
    {
290 267
      if(!_pred) {
291 268
        local_pred = true;
292 269
        _pred = Traits::createPredMap(*G);
293 270
      }
294 271
      if(!_dist) {
295 272
        local_dist = true;
296 273
        _dist = Traits::createDistMap(*G);
297 274
      }
298 275
      if(!_processed) {
299 276
        local_processed = true;
300 277
        _processed = Traits::createProcessedMap(*G);
301 278
      }
302 279
      if (!_heap_cross_ref) {
303 280
        local_heap_cross_ref = true;
304 281
        _heap_cross_ref = Traits::createHeapCrossRef(*G);
305 282
      }
306 283
      if (!_heap) {
307 284
        local_heap = true;
308 285
        _heap = Traits::createHeap(*_heap_cross_ref);
309 286
      }
310 287
    }
311 288

	
312 289
  public:
313 290

	
314 291
    typedef Dijkstra Create;
315 292

	
316 293
    ///\name Named template parameters
317 294

	
318 295
    ///@{
319 296

	
320 297
    template <class T>
321 298
    struct SetPredMapTraits : public Traits {
322 299
      typedef T PredMap;
323 300
      static PredMap *createPredMap(const Digraph &)
324 301
      {
325 302
        LEMON_ASSERT(false, "PredMap is not initialized");
326 303
        return 0; // ignore warnings
327 304
      }
328 305
    };
329 306
    ///\brief \ref named-templ-param "Named parameter" for setting
330 307
    ///PredMap type.
331 308
    ///
332 309
    ///\ref named-templ-param "Named parameter" for setting
333 310
    ///PredMap type.
334 311
    template <class T>
335 312
    struct SetPredMap
336 313
      : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
337 314
      typedef Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > Create;
338 315
    };
339 316

	
340 317
    template <class T>
341 318
    struct SetDistMapTraits : public Traits {
342 319
      typedef T DistMap;
343 320
      static DistMap *createDistMap(const Digraph &)
344 321
      {
345 322
        LEMON_ASSERT(false, "DistMap is not initialized");
346 323
        return 0; // ignore warnings
347 324
      }
348 325
    };
349 326
    ///\brief \ref named-templ-param "Named parameter" for setting
350 327
    ///DistMap type.
351 328
    ///
352 329
    ///\ref named-templ-param "Named parameter" for setting
353 330
    ///DistMap type.
354 331
    template <class T>
355 332
    struct SetDistMap
356 333
      : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
357 334
      typedef Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > Create;
358 335
    };
359 336

	
360 337
    template <class T>
361 338
    struct SetProcessedMapTraits : public Traits {
362 339
      typedef T ProcessedMap;
363 340
      static ProcessedMap *createProcessedMap(const Digraph &)
364 341
      {
365 342
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
366 343
        return 0; // ignore warnings
367 344
      }
368 345
    };
369 346
    ///\brief \ref named-templ-param "Named parameter" for setting
370 347
    ///ProcessedMap type.
371 348
    ///
372 349
    ///\ref named-templ-param "Named parameter" for setting
373 350
    ///ProcessedMap type.
374 351
    template <class T>
375 352
    struct SetProcessedMap
376 353
      : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
377 354
      typedef Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > Create;
378 355
    };
379 356

	
380 357
    struct SetStandardProcessedMapTraits : public Traits {
381 358
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
382 359
      static ProcessedMap *createProcessedMap(const Digraph &g)
383 360
      {
384 361
        return new ProcessedMap(g);
385 362
      }
386 363
    };
387 364
    ///\brief \ref named-templ-param "Named parameter" for setting
388 365
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
389 366
    ///
390 367
    ///\ref named-templ-param "Named parameter" for setting
391 368
    ///ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
392 369
    ///If you don't set it explicitly, it will be automatically allocated.
393 370
    struct SetStandardProcessedMap
394 371
      : public Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits > {
395 372
      typedef Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits >
396 373
      Create;
397 374
    };
398 375

	
399 376
    template <class H, class CR>
400 377
    struct SetHeapTraits : public Traits {
401 378
      typedef CR HeapCrossRef;
402 379
      typedef H Heap;
403 380
      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
404 381
        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
405 382
        return 0; // ignore warnings
406 383
      }
407 384
      static Heap *createHeap(HeapCrossRef &)
408 385
      {
409 386
        LEMON_ASSERT(false, "Heap is not initialized");
410 387
        return 0; // ignore warnings
411 388
      }
412 389
    };
413 390
    ///\brief \ref named-templ-param "Named parameter" for setting
414 391
    ///heap and cross reference type
415 392
    ///
416 393
    ///\ref named-templ-param "Named parameter" for setting heap and cross
417 394
    ///reference type.
418 395
    template <class H, class CR = typename Digraph::template NodeMap<int> >
419 396
    struct SetHeap
420 397
      : public Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > {
421 398
      typedef Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > Create;
422 399
    };
423 400

	
424 401
    template <class H, class CR>
425 402
    struct SetStandardHeapTraits : public Traits {
426 403
      typedef CR HeapCrossRef;
427 404
      typedef H Heap;
428 405
      static HeapCrossRef *createHeapCrossRef(const Digraph &G) {
429 406
        return new HeapCrossRef(G);
430 407
      }
431 408
      static Heap *createHeap(HeapCrossRef &R)
432 409
      {
433 410
        return new Heap(R);
434 411
      }
435 412
    };
436 413
    ///\brief \ref named-templ-param "Named parameter" for setting
437 414
    ///heap and cross reference type with automatic allocation
438 415
    ///
439 416
    ///\ref named-templ-param "Named parameter" for setting heap and cross
440 417
    ///reference type. It can allocate the heap and the cross reference
441 418
    ///object if the cross reference's constructor waits for the digraph as
442 419
    ///parameter and the heap's constructor waits for the cross reference.
443 420
    template <class H, class CR = typename Digraph::template NodeMap<int> >
444 421
    struct SetStandardHeap
445 422
      : public Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> > {
446 423
      typedef Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> >
447 424
      Create;
448 425
    };
449 426

	
450 427
    template <class T>
451 428
    struct SetOperationTraitsTraits : public Traits {
452 429
      typedef T OperationTraits;
453 430
    };
454 431

	
455 432
    /// \brief \ref named-templ-param "Named parameter" for setting
456 433
    ///\c OperationTraits type
457 434
    ///
458 435
    ///\ref named-templ-param "Named parameter" for setting
459 436
    ///\ref OperationTraits type.
460 437
    template <class T>
461 438
    struct SetOperationTraits
462 439
      : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
463 440
      typedef Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> >
464 441
      Create;
465 442
    };
466 443

	
467 444
    ///@}
468 445

	
469 446
  protected:
470 447

	
471 448
    Dijkstra() {}
472 449

	
473 450
  public:
474 451

	
475 452
    ///Constructor.
476 453

	
477 454
    ///Constructor.
478 455
    ///\param _g The digraph the algorithm runs on.
479 456
    ///\param _length The length map used by the algorithm.
480 457
    Dijkstra(const Digraph& _g, const LengthMap& _length) :
481 458
      G(&_g), length(&_length),
482 459
      _pred(NULL), local_pred(false),
483 460
      _dist(NULL), local_dist(false),
484 461
      _processed(NULL), local_processed(false),
485 462
      _heap_cross_ref(NULL), local_heap_cross_ref(false),
486 463
      _heap(NULL), local_heap(false)
487 464
    { }
488 465

	
489 466
    ///Destructor.
490 467
    ~Dijkstra()
491 468
    {
492 469
      if(local_pred) delete _pred;
493 470
      if(local_dist) delete _dist;
494 471
      if(local_processed) delete _processed;
495 472
      if(local_heap_cross_ref) delete _heap_cross_ref;
496 473
      if(local_heap) delete _heap;
497 474
    }
498 475

	
499 476
    ///Sets the length map.
500 477

	
501 478
    ///Sets the length map.
502 479
    ///\return <tt> (*this) </tt>
503 480
    Dijkstra &lengthMap(const LengthMap &m)
504 481
    {
505 482
      length = &m;
506 483
      return *this;
507 484
    }
508 485

	
509 486
    ///Sets the map that stores the predecessor arcs.
510 487

	
511 488
    ///Sets the map that stores the predecessor arcs.
512 489
    ///If you don't use this function before calling \ref run(),
513 490
    ///it will allocate one. The destructor deallocates this
514 491
    ///automatically allocated map, of course.
515 492
    ///\return <tt> (*this) </tt>
516 493
    Dijkstra &predMap(PredMap &m)
517 494
    {
518 495
      if(local_pred) {
519 496
        delete _pred;
520 497
        local_pred=false;
521 498
      }
522 499
      _pred = &m;
523 500
      return *this;
524 501
    }
525 502

	
526 503
    ///Sets the map that indicates which nodes are processed.
527 504

	
528 505
    ///Sets the map that indicates which nodes are processed.
529 506
    ///If you don't use this function before calling \ref run(),
530 507
    ///it will allocate one. The destructor deallocates this
531 508
    ///automatically allocated map, of course.
532 509
    ///\return <tt> (*this) </tt>
533 510
    Dijkstra &processedMap(ProcessedMap &m)
534 511
    {
535 512
      if(local_processed) {
536 513
        delete _processed;
537 514
        local_processed=false;
538 515
      }
539 516
      _processed = &m;
540 517
      return *this;
541 518
    }
542 519

	
543 520
    ///Sets the map that stores the distances of the nodes.
544 521

	
545 522
    ///Sets the map that stores the distances of the nodes calculated by the
546 523
    ///algorithm.
547 524
    ///If you don't use this function before calling \ref run(),
548 525
    ///it will allocate one. The destructor deallocates this
549 526
    ///automatically allocated map, of course.
550 527
    ///\return <tt> (*this) </tt>
551 528
    Dijkstra &distMap(DistMap &m)
552 529
    {
553 530
      if(local_dist) {
554 531
        delete _dist;
555 532
        local_dist=false;
556 533
      }
557 534
      _dist = &m;
558 535
      return *this;
559 536
    }
560 537

	
561 538
    ///Sets the heap and the cross reference used by algorithm.
562 539

	
563 540
    ///Sets the heap and the cross reference used by algorithm.
564 541
    ///If you don't use this function before calling \ref run(),
565 542
    ///it will allocate one. The destructor deallocates this
566 543
    ///automatically allocated heap and cross reference, of course.
567 544
    ///\return <tt> (*this) </tt>
568 545
    Dijkstra &heap(Heap& hp, HeapCrossRef &cr)
569 546
    {
570 547
      if(local_heap_cross_ref) {
571 548
        delete _heap_cross_ref;
572 549
        local_heap_cross_ref=false;
573 550
      }
574 551
      _heap_cross_ref = &cr;
575 552
      if(local_heap) {
576 553
        delete _heap;
577 554
        local_heap=false;
578 555
      }
579 556
      _heap = &hp;
580 557
      return *this;
581 558
    }
582 559

	
583 560
  private:
584 561

	
585 562
    void finalizeNodeData(Node v,Value dst)
586 563
    {
587 564
      _processed->set(v,true);
588 565
      _dist->set(v, dst);
589 566
    }
590 567

	
591 568
  public:
592 569

	
593 570
    ///\name Execution control
594 571
    ///The simplest way to execute the algorithm is to use one of the
595 572
    ///member functions called \ref lemon::Dijkstra::run() "run()".
596 573
    ///\n
597 574
    ///If you need more control on the execution, first you must call
598 575
    ///\ref lemon::Dijkstra::init() "init()", then you can add several
599 576
    ///source nodes with \ref lemon::Dijkstra::addSource() "addSource()".
600 577
    ///Finally \ref lemon::Dijkstra::start() "start()" will perform the
601 578
    ///actual path computation.
602 579

	
603 580
    ///@{
604 581

	
605 582
    ///Initializes the internal data structures.
606 583

	
607 584
    ///Initializes the internal data structures.
608 585
    ///
609 586
    void init()
610 587
    {
611 588
      create_maps();
612 589
      _heap->clear();
613 590
      for ( NodeIt u(*G) ; u!=INVALID ; ++u ) {
614 591
        _pred->set(u,INVALID);
615 592
        _processed->set(u,false);
616 593
        _heap_cross_ref->set(u,Heap::PRE_HEAP);
617 594
      }
618 595
    }
619 596

	
620 597
    ///Adds a new source node.
621 598

	
622 599
    ///Adds a new source node to the priority heap.
623 600
    ///The optional second parameter is the initial distance of the node.
624 601
    ///
625 602
    ///The function checks if the node has already been added to the heap and
626 603
    ///it is pushed to the heap only if either it was not in the heap
627 604
    ///or the shortest path found till then is shorter than \c dst.
628 605
    void addSource(Node s,Value dst=OperationTraits::zero())
629 606
    {
630 607
      if(_heap->state(s) != Heap::IN_HEAP) {
631 608
        _heap->push(s,dst);
632 609
      } else if(OperationTraits::less((*_heap)[s], dst)) {
633 610
        _heap->set(s,dst);
634 611
        _pred->set(s,INVALID);
635 612
      }
636 613
    }
637 614

	
638 615
    ///Processes the next node in the priority heap
639 616

	
640 617
    ///Processes the next node in the priority heap.
641 618
    ///
642 619
    ///\return The processed node.
643 620
    ///
644 621
    ///\warning The priority heap must not be empty.
645 622
    Node processNextNode()
646 623
    {
647 624
      Node v=_heap->top();
648 625
      Value oldvalue=_heap->prio();
649 626
      _heap->pop();
650 627
      finalizeNodeData(v,oldvalue);
651 628

	
652 629
      for(OutArcIt e(*G,v); e!=INVALID; ++e) {
653 630
        Node w=G->target(e);
654 631
        switch(_heap->state(w)) {
655 632
        case Heap::PRE_HEAP:
656 633
          _heap->push(w,OperationTraits::plus(oldvalue, (*length)[e]));
657 634
          _pred->set(w,e);
658 635
          break;
659 636
        case Heap::IN_HEAP:
660 637
          {
661 638
            Value newvalue = OperationTraits::plus(oldvalue, (*length)[e]);
662 639
            if ( OperationTraits::less(newvalue, (*_heap)[w]) ) {
663 640
              _heap->decrease(w, newvalue);
664 641
              _pred->set(w,e);
665 642
            }
666 643
          }
667 644
          break;
668 645
        case Heap::POST_HEAP:
669 646
          break;
670 647
        }
671 648
      }
672 649
      return v;
673 650
    }
674 651

	
675 652
    ///The next node to be processed.
676 653

	
677 654
    ///Returns the next node to be processed or \c INVALID if the
678 655
    ///priority heap is empty.
679 656
    Node nextNode() const
680 657
    {
681 658
      return !_heap->empty()?_heap->top():INVALID;
682 659
    }
683 660

	
684 661
    ///\brief Returns \c false if there are nodes
685 662
    ///to be processed.
686 663
    ///
687 664
    ///Returns \c false if there are nodes
688 665
    ///to be processed in the priority heap.
689 666
    bool emptyQueue() const { return _heap->empty(); }
690 667

	
691 668
    ///Returns the number of the nodes to be processed in the priority heap
692 669

	
693 670
    ///Returns the number of the nodes to be processed in the priority heap.
694 671
    ///
695 672
    int queueSize() const { return _heap->size(); }
696 673

	
697 674
    ///Executes the algorithm.
698 675

	
699 676
    ///Executes the algorithm.
700 677
    ///
701 678
    ///This method runs the %Dijkstra algorithm from the root node(s)
702 679
    ///in order to compute the shortest path to each node.
703 680
    ///
704 681
    ///The algorithm computes
705 682
    ///- the shortest path tree (forest),
706 683
    ///- the distance of each node from the root(s).
707 684
    ///
708 685
    ///\pre init() must be called and at least one root node should be
709 686
    ///added with addSource() before using this function.
710 687
    ///
711 688
    ///\note <tt>d.start()</tt> is just a shortcut of the following code.
712 689
    ///\code
713 690
    ///  while ( !d.emptyQueue() ) {
714 691
    ///    d.processNextNode();
715 692
    ///  }
716 693
    ///\endcode
717 694
    void start()
718 695
    {
719 696
      while ( !emptyQueue() ) processNextNode();
720 697
    }
721 698

	
722 699
    ///Executes the algorithm until the given target node is processed.
723 700

	
724 701
    ///Executes the algorithm until the given target node is processed.
725 702
    ///
726 703
    ///This method runs the %Dijkstra algorithm from the root node(s)
727 704
    ///in order to compute the shortest path to \c t.
728 705
    ///
729 706
    ///The algorithm computes
730 707
    ///- the shortest path to \c t,
731 708
    ///- the distance of \c t from the root(s).
732 709
    ///
733 710
    ///\pre init() must be called and at least one root node should be
734 711
    ///added with addSource() before using this function.
735 712
    void start(Node t)
736 713
    {
737 714
      while ( !_heap->empty() && _heap->top()!=t ) processNextNode();
738 715
      if ( !_heap->empty() ) {
739 716
        finalizeNodeData(_heap->top(),_heap->prio());
740 717
        _heap->pop();
741 718
      }
742 719
    }
743 720

	
744 721
    ///Executes the algorithm until a condition is met.
745 722

	
746 723
    ///Executes the algorithm until a condition is met.
747 724
    ///
748 725
    ///This method runs the %Dijkstra algorithm from the root node(s) in
749 726
    ///order to compute the shortest path to a node \c v with
750 727
    /// <tt>nm[v]</tt> true, if such a node can be found.
751 728
    ///
752 729
    ///\param nm A \c bool (or convertible) node map. The algorithm
753 730
    ///will stop when it reaches a node \c v with <tt>nm[v]</tt> true.
754 731
    ///
755 732
    ///\return The reached node \c v with <tt>nm[v]</tt> true or
756 733
    ///\c INVALID if no such node was found.
757 734
    ///
758 735
    ///\pre init() must be called and at least one root node should be
759 736
    ///added with addSource() before using this function.
760 737
    template<class NodeBoolMap>
761 738
    Node start(const NodeBoolMap &nm)
762 739
    {
763 740
      while ( !_heap->empty() && !nm[_heap->top()] ) processNextNode();
764 741
      if ( _heap->empty() ) return INVALID;
765 742
      finalizeNodeData(_heap->top(),_heap->prio());
766 743
      return _heap->top();
767 744
    }
768 745

	
769 746
    ///Runs the algorithm from the given source node.
770 747

	
771 748
    ///This method runs the %Dijkstra algorithm from node \c s
772 749
    ///in order to compute the shortest path to each node.
773 750
    ///
774 751
    ///The algorithm computes
775 752
    ///- the shortest path tree,
776 753
    ///- the distance of each node from the root.
777 754
    ///
778 755
    ///\note <tt>d.run(s)</tt> is just a shortcut of the following code.
779 756
    ///\code
780 757
    ///  d.init();
781 758
    ///  d.addSource(s);
782 759
    ///  d.start();
783 760
    ///\endcode
784 761
    void run(Node s) {
785 762
      init();
786 763
      addSource(s);
787 764
      start();
788 765
    }
789 766

	
790 767
    ///Finds the shortest path between \c s and \c t.
791 768

	
792 769
    ///This method runs the %Dijkstra algorithm from node \c s
793 770
    ///in order to compute the shortest path to node \c t
794 771
    ///(it stops searching when \c t is processed).
795 772
    ///
796 773
    ///\return \c true if \c t is reachable form \c s.
797 774
    ///
798 775
    ///\note Apart from the return value, <tt>d.run(s,t)</tt> is just a
799 776
    ///shortcut of the following code.
800 777
    ///\code
801 778
    ///  d.init();
802 779
    ///  d.addSource(s);
803 780
    ///  d.start(t);
804 781
    ///\endcode
805 782
    bool run(Node s,Node t) {
806 783
      init();
807 784
      addSource(s);
808 785
      start(t);
809 786
      return (*_heap_cross_ref)[t] == Heap::POST_HEAP;
810 787
    }
811 788

	
812 789
    ///@}
813 790

	
814 791
    ///\name Query Functions
815 792
    ///The result of the %Dijkstra algorithm can be obtained using these
816 793
    ///functions.\n
817 794
    ///Either \ref lemon::Dijkstra::run() "run()" or
818 795
    ///\ref lemon::Dijkstra::start() "start()" must be called before
819 796
    ///using them.
820 797

	
821 798
    ///@{
822 799

	
823 800
    ///The shortest path to a node.
824 801

	
825 802
    ///Returns the shortest path to a node.
826 803
    ///
827 804
    ///\warning \c t should be reachable from the root(s).
828 805
    ///
829 806
    ///\pre Either \ref run() or \ref start() must be called before
830 807
    ///using this function.
831 808
    Path path(Node t) const { return Path(*G, *_pred, t); }
832 809

	
833 810
    ///The distance of a node from the root(s).
834 811

	
835 812
    ///Returns the distance of a node from the root(s).
836 813
    ///
837 814
    ///\warning If node \c v is not reachable from the root(s), then
838 815
    ///the return value of this function is undefined.
839 816
    ///
840 817
    ///\pre Either \ref run() or \ref start() must be called before
841 818
    ///using this function.
842 819
    Value dist(Node v) const { return (*_dist)[v]; }
843 820

	
844 821
    ///Returns the 'previous arc' of the shortest path tree for a node.
845 822

	
846 823
    ///This function returns the 'previous arc' of the shortest path
847 824
    ///tree for the node \c v, i.e. it returns the last arc of a
Show white space 1536 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-2008
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
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/smart_graph.h>
21 21
#include <lemon/list_graph.h>
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/dijkstra.h>
24 24
#include <lemon/path.h>
25 25
#include <lemon/bin_heap.h>
26 26

	
27 27
#include "graph_test.h"
28 28
#include "test_tools.h"
29 29

	
30 30
using namespace lemon;
31 31

	
32 32
char test_lgf[] =
33 33
  "@nodes\n"
34 34
  "label\n"
35 35
  "0\n"
36 36
  "1\n"
37 37
  "2\n"
38 38
  "3\n"
39 39
  "4\n"
40 40
  "@arcs\n"
41 41
  "     label length\n"
42 42
  "0 1  0     1\n"
43 43
  "1 2  1     1\n"
44 44
  "2 3  2     1\n"
45 45
  "0 3  4     5\n"
46 46
  "0 3  5     10\n"
47 47
  "0 3  6     7\n"
48 48
  "4 2  7     1\n"
49 49
  "@attributes\n"
50 50
  "source 0\n"
51 51
  "target 3\n";
52 52

	
53 53
void checkDijkstraCompile()
54 54
{
55 55
  typedef int VType;
56 56
  typedef concepts::Digraph Digraph;
57 57
  typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
58 58
  typedef Dijkstra<Digraph, LengthMap> DType;
59 59
  typedef Digraph::Node Node;
60 60
  typedef Digraph::Arc Arc;
61 61

	
62 62
  Digraph G;
63 63
  Node s, t;
64 64
  Arc e;
65 65
  VType l;
66 66
  bool b;
67 67
  DType::DistMap d(G);
68 68
  DType::PredMap p(G);
69 69
  LengthMap length;
70 70
  Path<Digraph> pp;
71 71

	
72 72
  {
73 73
    DType dijkstra_test(G,length);
74 74

	
75 75
    dijkstra_test.run(s);
76 76
    dijkstra_test.run(s,t);
77 77

	
78 78
    l  = dijkstra_test.dist(t);
79 79
    e  = dijkstra_test.predArc(t);
80 80
    s  = dijkstra_test.predNode(t);
81 81
    b  = dijkstra_test.reached(t);
82 82
    d  = dijkstra_test.distMap();
83 83
    p  = dijkstra_test.predMap();
84 84
    pp = dijkstra_test.path(t);
85 85
  }
86 86
  {
87 87
    DType
88 88
      ::SetPredMap<concepts::ReadWriteMap<Node,Arc> >
89 89
      ::SetDistMap<concepts::ReadWriteMap<Node,VType> >
90 90
      ::SetProcessedMap<concepts::WriteMap<Node,bool> >
91 91
      ::SetStandardProcessedMap
92
      ::SetOperationTraits<DijkstraWidestPathOperationTraits<VType> >
92
      ::SetOperationTraits<DijkstraDefaultOperationTraits<VType> >
93 93
      ::SetHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
94 94
      ::SetStandardHeap<BinHeap<VType, concepts::ReadWriteMap<Node,int> > >
95 95
      ::Create dijkstra_test(G,length);
96 96

	
97 97
    dijkstra_test.run(s);
98 98
    dijkstra_test.run(s,t);
99 99

	
100 100
    l  = dijkstra_test.dist(t);
101 101
    e  = dijkstra_test.predArc(t);
102 102
    s  = dijkstra_test.predNode(t);
103 103
    b  = dijkstra_test.reached(t);
104 104
    pp = dijkstra_test.path(t);
105 105
  }
106 106

	
107 107
}
108 108

	
109 109
void checkDijkstraFunctionCompile()
110 110
{
111 111
  typedef int VType;
112 112
  typedef concepts::Digraph Digraph;
113 113
  typedef Digraph::Arc Arc;
114 114
  typedef Digraph::Node Node;
115 115
  typedef concepts::ReadMap<Digraph::Arc,VType> LengthMap;
116 116

	
117 117
  Digraph g;
118 118
  bool b;
119 119
  dijkstra(g,LengthMap()).run(Node());
120 120
  b=dijkstra(g,LengthMap()).run(Node(),Node());
121 121
  dijkstra(g,LengthMap())
122 122
    .predMap(concepts::ReadWriteMap<Node,Arc>())
123 123
    .distMap(concepts::ReadWriteMap<Node,VType>())
124 124
    .processedMap(concepts::WriteMap<Node,bool>())
125 125
    .run(Node());
126 126
  b=dijkstra(g,LengthMap())
127 127
    .predMap(concepts::ReadWriteMap<Node,Arc>())
128 128
    .distMap(concepts::ReadWriteMap<Node,VType>())
129 129
    .processedMap(concepts::WriteMap<Node,bool>())
130 130
    .path(concepts::Path<Digraph>())
131 131
    .dist(VType())
132 132
    .run(Node(),Node());
133 133
}
134 134

	
135 135
template <class Digraph>
136 136
void checkDijkstra() {
137 137
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
138 138
  typedef typename Digraph::template ArcMap<int> LengthMap;
139 139

	
140 140
  Digraph G;
141 141
  Node s, t;
142 142
  LengthMap length(G);
143 143

	
144 144
  std::istringstream input(test_lgf);
145 145
  digraphReader(G, input).
146 146
    arcMap("length", length).
147 147
    node("source", s).
148 148
    node("target", t).
149 149
    run();
150 150

	
151 151
  Dijkstra<Digraph, LengthMap>
152 152
        dijkstra_test(G, length);
153 153
  dijkstra_test.run(s);
154 154

	
155 155
  check(dijkstra_test.dist(t)==3,"Dijkstra found a wrong path.");
156 156

	
157 157
  Path<Digraph> p = dijkstra_test.path(t);
158 158
  check(p.length()==3,"path() found a wrong path.");
159 159
  check(checkPath(G, p),"path() found a wrong path.");
160 160
  check(pathSource(G, p) == s,"path() found a wrong path.");
161 161
  check(pathTarget(G, p) == t,"path() found a wrong path.");
162 162

	
163 163
  for(ArcIt e(G); e!=INVALID; ++e) {
164 164
    Node u=G.source(e);
165 165
    Node v=G.target(e);
166 166
    check( !dijkstra_test.reached(u) ||
167 167
           (dijkstra_test.dist(v) - dijkstra_test.dist(u) <= length[e]),
168 168
           "Wrong output. dist(target)-dist(source)-arc_length=" <<
169 169
           dijkstra_test.dist(v) - dijkstra_test.dist(u) - length[e]);
170 170
  }
171 171

	
172 172
  for(NodeIt v(G); v!=INVALID; ++v) {
173 173
    if (dijkstra_test.reached(v)) {
174 174
      check(v==s || dijkstra_test.predArc(v)!=INVALID, "Wrong tree.");
175 175
      if (dijkstra_test.predArc(v)!=INVALID ) {
176 176
        Arc e=dijkstra_test.predArc(v);
177 177
        Node u=G.source(e);
178 178
        check(u==dijkstra_test.predNode(v),"Wrong tree.");
179 179
        check(dijkstra_test.dist(v) - dijkstra_test.dist(u) == length[e],
180 180
              "Wrong distance! Difference: " <<
181 181
              std::abs(dijkstra_test.dist(v)-dijkstra_test.dist(u)-length[e]));
182 182
      }
183 183
    }
184 184
  }
185 185

	
186 186
  {
187 187
    NullMap<Node,Arc> myPredMap;
188 188
    dijkstra(G,length).predMap(myPredMap).run(s);
189 189
  }
190 190
}
191 191

	
192 192
int main() {
193 193
  checkDijkstra<ListDigraph>();
194 194
  checkDijkstra<SmartDigraph>();
195 195
  return 0;
196 196
}
0 comments (0 inline)