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 24 line context
... ...
@@ -40,42 +40,46 @@
40 40
  /// for finding a \ref min_cost_flow "minimum cost flow".
41 41
  ///
42 42
  /// \ref NetworkSimplex implements the primal Network Simplex algorithm
43 43
  /// for finding a \ref min_cost_flow "minimum cost flow".
44 44
  /// This algorithm is a specialized version of the linear programming
45 45
  /// simplex method directly for the minimum cost flow problem.
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()
76 80
    /// function.
77 81
    ///
78 82
    /// \ref NetworkSimplex provides five different pivot rule
79 83
    /// implementations that significantly affect the running time
80 84
    /// of the algorithm.
81 85
    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
... ...
@@ -108,124 +112,126 @@
108 112

	
109 113
      /// The Altering Candidate List pivot rule.
110 114
      /// It is a modified version of the Candidate List method.
111 115
      /// It keeps only the several best eligible arcs from the former
112 116
      /// candidate list and extends this list in every iteration.
113 117
      ALTERING_LIST
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
134 140
    };
135 141

	
136 142
  private:
137 143

	
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;
157 163

	
158 164
    // Data structures for storing the digraph
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;
176 182
    IntVector _succ_num;
177 183
    IntVector _last_succ;
178 184
    IntVector _dirty_revs;
179 185
    BoolVector _forward;
180 186
    IntVector _state;
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

	
208 214
    public:
209 215

	
210 216
      // Constructor
211 217
      FirstEligiblePivotRule(NetworkSimplex &ns) :
212 218
        _source(ns._source), _target(ns._target),
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;
226 232
          }
227 233
        }
228 234
        for (int e = 0; e < _next_arc; ++e) {
229 235
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
230 236
          if (c < 0) {
231 237
            _in_arc = e;
... ...
@@ -238,66 +244,66 @@
238 244

	
239 245
    }; //class FirstEligiblePivotRule
240 246

	
241 247

	
242 248
    // Implementation of the Best Eligible pivot rule
243 249
    class BestEligiblePivotRule
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
259 265
      BestEligiblePivotRule(NetworkSimplex &ns) :
260 266
        _source(ns._source), _target(ns._target),
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
          }
274 280
        }
275 281
        return min < 0;
276 282
      }
277 283

	
278 284
    }; //class BestEligiblePivotRule
279 285

	
280 286

	
281 287
    // Implementation of the Block Search pivot rule
282 288
    class BlockSearchPivotRule
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;
298 304

	
299 305
    public:
300 306

	
301 307
      // Constructor
302 308
      BlockSearchPivotRule(NetworkSimplex &ns) :
303 309
        _source(ns._source), _target(ns._target),
... ...
@@ -305,25 +311,25 @@
305 311
        _in_arc(ns.in_arc), _arc_num(ns._arc_num), _next_arc(0)
306 312
      {
307 313
        // The main parameters of the pivot rule
308 314
        const double BLOCK_SIZE_FACTOR = 2.0;
309 315
        const int MIN_BLOCK_SIZE = 10;
310 316

	
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;
324 330
            min_arc = e;
325 331
          }
326 332
          if (--cnt == 0) {
327 333
            if (min < 0) break;
328 334
            cnt = _block_size;
329 335
          }
... ...
@@ -349,27 +355,27 @@
349 355

	
350 356
    }; //class BlockSearchPivotRule
351 357

	
352 358

	
353 359
    // Implementation of the Candidate List pivot rule
354 360
    class CandidateListPivotRule
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;
370 376
      int _curr_length, _minor_count;
371 377
      int _next_arc;
372 378

	
373 379
    public:
374 380

	
375 381
      /// Constructor
... ...
@@ -385,25 +391,25 @@
385 391
        const int MIN_MINOR_LIMIT = 3;
386 392

	
387 393
        _list_length = std::max( int(LIST_LENGTH_FACTOR * sqrt(_arc_num)),
388 394
                                 MIN_LIST_LENGTH );
389 395
        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
