gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Fix wrong initialization in Preflow (#414)
0 2 0
default
2 files changed with 30 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
... ...
@@ -336,401 +336,399 @@
336 336
    }
337 337

	
338 338
    /// \brief Sets the target node.
339 339
    ///
340 340
    /// Sets the target node.
341 341
    /// \return <tt>(*this)</tt>
342 342
    Preflow& target(const Node& node) {
343 343
      _target = node;
344 344
      return *this;
345 345
    }
346 346

	
347 347
    /// \brief Sets the elevator used by algorithm.
348 348
    ///
349 349
    /// Sets the elevator used by algorithm.
350 350
    /// If you don't use this function before calling \ref run() or
351 351
    /// \ref init(), an instance will be allocated automatically.
352 352
    /// The destructor deallocates this automatically allocated elevator,
353 353
    /// of course.
354 354
    /// \return <tt>(*this)</tt>
355 355
    Preflow& elevator(Elevator& elevator) {
356 356
      if (_local_level) {
357 357
        delete _level;
358 358
        _local_level = false;
359 359
      }
360 360
      _level = &elevator;
361 361
      return *this;
362 362
    }
363 363

	
364 364
    /// \brief Returns a const reference to the elevator.
365 365
    ///
366 366
    /// Returns a const reference to the elevator.
367 367
    ///
368 368
    /// \pre Either \ref run() or \ref init() must be called before
369 369
    /// using this function.
370 370
    const Elevator& elevator() const {
371 371
      return *_level;
372 372
    }
373 373

	
374 374
    /// \brief Sets the tolerance used by algorithm.
375 375
    ///
376 376
    /// Sets the tolerance used by algorithm.
377 377
    Preflow& tolerance(const Tolerance& tolerance) {
378 378
      _tolerance = tolerance;
379 379
      return *this;
380 380
    }
381 381

	
382 382
    /// \brief Returns a const reference to the tolerance.
383 383
    ///
384 384
    /// Returns a const reference to the tolerance.
385 385
    const Tolerance& tolerance() const {
386 386
      return _tolerance;
387 387
    }
388 388

	
389 389
    /// \name Execution Control
390 390
    /// The simplest way to execute the preflow algorithm is to use
391 391
    /// \ref run() or \ref runMinCut().\n
392 392
    /// If you need more control on the initial solution or the execution,
393 393
    /// first you have to call one of the \ref init() functions, then
394 394
    /// \ref startFirstPhase() and if you need it \ref startSecondPhase().
395 395

	
396 396
    ///@{
397 397

	
398 398
    /// \brief Initializes the internal data structures.
399 399
    ///
400 400
    /// Initializes the internal data structures and sets the initial
401 401
    /// flow to zero on each arc.
402 402
    void init() {
403 403
      createStructures();
404 404

	
405 405
      _phase = true;
406 406
      for (NodeIt n(_graph); n != INVALID; ++n) {
407 407
        (*_excess)[n] = 0;
408 408
      }
409 409

	
410 410
      for (ArcIt e(_graph); e != INVALID; ++e) {
411 411
        _flow->set(e, 0);
412 412
      }
413 413

	
414 414
      typename Digraph::template NodeMap<bool> reached(_graph, false);
415 415

	
416 416
      _level->initStart();
417 417
      _level->initAddItem(_target);
418 418

	
419 419
      std::vector<Node> queue;
420 420
      reached[_source] = true;
421 421

	
422 422
      queue.push_back(_target);
423 423
      reached[_target] = true;
424 424
      while (!queue.empty()) {
425 425
        _level->initNewLevel();
426 426
        std::vector<Node> nqueue;
427 427
        for (int i = 0; i < int(queue.size()); ++i) {
428 428
          Node n = queue[i];
429 429
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
430 430
            Node u = _graph.source(e);
431 431
            if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
432 432
              reached[u] = true;
433 433
              _level->initAddItem(u);
434 434
              nqueue.push_back(u);
435 435
            }
436 436
          }
437 437
        }
438 438
        queue.swap(nqueue);
439 439
      }
440 440
      _level->initFinish();
