gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge bugfix #414
0 2 0
merge default
2 files changed with 30 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 256 line context
... ...
@@ -418,273 +418,271 @@
418 418
    /// Initializes the internal data structures and sets the initial
419 419
    /// flow to zero on each arc.
420 420
    void init() {
421 421
      createStructures();
422 422

	
423 423
      _phase = true;
424 424
      for (NodeIt n(_graph); n != INVALID; ++n) {
425 425
        (*_excess)[n] = 0;
426 426
      }
427 427

	
428 428
      for (ArcIt e(_graph); e != INVALID; ++e) {
429 429
        _flow->set(e, 0);
430 430
      }
431 431

	
432 432
      typename Digraph::template NodeMap<bool> reached(_graph, false);
433 433

	
434 434
      _level->initStart();
435 435
      _level->initAddItem(_target);
436 436

	
437 437
      std::vector<Node> queue;
438 438
      reached[_source] = true;
439 439

	
440 440
      queue.push_back(_target);
441 441
      reached[_target] = true;
442 442
      while (!queue.empty()) {
443 443
        _level->initNewLevel();
444 444
        std::vector<Node> nqueue;
445 445
        for (int i = 0; i < int(queue.size()); ++i) {
446 446
          Node n = queue[i];
447 447
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
448 448
            Node u = _graph.source(e);
449 449
            if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
450 450
              reached[u] = true;
451 451
              _level->initAddItem(u);
452 452
              nqueue.push_back(u);
453 453
            }
454 454
          }
455 455
        }
456 456
        queue.swap(nqueue);
457 457
      }
458 458
      _level->initFinish();
459 459

	
460 460
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
461 461
        if (_tolerance.positive((*_capacity)[e])) {
462 462
          Node u = _graph.target(e);
463 463
          if ((*_level)[u] == _level->maxLevel()) continue;
464 464
          _flow->set(e, (*_capacity)[e]);
465 465
          (*_excess)[u] += (*_capacity)[e];
466 466
          if (u != _target && !_level->active(u)) {
467 467
            _level->activate(u);
468 468
          }
469 469
        }
470 470
      }
471 471
    }
472 472

	
473 473
    /// \brief Initializes the internal data structures using the
474 474
    /// given flow map.
475 475
    ///
476 476
    /// Initializes the internal data structures and sets the initial
477 477
    /// flow to the given \c flowMap. The \c flowMap should contain a
478 478
    /// flow or at least a preflow, i.e. at each node excluding the
479 479
    /// source node the incoming flow should greater or equal to the
480 480
    /// outgoing flow.
481 481
    /// \return \c false if the given \c flowMap is not a preflow.
482 482
    template <typename FlowMap>
483 483
    bool init(const FlowMap& flowMap) {
484 484
      createStructures();
485 485

	
486 486
      for (ArcIt e(_graph); e != INVALID; ++e) {
487 487
        _flow->set(e, flowMap[e]);
488 488
      }
489 489

	
490 490
      for (NodeIt n(_graph); n != INVALID; ++n) {
491 491
        Value excess = 0;
492 492
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
493 493
          excess += (*_flow)[e];
494 494
        }
495 495
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
496 496
          excess -= (*_flow)[e];
497 497
        }
498 498
        if (excess < 0 && n != _source) return false;
499 499
        (*_excess)[n] = excess;
500 500
      }
501 501

	
502 502
      typename Digraph::template NodeMap<bool> reached(_graph, false);
503 503

	
504 504
      _level->initStart();
505 505
      _level->initAddItem(_target);
506 506

	
507 507
      std::vector<Node> queue;
508 508
      reached[_source] = true;
509 509

	
510 510
      queue.push_back(_target);
511 511
      reached[_target] = true;
