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 6 line context
... ...
@@ -49,24 +49,28 @@
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

	
... ...
@@ -117,14 +121,16 @@
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 {
... ...
@@ -141,13 +147,13 @@
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;
... ...
@@ -162,11 +168,11 @@
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;
... ...
@@ -184,7 +190,7 @@
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

	
... ...
@@ -196,9 +202,9 @@
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

	
... ...
@@ -216,7 +222,7 @@
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) {
... ...
@@ -247,9 +253,9 @@
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

	
... ...
@@ -264,7 +270,7 @@
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) {
... ...
@@ -286,9 +292,9 @@
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

	
... ...
@@ -314,7 +320,7 @@
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) {
... ...
@@ -358,9 +364,9 @@
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

	
... ...
@@ -394,7 +400,7 @@
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
... ...
@@ -463,9 +469,9 @@
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

	
... ...
@@ -473,15 +479,15 @@
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
        }
... ...
@@ -590,9 +596,12 @@
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.
... ...
@@ -609,14 +618,14 @@
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
      }
... ...
@@ -629,17 +638,17 @@
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
      }
... ...
@@ -666,13 +675,13 @@
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.
... ...
@@ -690,14 +699,14 @@
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
      }
... ...
@@ -712,7 +721,7 @@
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>
... ...
@@ -720,7 +729,7 @@
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
      }
... ...
@@ -741,7 +750,7 @@
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;
... ...
@@ -874,14 +883,14 @@
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
    ///
... ...
@@ -900,8 +909,8 @@
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

	
... ...
@@ -910,7 +919,7 @@
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

	
... ...
@@ -930,7 +939,7 @@
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

	
... ...
@@ -996,7 +1005,7 @@
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;
... ...
@@ -1035,6 +1044,8 @@
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];
... ...
@@ -1057,9 +1068,8 @@
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)
... ...
@@ -1073,7 +1083,7 @@
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;
... ...
@@ -1083,8 +1093,6 @@
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;
... ...
@@ -1137,7 +1145,7 @@
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
... ...
@@ -1175,7 +1183,7 @@
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;
... ...
@@ -1316,7 +1324,7 @@
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) {
Ignore white space 6 line context
... ...
@@ -77,7 +77,7 @@
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:
... ...
@@ -116,18 +116,19 @@
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;
... ...
@@ -206,15 +207,16 @@
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
0 comments (0 inline)