441 441

	
442 442
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
443 443
        if (_tolerance.positive((*_capacity)[e])) {
444 444
          Node u = _graph.target(e);
445 445
          if ((*_level)[u] == _level->maxLevel()) continue;
446 446
          _flow->set(e, (*_capacity)[e]);
447 447
          (*_excess)[u] += (*_capacity)[e];
448 448
          if (u != _target && !_level->active(u)) {
449 449
            _level->activate(u);
450 450
          }
451 451
        }
452 452
      }
453 453
    }
454 454

	
455 455
    /// \brief Initializes the internal data structures using the
456 456
    /// given flow map.
457 457
    ///
458 458
    /// Initializes the internal data structures and sets the initial
459 459
    /// flow to the given \c flowMap. The \c flowMap should contain a
460 460
    /// flow or at least a preflow, i.e. at each node excluding the
461 461
    /// source node the incoming flow should greater or equal to the
462 462
    /// outgoing flow.
463 463
    /// \return \c false if the given \c flowMap is not a preflow.
464 464
    template <typename FlowMap>
465 465
    bool init(const FlowMap& flowMap) {
466 466
      createStructures();
467 467

	
468 468
      for (ArcIt e(_graph); e != INVALID; ++e) {
469 469
        _flow->set(e, flowMap[e]);
470 470
      }
471 471

	
472 472
      for (NodeIt n(_graph); n != INVALID; ++n) {
473 473
        Value excess = 0;
474 474
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
475 475
          excess += (*_flow)[e];
476 476
        }
477 477
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
478 478
          excess -= (*_flow)[e];
479 479
        }
480 480
        if (excess < 0 && n != _source) return false;
481 481
        (*_excess)[n] = excess;
482 482
      }
483 483

	
484 484
      typename Digraph::template NodeMap<bool> reached(_graph, false);
485 485

	
486 486
      _level->initStart();
487 487
      _level->initAddItem(_target);
488 488

	
489 489
      std::vector<Node> queue;
490 490
      reached[_source] = true;
491 491

	
492 492
      queue.push_back(_target);
493 493
      reached[_target] = true;
494 494
      while (!queue.empty()) {
495 495
        _level->initNewLevel();
496 496
        std::vector<Node> nqueue;
497 497
        for (int i = 0; i < int(queue.size()); ++i) {
498 498
          Node n = queue[i];
499 499
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
500 500
            Node u = _graph.source(e);
501 501
            if (!reached[u] &&
502 502
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
503 503
              reached[u] = true;
504 504
              _level->initAddItem(u);
505 505
              nqueue.push_back(u);
506 506
            }
507 507
          }
508 508
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
509 509
            Node v = _graph.target(e);
510 510
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
511 511
              reached[v] = true;
512 512
              _level->initAddItem(v);
513 513
              nqueue.push_back(v);
514 514
            }
515 515
          }
516 516
        }
517 517
        queue.swap(nqueue);
518 518
      }
519 519
      _level->initFinish();
520 520

	
521 521
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
522 522
        Value rem = (*_capacity)[e] - (*_flow)[e];
523 523
        if (_tolerance.positive(rem)) {
524 524
          Node u = _graph.target(e);
525 525
          if ((*_level)[u] == _level->maxLevel()) continue;
526 526
          _flow->set(e, (*_capacity)[e]);
527 527
          (*_excess)[u] += rem;
528
          if (u != _target && !_level->active(u)) {
529
            _level->activate(u);
530
          }
531 528
        }
532 529
      }
533 530
      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
534 531
        Value rem = (*_flow)[e];
535 532
        if (_tolerance.positive(rem)) {
536 533
          Node v = _graph.source(e);
537 534
          if ((*_level)[v] == _level->maxLevel()) continue;
538 535
          _flow->set(e, 0);
539 536
          (*_excess)[v] += rem;
540
          if (v != _target && !_level->active(v)) {
541
            _level->activate(v);
542
          }
543 537
        }
544 538
      }
539
      for (NodeIt n(_graph); n != INVALID; ++n) 
540
        if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n]))
541
          _level->activate(n);
542
          
545 543
      return true;
546 544
    }