390 396
                                 MIN_MINOR_LIMIT );
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;
404 410
          for (int i = 0; i < _curr_length; ++i) {
405 411
            e = _candidates[i];
406 412
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
407 413
            if (c < min) {
408 414
              min = c;
409 415
              min_arc = e;
... ...
@@ -454,43 +460,43 @@
454 460

	
455 461
    }; //class CandidateListPivotRule
456 462

	
457 463

	
458 464
    // Implementation of the Altering Candidate List pivot rule
459 465
    class AlteringListPivotRule
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;
491 497

	
492 498
    public:
493 499

	
494 500
      // Constructor
495 501
      AlteringListPivotRule(NetworkSimplex &ns) :
496 502
        _source(ns._source), _target(ns._target),
... ...
@@ -581,74 +587,77 @@
581 587
    ///
582 588
    /// Constructor.
583 589
    ///
584 590
    /// \param graph The digraph the algorithm runs on.
585 591
    NetworkSimplex(const GR& graph) :
586 592
      _graph(graph),
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;
602 611
    }
603 612

	
604 613
    /// \brief Set the lower bounds on the arcs.
605 614
    ///
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

	
649 658
    /// \brief Set the upper bounds (capacities) on the arcs.
650 659
    ///
651 660
    /// This function sets the upper bounds (capacities) on the arcs.
652 661
    /// It is just an alias for \ref upperMap().
653 662
    ///
654 663
    /// \return <tt>(*this)</tt>
... ...
@@ -657,100 +666,100 @@
657 666
      return upperMap(map);
658 667
    }
659 668

	
660 669
    /// \brief Set the lower and upper bounds on the arcs.
661 670
    ///
662 671
    /// This function sets the lower and upper bounds on the arcs.
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>
682 691
    NetworkSimplex& boundMaps(const LOWER& lower, const UPPER& upper) {
683 692
      return lowerMap(lower).upperMap(upper);
684 693
    }
685 694

	
686 695
    /// \brief Set the costs of the arcs.
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

	
707 716
    /// \brief Set the supply values of the nodes.
708 717
    ///
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

	
730 739
    /// \brief Set single source and target nodes and a supply value.
731 740
    ///
732 741
    /// This function sets a single source node and a single target node
733 742
    /// and the required flow value.
734 743
    /// If neither this function nor \ref supplyMap() is used before
735 744
    /// calling \ref run(), the supply of each node will be set to zero.
736 745
    /// (It makes sense only if non-zero lower bounds are given.)
737 746
    ///
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;
751 760
      return *this;
752 761
    }
753 762

	
754 763
    /// \brief Set the flow map.
755 764
    ///
756 765
    /// This function sets the flow map.
... ...
@@ -865,81 +874,81 @@
865 874
    /// @}
866 875

	
867 876
    /// \name Query Functions
868 877
    /// The results of the algorithm can be obtained using these
869 878
    /// functions.\n
870 879
    /// The \ref run() function must be called before using them.
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 {
891 900
      Num c = 0;
892 901
      if (_pcost) {
893 902
        for (ArcIt e(_graph); e != INVALID; ++e)
894 903
          c += (*_flow_map)[e] * (*_pcost)[e];
895 904
      } else {
896 905
        for (ArcIt e(_graph); e != INVALID; ++e)
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
920 929
    /// the found flow.
921 930
    ///
922 931
    /// \pre \ref run() must be called before using this function.
923 932
    const FlowMap& flowMap() const {
924 933
      return *_flow_map;
925 934
    }
926 935

	
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
    ///
940 949
    /// This function returns a const reference to a node map storing
941 950
    /// the found potentials, which form the dual solution of the
942 951
    /// \ref min_cost_flow "minimum cost flow" problem.
943 952
    ///
944 953
    /// \pre \ref run() must be called before using this function.
945 954
    const PotentialMap& potentialMap() const {
... ...
@@ -987,25 +996,25 @@
987 996
      _succ_num.resize(all_node_num);
988 997
      _last_succ.resize(all_node_num);
989 998
      _state.resize(all_arc_num);
990 999

	
991 1000
      // Initialize node related data
992 1001
      bool valid_supply = true;
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
        }
1006 1015
        valid_supply = (sum == 0);
1007 1016
      } else {
1008 1017
        int i = 0;
1009 1018
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1010 1019
          _node_id[n] = i;
1011 1020
          _supply[i] = 0;
... ...
@@ -1026,74 +1035,73 @@
1026 1035
      _supply[_root] = 0;
1027 1036
      _pi[_root] = 0;
1028 1037

	
1029 1038
      // Store the arcs in a mixed order
1030 1039
      int k = std::max(int(sqrt(_arc_num)), 10);
1031 1040
      int i = 0;
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];
1044 1055
          _cost[i] = (*_pcost)[e];
1045 1056
          _flow[i] = 0;
1046 1057
          _state[i] = STATE_LOWER;
1047 1058
        }
