gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Separate types for flow and cost values in NetworkSimplex (#234)
0 2 0
default
2 files changed with 90 insertions and 80 deletions:
↑ Collapse diff ↑
Ignore white space 12 line context
... ...
@@ -46,30 +46,34 @@
46 46
  /// It is one of the most efficient solution methods.
47 47
  ///
48 48
  /// In general this class is the fastest implementation available
49 49
  /// in LEMON for the minimum cost flow problem.
50 50
  ///
51 51
  /// \tparam GR The digraph type the algorithm runs on.
52
  /// \tparam V The value type used in the algorithm.
53
  /// By default it is \c int.
52
  /// \tparam F The value type used for flow amounts, capacity bounds
53
  /// and supply values in the algorithm. By default it is \c int.
54
  /// \tparam C The value type used for costs and potentials in the
55
  /// algorithm. By default it is the same as \c F.
54 56
  ///
55
  /// \warning The value type must be a signed integer type.
57
  /// \warning Both value types must be signed integer types.
56 58
  ///
57 59
  /// \note %NetworkSimplex provides five different pivot rule
58 60
  /// implementations. For more information see \ref PivotRule.
59
  template <typename GR, typename V = int>
61
  template <typename GR, typename F = int, typename C = F>
60 62
  class NetworkSimplex
61 63
  {
62 64
  public:
63 65

	
64
    /// The value type of the algorithm
65
    typedef V Value;
66
    /// The flow type of the algorithm
67
    typedef F Flow;
68
    /// The cost type of the algorithm
69
    typedef C Cost;
66 70
    /// The type of the flow map
67
    typedef typename GR::template ArcMap<Value> FlowMap;
71
    typedef typename GR::template ArcMap<Flow> FlowMap;
68 72
    /// The type of the potential map
69
    typedef typename GR::template NodeMap<Value> PotentialMap;
73
    typedef typename GR::template NodeMap<Cost> PotentialMap;
70 74

	
71 75
  public:
72 76

	
73 77
    /// \brief Enum type for selecting the pivot rule.
74 78
    ///
75 79
    /// Enum type for selecting the pivot rule for the \ref run()
... ...
@@ -114,20 +118,22 @@
114 118
    };
115 119

	
116 120
  private:
117 121

	
118 122
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
119 123

	
120
    typedef typename GR::template ArcMap<Value> ValueArcMap;
121
    typedef typename GR::template NodeMap<Value> ValueNodeMap;
124
    typedef typename GR::template ArcMap<Flow> FlowArcMap;
125
    typedef typename GR::template ArcMap<Cost> CostArcMap;
126
    typedef typename GR::template NodeMap<Flow> FlowNodeMap;
122 127

	
123 128
    typedef std::vector<Arc> ArcVector;
124 129
    typedef std::vector<Node> NodeVector;
125 130
    typedef std::vector<int> IntVector;
126 131
    typedef std::vector<bool> BoolVector;
127
    typedef std::vector<Value> ValueVector;
132
    typedef std::vector<Flow> FlowVector;
133
    typedef std::vector<Cost> CostVector;
128 134

	
129 135
    // State constants for arcs
130 136
    enum ArcStateEnum {
131 137
      STATE_UPPER = -1,
132 138
      STATE_TREE  =  0,
133 139
      STATE_LOWER =  1
... ...
@@ -138,19 +144,19 @@
138 144
    // Data related to the underlying digraph
139 145
    const GR &_graph;
140 146
    int _node_num;
141 147
    int _arc_num;
142 148

	
143 149
    // Parameters of the problem
144
    ValueArcMap *_plower;
145
    ValueArcMap *_pupper;
146
    ValueArcMap *_pcost;
147
    ValueNodeMap *_psupply;
150
    FlowArcMap *_plower;
151
    FlowArcMap *_pupper;
152
    CostArcMap *_pcost;
153
    FlowNodeMap *_psupply;
148 154
    bool _pstsup;
149 155
    Node _psource, _ptarget;
150
    Value _pstflow;
156
    Flow _pstflow;
151 157

	
152 158
    // Result maps
153 159
    FlowMap *_flow_map;
154 160
    PotentialMap *_potential_map;
155 161
    bool _local_flow;
156 162
    bool _local_potential;
... ...
@@ -159,17 +165,17 @@
159 165
    IntNodeMap _node_id;
160 166
    ArcVector _arc_ref;
161 167
    IntVector _source;
162 168
    IntVector _target;
163 169

	
164 170
    // Node and arc data
165
    ValueVector _cap;
166
    ValueVector _cost;
167
    ValueVector _supply;
168
    ValueVector _flow;
169
    ValueVector _pi;
171
    FlowVector _cap;
172
    CostVector _cost;
173
    FlowVector _supply;
174
    FlowVector _flow;
175
    CostVector _pi;
170 176

	
171 177
    // Data for storing the spanning tree structure
172 178
    IntVector _parent;
173 179
    IntVector _pred;
174 180
    IntVector _thread;
175 181
    IntVector _rev_thread;
... ...
@@ -181,27 +187,27 @@
181 187
    int _root;
182 188

	
183 189
    // Temporary data used in the current pivot iteration
184 190
    int in_arc, join, u_in, v_in, u_out, v_out;
185 191
    int first, second, right, last;
186 192
    int stem, par_stem, new_stem;
187
    Value delta;
193
    Flow delta;
188 194

	
189 195
  private:
190 196

	
191 197
    // Implementation of the First Eligible pivot rule
192 198
    class FirstEligiblePivotRule
193 199
    {
194 200
    private:
195 201

	
196 202
      // References to the NetworkSimplex class
197 203
      const IntVector  &_source;
198 204
      const IntVector  &_target;
199
      const ValueVector &_cost;
205
      const CostVector &_cost;
200 206
      const IntVector  &_state;
201
      const ValueVector &_pi;
207
      const CostVector &_pi;
202 208
      int &_in_arc;
203 209
      int _arc_num;
204 210

	
205 211
      // Pivot rule data
206 212
      int _next_arc;
207 213

	
... ...
@@ -213,13 +219,13 @@
213 219
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
214 220
        _in_arc(ns.in_arc), _arc_num(ns._arc_num), _next_arc(0)
215 221
      {}
216 222

	
217 223
      // Find next entering arc
218 224
      bool findEnteringArc() {
219
        Value c;
225
        Cost c;
220 226
        for (int e = _next_arc; e < _arc_num; ++e) {
221 227
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
222 228
          if (c < 0) {
223 229
            _in_arc = e;
224 230
            _next_arc = e + 1;
225 231
            return true;
... ...
@@ -244,15 +250,15 @@
244 250
    {
245 251
    private:
246 252

	
247 253
      // References to the NetworkSimplex class
248 254
      const IntVector  &_source;
249 255
      const IntVector  &_target;
250
      const ValueVector &_cost;
256
      const CostVector &_cost;
251 257
      const IntVector  &_state;
252
      const ValueVector &_pi;
258
      const CostVector &_pi;
253 259
      int &_in_arc;
254 260
      int _arc_num;
255 261

	
256 262
    public:
257 263

	
258 264
      // Constructor
... ...
@@ -261,13 +267,13 @@
261 267
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
262 268
        _in_arc(ns.in_arc), _arc_num(ns._arc_num)
263 269
      {}
264 270

	
265 271
      // Find next entering arc
266 272
      bool findEnteringArc() {
267
        Value c, min = 0;
273
        Cost c, min = 0;
268 274
        for (int e = 0; e < _arc_num; ++e) {
269 275
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
270 276
          if (c < min) {
271 277
            min = c;
272 278
            _in_arc = e;
273 279
          }
... ...
@@ -283,15 +289,15 @@
283 289
    {
284 290
    private:
285 291

	
286 292
      // References to the NetworkSimplex class
287 293
      const IntVector  &_source;
288 294
      const IntVector  &_target;
289
      const ValueVector &_cost;
295
      const CostVector &_cost;
290 296
      const IntVector  &_state;
291
      const ValueVector &_pi;
297
      const CostVector &_pi;
292 298
      int &_in_arc;
293 299
      int _arc_num;
294 300

	
295 301
      // Pivot rule data
296 302
      int _block_size;
297 303
      int _next_arc;
... ...
@@ -311,13 +317,13 @@
311 317
        _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_arc_num)),
312 318
                                MIN_BLOCK_SIZE );
313 319
      }
314 320

	
315 321
      // Find next entering arc
316 322
      bool findEnteringArc() {
317
        Value c, min = 0;
323
        Cost c, min = 0;
318 324
        int cnt = _block_size;
319 325
        int e, min_arc = _next_arc;
320 326
        for (e = _next_arc; e < _arc_num; ++e) {
321 327
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
322 328
          if (c < min) {
323 329
            min = c;
... ...
@@ -355,15 +361,15 @@
355 361
    {
356 362
    private:
357 363

	
358 364
      // References to the NetworkSimplex class
359 365
      const IntVector  &_source;
360 366
      const IntVector  &_target;
361
      const ValueVector &_cost;
367
      const CostVector &_cost;
362 368
      const IntVector  &_state;
363
      const ValueVector &_pi;
369
      const CostVector &_pi;
364 370
      int &_in_arc;
365 371
      int _arc_num;
366 372

	
367 373
      // Pivot rule data
368 374
      IntVector _candidates;
369 375
      int _list_length, _minor_limit;
... ...
@@ -391,13 +397,13 @@
391 397
        _curr_length = _minor_count = 0;
392 398
        _candidates.resize(_list_length);
393 399
      }
394 400

	
395 401
      /// Find next entering arc
396 402
      bool findEnteringArc() {
397
        Value min, c;
403
        Cost min, c;
398 404
        int e, min_arc = _next_arc;
399 405
        if (_curr_length > 0 && _minor_count < _minor_limit) {
400 406
          // Minor iteration: select the best eligible arc from the
401 407
          // current candidate list
402 408
          ++_minor_count;
403 409
          min = 0;
... ...
@@ -460,31 +466,31 @@
460 466
    {
461 467
    private:
462 468

	
463 469
      // References to the NetworkSimplex class
464 470
      const IntVector  &_source;
465 471
      const IntVector  &_target;
466
      const ValueVector &_cost;
472
      const CostVector &_cost;
467 473
      const IntVector  &_state;
468
      const ValueVector &_pi;
474
      const CostVector &_pi;
469 475
      int &_in_arc;
470 476
      int _arc_num;
471 477

	
472 478
      // Pivot rule data
473 479
      int _block_size, _head_length, _curr_length;
474 480
      int _next_arc;
475 481
      IntVector _candidates;
476
      ValueVector _cand_cost;
482
      CostVector _cand_cost;
477 483

	
478 484
      // Functor class to compare arcs during sort of the candidate list
479 485
      class SortFunc
480 486
      {
481 487
      private:
482
        const ValueVector &_map;
488
        const CostVector &_map;
483 489
      public:
484
        SortFunc(const ValueVector &map) : _map(map) {}
490
        SortFunc(const CostVector &map) : _map(map) {}
485 491
        bool operator()(int left, int right) {
486 492
          return _map[left] > _map[right];
487 493
        }
488 494
      };
489 495

	
490 496
      SortFunc _sort_func;
... ...
@@ -587,15 +593,18 @@
587 593
      _plower(NULL), _pupper(NULL), _pcost(NULL),
588 594
      _psupply(NULL), _pstsup(false),
589 595
      _flow_map(NULL), _potential_map(NULL),
590 596
      _local_flow(false), _local_potential(false),
591 597
      _node_id(graph)
592 598
    {
593
      LEMON_ASSERT(std::numeric_limits<Value>::is_integer &&
594
                   std::numeric_limits<Value>::is_signed,
595
        "The value type of NetworkSimplex must be a signed integer");
599
      LEMON_ASSERT(std::numeric_limits<Flow>::is_integer &&
600
                   std::numeric_limits<Flow>::is_signed,
601
        "The flow type of NetworkSimplex must be signed integer");
602
      LEMON_ASSERT(std::numeric_limits<Cost>::is_integer &&
603
                   std::numeric_limits<Cost>::is_signed,
604
        "The cost type of NetworkSimplex must be signed integer");
596 605
    }
597 606

	
598 607
    /// Destructor.
599 608
    ~NetworkSimplex() {
600 609
      if (_local_flow) delete _flow_map;
601 610
      if (_local_potential) delete _potential_map;
... ...
@@ -606,43 +615,43 @@
606 615
    /// This function sets the lower bounds on the arcs.
607 616
    /// If neither this function nor \ref boundMaps() is used before
608 617
    /// calling \ref run(), the lower bounds will be set to zero
609 618
    /// on all arcs.
610 619
    ///
611 620
    /// \param map An arc map storing the lower bounds.
612
    /// Its \c Value type must be convertible to the \c Value type
621
    /// Its \c Value type must be convertible to the \c Flow type
613 622
    /// of the algorithm.
614 623
    ///
615 624
    /// \return <tt>(*this)</tt>
616 625
    template <typename LOWER>
617 626
    NetworkSimplex& lowerMap(const LOWER& map) {
618 627
      delete _plower;
619
      _plower = new ValueArcMap(_graph);
628
      _plower = new FlowArcMap(_graph);
620 629
      for (ArcIt a(_graph); a != INVALID; ++a) {
621 630
        (*_plower)[a] = map[a];
622 631
      }
623 632
      return *this;
624 633
    }
625 634

	
626 635
    /// \brief Set the upper bounds (capacities) on the arcs.
627 636
    ///
628 637
    /// This function sets the upper bounds (capacities) on the arcs.
629 638
    /// If none of the functions \ref upperMap(), \ref capacityMap()
630 639
    /// and \ref boundMaps() is used before calling \ref run(),
631 640
    /// the upper bounds (capacities) will be set to
632
    /// \c std::numeric_limits<Value>::max() on all arcs.
641
    /// \c std::numeric_limits<Flow>::max() on all arcs.
633 642
    ///
634 643
    /// \param map An arc map storing the upper bounds.
635
    /// Its \c Value type must be convertible to the \c Value type
644
    /// Its \c Value type must be convertible to the \c Flow type
636 645
    /// of the algorithm.
637 646
    ///
638 647
    /// \return <tt>(*this)</tt>
639 648
    template<typename UPPER>
640 649
    NetworkSimplex& upperMap(const UPPER& map) {
641 650
      delete _pupper;
642
      _pupper = new ValueArcMap(_graph);
651
      _pupper = new FlowArcMap(_graph);
643 652
      for (ArcIt a(_graph); a != INVALID; ++a) {
644 653
        (*_pupper)[a] = map[a];
645 654
      }
646 655
      return *this;
647 656
    }
648 657

	
... ...
@@ -663,19 +672,19 @@
663 672
    /// If neither this function nor \ref lowerMap() is used before
664 673
    /// calling \ref run(), the lower bounds will be set to zero
665 674
    /// on all arcs.
666 675
    /// If none of the functions \ref upperMap(), \ref capacityMap()
667 676
    /// and \ref boundMaps() is used before calling \ref run(),
668 677
    /// the upper bounds (capacities) will be set to
669
    /// \c std::numeric_limits<Value>::max() on all arcs.
678
    /// \c std::numeric_limits<Flow>::max() on all arcs.
670 679
    ///
671 680
    /// \param lower An arc map storing the lower bounds.
672 681
    /// \param upper An arc map storing the upper bounds.
673 682
    ///
674 683
    /// The \c Value type of the maps must be convertible to the
675
    /// \c Value type of the algorithm.
684
    /// \c Flow type of the algorithm.
676 685
    ///
677 686
    /// \note This function is just a shortcut of calling \ref lowerMap()
678 687
    /// and \ref upperMap() separately.
679 688
    ///
680 689
    /// \return <tt>(*this)</tt>
681 690
    template <typename LOWER, typename UPPER>
... ...
@@ -687,20 +696,20 @@
687 696
    ///
688 697
    /// This function sets the costs of the arcs.
689 698
    /// If it is not used before calling \ref run(), the costs
690 699
    /// will be set to \c 1 on all arcs.
691 700
    ///
692 701
    /// \param map An arc map storing the costs.
693
    /// Its \c Value type must be convertible to the \c Value type
702
    /// Its \c Value type must be convertible to the \c Cost type
694 703
    /// of the algorithm.
695 704
    ///
696 705
    /// \return <tt>(*this)</tt>
697 706
    template<typename COST>
698 707
    NetworkSimplex& costMap(const COST& map) {
699 708
      delete _pcost;
700
      _pcost = new ValueArcMap(_graph);
709
      _pcost = new CostArcMap(_graph);
701 710
      for (ArcIt a(_graph); a != INVALID; ++a) {
702 711
        (*_pcost)[a] = map[a];
703 712
      }
704 713
      return *this;
705 714
    }
706 715

	
... ...
@@ -709,21 +718,21 @@
709 718
    /// This function sets the supply values of the nodes.
710 719
    /// If neither this function nor \ref stSupply() is used before
711 720
    /// calling \ref run(), the supply of each node will be set to zero.
712 721
    /// (It makes sense only if non-zero lower bounds are given.)
713 722
    ///
714 723
    /// \param map A node map storing the supply values.
715
    /// Its \c Value type must be convertible to the \c Value type
724
    /// Its \c Value type must be convertible to the \c Flow type
716 725
    /// of the algorithm.
717 726
    ///
718 727
    /// \return <tt>(*this)</tt>
719 728
    template<typename SUP>
720 729
    NetworkSimplex& supplyMap(const SUP& map) {
721 730
      delete _psupply;
722 731
      _pstsup = false;
723
      _psupply = new ValueNodeMap(_graph);
732
      _psupply = new FlowNodeMap(_graph);
724 733
      for (NodeIt n(_graph); n != INVALID; ++n) {
725 734
        (*_psupply)[n] = map[n];
726 735
      }
727 736
      return *this;
728 737
    }
729 738

	
... ...
@@ -738,13 +747,13 @@
738 747
    /// \param s The source node.
739 748
    /// \param t The target node.
740 749
    /// \param k The required amount of flow from node \c s to node \c t
741 750
    /// (i.e. the supply of \c s and the demand of \c t).
742 751
    ///
743 752
    /// \return <tt>(*this)</tt>
744
    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
753
    NetworkSimplex& stSupply(const Node& s, const Node& t, Flow k) {
745 754
      delete _psupply;
746 755
      _psupply = NULL;
747 756
      _pstsup = true;
748 757
      _psource = s;
749 758
      _ptarget = t;
750 759
      _pstflow = k;
... ...
@@ -871,20 +880,20 @@
871 880

	
872 881
    /// @{
873 882

	
874 883
    /// \brief Return the total cost of the found flow.
875 884
    ///
876 885
    /// This function returns the total cost of the found flow.
877
    /// The complexity of the function is \f$ O(e) \f$.
886
    /// The complexity of the function is O(e).
878 887
    ///
879 888
    /// \note The return type of the function can be specified as a
880 889
    /// template parameter. For example,
881 890
    /// \code
882 891
    ///   ns.totalCost<double>();
883 892
    /// \endcode
884
    /// It is useful if the total cost cannot be stored in the \c Value
893
    /// It is useful if the total cost cannot be stored in the \c Cost
885 894
    /// type of the algorithm, which is the default return type of the
886 895
    /// function.
887 896
    ///
888 897
    /// \pre \ref run() must be called before using this function.
889 898
    template <typename Num>
890 899
    Num totalCost() const {
... ...
@@ -897,23 +906,23 @@
897 906
          c += (*_flow_map)[e];
898 907
      }
899 908
      return c;
900 909
    }
901 910

	
902 911
#ifndef DOXYGEN
903
    Value totalCost() const {
904
      return totalCost<Value>();
912
    Cost totalCost() const {
913
      return totalCost<Cost>();
905 914
    }
906 915
#endif
907 916

	
908 917
    /// \brief Return the flow on the given arc.
909 918
    ///
910 919
    /// This function returns the flow on the given arc.
911 920
    ///
912 921
    /// \pre \ref run() must be called before using this function.
913
    Value flow(const Arc& a) const {
922
    Flow flow(const Arc& a) const {
914 923
      return (*_flow_map)[a];
915 924
    }
916 925

	
917 926
    /// \brief Return a const reference to the flow map.
918 927
    ///
919 928
    /// This function returns a const reference to an arc map storing
... ...
@@ -927,13 +936,13 @@
927 936
    /// \brief Return the potential (dual value) of the given node.
928 937
    ///
929 938
    /// This function returns the potential (dual value) of the
930 939
    /// given node.
931 940
    ///
932 941
    /// \pre \ref run() must be called before using this function.
933
    Value potential(const Node& n) const {
942
    Cost potential(const Node& n) const {
934 943
      return (*_potential_map)[n];
935 944
    }
936 945

	
937 946
    /// \brief Return a const reference to the potential map
938 947
    /// (the dual solution).
939 948
    ///
... ...
@@ -993,13 +1002,13 @@
993 1002
      if (!_pstsup && !_psupply) {
994 1003
        _pstsup = true;
995 1004
        _psource = _ptarget = NodeIt(_graph);
996 1005
        _pstflow = 0;
997 1006
      }
998 1007
      if (_psupply) {
999
        Value sum = 0;
1008
        Flow sum = 0;
1000 1009
        int i = 0;
1001 1010
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1002 1011
          _node_id[n] = i;
1003 1012
          _supply[i] = (*_psupply)[n];
1004 1013
          sum += _supply[i];
1005 1014
        }
... ...
@@ -1032,12 +1041,14 @@
1032 1041
      for (ArcIt e(_graph); e != INVALID; ++e) {
1033 1042
        _arc_ref[i] = e;
1034 1043
        if ((i += k) >= _arc_num) i = (i % k) + 1;
1035 1044
      }
1036 1045

	
1037 1046
      // Initialize arc maps
1047
      Flow max_cap = std::numeric_limits<Flow>::max();
1048
      Cost max_cost = std::numeric_limits<Cost>::max() / 4;
1038 1049
      if (_pupper && _pcost) {
1039 1050
        for (int i = 0; i != _arc_num; ++i) {
1040 1051
          Arc e = _arc_ref[i];
1041 1052
          _source[i] = _node_id[_graph.source(e)];
1042 1053
          _target[i] = _node_id[_graph.target(e)];
1043 1054
          _cap[i] = (*_pupper)[e];
... ...
@@ -1054,15 +1065,14 @@
1054 1065
          _state[i] = STATE_LOWER;
1055 1066
        }
1056 1067
        if (_pupper) {
1057 1068
          for (int i = 0; i != _arc_num; ++i)
1058 1069
            _cap[i] = (*_pupper)[_arc_ref[i]];
1059 1070
        } else {
1060
          Value val = std::numeric_limits<Value>::max();
1061 1071
          for (int i = 0; i != _arc_num; ++i)
1062
            _cap[i] = val;
1072
            _cap[i] = max_cap;
1063 1073
        }
1064 1074
        if (_pcost) {
1065 1075
          for (int i = 0; i != _arc_num; ++i)
1066 1076
            _cost[i] = (*_pcost)[_arc_ref[i]];
1067 1077
        } else {
1068 1078
          for (int i = 0; i != _arc_num; ++i)
... ...
@@ -1070,24 +1080,22 @@
1070 1080
        }
1071 1081
      }
1072 1082

	
1073 1083
      // Remove non-zero lower bounds
1074 1084
      if (_plower) {
1075 1085
        for (int i = 0; i != _arc_num; ++i) {
1076
          Value c = (*_plower)[_arc_ref[i]];
1086
          Flow c = (*_plower)[_arc_ref[i]];
1077 1087
          if (c != 0) {
1078 1088
            _cap[i] -= c;
1079 1089
            _supply[_source[i]] -= c;
1080 1090
            _supply[_target[i]] += c;
1081 1091
          }
1082 1092
        }
1083 1093
      }
1084 1094

	
1085 1095
      // Add artificial arcs and initialize the spanning tree data structure
1086
      Value max_cap = std::numeric_limits<Value>::max();
1087
      Value max_cost = std::numeric_limits<Value>::max() / 4;
1088 1096
      for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1089 1097
        _thread[u] = u + 1;
1090 1098
        _rev_thread[u + 1] = u;
1091 1099
        _succ_num[u] = 1;
1092 1100
        _last_succ[u] = u;
1093 1101
        _parent[u] = _root;
... ...
@@ -1134,13 +1142,13 @@
1134 1142
      } else {
1135 1143
        first  = _target[in_arc];
1136 1144
        second = _source[in_arc];
1137 1145
      }
1138 1146
      delta = _cap[in_arc];
1139 1147
      int result = 0;
1140
      Value d;
1148
      Flow d;
1141 1149
      int e;
1142 1150

	
1143 1151
      // Search the cycle along the path form the first node to the root
1144 1152
      for (int u = first; u != join; u = _parent[u]) {
1145 1153
        e = _pred[u];
1146 1154
        d = _forward[u] ? _flow[e] : _cap[e] - _flow[e];
... ...
@@ -1172,13 +1180,13 @@
1172 1180
    }
1173 1181

	
1174 1182
    // Change _flow and _state vectors
1175 1183
    void changeFlow(bool change) {
1176 1184
      // Augment along the cycle
1177 1185
      if (delta > 0) {
1178
        Value val = _state[in_arc] * delta;
1186
        Flow val = _state[in_arc] * delta;
1179 1187
        _flow[in_arc] += val;
1180 1188
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
1181 1189
          _flow[_pred[u]] += _forward[u] ? -val : val;
1182 1190
        }
1183 1191
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
1184 1192
          _flow[_pred[u]] += _forward[u] ? val : -val;
... ...
@@ -1313,13 +1321,13 @@
1313 1321
        _succ_num[u] -= old_succ_num;
1314 1322
      }
1315 1323
    }
1316 1324

	
1317 1325
    // Update potentials
1318 1326
    void updatePotential() {
1319
      Value sigma = _forward[u_in] ?
1327
      Cost sigma = _forward[u_in] ?
1320 1328
        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
1321 1329
        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
1322 1330
      if (_succ_num[u_in] > _node_num / 2) {
1323 1331
        // Update in the upper subtree (which contains the root)
1324 1332
        int before = _rev_thread[u_in];
1325 1333
        int after = _thread[_last_succ[u_in]];
Ignore white space 6 line context
... ...
@@ -74,13 +74,13 @@
74 74
  "@attributes\n"
75 75
  "source 1\n"
76 76
  "target 12\n";
77 77

	
78 78

	
79 79
// Check the interface of an MCF algorithm
80
template <typename GR, typename Value>
80
template <typename GR, typename Flow, typename Cost>
81 81
class McfClassConcept
82 82
{
83 83
public:
84 84

	
85 85
  template <typename MCF>
86 86
  struct Constraints {
... ...
@@ -113,24 +113,25 @@
113 113
      ignore_unused_variable_warning(pm);
114 114
      ignore_unused_variable_warning(x);
115 115
    }
116 116

	
117 117
    typedef typename GR::Node Node;
118 118
    typedef typename GR::Arc Arc;
119
    typedef concepts::ReadMap<Node, Value> NM;
120
    typedef concepts::ReadMap<Arc, Value> AM;
119
    typedef concepts::ReadMap<Node, Flow> NM;
120
    typedef concepts::ReadMap<Arc, Flow> FAM;
121
    typedef concepts::ReadMap<Arc, Cost> CAM;
121 122

	
122 123
    const GR &g;
123
    const AM &lower;
124
    const AM &upper;
125
    const AM &cost;
124
    const FAM &lower;
125
    const FAM &upper;
126
    const CAM &cost;
126 127
    const NM &sup;
127 128
    const Node &n;
128 129
    const Arc &a;
129
    const Value &k;
130
    Value v;
130
    const Flow &k;
131
    Flow v;
131 132
    bool b;
132 133

	
133 134
    typename MCF::FlowMap &flow;
134 135
    typename MCF::PotentialMap &pot;
135 136
  };
136 137

	
... ...
@@ -203,21 +204,22 @@
203 204
}
204 205

	
205 206
int main()
206 207
{
207 208
  // Check the interfaces
208 209
  {
209
    typedef int Value;
210
    typedef int Flow;
211
    typedef int Cost;
210 212
    // TODO: This typedef should be enabled if the standard maps are
211 213
    // reference maps in the graph concepts (See #190).
212 214
/**/
213 215
    //typedef concepts::Digraph GR;
214 216
    typedef ListDigraph GR;
215 217
/**/
216
    checkConcept< McfClassConcept<GR, Value>,
217
                  NetworkSimplex<GR, Value> >();
218
    checkConcept< McfClassConcept<GR, Flow, Cost>,
219
                  NetworkSimplex<GR, Flow, Cost> >();
218 220
  }
219 221

	
220 222
  // Run various MCF tests
221 223
  typedef ListDigraph Digraph;
222 224
  DIGRAPH_TYPEDEFS(ListDigraph);
223 225

	
0 comments (0 inline)