547 545

	
548 546
    /// \brief Starts the first phase of the preflow algorithm.
549 547
    ///
550 548
    /// The preflow algorithm consists of two phases, this method runs
551 549
    /// the first phase. After the first phase the maximum flow value
552 550
    /// and a minimum value cut can already be computed, although a
553 551
    /// maximum flow is not yet obtained. So after calling this method
554 552
    /// \ref flowValue() returns the value of a maximum flow and \ref
555 553
    /// minCut() returns a minimum cut.
556 554
    /// \pre One of the \ref init() functions must be called before
557 555
    /// using this function.
558 556
    void startFirstPhase() {
559 557
      _phase = true;
560 558

	
561 559
      while (true) {
562 560
        int num = _node_num;
563 561

	
564 562
        Node n = INVALID;
565 563
        int level = -1;
566 564

	
567 565
        while (num > 0) {
568 566
          n = _level->highestActive();
569 567
          if (n == INVALID) goto first_phase_done;
570 568
          level = _level->highestActiveLevel();
571 569
          --num;
572 570
          
573 571
          Value excess = (*_excess)[n];
574 572
          int new_level = _level->maxLevel();
575 573

	
576 574
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
577 575
            Value rem = (*_capacity)[e] - (*_flow)[e];
578 576
            if (!_tolerance.positive(rem)) continue;
579 577
            Node v = _graph.target(e);
580 578
            if ((*_level)[v] < level) {
581 579
              if (!_level->active(v) && v != _target) {
582 580
                _level->activate(v);
583 581
              }
584 582
              if (!_tolerance.less(rem, excess)) {
585 583
                _flow->set(e, (*_flow)[e] + excess);
586 584
                (*_excess)[v] += excess;
587 585
                excess = 0;
588 586
                goto no_more_push_1;
589 587
              } else {
590 588
                excess -= rem;
591 589
                (*_excess)[v] += rem;
592 590
                _flow->set(e, (*_capacity)[e]);
593 591
              }
594 592
            } else if (new_level > (*_level)[v]) {
595 593
              new_level = (*_level)[v];
596 594
            }
597 595
          }
598 596

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

	
622 620
        no_more_push_1:
623 621

	
624 622
          (*_excess)[n] = excess;
625 623

	
626 624
          if (excess != 0) {
627 625
            if (new_level + 1 < _level->maxLevel()) {
628 626
              _level->liftHighestActive(new_level + 1);
629 627
            } else {
630 628
              _level->liftHighestActiveToTop();
631 629
            }
632 630
            if (_level->emptyLevel(level)) {
633 631
              _level->liftToTop(level);
634 632
            }
635 633
          } else {
636 634
            _level->deactivate(n);
637 635
          }
638 636
        }
639 637

	
640 638
        num = _node_num * 20;
641 639
        while (num > 0) {
642 640
          while (level >= 0 && _level->activeFree(level)) {
643 641
            --level;
644 642
          }
645 643
          if (level == -1) {
646 644
            n = _level->highestActive();
647 645
            level = _level->highestActiveLevel();
648 646
            if (n == INVALID) goto first_phase_done;
649 647
          } else {
650 648
            n = _level->activeOn(level);
651 649
          }
652 650
          --num;
653 651

	
654 652
          Value excess = (*_excess)[n];
655 653
          int new_level = _level->maxLevel();
656 654

	
657 655
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
658 656
            Value rem = (*_capacity)[e] - (*_flow)[e];
659 657
            if (!_tolerance.positive(rem)) continue;
660 658
            Node v = _graph.target(e);
661 659
            if ((*_level)[v] < level) {
662 660
              if (!_level->active(v) && v != _target) {
663 661
                _level->activate(v);
664 662
              }
665 663
              if (!_tolerance.less(rem, excess)) {
666 664
                _flow->set(e, (*_flow)[e] + excess);
667 665
                (*_excess)[v] += excess;
668 666
                excess = 0;
669 667
                goto no_more_push_2;
670 668
              } else {
671 669
                excess -= rem;
672 670
                (*_excess)[v] += rem;
673 671
                _flow->set(e, (*_capacity)[e]);
674 672
              }
675 673
            } else if (new_level > (*_level)[v]) {
676 674
              new_level = (*_level)[v];
677 675
            }
678 676
          }
679 677

	
680 678
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
681 679
            Value rem = (*_flow)[e];
682 680
            if (!_tolerance.positive(rem)) continue;
683 681
            Node v = _graph.source(e);
684 682
            if ((*_level)[v] < level) {
685 683
              if (!_level->active(v) && v != _target) {
686 684
                _level->activate(v);
687 685
              }
688 686
              if (!_tolerance.less(rem, excess)) {
689 687
                _flow->set(e, (*_flow)[e] - excess);
690 688
                (*_excess)[v] += excess;
691 689
                excess = 0;
692 690
                goto no_more_push_2;
693 691
              } else {
694 692
                excess -= rem;
695 693
                (*_excess)[v] += rem;
696 694
                _flow->set(e, 0);
697 695
              }
698 696
            } else if (new_level > (*_level)[v]) {
699 697
              new_level = (*_level)[v];
700 698
            }
701 699
          }
