gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
More options for run() in scaling MCF algorithms (#180) - Three methods can be selected and the scaling factor can be given for CostScaling. - The scaling factor can be given for CapacityScaling.
0 2 0
default
2 files changed with 71 insertions and 42 deletions:
↑ Collapse diff ↑
Ignore white space 96 line context
... ...
@@ -128,97 +128,97 @@
128 128
      UNBOUNDED
129 129
    };
130 130
  
131 131
  private:
132 132

	
133 133
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
134 134

	
135 135
    typedef std::vector<int> IntVector;
136 136
    typedef std::vector<bool> BoolVector;
137 137
    typedef std::vector<Value> ValueVector;
138 138
    typedef std::vector<Cost> CostVector;
139 139

	
140 140
  private:
141 141

	
142 142
    // Data related to the underlying digraph
143 143
    const GR &_graph;
144 144
    int _node_num;
145 145
    int _arc_num;
146 146
    int _res_arc_num;
147 147
    int _root;
148 148

	
149 149
    // Parameters of the problem
150 150
    bool _have_lower;
151 151
    Value _sum_supply;
152 152

	
153 153
    // Data structures for storing the digraph
154 154
    IntNodeMap _node_id;
155 155
    IntArcMap _arc_idf;
156 156
    IntArcMap _arc_idb;
157 157
    IntVector _first_out;
158 158
    BoolVector _forward;
159 159
    IntVector _source;
160 160
    IntVector _target;
161 161
    IntVector _reverse;
162 162

	
163 163
    // Node and arc data
164 164
    ValueVector _lower;
165 165
    ValueVector _upper;
166 166
    CostVector _cost;
167 167
    ValueVector _supply;
168 168

	
169 169
    ValueVector _res_cap;
170 170
    CostVector _pi;
171 171
    ValueVector _excess;
172 172
    IntVector _excess_nodes;
173 173
    IntVector _deficit_nodes;
174 174

	
175 175
    Value _delta;
176
    int _phase_num;
176
    int _factor;
177 177
    IntVector _pred;
178 178

	
179 179
  public:
180 180
  
181 181
    /// \brief Constant for infinite upper bounds (capacities).
182 182
    ///
183 183
    /// Constant for infinite upper bounds (capacities).
184 184
    /// It is \c std::numeric_limits<Value>::infinity() if available,
185 185
    /// \c std::numeric_limits<Value>::max() otherwise.
186 186
    const Value INF;
187 187

	
188 188
  private:
189 189

	
190 190
    // Special implementation of the Dijkstra algorithm for finding
191 191
    // shortest paths in the residual network of the digraph with
192 192
    // respect to the reduced arc costs and modifying the node
193 193
    // potentials according to the found distance labels.
194 194
    class ResidualDijkstra
