gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Avoid STL panic at Elevator when compiled with -D_GLIBCXX_DEBUG
0 1 0
default
1 file changed with 7 insertions and 7 deletions:
↑ Collapse diff ↑
Ignore white space 192 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_ELEVATOR_H
20 20
#define LEMON_ELEVATOR_H
21 21

	
22 22
///\ingroup auxdat
23 23
///\file
24 24
///\brief Elevator class
25 25
///
26 26
///Elevator class implements an efficient data structure
27 27
///for labeling items in push-relabel type algorithms.
28 28
///
29 29

	
30 30
#include <test/test_tools.h>
31 31
namespace lemon {
32 32

	
33 33
  ///Class for handling "labels" in push-relabel type algorithms.
34 34

	
35 35
  ///A class for handling "labels" in push-relabel type algorithms.
36 36
  ///
37 37
  ///\ingroup auxdat
38 38
  ///Using this class you can assign "labels" (nonnegative integer numbers)
39 39
  ///to the edges or nodes of a graph, manipulate and query them through
40 40
  ///operations typically arising in "push-relabel" type algorithms.
41 41
  ///
42 42
  ///Each item is either \em active or not, and you can also choose a
43 43
  ///highest level active item.
44 44
  ///
45 45
  ///\sa LinkedElevator
46 46
  ///
47 47
  ///\param Graph the underlying graph type
48 48
  ///\param Item Type of the items the data is assigned to (Graph::Node,
49 49
  ///Graph::Edge, Graph::UEdge)
50 50
  template<class Graph, class Item>
51 51
  class Elevator
52 52
  {
53 53
  public:
54 54

	
55 55
    typedef Item Key;
56 56
    typedef int Value;
57 57

	
58 58
  private:
59 59

	
60
    typedef typename std::vector<Item>::iterator Vit;
60
    typedef Item *Vit;
61 61
    typedef typename ItemSetTraits<Graph,Item>::template Map<Vit>::Type VitMap;
62 62
    typedef typename ItemSetTraits<Graph,Item>::template Map<int>::Type IntMap;
63 63

	
64 64
    const Graph &_g;
65 65
    int _max_level;
66 66
    int _item_num;
67 67
    VitMap _where;
68 68
    IntMap _level;
69 69
    std::vector<Item> _items;
70 70
    std::vector<Vit> _first;
71 71
    std::vector<Vit> _last_active;
72 72

	
73 73
    int _highest_active;
74 74

	
75 75
    void copy(Item i, Vit p)
76 76
    {
77 77
      _where[*p=i]=p;
78 78
    }
79 79
    void copy(Vit s, Vit p)
80 80
    {
81 81
      if(s!=p)
82 82
        {
83 83
          Item i=*s;
84 84
          *p=i;
85 85
          _where[i]=p;
86 86
        }
87 87
    }
88 88
    void swap(Vit i, Vit j)
89 89
    {
90 90
      Item ti=*i;
91 91
      Vit ct = _where[ti];
92 92
      _where[ti]=_where[*i=*j];
93 93
      _where[*j]=ct;
94 94
      *j=ti;
95 95
    }
96 96

	
97 97
  public:
98 98

	
99 99
    ///Constructor with given maximum level.
100 100

	
101 101
    ///Constructor with given maximum level.
102 102
    ///
103 103
    ///\param g The underlying graph
104 104
    ///\param max_level Set the range of the possible labels to
105 105
    ///[0...\c max_level]
106 106
    Elevator(const Graph &g,int max_level) :
107 107
      _g(g),
108 108
      _max_level(max_level),
109 109
      _item_num(_max_level),
110 110
      _where(g),
111 111
      _level(g,0),
112 112
      _items(_max_level),
113 113
      _first(_max_level+2),
114 114
      _last_active(_max_level+2),
115 115
      _highest_active(-1) {}
116 116
    ///Constructor.
117 117

	
118 118
    ///Constructor.
119 119
    ///
120 120
    ///\param g The underlying graph
121 121
    ///The range of the possible labels is [0...\c max_level],
122 122
    ///where \c max_level is equal to the number of labeled items in the graph.
123 123
    Elevator(const Graph &g) :
124 124
      _g(g),
125 125
      _max_level(countItems<Graph, Item>(g)),
126 126
      _item_num(_max_level),
127 127
      _where(g),
128 128
      _level(g,0),
129 129
      _items(_max_level),
130 130
      _first(_max_level+2),
131 131
      _last_active(_max_level+2),
132 132
      _highest_active(-1)
133 133
    {
134 134
    }
135 135

	
136 136
    ///Activate item \c i.
137 137

	
138 138
    ///Activate item \c i.
139 139
    ///\pre Item \c i shouldn't be active before.
140 140
    void activate(Item i)
141 141
    {
142 142
      const int l=_level[i];
143 143
      swap(_where[i],++_last_active[l]);
144 144
      if(l>_highest_active) _highest_active=l;
145 145
    }
146 146

	
147 147
    ///Deactivate item \c i.
148 148

	
149 149
    ///Deactivate item \c i.
150 150
    ///\pre Item \c i must be active before.
151 151
    void deactivate(Item i)
152 152
    {
153 153
      swap(_where[i],_last_active[_level[i]]--);
154 154
      while(_highest_active>=0 &&
155 155
            _last_active[_highest_active]<_first[_highest_active])
156 156
        _highest_active--;
... ...
@@ -340,236 +340,236 @@
340 340
      copy(--_first[level+1],_last_active[level]--);
341 341
      for(int l=level+1;l<_max_level;l++)
342 342
        {
343 343
          copy(_last_active[l],_first[l]);
344 344
          copy(--_first[l+1], _last_active[l]--);
345 345
        }
346 346
      copy(ai,_first[_max_level]);
347 347
      --_last_active[_max_level];
348 348
      _level[ai]=_max_level;
349 349

	
350 350
      if (_highest_active==level) {
351 351
        while(_highest_active>=0 &&
352 352
              _last_active[_highest_active]<_first[_highest_active])
353 353
          _highest_active--;
354 354
      }
355 355
    }
356 356

	
357 357
    ///@}
358 358

	
359 359
    ///Lift an active item to a higher level.
360 360

	
361 361
    ///Lift an active item to a higher level.
362 362
    ///\param i The item to be lifted. It must be active.
363 363
    ///\param new_level The new level of \c i. It must be strictly higher
364 364
    ///than the current level.
365 365
    ///
366 366
    void lift(Item i, int new_level)
367 367
    {
368 368
      const int lo = _level[i];
369 369
      const Vit w = _where[i];
370 370

	
371 371
      copy(_last_active[lo],w);
372 372
      copy(--_first[lo+1],_last_active[lo]--);
373 373
      for(int l=lo+1;l<new_level;l++)
374 374
        {
375 375
          copy(_last_active[l],_first[l]);
376 376
          copy(--_first[l+1],_last_active[l]--);
377 377
        }
378 378
      copy(i,_first[new_level]);
379 379
      _level[i]=new_level;
380 380
      if(new_level>_highest_active) _highest_active=new_level;
381 381
    }
382 382

	
383 383
    ///Move an inactive item to the top but one level (in a dirty way).
384 384

	
385 385
    ///This function moves an inactive item to the top but one level.
386 386
    ///It makes the underlying datastructure corrupt, so use is only if
387 387
    ///you really know what it is for.
388 388
    ///\pre The item is on the top level.
389 389
    void dirtyTopButOne(Item i) {
390 390
      _level[i] = _max_level - 1;
391 391
    }
392 392

	
393 393
    ///Lift all items on and above a level to the top (and deactivate them).
394 394

	
395 395
    ///This function lifts all items on and above level \c l to \c
396 396
    ///maxLevel(), and also deactivates them.
397 397
    void liftToTop(int l)
398 398
    {
399 399
      const Vit f=_first[l];
400 400
      const Vit tl=_first[_max_level];
401 401
      for(Vit i=f;i!=tl;++i)
402 402
        _level[*i]=_max_level;
403 403
      for(int i=l;i<=_max_level;i++)
404 404
        {
405 405
          _first[i]=f;
406 406
          _last_active[i]=f-1;
407 407
        }
408 408
      for(_highest_active=l-1;
409 409
          _highest_active>=0 &&
410 410
            _last_active[_highest_active]<_first[_highest_active];
411 411
          _highest_active--) ;
412 412
    }
413 413

	
414 414
  private:
415 415
    int _init_lev;
416 416
    Vit _init_num;
417 417

	
418 418
  public:
419 419

	
420 420
    ///\name Initialization
421 421
    ///Using this function you can initialize the levels of the item.
422 422
    ///\n
423 423
    ///This initializatios is started with calling \c initStart().
424 424
    ///Then the
425 425
    ///items should be listed levels by levels statring with the lowest one
426 426
    ///(with level 0). This is done by using \c initAddItem()
427 427
    ///and \c initNewLevel(). Finally \c initFinish() must be called.
428 428
    ///The items not listed will be put on the highest level.
429 429
    ///@{
430 430

	
431 431
    ///Start the initialization process.
432 432

	
433 433
    void initStart()
434 434
    {
435 435
      _init_lev=0;
436
      _init_num=_items.begin();
437
      _first[0]=_items.begin();
438
      _last_active[0]=_items.begin()-1;
439
      Vit n=_items.begin();
436
      _init_num=&_items[0];
437
      _first[0]=&_items[0];
438
      _last_active[0]=&_items[0]-1;
439
      Vit n=&_items[0];
440 440
      for(typename ItemSetTraits<Graph,Item>::ItemIt i(_g);i!=INVALID;++i)
441 441
        {
442 442
          *n=i;
443 443
          _where[i]=n;
444 444
          _level[i]=_max_level;
445 445
          ++n;
446 446
        }
447 447
    }
448 448

	
449 449
    ///Add an item to the current level.
450 450

	
451 451
    void initAddItem(Item i)
452 452
    {
453 453
     swap(_where[i],_init_num);
454 454
      _level[i]=_init_lev;
455 455
      ++_init_num;
456 456
    }
457 457

	
458 458
    ///Start a new level.
459 459

	
460 460
    ///Start a new level.
461 461
    ///It shouldn't be used before the items on level 0 are listed.
462 462
    void initNewLevel()
463 463
    {
464 464
      _init_lev++;
465 465
      _first[_init_lev]=_init_num;
466 466
      _last_active[_init_lev]=_init_num-1;
467 467
    }
468 468

	
469 469
    ///Finalize the initialization process.
470 470

	
471 471
    void initFinish()
472 472
    {
473 473
      for(_init_lev++;_init_lev<=_max_level;_init_lev++)
474 474
        {
475 475
          _first[_init_lev]=_init_num;
476 476
          _last_active[_init_lev]=_init_num-1;
477 477
        }
478
      _first[_max_level+1]=_items.begin()+_item_num;
479
      _last_active[_max_level+1]=_items.begin()+_item_num-1;
478
      _first[_max_level+1]=&_items[0]+_item_num;
479
      _last_active[_max_level+1]=&_items[0]+_item_num-1;
480 480
      _highest_active = -1;
481 481
    }
482 482

	
483 483
    ///@}
484 484

	
485 485
  };
486 486

	
487 487
  ///Class for handling "labels" in push-relabel type algorithms.
488 488

	
489 489
  ///A class for handling "labels" in push-relabel type algorithms.
490 490
  ///
491 491
  ///\ingroup auxdat
492 492
  ///Using this class you can assign "labels" (nonnegative integer numbers)
493 493
  ///to the edges or nodes of a graph, manipulate and query them through
494 494
  ///operations typically arising in "push-relabel" type algorithms.
495 495
  ///
496 496
  ///Each item is either \em active or not, and you can also choose a
497 497
  ///highest level active item.
498 498
  ///
499 499
  ///\sa Elevator
500 500
  ///
501 501
  ///\param Graph the underlying graph type
502 502
  ///\param Item Type of the items the data is assigned to (Graph::Node,
503 503
  ///Graph::Edge, Graph::UEdge)
504 504
  template <class Graph, class Item>
505 505
  class LinkedElevator {
506 506
  public:
507 507

	
508 508
    typedef Item Key;
509 509
    typedef int Value;
510 510

	
511 511
  private:
512 512

	
513 513
    typedef typename ItemSetTraits<Graph,Item>::
514 514
    template Map<Item>::Type ItemMap;
515 515
    typedef typename ItemSetTraits<Graph,Item>::
516 516
    template Map<int>::Type IntMap;
517 517
    typedef typename ItemSetTraits<Graph,Item>::
518 518
    template Map<bool>::Type BoolMap;
519 519

	
520 520
    const Graph &_graph;
521 521
    int _max_level;
522 522
    int _item_num;
523 523
    std::vector<Item> _first, _last;
524 524
    ItemMap _prev, _next;
525 525
    int _highest_active;
526 526
    IntMap _level;
527 527
    BoolMap _active;
528 528

	
529 529
  public:
530 530
    ///Constructor with given maximum level.
531 531

	
532 532
    ///Constructor with given maximum level.
533 533
    ///
534 534
    ///\param g The underlying graph
535 535
    ///\param max_level Set the range of the possible labels to
536 536
    ///[0...\c max_level]
537 537
    LinkedElevator(const Graph& graph, int max_level)
538 538
      : _graph(graph), _max_level(max_level), _item_num(_max_level),
539 539
        _first(_max_level + 1), _last(_max_level + 1),
540 540
        _prev(graph), _next(graph),
541 541
        _highest_active(-1), _level(graph), _active(graph) {}
542 542

	
543 543
    ///Constructor.
544 544

	
545 545
    ///Constructor.
546 546
    ///
547 547
    ///\param g The underlying graph
548 548
    ///The range of the possible labels is [0...\c max_level],
549 549
    ///where \c max_level is equal to the number of labeled items in the graph.
550 550
    LinkedElevator(const Graph& graph)
551 551
      : _graph(graph), _max_level(countItems<Graph, Item>(graph)),
552 552
        _item_num(_max_level),
553 553
        _first(_max_level + 1), _last(_max_level + 1),
554 554
        _prev(graph, INVALID), _next(graph, INVALID),
555 555
        _highest_active(-1), _level(graph), _active(graph) {}
556 556

	
557 557

	
558 558
    ///Activate item \c i.
559 559

	
560 560
    ///Activate item \c i.
561 561
    ///\pre Item \c i shouldn't be active before.
562 562
    void activate(Item i) {
563 563
      _active.set(i, true);
564 564

	
565 565
      int level = _level[i];
566 566
      if (level > _highest_active) {
567 567
        _highest_active = level;
568 568
      }
569 569

	
570 570
      if (_prev[i] == INVALID || _active[_prev[i]]) return;
571 571
      //unlace
572 572
      _next.set(_prev[i], _next[i]);
573 573
      if (_next[i] != INVALID) {
574 574
        _prev.set(_next[i], _prev[i]);
575 575
      } else {
0 comments (0 inline)