512 512
      while (!queue.empty()) {
513 513
        _level->initNewLevel();
514 514
        std::vector<Node> nqueue;
515 515
        for (int i = 0; i < int(queue.size()); ++i) {
516 516
          Node n = queue[i];
517 517
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
518 518
            Node u = _graph.source(e);
519 519
            if (!reached[u] &&
520 520
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
521 521
              reached[u] = true;
522 522
              _level->initAddItem(u);
523 523
              nqueue.push_back(u);
524 524
            }
525 525
          }
526 526
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
527 527
            Node v = _graph.target(e);
528 528
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
529 529
              reached[v] = true;
530 530
              _level->initAddItem(v);
531 531
              nqueue.push_back(v);
532 532
            }
533 533
          }
534 534
        }
535 535
        queue.swap(nqueue);
536 536
      }
537 537
      _level->initFinish();
538 538

	
539 539
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
540 540
        Value rem = (*_capacity)[e] - (*_flow)[e];
541 541
        if (_tolerance.positive(rem)) {
542 542
          Node u = _graph.target(e);
543 543
          if ((*_level)[u] == _level->maxLevel()) continue;
544 544
          _flow->set(e, (*_capacity)[e]);
545 545
          (*_excess)[u] += rem;
546
          if (u != _target && !_level->active(u)) {
547
            _level->activate(u);
548
          }
549 546
        }
550 547
      }
551 548
      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
552 549
        Value rem = (*_flow)[e];
553 550
        if (_tolerance.positive(rem)) {
554 551
          Node v = _graph.source(e);
555 552
          if ((*_level)[v] == _level->maxLevel()) continue;
556 553
          _flow->set(e, 0);
557 554
          (*_excess)[v] += rem;
558
          if (v != _target && !_level->active(v)) {
559
            _level->activate(v);
560
          }
561 555
        }
562 556
      }
557
      for (NodeIt n(_graph); n != INVALID; ++n) 
558
        if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n]))
559
          _level->activate(n);
560
          
563 561
      return true;
564 562
    }
565 563

	
566 564
    /// \brief Starts the first phase of the preflow algorithm.
567 565
    ///
568 566
    /// The preflow algorithm consists of two phases, this method runs
569 567
    /// the first phase. After the first phase the maximum flow value
570 568
    /// and a minimum value cut can already be computed, although a
571 569
    /// maximum flow is not yet obtained. So after calling this method
572 570
    /// \ref flowValue() returns the value of a maximum flow and \ref
573 571
    /// minCut() returns a minimum cut.
574 572
    /// \pre One of the \ref init() functions must be called before
575 573
    /// using this function.
576 574
    void startFirstPhase() {
577 575
      _phase = true;
578 576

	
579 577
      while (true) {
580 578
        int num = _node_num;
581 579

	
582 580
        Node n = INVALID;
583 581
        int level = -1;
584 582

	
585 583
        while (num > 0) {
586 584
          n = _level->highestActive();
587 585
          if (n == INVALID) goto first_phase_done;
588 586
          level = _level->highestActiveLevel();
589 587
          --num;
590 588
          
591 589
          Value excess = (*_excess)[n];
592 590
          int new_level = _level->maxLevel();
593 591

	
594 592
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
595 593
            Value rem = (*_capacity)[e] - (*_flow)[e];
596 594
            if (!_tolerance.positive(rem)) continue;
597 595
            Node v = _graph.target(e);
598 596
            if ((*_level)[v] < level) {
599 597
              if (!_level->active(v) && v != _target) {
600 598
                _level->activate(v);
601 599
              }
602 600
              if (!_tolerance.less(rem, excess)) {
603 601
                _flow->set(e, (*_flow)[e] + excess);
604 602
                (*_excess)[v] += excess;
605 603
                excess = 0;
606 604
                goto no_more_push_1;
607 605
              } else {
608 606
                excess -= rem;
609 607
                (*_excess)[v] += rem;
610 608
                _flow->set(e, (*_capacity)[e]);
611 609
              }
612 610
            } else if (new_level > (*_level)[v]) {
613 611
              new_level = (*_level)[v];
614 612
            }
615 613
          }
616 614

	
617 615
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
618 616
            Value rem = (*_flow)[e];
619 617
            if (!_tolerance.positive(rem)) continue;
620 618
            Node v = _graph.source(e);
621 619
            if ((*_level)[v] < level) {
622 620
              if (!_level->active(v) && v != _target) {
623 621
                _level->activate(v);
624 622
              }
625 623
              if (!_tolerance.less(rem, excess)) {
626 624
                _flow->set(e, (*_flow)[e] - excess);
627 625
                (*_excess)[v] += excess;
628 626
                excess = 0;
629 627
                goto no_more_push_1;
630 628
              } else {
631 629
                excess -= rem;
632 630
                (*_excess)[v] += rem;
633 631
                _flow->set(e, 0);
634 632
              }
635 633
            } else if (new_level > (*_level)[v]) {
636 634
              new_level = (*_level)[v];
637 635
            }
638 636
          }
639 637

	
640 638
        no_more_push_1:
641 639

	
642 640
          (*_excess)[n] = excess;
643 641

	
644 642
          if (excess != 0) {
645 643
            if (new_level + 1 < _level->maxLevel()) {
646 644
              _level->liftHighestActive(new_level + 1);
647 645
            } else {
648 646
              _level->liftHighestActiveToTop();
649 647
            }
650 648
            if (_level->emptyLevel(level)) {
651 649
              _level->liftToTop(level);
652 650
            }
653 651
          } else {
654 652
            _level->deactivate(n);
655 653
          }
656 654
        }