702 700

	
703 701
        no_more_push_2:
704 702

	
705 703
          (*_excess)[n] = excess;
706 704

	
707 705
          if (excess != 0) {
708 706
            if (new_level + 1 < _level->maxLevel()) {
709 707
              _level->liftActiveOn(level, new_level + 1);
710 708
            } else {
711 709
              _level->liftActiveToTop(level);
712 710
            }
713 711
            if (_level->emptyLevel(level)) {
714 712
              _level->liftToTop(level);
715 713
            }
716 714
          } else {
717 715
            _level->deactivate(n);
718 716
          }
719 717
        }
720 718
      }
721 719
    first_phase_done:;
722 720
    }
723 721

	
724 722
    /// \brief Starts the second phase of the preflow algorithm.
725 723
    ///
726 724
    /// The preflow algorithm consists of two phases, this method runs
727 725
    /// the second phase. After calling one of the \ref init() functions
728 726
    /// and \ref startFirstPhase() and then \ref startSecondPhase(),
729 727
    /// \ref flowMap() returns a maximum flow, \ref flowValue() returns the
730 728
    /// value of a maximum flow, \ref minCut() returns a minimum cut
731 729
    /// \pre One of the \ref init() functions and \ref startFirstPhase()
732 730
    /// must be called before using this function.
733 731
    void startSecondPhase() {
734 732
      _phase = false;
735 733

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

	
19 19
#include <iostream>
20 20

	
21 21
#include "test_tools.h"
22 22
#include <lemon/smart_graph.h>
23 23
#include <lemon/preflow.h>
24 24
#include <lemon/concepts/digraph.h>
25 25
#include <lemon/concepts/maps.h>
26 26
#include <lemon/lgf_reader.h>
27 27
#include <lemon/elevator.h>
28 28

	
29 29
using namespace lemon;
30 30

	
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
  preflow_test
99 99
    .capacityMap(cap)
100 100
    .flowMap(flow)
101 101
    .source(n)
102 102
    .target(n);
103 103

	
104 104
  preflow_test.init();
105 105
  preflow_test.init(cap);
106 106
  preflow_test.startFirstPhase();
107 107
  preflow_test.startSecondPhase();
108 108
  preflow_test.run();
109 109
  preflow_test.runMinCut();
110 110

	
111 111
  v = const_preflow_test.flowValue();
112 112
  v = const_preflow_test.flow(e);
113 113
  const FlowMap& fm = const_preflow_test.flowMap();
114 114
  b = const_preflow_test.minCut(n);
115 115
  const_preflow_test.minCutMap(cut);
116 116
  
117 117
  ignore_unused_variable_warning(fm);
118 118
}
119 119

	
120 120
int cutValue (const SmartDigraph& g,
121 121
              const SmartDigraph::NodeMap<bool>& cut,
122 122
              const SmartDigraph::ArcMap<int>& cap) {
123 123

	
124 124
  int c=0;
125 125
  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
126 126
    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
127 127
  }
128 128
  return c;