1048 1059
      } else {
1049 1060
        for (int i = 0; i != _arc_num; ++i) {
1050 1061
          Arc e = _arc_ref[i];
1051 1062
          _source[i] = _node_id[_graph.source(e)];
1052 1063
          _target[i] = _node_id[_graph.target(e)];
1053 1064
          _flow[i] = 0;
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)
1069 1079
            _cost[i] = 1;
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;
1094 1102
        _pred[u] = e;
1095 1103
        _cost[e] = max_cost;
1096 1104
        _cap[e] = max_cap;
1097 1105
        _state[e] = STATE_TREE;
1098 1106
        if (_supply[u] >= 0) {
1099 1107
          _flow[e] = _supply[u];
... ...
@@ -1128,25 +1136,25 @@
1128 1136
    bool findLeavingArc() {
1129 1137
      // Initialize first and second nodes according to the direction
1130 1138
      // of the cycle
1131 1139
      if (_state[in_arc] == STATE_LOWER) {
1132 1140
        first  = _source[in_arc];
1133 1141
        second = _target[in_arc];
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];
1147 1155
        if (d < delta) {
1148 1156
          delta = d;
1149 1157
          u_out = u;
1150 1158
          result = 1;
1151 1159
        }
1152 1160
      }
... ...
@@ -1166,25 +1174,25 @@
1166 1174
        v_in = second;
1167 1175
      } else {
1168 1176
        u_in = second;
1169 1177
        v_in = first;
1170 1178
      }
1171 1179
      return result != 0;
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;
1185 1193
        }
1186 1194
      }
1187 1195
      // Update the state of the entering and leaving arcs
1188 1196
      if (change) {
1189 1197
        _state[in_arc] = STATE_TREE;
1190 1198
        _state[_pred[u_out]] =
... ...
@@ -1307,25 +1315,25 @@
1307 1315
      // Update _succ_num from v_in to join
1308 1316
      for (u = v_in; u != join; u = _parent[u]) {
1309 1317
        _succ_num[u] += old_succ_num;
1310 1318
      }
1311 1319
      // Update _succ_num from v_out to join
1312 1320
      for (u = v_out; u != join; u = _parent[u]) {
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]];
1326 1334
        _thread[before] = after;
1327 1335
        _pi[_root] -= sigma;
1328 1336
        for (int u = _thread[_root]; u != _root; u = _thread[u]) {
1329 1337
          _pi[u] -= sigma;
1330 1338
        }
1331 1339
        _thread[before] = u_in;
Ignore white space 6 line context
... ...
@@ -68,25 +68,25 @@
68 68
  "10 12    70   13    0    5\n"
69 69
  "10  2   100    7    0    0\n"
70 70
  "10  7    60   10    0    0\n"
71 71
  "11 10    20   14    0    6\n"
72 72
  "12 11    30   10    0    0\n"
73 73
  "\n"
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 {
87 87
    void constraints() {
88 88
      checkConcept<concepts::Digraph, GR>();
89 89

	
90 90
      MCF mcf(g);
91 91

	
92 92
      b = mcf.reset()
... ...
@@ -107,36 +107,37 @@
107 107
      v = mcf.flow(a);
108 108
      v = mcf.potential(n);
109 109
      mcf.flowMap(flow);
110 110
      mcf.potentialMap(pot);
111 111

	
112 112
      ignore_unused_variable_warning(fm);
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

	
137 138
};
138 139

	
139 140

	
140 141
// Check the feasibility of the given flow (primal soluiton)
141 142
template < typename GR, typename LM, typename UM,
142 143
           typename SM, typename FM >
... ...
@@ -197,33 +198,34 @@
197 198
          "The flow is not feasible " + test_id);
198 199
    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
199 200
    check(checkPotential(gr, lower, upper, cost, mcf.flowMap(),
200 201
                         mcf.potentialMap()),
201 202
          "Wrong potentials " + test_id);
202 203
  }
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

	
224 226
  // Read the test digraph
225 227
  Digraph gr;
226 228
  Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), u(gr);
227 229
  Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr);
228 230
  ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
229 231
  Node v, w;
0 comments (0 inline)