195 195
    {
196 196
    private:
197 197

	
198 198
      int _node_num;
199 199
      const IntVector &_first_out;
200 200
      const IntVector &_target;
201 201
      const CostVector &_cost;
202 202
      const ValueVector &_res_cap;
203 203
      const ValueVector &_excess;
204 204
      CostVector &_pi;
205 205
      IntVector &_pred;
206 206
      
207 207
      IntVector _proc_nodes;
208 208
      CostVector _dist;
209 209
      
210 210
    public:
211 211

	
212 212
      ResidualDijkstra(CapacityScaling& cs) :
213 213
        _node_num(cs._node_num), _first_out(cs._first_out), 
214 214
        _target(cs._target), _cost(cs._cost), _res_cap(cs._res_cap),
215 215
        _excess(cs._excess), _pi(cs._pi), _pred(cs._pred),
216 216
        _dist(cs._node_num)
217 217
      {}
218 218

	
219 219
      int run(int s, Value delta = 1) {
220 220
        RangeMap<int> heap_cross_ref(_node_num, Heap::PRE_HEAP);
221 221
        Heap heap(heap_cross_ref);
222 222
        heap.push(s, 0);
223 223
        _pred[s] = -1;
224 224
        _proc_nodes.clear();
... ...
@@ -468,130 +468,130 @@
468 468
    /// This function sets a single source node and a single target node
469 469
    /// and the required flow value.
470 470
    /// If neither this function nor \ref supplyMap() is used before
471 471
    /// calling \ref run(), the supply of each node will be set to zero.
472 472
    ///
473 473
    /// Using this function has the same effect as using \ref supplyMap()
474 474
    /// with such a map in which \c k is assigned to \c s, \c -k is
475 475
    /// assigned to \c t and all other nodes have zero supply value.
476 476
    ///
477 477
    /// \param s The source node.
478 478
    /// \param t The target node.
479 479
    /// \param k The required amount of flow from node \c s to node \c t
480 480
    /// (i.e. the supply of \c s and the demand of \c t).
481 481
    ///
482 482
    /// \return <tt>(*this)</tt>
483 483
    CapacityScaling& stSupply(const Node& s, const Node& t, Value k) {
484 484
      for (int i = 0; i != _node_num; ++i) {
485 485
        _supply[i] = 0;
486 486
      }
487 487
      _supply[_node_id[s]] =  k;
488 488
      _supply[_node_id[t]] = -k;
489 489
      return *this;
490 490
    }
491 491
    
492 492
    /// @}
493 493

	
494 494
    /// \name Execution control
495 495
    /// The algorithm can be executed using \ref run().
496 496

	
497 497
    /// @{
498 498

	
499 499
    /// \brief Run the algorithm.
500 500
    ///
501 501
    /// This function runs the algorithm.
502 502
    /// The paramters can be specified using functions \ref lowerMap(),
503 503
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
504 504
    /// For example,
505 505
    /// \code
506 506
    ///   CapacityScaling<ListDigraph> cs(graph);
507 507
    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
508 508
    ///     .supplyMap(sup).run();
509 509
    /// \endcode
510 510
    ///
511 511
    /// This function can be called more than once. All the parameters
512 512
    /// that have been given are kept for the next call, unless
513 513
    /// \ref reset() is called, thus only the modified parameters
514 514
    /// have to be set again. See \ref reset() for examples.
515 515
    /// However the underlying digraph must not be modified after this
516
    /// class have been constructed, since it copies the digraph.
516
    /// class have been constructed, since it copies and extends the graph.
517 517
    ///
518
    /// \param scaling Enable or disable capacity scaling.
519
    /// If the maximum upper bound and/or the amount of total supply
520
    /// is rather small, the algorithm could be slightly faster without
521
    /// scaling.
518
    /// \param factor The capacity scaling factor. It must be larger than
519
    /// one to use scaling. If it is less or equal to one, then scaling
520
    /// will be disabled.
522 521
    ///
523 522
    /// \return \c INFEASIBLE if no feasible flow exists,
524 523
    /// \n \c OPTIMAL if the problem has optimal solution
525 524
    /// (i.e. it is feasible and bounded), and the algorithm has found
526 525
    /// optimal flow and node potentials (primal and dual solutions),
527 526
    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
528 527
    /// and infinite upper bound. It means that the objective function
529 528
    /// is unbounded on that arc, however note that it could actually be
530 529
    /// bounded over the feasible flows, but this algroithm cannot handle
531 530
    /// these cases.
532 531
    ///
533 532
    /// \see ProblemType
534
    ProblemType run(bool scaling = true) {
535
      ProblemType pt = init(scaling);
533
    ProblemType run(int factor = 4) {
534
      _factor = factor;
535
      ProblemType pt = init();
536 536
      if (pt != OPTIMAL) return pt;
537 537
      return start();
538 538
    }
539 539

	
540 540
    /// \brief Reset all the parameters that have been given before.
541 541
    ///
542 542
    /// This function resets all the paramaters that have been given
543 543
    /// before using functions \ref lowerMap(), \ref upperMap(),
544 544
    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
545 545
    ///
546 546
    /// It is useful for multiple run() calls. If this function is not
547 547
    /// used, all the parameters given before are kept for the next
548 548
    /// \ref run() call.
549
    /// However the underlying digraph must not be modified after this
549
    /// However, the underlying digraph must not be modified after this
550 550
    /// class have been constructed, since it copies and extends the graph.
551 551
    ///
552 552
    /// For example,
553 553
    /// \code
554 554
    ///   CapacityScaling<ListDigraph> cs(graph);
555 555
    ///
556 556
    ///   // First run
557 557
    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
558 558
    ///     .supplyMap(sup).run();
559 559
    ///
560 560
    ///   // Run again with modified cost map (reset() is not called,
561 561
    ///   // so only the cost map have to be set again)
562 562
    ///   cost[e] += 100;
563 563
    ///   cs.costMap(cost).run();
564 564
    ///
565 565
    ///   // Run again from scratch using reset()
566 566
    ///   // (the lower bounds will be set to zero on all arcs)
567 567
    ///   cs.reset();
568 568
    ///   cs.upperMap(capacity).costMap(cost)
569 569
    ///     .supplyMap(sup).run();
570 570
    /// \endcode
571 571
    ///
572 572
    /// \return <tt>(*this)</tt>
573 573
    CapacityScaling& reset() {
574 574
      for (int i = 0; i != _node_num; ++i) {
575 575
        _supply[i] = 0;
576 576
      }
577 577
      for (int j = 0; j != _res_arc_num; ++j) {
578 578
        _lower[j] = 0;
579 579
        _upper[j] = INF;
580 580
        _cost[j] = _forward[j] ? 1 : -1;
581 581
      }
582 582
      _have_lower = false;
583 583
      return *this;
584 584
    }
585 585

	
586 586
    /// @}
587 587

	
588 588
    /// \name Query Functions
589 589
    /// The results of the algorithm can be obtained using these
590 590
    /// functions.\n
591 591
    /// The \ref run() function must be called before using them.
592 592

	
593 593
    /// @{
594 594

	
595 595
    /// \brief Return the total cost of the found flow.
596 596
    ///
597 597
    /// This function returns the total cost of the found flow.
... ...
@@ -632,308 +632,303 @@
632 632
    Value flow(const Arc& a) const {
633 633
      return _res_cap[_arc_idb[a]];
634 634
    }
635 635

	
636 636
    /// \brief Return the flow map (the primal solution).
637 637
    ///
638 638
    /// This function copies the flow value on each arc into the given
639 639
    /// map. The \c Value type of the algorithm must be convertible to
640 640
    /// the \c Value type of the map.
641 641
    ///
642 642
    /// \pre \ref run() must be called before using this function.
643 643
    template <typename FlowMap>
644 644
    void flowMap(FlowMap &map) const {
645 645
      for (ArcIt a(_graph); a != INVALID; ++a) {
646 646
        map.set(a, _res_cap[_arc_idb[a]]);
647 647
      }
648 648
    }
649 649

	
650 650
    /// \brief Return the potential (dual value) of the given node.
651 651
    ///
652 652
    /// This function returns the potential (dual value) of the
653 653
    /// given node.
654 654
    ///
655 655
    /// \pre \ref run() must be called before using this function.
656 656
    Cost potential(const Node& n) const {
657 657
      return _pi[_node_id[n]];
658 658
    }
659 659

	
660 660
    /// \brief Return the potential map (the dual solution).
661 661
    ///
662 662
    /// This function copies the potential (dual value) of each node
663 663
    /// into the given map.
664 664
    /// The \c Cost type of the algorithm must be convertible to the
665 665
    /// \c Value type of the map.
666 666
    ///
667 667
    /// \pre \ref run() must be called before using this function.
668 668
    template <typename PotentialMap>
669 669
    void potentialMap(PotentialMap &map) const {
670 670
      for (NodeIt n(_graph); n != INVALID; ++n) {
671 671
        map.set(n, _pi[_node_id[n]]);
672 672
      }
673 673
    }
674 674

	
675 675
    /// @}
676 676

	
677 677
  private:
678 678

	
679 679
    // Initialize the algorithm
680
    ProblemType init(bool scaling) {
680
    ProblemType init() {
681 681
      if (_node_num == 0) return INFEASIBLE;
682 682

	
683 683
      // Check the sum of supply values
684 684
      _sum_supply = 0;
685 685
      for (int i = 0; i != _root; ++i) {
686 686
        _sum_supply += _supply[i];
687 687
      }
688 688
      if (_sum_supply > 0) return INFEASIBLE;
689 689
      
690 690
      // Initialize maps
691 691
      for (int i = 0; i != _root; ++i) {
692 692
        _pi[i] = 0;
693 693
        _excess[i] = _supply[i];
694 694
      }
695 695

	
696 696
      // Remove non-zero lower bounds
697 697
      if (_have_lower) {
698 698
        for (int i = 0; i != _root; ++i) {
699 699
          for (int j = _first_out[i]; j != _first_out[i+1]; ++j) {
700 700
            if (_forward[j]) {
701 701
              Value c = _lower[j];
702 702
              if (c >= 0) {
703 703
                _res_cap[j] = _upper[j] < INF ? _upper[j] - c : INF;
704 704
              } else {
705 705
                _res_cap[j] = _upper[j] < INF + c ? _upper[j] - c : INF;
706 706
              }
707 707
              _excess[i] -= c;
708 708
              _excess[_target[j]] += c;
709 709
            } else {
710 710
              _res_cap[j] = 0;
711 711
            }
712 712
          }
713 713
        }
714 714
      } else {
715 715
        for (int j = 0; j != _res_arc_num; ++j) {
716 716
          _res_cap[j] = _forward[j] ? _upper[j] : 0;
717 717
        }
718 718
      }
719 719

	
720 720
      // Handle negative costs
721 721
      for (int u = 0; u != _root; ++u) {
722 722
        for (int a = _first_out[u]; a != _first_out[u+1]; ++a) {
723 723
          Value rc = _res_cap[a];
724 724
          if (_cost[a] < 0 && rc > 0) {
725 725
            if (rc == INF) return UNBOUNDED;
726 726
            _excess[u] -= rc;
727 727
            _excess[_target[a]] += rc;
728 728
            _res_cap[a] = 0;
729 729
            _res_cap[_reverse[a]] += rc;
730 730
          }
731 731
        }
732 732
      }
733 733
      
734 734
      // Handle GEQ supply type
735 735
      if (_sum_supply < 0) {
736 736
        _pi[_root] = 0;
737 737
        _excess[_root] = -_sum_supply;
738 738
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
739 739
          int u = _target[a];
740 740
          if (_excess[u] < 0) {
741 741
            _res_cap[a] = -_excess[u] + 1;
742 742
          } else {
743 743
            _res_cap[a] = 1;
744 744
          }
745 745
          _res_cap[_reverse[a]] = 0;
746 746
          _cost[a] = 0;
747 747
          _cost[_reverse[a]] = 0;
748 748
        }
749 749
      } else {
750 750
        _pi[_root] = 0;
751 751
        _excess[_root] = 0;
752 752
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
753 753
          _res_cap[a] = 1;
754 754
          _res_cap[_reverse[a]] = 0;
755 755
          _cost[a] = 0;
756 756
          _cost[_reverse[a]] = 0;
757 757
        }
758 758
      }
759 759

	
760 760
      // Initialize delta value
761
      if (scaling) {
761
      if (_factor > 1) {
762 762
        // With scaling
763 763
        Value max_sup = 0, max_dem = 0;
764 764
        for (int i = 0; i != _node_num; ++i) {
765 765
          if ( _excess[i] > max_sup) max_sup =  _excess[i];
766 766
          if (-_excess[i] > max_dem) max_dem = -_excess[i];
767 767
        }
768 768
        Value max_cap = 0;
769 769
        for (int j = 0; j != _res_arc_num; ++j) {
770 770
          if (_res_cap[j] > max_cap) max_cap = _res_cap[j];
771 771
        }
772 772
        max_sup = std::min(std::min(max_sup, max_dem), max_cap);
773
        _phase_num = 0;
774
        for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2)
775
          ++_phase_num;
773
        for (_delta = 1; 2 * _delta <= max_sup; _delta *= 2) ;
776 774
      } else {
777 775
        // Without scaling
778 776
        _delta = 1;
779 777
      }
780 778

	
781 779
      return OPTIMAL;
782 780
    }
783 781

	
784 782
    ProblemType start() {
785 783
      // Execute the algorithm
786 784
      ProblemType pt;
787 785
      if (_delta > 1)
788 786
        pt = startWithScaling();
789 787
      else
790 788
        pt = startWithoutScaling();
791 789

	
792 790
      // Handle non-zero lower bounds
793 791
      if (_have_lower) {
794 792
        for (int j = 0; j != _res_arc_num - _node_num + 1; ++j) {
795 793
          if (!_forward[j]) _res_cap[j] += _lower[j];
796 794
        }
797 795
      }
798 796

	
799 797
      // Shift potentials if necessary
800 798
      Cost pr = _pi[_root];
801 799
      if (_sum_supply < 0 || pr > 0) {
802 800
        for (int i = 0; i != _node_num; ++i) {
803 801
          _pi[i] -= pr;
804 802
        }        
805 803
      }
806 804
      
807 805
      return pt;
808 806
    }
809 807

	
810 808
    // Execute the capacity scaling algorithm
811 809
    ProblemType startWithScaling() {
812 810
      // Perform capacity scaling phases
813 811
      int s, t;
814
      int phase_cnt = 0;
815
      int factor = 4;
816 812
      ResidualDijkstra _dijkstra(*this);
817 813
      while (true) {
818 814
        // Saturate all arcs not satisfying the optimality condition
819 815
        for (int u = 0; u != _node_num; ++u) {
820 816
          for (int a = _first_out[u]; a != _first_out[u+1]; ++a) {
821 817
            int v = _target[a];
822 818
            Cost c = _cost[a] + _pi[u] - _pi[v];
823 819
            Value rc = _res_cap[a];
824 820
            if (c < 0 && rc >= _delta) {
825 821
              _excess[u] -= rc;
826 822
              _excess[v] += rc;
827 823
              _res_cap[a] = 0;
828 824
              _res_cap[_reverse[a]] += rc;
829 825
            }
830 826
          }
831 827
        }
832 828

	
833 829
        // Find excess nodes and deficit nodes
834 830
        _excess_nodes.clear();
835 831
        _deficit_nodes.clear();
836 832
        for (int u = 0; u != _node_num; ++u) {
837 833
          if (_excess[u] >=  _delta) _excess_nodes.push_back(u);
838 834
          if (_excess[u] <= -_delta) _deficit_nodes.push_back(u);
839 835
        }
840 836
        int next_node = 0, next_def_node = 0;
841 837

	
842 838
        // Find augmenting shortest paths
843 839
        while (next_node < int(_excess_nodes.size())) {
844 840
          // Check deficit nodes
845 841
          if (_delta > 1) {
846 842
            bool delta_deficit = false;
847 843
            for ( ; next_def_node < int(_deficit_nodes.size());
848 844
                    ++next_def_node ) {
849 845
              if (_excess[_deficit_nodes[next_def_node]] <= -_delta) {
850 846
                delta_deficit = true;
851 847
                break;
852 848
              }
853 849
            }
854 850
            if (!delta_deficit) break;
855 851
          }
856 852

	
857 853
          // Run Dijkstra in the residual network
858 854
          s = _excess_nodes[next_node];
859 855
          if ((t = _dijkstra.run(s, _delta)) == -1) {
860 856
            if (_delta > 1) {
861 857
              ++next_node;
862 858
              continue;
863 859
            }
864 860
            return INFEASIBLE;
865 861
          }
866 862

	
867 863
          // Augment along a shortest path from s to t
868 864
          Value d = std::min(_excess[s], -_excess[t]);
869 865
          int u = t;
870 866
          int a;
871 867
          if (d > _delta) {
872 868
            while ((a = _pred[u]) != -1) {
873 869
              if (_res_cap[a] < d) d = _res_cap[a];
874 870
              u = _source[a];
875 871
            }
876 872
          }
877 873
          u = t;
878 874
          while ((a = _pred[u]) != -1) {
879 875
            _res_cap[a] -= d;
880 876
            _res_cap[_reverse[a]] += d;
881 877
            u = _source[a];
882 878
          }
883 879
          _excess[s] -= d;
884 880
          _excess[t] += d;
885 881

	
886 882
          if (_excess[s] < _delta) ++next_node;
887 883
        }
888 884

	
889 885
        if (_delta == 1) break;
890
        if (++phase_cnt == _phase_num / 4) factor = 2;
891
        _delta = _delta <= factor ? 1 : _delta / factor;
886
        _delta = _delta <= _factor ? 1 : _delta / _factor;
892 887
      }
893 888

	
894 889
      return OPTIMAL;
895 890
    }
896 891

	
897 892
    // Execute the successive shortest path algorithm
898 893
    ProblemType startWithoutScaling() {
899 894
      // Find excess nodes
900 895
      _excess_nodes.clear();
901 896
      for (int i = 0; i != _node_num; ++i) {
902 897
        if (_excess[i] > 0) _excess_nodes.push_back(i);
903 898
      }
904 899
      if (_excess_nodes.size() == 0) return OPTIMAL;
905 900
      int next_node = 0;
906 901

	
907 902
      // Find shortest paths
908 903
      int s, t;
909 904
      ResidualDijkstra _dijkstra(*this);
910 905
      while ( _excess[_excess_nodes[next_node]] > 0 ||
911 906
              ++next_node < int(_excess_nodes.size()) )
912 907
      {
913 908
        // Run Dijkstra in the residual network
914 909
        s = _excess_nodes[next_node];
915 910
        if ((t = _dijkstra.run(s)) == -1) return INFEASIBLE;
916 911

	
917 912
        // Augment along a shortest path from s to t
918 913
        Value d = std::min(_excess[s], -_excess[t]);
919 914
        int u = t;
920 915
        int a;
921 916
        if (d > 1) {
922 917
          while ((a = _pred[u]) != -1) {
923 918
            if (_res_cap[a] < d) d = _res_cap[a];
924 919
            u = _source[a];
925 920
          }
926 921
        }
927 922
        u = t;
928 923
        while ((a = _pred[u]) != -1) {
929 924
          _res_cap[a] -= d;
930 925
          _res_cap[_reverse[a]] += d;
931 926
          u = _source[a];
932 927
        }
933 928
        _excess[s] -= d;
934 929
        _excess[t] += d;
935 930
      }
936 931

	
937 932
      return OPTIMAL;
938 933
    }
939 934

	
Ignore white space 96 line context
... ...
@@ -65,145 +65,176 @@
65 65
    /// It is \c long \c long if the \c Cost type is integer,
66 66
    /// otherwise it is \c double.
67 67
    /// \c Cost must be convertible to \c LargeCost.
68 68
    typedef double LargeCost;
69 69
  };
70 70

	
71 71
  // Default traits class for integer cost types
72 72
  template <typename GR, typename V, typename C>
73 73
  struct CostScalingDefaultTraits<GR, V, C, true>
74 74
  {
75 75
    typedef GR Digraph;
76 76
    typedef V Value;
77 77
    typedef C Cost;
78 78
#ifdef LEMON_HAVE_LONG_LONG
79 79
    typedef long long LargeCost;
80 80
#else
81 81
    typedef long LargeCost;
82 82
#endif
83 83
  };
84 84

	
85 85

	
86 86
  /// \addtogroup min_cost_flow_algs
87 87
  /// @{
88 88

	
89 89
  /// \brief Implementation of the Cost Scaling algorithm for
90 90
  /// finding a \ref min_cost_flow "minimum cost flow".
91 91
  ///
92 92
  /// \ref CostScaling implements a cost scaling algorithm that performs
93 93
  /// push/augment and relabel operations for finding a minimum cost
94 94
  /// flow. It is an efficient primal-dual solution method, which
95 95
  /// can be viewed as the generalization of the \ref Preflow
96 96
  /// "preflow push-relabel" algorithm for the maximum flow problem.
97 97
  ///
98 98
  /// Most of the parameters of the problem (except for the digraph)
99 99
  /// can be given using separate functions, and the algorithm can be
100 100
  /// executed using the \ref run() function. If some parameters are not
101 101
  /// specified, then default values will be used.
102 102
  ///
103 103
  /// \tparam GR The digraph type the algorithm runs on.
104 104
  /// \tparam V The value type used for flow amounts, capacity bounds
105 105
  /// and supply values in the algorithm. By default it is \c int.
106 106
  /// \tparam C The value type used for costs and potentials in the
107 107
  /// algorithm. By default it is the same as \c V.
108 108
  ///
109 109
  /// \warning Both value types must be signed and all input data must
110 110
  /// be integer.
111 111
  /// \warning This algorithm does not support negative costs for such
112 112
  /// arcs that have infinite upper bound.
113
  ///
114
  /// \note %CostScaling provides three different internal methods,
115
  /// from which the most efficient one is used by default.
116
  /// For more information, see \ref Method.
113 117
#ifdef DOXYGEN
114 118
  template <typename GR, typename V, typename C, typename TR>
115 119
#else
116 120
  template < typename GR, typename V = int, typename C = V,
117 121
             typename TR = CostScalingDefaultTraits<GR, V, C> >
118 122
#endif
119 123
  class CostScaling
120 124
  {
121 125
  public:
122 126

	
123 127
    /// The type of the digraph
124 128
    typedef typename TR::Digraph Digraph;
125 129
    /// The type of the flow amounts, capacity bounds and supply values
126 130
    typedef typename TR::Value Value;
127 131
    /// The type of the arc costs
128 132
    typedef typename TR::Cost Cost;
129 133

	
130 134
    /// \brief The large cost type
131 135
    ///
132 136
    /// The large cost type used for internal computations.
133 137
    /// Using the \ref CostScalingDefaultTraits "default traits class",
134 138
    /// it is \c long \c long if the \c Cost type is integer,
135 139
    /// otherwise it is \c double.
136 140
    typedef typename TR::LargeCost LargeCost;
137 141

	
138 142
    /// The \ref CostScalingDefaultTraits "traits class" of the algorithm
139 143
    typedef TR Traits;
140 144

	
141 145
  public:
142 146

	
143 147
    /// \brief Problem type constants for the \c run() function.
144 148
    ///
145 149
    /// Enum type containing the problem type constants that can be
146 150
    /// returned by the \ref run() function of the algorithm.
147 151
    enum ProblemType {
148 152
      /// The problem has no feasible solution (flow).
149 153
      INFEASIBLE,
150 154
      /// The problem has optimal solution (i.e. it is feasible and
151 155
      /// bounded), and the algorithm has found optimal flow and node
152 156
      /// potentials (primal and dual solutions).
153 157
      OPTIMAL,
154 158
      /// The digraph contains an arc of negative cost and infinite
155 159
      /// upper bound. It means that the objective function is unbounded
156 160
      /// on that arc, however note that it could actually be bounded
157 161
      /// over the feasible flows, but this algroithm cannot handle
158 162
      /// these cases.
159 163
      UNBOUNDED
160 164
    };
161 165

	
166
    /// \brief Constants for selecting the internal method.
167
    ///
168
    /// Enum type containing constants for selecting the internal method
169
    /// for the \ref run() function.
170
    ///
171
    /// \ref CostScaling provides three internal methods that differ mainly
172
    /// in their base operations, which are used in conjunction with the
173
    /// relabel operation.
174
    /// By default, the so called \ref PARTIAL_AUGMENT
175
    /// "Partial Augment-Relabel" method is used, which proved to be
176
    /// the most efficient and the most robust on various test inputs.
177
    /// However, the other methods can be selected using the \ref run()
178
    /// function with the proper parameter.
179
    enum Method {
180
      /// Local push operations are used, i.e. flow is moved only on one
181
      /// admissible arc at once.
182
      PUSH,
183
      /// Augment operations are used, i.e. flow is moved on admissible
184
      /// paths from a node with excess to a node with deficit.
185
      AUGMENT,
186
      /// Partial augment operations are used, i.e. flow is moved on 
187
      /// admissible paths started from a node with excess, but the
188
      /// lengths of these paths are limited. This method can be viewed
189
      /// as a combined version of the previous two operations.
190
      PARTIAL_AUGMENT
191
    };
192

	
162 193
  private:
163 194

	
164 195
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
165 196

	
166 197
    typedef std::vector<int> IntVector;
167 198
    typedef std::vector<char> BoolVector;
168 199
    typedef std::vector<Value> ValueVector;
169 200
    typedef std::vector<Cost> CostVector;
170 201
    typedef std::vector<LargeCost> LargeCostVector;
171 202

	
172 203
  private:
173 204
  
174 205
    template <typename KT, typename VT>
175 206
    class VectorMap {
176 207
    public:
177 208
      typedef KT Key;
178 209
      typedef VT Value;
179 210
      
180 211
      VectorMap(std::vector<Value>& v) : _v(v) {}
181 212
      
182 213
      const Value& operator[](const Key& key) const {
183 214
        return _v[StaticDigraph::id(key)];
184 215
      }
185 216

	
186 217
      Value& operator[](const Key& key) {
187 218
        return _v[StaticDigraph::id(key)];
188 219
      }
189 220
      
190 221
      void set(const Key& key, const Value& val) {
191 222
        _v[StaticDigraph::id(key)] = val;
192 223
      }
193 224

	
194 225
    private:
195 226
      std::vector<Value>& _v;
196 227
    };
197 228

	
198 229
    typedef VectorMap<StaticDigraph::Node, LargeCost> LargeCostNodeMap;
199 230
    typedef VectorMap<StaticDigraph::Arc, LargeCost> LargeCostArcMap;
200 231

	
201 232
  private:
202 233

	
203 234
    // Data related to the underlying digraph
204 235
    const GR &_graph;
205 236
    int _node_num;
206 237
    int _arc_num;
207 238
    int _res_node_num;
208 239
    int _res_arc_num;
209 240
    int _root;
... ...
@@ -460,119 +491,119 @@
460 491
    ///
461 492
    /// This function sets a single source node and a single target node
462 493
    /// and the required flow value.
463 494
    /// If neither this function nor \ref supplyMap() is used before
464 495
    /// calling \ref run(), the supply of each node will be set to zero.
465 496
    ///
466 497
    /// Using this function has the same effect as using \ref supplyMap()
467 498
    /// with such a map in which \c k is assigned to \c s, \c -k is
468 499
    /// assigned to \c t and all other nodes have zero supply value.
469 500
    ///
470 501
    /// \param s The source node.
471 502
    /// \param t The target node.
472 503
    /// \param k The required amount of flow from node \c s to node \c t
473 504
    /// (i.e. the supply of \c s and the demand of \c t).
474 505
    ///
475 506
    /// \return <tt>(*this)</tt>
476 507
    CostScaling& stSupply(const Node& s, const Node& t, Value k) {
477 508
      for (int i = 0; i != _res_node_num; ++i) {
478 509
        _supply[i] = 0;
479 510
      }
480 511
      _supply[_node_id[s]] =  k;
481 512
      _supply[_node_id[t]] = -k;
482 513
      return *this;
483 514
    }
484 515
    
485 516
    /// @}
486 517

	
487 518
    /// \name Execution control
488 519
    /// The algorithm can be executed using \ref run().
489 520

	
490 521
    /// @{
491 522

	
492 523
    /// \brief Run the algorithm.
493 524
    ///
494 525
    /// This function runs the algorithm.
495 526
    /// The paramters can be specified using functions \ref lowerMap(),
496 527
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply().
497 528
    /// For example,
498 529
    /// \code
499 530
    ///   CostScaling<ListDigraph> cs(graph);
500 531
    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
501 532
    ///     .supplyMap(sup).run();
502 533
    /// \endcode
503 534
    ///
504 535
    /// This function can be called more than once. All the parameters
505 536
    /// that have been given are kept for the next call, unless
506 537
    /// \ref reset() is called, thus only the modified parameters
507 538
    /// have to be set again. See \ref reset() for examples.
508
    /// However the underlying digraph must not be modified after this
509
    /// class have been constructed, since it copies the digraph.
539
    /// However, the underlying digraph must not be modified after this
540
    /// class have been constructed, since it copies and extends the graph.
510 541
    ///
511
    /// \param partial_augment By default the algorithm performs
512
    /// partial augment and relabel operations in the cost scaling
513
    /// phases. Set this parameter to \c false for using local push and
514
    /// relabel operations instead.
542
    /// \param method The internal method that will be used in the
543
    /// algorithm. For more information, see \ref Method.
544
    /// \param factor The cost scaling factor. It must be larger than one.
515 545
    ///
516 546
    /// \return \c INFEASIBLE if no feasible flow exists,
517 547
    /// \n \c OPTIMAL if the problem has optimal solution
518 548
    /// (i.e. it is feasible and bounded), and the algorithm has found
519 549
    /// optimal flow and node potentials (primal and dual solutions),
520 550
    /// \n \c UNBOUNDED if the digraph contains an arc of negative cost
521 551
    /// and infinite upper bound. It means that the objective function
522 552
    /// is unbounded on that arc, however note that it could actually be
523 553
    /// bounded over the feasible flows, but this algroithm cannot handle
524 554
    /// these cases.
525 555
    ///
526
    /// \see ProblemType
527
    ProblemType run(bool partial_augment = true) {
556
    /// \see ProblemType, Method
557
    ProblemType run(Method method = PARTIAL_AUGMENT, int factor = 8) {
558
      _alpha = factor;
528 559
      ProblemType pt = init();
529 560
      if (pt != OPTIMAL) return pt;
530
      start(partial_augment);
561
      start(method);
531 562
      return OPTIMAL;
532 563
    }
533 564

	
534 565
    /// \brief Reset all the parameters that have been given before.
535 566
    ///
536 567
    /// This function resets all the paramaters that have been given
537 568
    /// before using functions \ref lowerMap(), \ref upperMap(),
538 569
    /// \ref costMap(), \ref supplyMap(), \ref stSupply().
539 570
    ///
540 571
    /// It is useful for multiple run() calls. If this function is not
541 572
    /// used, all the parameters given before are kept for the next
542 573
    /// \ref run() call.
543 574
    /// However the underlying digraph must not be modified after this
544 575
    /// class have been constructed, since it copies and extends the graph.
545 576
    ///
546 577
    /// For example,
547 578
    /// \code
548 579
    ///   CostScaling<ListDigraph> cs(graph);
549 580
    ///
550 581
    ///   // First run
551 582
    ///   cs.lowerMap(lower).upperMap(upper).costMap(cost)
552 583
    ///     .supplyMap(sup).run();
553 584
    ///
554 585
    ///   // Run again with modified cost map (reset() is not called,
555 586
    ///   // so only the cost map have to be set again)
556 587
    ///   cost[e] += 100;
557 588
    ///   cs.costMap(cost).run();
558 589
    ///
559 590
    ///   // Run again from scratch using reset()
560 591
    ///   // (the lower bounds will be set to zero on all arcs)
561 592
    ///   cs.reset();
562 593
    ///   cs.upperMap(capacity).costMap(cost)
563 594
    ///     .supplyMap(sup).run();
564 595
    /// \endcode
565 596
    ///
566 597
    /// \return <tt>(*this)</tt>
567 598
    CostScaling& reset() {
568 599
      for (int i = 0; i != _res_node_num; ++i) {
569 600
        _supply[i] = 0;
570 601
      }
571 602
      int limit = _first_out[_root];
572 603
      for (int j = 0; j != limit; ++j) {
573 604
        _lower[j] = 0;
574 605
        _upper[j] = INF;
575 606
        _scost[j] = _forward[j] ? 1 : -1;
576 607
      }
577 608
      for (int j = limit; j != _res_arc_num; ++j) {
578 609
        _lower[j] = 0;
... ...
@@ -636,99 +667,96 @@
636 667

	
637 668
    /// \brief Return the flow map (the primal solution).
638 669
    ///
639 670
    /// This function copies the flow value on each arc into the given
640 671
    /// map. The \c Value type of the algorithm must be convertible to
641 672
    /// the \c Value type of the map.
642 673
    ///
643 674
    /// \pre \ref run() must be called before using this function.
644 675
    template <typename FlowMap>
645 676
    void flowMap(FlowMap &map) const {
646 677
      for (ArcIt a(_graph); a != INVALID; ++a) {
647 678
        map.set(a, _res_cap[_arc_idb[a]]);
648 679
      }
649 680
    }
650 681

	
651 682
    /// \brief Return the potential (dual value) of the given node.
652 683
    ///
653 684
    /// This function returns the potential (dual value) of the
654 685
    /// given node.
655 686
    ///
656 687
    /// \pre \ref run() must be called before using this function.
657 688
    Cost potential(const Node& n) const {
658 689
      return static_cast<Cost>(_pi[_node_id[n]]);
659 690
    }
660 691

	
661 692
    /// \brief Return the potential map (the dual solution).
662 693
    ///
663 694
    /// This function copies the potential (dual value) of each node
664 695
    /// into the given map.
665 696
    /// The \c Cost type of the algorithm must be convertible to the
666 697
    /// \c Value type of the map.
667 698
    ///
668 699
    /// \pre \ref run() must be called before using this function.
669 700
    template <typename PotentialMap>
670 701
    void potentialMap(PotentialMap &map) const {
671 702
      for (NodeIt n(_graph); n != INVALID; ++n) {
672 703
        map.set(n, static_cast<Cost>(_pi[_node_id[n]]));
673 704
      }
674 705
    }
675 706

	
676 707
    /// @}
677 708

	
678 709
  private:
679 710

	
680 711
    // Initialize the algorithm
681 712
    ProblemType init() {
682 713
      if (_res_node_num == 0) return INFEASIBLE;
683 714

	
684
      // Scaling factor
685
      _alpha = 8;
686

	
687 715
      // Check the sum of supply values
688 716
      _sum_supply = 0;
689 717
      for (int i = 0; i != _root; ++i) {
690 718
        _sum_supply += _supply[i];
691 719
      }
692 720
      if (_sum_supply > 0) return INFEASIBLE;
693 721
      
694 722

	
695 723
      // Initialize vectors
696 724
      for (int i = 0; i != _res_node_num; ++i) {
697 725
        _pi[i] = 0;
698 726
        _excess[i] = _supply[i];
699 727
      }
700 728
      
701 729
      // Remove infinite upper bounds and check negative arcs
702 730
      const Value MAX = std::numeric_limits<Value>::max();
703 731
      int last_out;
704 732
      if (_have_lower) {
705 733
        for (int i = 0; i != _root; ++i) {
706 734
          last_out = _first_out[i+1];
707 735
          for (int j = _first_out[i]; j != last_out; ++j) {
708 736
            if (_forward[j]) {
709 737
              Value c = _scost[j] < 0 ? _upper[j] : _lower[j];
710 738
              if (c >= MAX) return UNBOUNDED;
711 739
              _excess[i] -= c;
712 740
              _excess[_target[j]] += c;
713 741
            }
714 742
          }
715 743
        }
716 744
      } else {
717 745
        for (int i = 0; i != _root; ++i) {
718 746
          last_out = _first_out[i+1];
719 747
          for (int j = _first_out[i]; j != last_out; ++j) {
720 748
            if (_forward[j] && _scost[j] < 0) {
721 749
              Value c = _upper[j];
722 750
              if (c >= MAX) return UNBOUNDED;
723 751
              _excess[i] -= c;
724 752
              _excess[_target[j]] += c;
725 753
            }
726 754
          }
727 755
        }
728 756
      }
729 757
      Value ex, max_cap = 0;
730 758
      for (int i = 0; i != _res_node_num; ++i) {
731 759
        ex = _excess[i];
732 760
        _excess[i] = 0;
733 761
        if (ex < 0) max_cap -= ex;
734 762
      }
... ...
@@ -772,264 +800,270 @@
772 800
        }
773 801
      }
774 802

	
775 803
      // Find a feasible flow using Circulation
776 804
      Circulation<Digraph, ConstMap<Arc, Value>, ValueArcMap, ValueNodeMap>
777 805
        circ(_graph, low, cap, sup);
778 806
      if (!circ.flowMap(flow).run()) return INFEASIBLE;
779 807

	
780 808
      // Set residual capacities and handle GEQ supply type
781 809
      if (_sum_supply < 0) {
782 810
        for (ArcIt a(_graph); a != INVALID; ++a) {
783 811
          Value fa = flow[a];
784 812
          _res_cap[_arc_idf[a]] = cap[a] - fa;
785 813
          _res_cap[_arc_idb[a]] = fa;
786 814
          sup[_graph.source(a)] -= fa;
787 815
          sup[_graph.target(a)] += fa;
788 816
        }
789 817
        for (NodeIt n(_graph); n != INVALID; ++n) {
790 818
          _excess[_node_id[n]] = sup[n];
791 819
        }
792 820
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
793 821
          int u = _target[a];
794 822
          int ra = _reverse[a];
795 823
          _res_cap[a] = -_sum_supply + 1;
796 824
          _res_cap[ra] = -_excess[u];
797 825
          _cost[a] = 0;
798 826
          _cost[ra] = 0;
799 827
          _excess[u] = 0;
800 828
        }
801 829
      } else {
802 830
        for (ArcIt a(_graph); a != INVALID; ++a) {
803 831
          Value fa = flow[a];
804 832
          _res_cap[_arc_idf[a]] = cap[a] - fa;
805 833
          _res_cap[_arc_idb[a]] = fa;
806 834
        }
807 835
        for (int a = _first_out[_root]; a != _res_arc_num; ++a) {
808 836
          int ra = _reverse[a];
809 837
          _res_cap[a] = 1;
810 838
          _res_cap[ra] = 0;
811 839
          _cost[a] = 0;
812 840
          _cost[ra] = 0;
813 841
        }
814 842
      }
815 843
      
816 844
      return OPTIMAL;
817 845
    }
818 846

	
819 847
    // Execute the algorithm and transform the results
820
    void start(bool partial_augment) {
848
    void start(Method method) {
849
      // Maximum path length for partial augment
850
      const int MAX_PATH_LENGTH = 4;
851
      
821 852
      // Execute the algorithm
822
      if (partial_augment) {
823
        startPartialAugment();
824
      } else {
825
        startPushRelabel();
853
      switch (method) {
854
        case PUSH:
855
          startPush();
856
          break;
857
        case AUGMENT:
858
          startAugment();
859
          break;
860
        case PARTIAL_AUGMENT:
861
          startAugment(MAX_PATH_LENGTH);
862
          break;
826 863
      }
827 864

	
828 865
      // Compute node potentials for the original costs
829 866
      _arc_vec.clear();
830 867
      _cost_vec.clear();
831 868
      for (int j = 0; j != _res_arc_num; ++j) {
832 869
        if (_res_cap[j] > 0) {
833 870
          _arc_vec.push_back(IntPair(_source[j], _target[j]));
834 871
          _cost_vec.push_back(_scost[j]);
835 872
        }
836 873
      }
837 874
      _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
838 875

	
839 876
      typename BellmanFord<StaticDigraph, LargeCostArcMap>
840 877
        ::template SetDistMap<LargeCostNodeMap>::Create bf(_sgr, _cost_map);
841 878
      bf.distMap(_pi_map);
842 879
      bf.init(0);
843 880
      bf.start();
844 881

	
845 882
      // Handle non-zero lower bounds
846 883
      if (_have_lower) {
847 884
        int limit = _first_out[_root];
848 885
        for (int j = 0; j != limit; ++j) {
849 886
          if (!_forward[j]) _res_cap[j] += _lower[j];
850 887
        }
851 888
      }
852 889
    }
853 890

	
854
    /// Execute the algorithm performing partial augmentation and
855
    /// relabel operations
856
    void startPartialAugment() {
891
    /// Execute the algorithm performing augment and relabel operations
892
    void startAugment(int max_length = std::numeric_limits<int>::max()) {
857 893
      // Paramters for heuristics
858 894
      const int BF_HEURISTIC_EPSILON_BOUND = 1000;
859 895
      const int BF_HEURISTIC_BOUND_FACTOR  = 3;
860
      // Maximum augment path length
861
      const int MAX_PATH_LENGTH = 4;
862 896

	
863 897
      // Perform cost scaling phases
864 898
      IntVector pred_arc(_res_node_num);
865 899
      std::vector<int> path_nodes;
866 900
      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
867 901
                                        1 : _epsilon / _alpha )
868 902
      {
869 903
        // "Early Termination" heuristic: use Bellman-Ford algorithm
870 904
        // to check if the current flow is optimal
871 905
        if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
872 906
          _arc_vec.clear();
873 907
          _cost_vec.clear();
874 908
          for (int j = 0; j != _res_arc_num; ++j) {
875 909
            if (_res_cap[j] > 0) {
876 910
              _arc_vec.push_back(IntPair(_source[j], _target[j]));
877 911
              _cost_vec.push_back(_cost[j] + 1);
878 912
            }
879 913
          }
880 914
          _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
881 915

	
882 916
          BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
883 917
          bf.init(0);
884 918
          bool done = false;
885 919
          int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(_res_node_num));
886 920
          for (int i = 0; i < K && !done; ++i)
887 921
            done = bf.processNextWeakRound();
888 922
          if (done) break;
889 923
        }
890 924

	
891 925
        // Saturate arcs not satisfying the optimality condition
892 926
        for (int a = 0; a != _res_arc_num; ++a) {
893 927
          if (_res_cap[a] > 0 &&
894 928
              _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
895 929
            Value delta = _res_cap[a];
896 930
            _excess[_source[a]] -= delta;
897 931
            _excess[_target[a]] += delta;
898 932
            _res_cap[a] = 0;
899 933
            _res_cap[_reverse[a]] += delta;
900 934
          }
901 935
        }
902 936
        
903 937
        // Find active nodes (i.e. nodes with positive excess)
904 938
        for (int u = 0; u != _res_node_num; ++u) {
905 939
          if (_excess[u] > 0) _active_nodes.push_back(u);
906 940
        }
907 941

	
908 942
        // Initialize the next arcs
909 943
        for (int u = 0; u != _res_node_num; ++u) {
910 944
          _next_out[u] = _first_out[u];
911 945
        }
912 946

	
913 947
        // Perform partial augment and relabel operations
914 948
        while (true) {
915 949
          // Select an active node (FIFO selection)
916 950
          while (_active_nodes.size() > 0 &&
917 951
                 _excess[_active_nodes.front()] <= 0) {
918 952
            _active_nodes.pop_front();
919 953
          }
920 954
          if (_active_nodes.size() == 0) break;
921 955
          int start = _active_nodes.front();
922 956
          path_nodes.clear();
923 957
          path_nodes.push_back(start);
924 958

	
925 959
          // Find an augmenting path from the start node
926 960
          int tip = start;
927 961
          while (_excess[tip] >= 0 &&
928
                 int(path_nodes.size()) <= MAX_PATH_LENGTH) {
962
                 int(path_nodes.size()) <= max_length) {
929 963
            int u;
930 964
            LargeCost min_red_cost, rc;
931 965
            int last_out = _sum_supply < 0 ?
932 966
              _first_out[tip+1] : _first_out[tip+1] - 1;
933 967
            for (int a = _next_out[tip]; a != last_out; ++a) {
934 968
              if (_res_cap[a] > 0 &&
935 969
                  _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
936 970
                u = _target[a];
937 971
                pred_arc[u] = a;
938 972
                _next_out[tip] = a;
939 973
                tip = u;
940 974
                path_nodes.push_back(tip);
941 975
                goto next_step;
942 976
              }
943 977
            }
944 978

	
945 979
            // Relabel tip node
946 980
            min_red_cost = std::numeric_limits<LargeCost>::max() / 2;
947 981
            for (int a = _first_out[tip]; a != last_out; ++a) {
948 982
              rc = _cost[a] + _pi[_source[a]] - _pi[_target[a]];
949 983
              if (_res_cap[a] > 0 && rc < min_red_cost) {
950 984
                min_red_cost = rc;
951 985
              }
952 986
            }
953 987
            _pi[tip] -= min_red_cost + _epsilon;
954 988

	
955 989
            // Reset the next arc of tip
956 990
            _next_out[tip] = _first_out[tip];
957 991

	
958 992
            // Step back
959 993
            if (tip != start) {
960 994
              path_nodes.pop_back();
961 995
              tip = path_nodes.back();
962 996
            }
963 997

	
964 998
          next_step: ;
965 999
          }
966 1000

	
967 1001
          // Augment along the found path (as much flow as possible)
968 1002
          Value delta;
969 1003
          int u, v = path_nodes.front(), pa;
970 1004
          for (int i = 1; i < int(path_nodes.size()); ++i) {
971 1005
            u = v;
972 1006
            v = path_nodes[i];
973 1007
            pa = pred_arc[v];
974 1008
            delta = std::min(_res_cap[pa], _excess[u]);
975 1009
            _res_cap[pa] -= delta;
976 1010
            _res_cap[_reverse[pa]] += delta;
977 1011
            _excess[u] -= delta;
978 1012
            _excess[v] += delta;
979 1013
            if (_excess[v] > 0 && _excess[v] <= delta)
980 1014
              _active_nodes.push_back(v);
981 1015
          }
982 1016
        }
983 1017
      }
984 1018
    }
985 1019

	
986 1020
    /// Execute the algorithm performing push and relabel operations
987
    void startPushRelabel() {
1021
    void startPush() {
988 1022
      // Paramters for heuristics
989 1023
      const int BF_HEURISTIC_EPSILON_BOUND = 1000;
990 1024
      const int BF_HEURISTIC_BOUND_FACTOR  = 3;
991 1025

	
992 1026
      // Perform cost scaling phases
993 1027
      BoolVector hyper(_res_node_num, false);
994 1028
      for ( ; _epsilon >= 1; _epsilon = _epsilon < _alpha && _epsilon > 1 ?
995 1029
                                        1 : _epsilon / _alpha )
996 1030
      {
997 1031
        // "Early Termination" heuristic: use Bellman-Ford algorithm
998 1032
        // to check if the current flow is optimal
999 1033
        if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) {
1000 1034
          _arc_vec.clear();
1001 1035
          _cost_vec.clear();
1002 1036
          for (int j = 0; j != _res_arc_num; ++j) {
1003 1037
            if (_res_cap[j] > 0) {
1004 1038
              _arc_vec.push_back(IntPair(_source[j], _target[j]));
1005 1039
              _cost_vec.push_back(_cost[j] + 1);
1006 1040
            }
1007 1041
          }
1008 1042
          _sgr.build(_res_node_num, _arc_vec.begin(), _arc_vec.end());
1009 1043

	
1010 1044
          BellmanFord<StaticDigraph, LargeCostArcMap> bf(_sgr, _cost_map);
1011 1045
          bf.init(0);
1012 1046
          bool done = false;
1013 1047
          int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(_res_node_num));
1014 1048
          for (int i = 0; i < K && !done; ++i)
1015 1049
            done = bf.processNextWeakRound();
1016 1050
          if (done) break;
1017 1051
        }
1018 1052

	
1019 1053
        // Saturate arcs not satisfying the optimality condition
1020 1054
        for (int a = 0; a != _res_arc_num; ++a) {
1021 1055
          if (_res_cap[a] > 0 &&
1022 1056
              _cost[a] + _pi[_source[a]] - _pi[_target[a]] < 0) {
1023 1057
            Value delta = _res_cap[a];
1024 1058
            _excess[_source[a]] -= delta;
1025 1059
            _excess[_target[a]] += delta;
1026 1060
            _res_cap[a] = 0;
1027 1061
            _res_cap[_reverse[a]] += delta;
1028 1062
          }
1029 1063
        }
1030 1064

	
1031 1065
        // Find active nodes (i.e. nodes with positive excess)
1032 1066
        for (int u = 0; u != _res_node_num; ++u) {
1033 1067
          if (_excess[u] > 0) _active_nodes.push_back(u);
1034 1068
        }
1035 1069

	
0 comments (0 inline)