657 655

	
658 656
        num = _node_num * 20;
659 657
        while (num > 0) {
660 658
          while (level >= 0 && _level->activeFree(level)) {
661 659
            --level;
662 660
          }
663 661
          if (level == -1) {
664 662
            n = _level->highestActive();
665 663
            level = _level->highestActiveLevel();
666 664
            if (n == INVALID) goto first_phase_done;
667 665
          } else {
668 666
            n = _level->activeOn(level);
669 667
          }
670 668
          --num;
671 669

	
672 670
          Value excess = (*_excess)[n];
673 671
          int new_level = _level->maxLevel();
674 672

	
675 673
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
676 674
            Value rem = (*_capacity)[e] - (*_flow)[e];
677 675
            if (!_tolerance.positive(rem)) continue;
678 676
            Node v = _graph.target(e);
679 677
            if ((*_level)[v] < level) {
680 678
              if (!_level->active(v) && v != _target) {
681 679
                _level->activate(v);
682 680
              }
683 681
              if (!_tolerance.less(rem, excess)) {
684 682
                _flow->set(e, (*_flow)[e] + excess);
685 683
                (*_excess)[v] += excess;
686 684
                excess = 0;
687 685
                goto no_more_push_2;
688 686
              } else {
689 687
                excess -= rem;
690 688
                (*_excess)[v] += rem;
Ignore white space 256 line context
... ...
@@ -31,220 +31,246 @@
31 31
char test_lgf[] =
32 32
  "@nodes\n"
33 33
  "label\n"
34 34
  "0\n"
35 35
  "1\n"
36 36
  "2\n"
37 37
  "3\n"
38 38
  "4\n"
39 39
  "5\n"
40 40
  "6\n"
41 41
  "7\n"
42 42
  "8\n"
43 43
  "9\n"
44 44
  "@arcs\n"
45 45
  "    label capacity\n"
46 46
  "0 1 0     20\n"
47 47
  "0 2 1     0\n"
48 48
  "1 1 2     3\n"
49 49
  "1 2 3     8\n"
50 50
  "1 3 4     8\n"
51 51
  "2 5 5     5\n"
52 52
  "3 2 6     5\n"
53 53
  "3 5 7     5\n"
54 54
  "3 6 8     5\n"
55 55
  "4 3 9     3\n"
56 56
  "5 7 10    3\n"
57 57
  "5 6 11    10\n"
58 58
  "5 8 12    10\n"
59 59
  "6 8 13    8\n"
60 60
  "8 9 14    20\n"
61 61
  "8 1 15    5\n"
62 62
  "9 5 16    5\n"
63 63
  "@attributes\n"
64 64
  "source 1\n"
65 65
  "target 8\n";
66 66

	
67 67
void checkPreflowCompile()
68 68
{
69 69
  typedef int VType;
70 70
  typedef concepts::Digraph Digraph;
71 71

	
72 72
  typedef Digraph::Node Node;
73 73
  typedef Digraph::Arc Arc;
74 74
  typedef concepts::ReadMap<Arc,VType> CapMap;
75 75
  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
76 76
  typedef concepts::WriteMap<Node,bool> CutMap;
77 77

	
78 78
  typedef Elevator<Digraph, Digraph::Node> Elev;
79 79
  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
80 80

	
81 81
  Digraph g;
82 82
  Node n;
83 83
  Arc e;
84 84
  CapMap cap;
85 85
  FlowMap flow;
86 86
  CutMap cut;
87 87
  VType v;
88 88
  bool b;
89 89

	
90 90
  typedef Preflow<Digraph, CapMap>
91 91
            ::SetFlowMap<FlowMap>
92 92
            ::SetElevator<Elev>
93 93
            ::SetStandardElevator<LinkedElev>
94 94
            ::Create PreflowType;
95 95
  PreflowType preflow_test(g, cap, n, n);
96 96
  const PreflowType& const_preflow_test = preflow_test;
97 97

	
98 98
  const PreflowType::Elevator& elev = const_preflow_test.elevator();
99 99
  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
100 100
  PreflowType::Tolerance tol = const_preflow_test.tolerance();
101 101
  preflow_test.tolerance(tol);
102 102

	
103 103
  preflow_test
104 104
    .capacityMap(cap)
105 105
    .flowMap(flow)
106 106
    .source(n)
107 107
    .target(n);
108 108

	
109 109
  preflow_test.init();
110 110
  preflow_test.init(cap);
111 111
  preflow_test.startFirstPhase();
112 112
  preflow_test.startSecondPhase();
113 113
  preflow_test.run();
114 114
  preflow_test.runMinCut();
115 115

	
116 116
  v = const_preflow_test.flowValue();
117 117
  v = const_preflow_test.flow(e);
118 118
  const FlowMap& fm = const_preflow_test.flowMap();
119 119
  b = const_preflow_test.minCut(n);
120 120
  const_preflow_test.minCutMap(cut);
121 121

	
122 122
  ignore_unused_variable_warning(fm);
123 123
}
124 124

	
125 125
int cutValue (const SmartDigraph& g,
126 126
              const SmartDigraph::NodeMap<bool>& cut,
127 127
              const SmartDigraph::ArcMap<int>& cap) {
128 128

	
129 129
  int c=0;
130 130
  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
131 131
    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
132 132
  }
133 133
  return c;
134 134
}
135 135

	
136 136
bool checkFlow(const SmartDigraph& g,
137 137
               const SmartDigraph::ArcMap<int>& flow,
138 138
               const SmartDigraph::ArcMap<int>& cap,
139 139
               SmartDigraph::Node s, SmartDigraph::Node t) {
140 140

	
141 141
  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
142 142
    if (flow[e] < 0 || flow[e] > cap[e]) return false;
143 143
  }
144 144

	
145 145
  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
146 146
    if (n == s || n == t) continue;
147 147
    int sum = 0;
148 148
    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
149 149
      sum += flow[e];
150 150
    }
151 151
    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
152 152
      sum -= flow[e];
153 153
    }