129 129
}
130 130

	
131 131
bool checkFlow(const SmartDigraph& g,
132 132
               const SmartDigraph::ArcMap<int>& flow,
133 133
               const SmartDigraph::ArcMap<int>& cap,
134 134
               SmartDigraph::Node s, SmartDigraph::Node t) {
135 135

	
136 136
  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
137 137
    if (flow[e] < 0 || flow[e] > cap[e]) return false;
138 138
  }
139 139

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

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

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

	
177

	
154 178
int main() {
155 179

	
156 180
  typedef SmartDigraph Digraph;
157 181

	
158 182
  typedef Digraph::Node Node;
159 183
  typedef Digraph::NodeIt NodeIt;
160 184
  typedef Digraph::ArcIt ArcIt;
161 185
  typedef Digraph::ArcMap<int> CapMap;
162 186
  typedef Digraph::ArcMap<int> FlowMap;
163 187
  typedef Digraph::NodeMap<bool> CutMap;
164 188

	
165 189
  typedef Preflow<Digraph, CapMap> PType;
166 190

	
167 191
  Digraph g;
168 192
  Node s, t;
169 193
  CapMap cap(g);
170 194
  std::istringstream input(test_lgf);
171 195
  DigraphReader<Digraph>(g,input).
172 196
    arcMap("capacity", cap).
173 197
    node("source",s).
174 198
    node("target",t).
175 199
    run();
176 200

	
177 201
  PType preflow_test(g, cap, s, t);
178 202
  preflow_test.run();
179 203

	
180 204
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
181 205
        "The flow is not feasible.");
182 206

	
183 207
  CutMap min_cut(g);
184 208
  preflow_test.minCutMap(min_cut);
185 209
  int min_cut_value=cutValue(g,min_cut,cap);
186 210

	
187 211
  check(preflow_test.flowValue() == min_cut_value,
188 212
        "The max flow value is not equal to the three min cut values.");
189 213

	
190 214
  FlowMap flow(g);
191 215
  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
192 216

	
193 217
  int flow_value=preflow_test.flowValue();
194 218

	
195 219
  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
196 220
  preflow_test.init(flow);
197 221
  preflow_test.startFirstPhase();
198 222

	
199 223
  CutMap min_cut1(g);
200 224
  preflow_test.minCutMap(min_cut1);
201 225
  min_cut_value=cutValue(g,min_cut1,cap);
202 226

	
203 227
  check(preflow_test.flowValue() == min_cut_value &&
204 228
        min_cut_value == 2*flow_value,
205 229
        "The max flow value or the min cut value is wrong.");
206 230

	
207 231
  preflow_test.startSecondPhase();
208 232

	
209 233
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
210 234
        "The flow is not feasible.");
211 235

	
212 236
  CutMap min_cut2(g);
213 237
  preflow_test.minCutMap(min_cut2);
214 238
  min_cut_value=cutValue(g,min_cut2,cap);
215 239

	
216 240
  check(preflow_test.flowValue() == min_cut_value &&
217 241
        min_cut_value == 2*flow_value,
218 242
        "The max flow value or the three min cut values were not doubled");
219 243

	
220 244

	
221 245
  preflow_test.flowMap(flow);
222 246

	
223 247
  NodeIt tmp1(g,s);
224 248
  ++tmp1;
225 249
  if ( tmp1 != INVALID ) s=tmp1;
226 250

	
227 251
  NodeIt tmp2(g,t);
228 252
  ++tmp2;
229 253
  if ( tmp2 != INVALID ) t=tmp2;
230 254

	
231 255
  preflow_test.source(s);
232 256
  preflow_test.target(t);
233 257

	
234 258
  preflow_test.run();
235 259

	
236 260
  CutMap min_cut3(g);
237 261
  preflow_test.minCutMap(min_cut3);
238 262
  min_cut_value=cutValue(g,min_cut3,cap);
239 263

	
240 264

	
241 265
  check(preflow_test.flowValue() == min_cut_value,
242 266
        "The max flow value or the three min cut values are incorrect.");
243 267

	
268
  initFlowTest();
269
  
244 270
  return 0;
245 271
}
0 comments (0 inline)