154 154
    if (sum != 0) return false;
155 155
  }
156 156
  return true;
157 157
}
158 158

	
159
void initFlowTest()
160
{
161
  DIGRAPH_TYPEDEFS(SmartDigraph);
162
  
163
  SmartDigraph g;
164
  SmartDigraph::ArcMap<int> cap(g),iflow(g);
165
  Node s=g.addNode(); Node t=g.addNode();
166
  Node n1=g.addNode(); Node n2=g.addNode();
167
  Arc a;
168
  a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
169
  a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
170
  a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
171

	
172
  Preflow<SmartDigraph> pre(g,cap,s,t);
173
  pre.init(iflow);
174
  pre.startFirstPhase();
175
  check(pre.flowValue() == 10, "The incorrect max flow value.");
176
  check(pre.minCut(s), "Wrong min cut (Node s).");
177
  check(pre.minCut(n1), "Wrong min cut (Node n1).");
178
  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
179
  check(!pre.minCut(t), "Wrong min cut (Node t).");
180
}
181

	
182

	
159 183
int main() {
160 184

	
161 185
  typedef SmartDigraph Digraph;
162 186

	
163 187
  typedef Digraph::Node Node;
164 188
  typedef Digraph::NodeIt NodeIt;
165 189
  typedef Digraph::ArcIt ArcIt;
166 190
  typedef Digraph::ArcMap<int> CapMap;
167 191
  typedef Digraph::ArcMap<int> FlowMap;
168 192
  typedef Digraph::NodeMap<bool> CutMap;
169 193

	
170 194
  typedef Preflow<Digraph, CapMap> PType;
171 195

	
172 196
  Digraph g;
173 197
  Node s, t;
174 198
  CapMap cap(g);
175 199
  std::istringstream input(test_lgf);
176 200
  DigraphReader<Digraph>(g,input).
177 201
    arcMap("capacity", cap).
178 202
    node("source",s).
179 203
    node("target",t).
180 204
    run();
181 205

	
182 206
  PType preflow_test(g, cap, s, t);
183 207
  preflow_test.run();
184 208

	
185 209
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
186 210
        "The flow is not feasible.");
187 211

	
188 212
  CutMap min_cut(g);
189 213
  preflow_test.minCutMap(min_cut);
190 214
  int min_cut_value=cutValue(g,min_cut,cap);
191 215

	
192 216
  check(preflow_test.flowValue() == min_cut_value,
193 217
        "The max flow value is not equal to the three min cut values.");
194 218

	
195 219
  FlowMap flow(g);
196 220
  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
197 221

	
198 222
  int flow_value=preflow_test.flowValue();
199 223

	
200 224
  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
201 225
  preflow_test.init(flow);
202 226
  preflow_test.startFirstPhase();
203 227

	
204 228
  CutMap min_cut1(g);
205 229
  preflow_test.minCutMap(min_cut1);
206 230
  min_cut_value=cutValue(g,min_cut1,cap);
207 231

	
208 232
  check(preflow_test.flowValue() == min_cut_value &&
209 233
        min_cut_value == 2*flow_value,
210 234
        "The max flow value or the min cut value is wrong.");
211 235

	
212 236
  preflow_test.startSecondPhase();
213 237

	
214 238
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
215 239
        "The flow is not feasible.");
216 240

	
217 241
  CutMap min_cut2(g);
218 242
  preflow_test.minCutMap(min_cut2);
219 243
  min_cut_value=cutValue(g,min_cut2,cap);
220 244

	
221 245
  check(preflow_test.flowValue() == min_cut_value &&
222 246
        min_cut_value == 2*flow_value,
223 247
        "The max flow value or the three min cut values were not doubled");
224 248

	
225 249

	
226 250
  preflow_test.flowMap(flow);
227 251

	
228 252
  NodeIt tmp1(g,s);
229 253
  ++tmp1;
230 254
  if ( tmp1 != INVALID ) s=tmp1;
231 255

	
232 256
  NodeIt tmp2(g,t);
233 257
  ++tmp2;
234 258
  if ( tmp2 != INVALID ) t=tmp2;
235 259

	
236 260
  preflow_test.source(s);
237 261
  preflow_test.target(t);
238 262

	
239 263
  preflow_test.run();
240 264

	
241 265
  CutMap min_cut3(g);
242 266
  preflow_test.minCutMap(min_cut3);
243 267
  min_cut_value=cutValue(g,min_cut3,cap);
244 268

	
245 269

	
246 270
  check(preflow_test.flowValue() == min_cut_value,
247 271
        "The max flow value or the three min cut values are incorrect.");
248 272

	
273
  initFlowTest();
274
  
249 275
  return 0;
250 276
}
0 comments (0 inline)