gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Support real types + numerical stability fix in NS (#254) - Real types are supported by appropriate inicialization. - A feature of the XTI spanning tree structure is removed to ensure numerical stability (could cause problems using integer types). The node potentials are updated always on the lower subtree, in order to prevent overflow problems. The former method isn't notably faster during to our tests.
0 1 0
default
1 file changed with 24 insertions and 21 deletions:
↑ Collapse diff ↑
Show white space 768 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_NETWORK_SIMPLEX_H
20 20
#define LEMON_NETWORK_SIMPLEX_H
21 21

	
22 22
/// \ingroup min_cost_flow
23 23
///
24 24
/// \file
25 25
/// \brief Network Simplex algorithm for finding a minimum cost flow.
26 26

	
27 27
#include <vector>
28 28
#include <limits>
29 29
#include <algorithm>
30 30

	
31 31
#include <lemon/core.h>
32 32
#include <lemon/math.h>
33 33

	
34 34
namespace lemon {
35 35

	
36 36
  /// \addtogroup min_cost_flow
37 37
  /// @{
38 38

	
39 39
  /// \brief Implementation of the primal Network Simplex algorithm
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 52
  /// \tparam F The value type used for flow amounts, capacity bounds
53 53
  /// and supply values in the algorithm. By default it is \c int.
54 54
  /// \tparam C The value type used for costs and potentials in the
55 55
  /// algorithm. By default it is the same as \c F.
56 56
  ///
57
  /// \warning Both value types must be signed integer types.
57
  /// \warning Both value types must be signed and all input data must
58
  /// be integer.
58 59
  ///
59 60
  /// \note %NetworkSimplex provides five different pivot rule
60 61
  /// implementations. For more information see \ref PivotRule.
61 62
  template <typename GR, typename F = int, typename C = F>
62 63
  class NetworkSimplex
63 64
  {
64 65
  public:
65 66

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

	
75 76
  public:
76 77

	
77 78
    /// \brief Enum type for selecting the pivot rule.
78 79
    ///
79 80
    /// Enum type for selecting the pivot rule for the \ref run()
80 81
    /// function.
81 82
    ///
82 83
    /// \ref NetworkSimplex provides five different pivot rule
83 84
    /// implementations that significantly affect the running time
84 85
    /// of the algorithm.
85 86
    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
86 87
    /// proved to be the most efficient and the most robust on various
87 88
    /// test inputs according to our benchmark tests.
88 89
    /// However another pivot rule can be selected using the \ref run()
89 90
    /// function with the proper parameter.
90 91
    enum PivotRule {
91 92

	
92 93
      /// The First Eligible pivot rule.
93 94
      /// The next eligible arc is selected in a wraparound fashion
94 95
      /// in every iteration.
95 96
      FIRST_ELIGIBLE,
96 97

	
97 98
      /// The Best Eligible pivot rule.
98 99
      /// The best eligible arc is selected in every iteration.
99 100
      BEST_ELIGIBLE,
100 101

	
101 102
      /// The Block Search pivot rule.
102 103
      /// A specified number of arcs are examined in every iteration
103 104
      /// in a wraparound fashion and the best eligible arc is selected
104 105
      /// from this block.
105 106
      BLOCK_SEARCH,
106 107

	
107 108
      /// The Candidate List pivot rule.
108 109
      /// In a major iteration a candidate list is built from eligible arcs
109 110
      /// in a wraparound fashion and in the following minor iterations
110 111
      /// the best eligible arc is selected from this list.
111 112
      CANDIDATE_LIST,
112 113

	
113 114
      /// The Altering Candidate List pivot rule.
114 115
      /// It is a modified version of the Candidate List method.
115 116
      /// It keeps only the several best eligible arcs from the former
116 117
      /// candidate list and extends this list in every iteration.
117 118
      ALTERING_LIST
118 119
    };
119 120

	
120 121
  private:
121 122

	
122 123
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
123 124

	
124 125
    typedef typename GR::template ArcMap<Flow> FlowArcMap;
125 126
    typedef typename GR::template ArcMap<Cost> CostArcMap;
126 127
    typedef typename GR::template NodeMap<Flow> FlowNodeMap;
127 128

	
128 129
    typedef std::vector<Arc> ArcVector;
129 130
    typedef std::vector<Node> NodeVector;
130 131
    typedef std::vector<int> IntVector;
131 132
    typedef std::vector<bool> BoolVector;
132 133
    typedef std::vector<Flow> FlowVector;
133 134
    typedef std::vector<Cost> CostVector;
134 135

	
135 136
    // State constants for arcs
136 137
    enum ArcStateEnum {
137 138
      STATE_UPPER = -1,
138 139
      STATE_TREE  =  0,
139 140
      STATE_LOWER =  1
140 141
    };
141 142

	
142 143
  private:
143 144

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

	
149 150
    // Parameters of the problem
150 151
    FlowArcMap *_plower;
151 152
    FlowArcMap *_pupper;
152 153
    CostArcMap *_pcost;
153 154
    FlowNodeMap *_psupply;
154 155
    bool _pstsup;
155 156
    Node _psource, _ptarget;
156 157
    Flow _pstflow;
157 158

	
158 159
    // Result maps
159 160
    FlowMap *_flow_map;
160 161
    PotentialMap *_potential_map;
161 162
    bool _local_flow;
162 163
    bool _local_potential;
163 164

	
164 165
    // Data structures for storing the digraph
165 166
    IntNodeMap _node_id;
166 167
    ArcVector _arc_ref;
167 168
    IntVector _source;
168 169
    IntVector _target;
169 170

	
170 171
    // Node and arc data
171 172
    FlowVector _cap;
172 173
    CostVector _cost;
173 174
    FlowVector _supply;
174 175
    FlowVector _flow;
175 176
    CostVector _pi;
176 177

	
177 178
    // Data for storing the spanning tree structure
178 179
    IntVector _parent;
179 180
    IntVector _pred;
180 181
    IntVector _thread;
181 182
    IntVector _rev_thread;
182 183
    IntVector _succ_num;
183 184
    IntVector _last_succ;
184 185
    IntVector _dirty_revs;
185 186
    BoolVector _forward;
186 187
    IntVector _state;
187 188
    int _root;
188 189

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

	
195 196
  private:
196 197

	
197 198
    // Implementation of the First Eligible pivot rule
198 199
    class FirstEligiblePivotRule
199 200
    {
200 201
    private:
201 202

	
202 203
      // References to the NetworkSimplex class
203 204
      const IntVector  &_source;
204 205
      const IntVector  &_target;
205 206
      const CostVector &_cost;
206 207
      const IntVector  &_state;
207 208
      const CostVector &_pi;
208 209
      int &_in_arc;
209 210
      int _arc_num;
210 211

	
211 212
      // Pivot rule data
212 213
      int _next_arc;
213 214

	
214 215
    public:
215 216

	
216 217
      // Constructor
217 218
      FirstEligiblePivotRule(NetworkSimplex &ns) :
218 219
        _source(ns._source), _target(ns._target),
219 220
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
220 221
        _in_arc(ns.in_arc), _arc_num(ns._arc_num), _next_arc(0)
221 222
      {}
222 223

	
223 224
      // Find next entering arc
224 225
      bool findEnteringArc() {
225 226
        Cost c;
226 227
        for (int e = _next_arc; e < _arc_num; ++e) {
227 228
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
228 229
          if (c < 0) {
229 230
            _in_arc = e;
230 231
            _next_arc = e + 1;
231 232
            return true;
232 233
          }
233 234
        }
234 235
        for (int e = 0; e < _next_arc; ++e) {
235 236
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
236 237
          if (c < 0) {
237 238
            _in_arc = e;
238 239
            _next_arc = e + 1;
239 240
            return true;
240 241
          }
241 242
        }
242 243
        return false;
243 244
      }
244 245

	
245 246
    }; //class FirstEligiblePivotRule
246 247

	
247 248

	
248 249
    // Implementation of the Best Eligible pivot rule
249 250
    class BestEligiblePivotRule
250 251
    {
251 252
    private:
252 253

	
253 254
      // References to the NetworkSimplex class
254 255
      const IntVector  &_source;
255 256
      const IntVector  &_target;
256 257
      const CostVector &_cost;
257 258
      const IntVector  &_state;
258 259
      const CostVector &_pi;
259 260
      int &_in_arc;
260 261
      int _arc_num;
261 262

	
262 263
    public:
263 264

	
264 265
      // Constructor
265 266
      BestEligiblePivotRule(NetworkSimplex &ns) :
266 267
        _source(ns._source), _target(ns._target),
267 268
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
268 269
        _in_arc(ns.in_arc), _arc_num(ns._arc_num)
269 270
      {}
270 271

	
271 272
      // Find next entering arc
272 273
      bool findEnteringArc() {
273 274
        Cost c, min = 0;
274 275
        for (int e = 0; e < _arc_num; ++e) {
275 276
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
276 277
          if (c < min) {
277 278
            min = c;
278 279
            _in_arc = e;
279 280
          }
280 281
        }
281 282
        return min < 0;
282 283
      }
283 284

	
284 285
    }; //class BestEligiblePivotRule
285 286

	
286 287

	
287 288
    // Implementation of the Block Search pivot rule
288 289
    class BlockSearchPivotRule
289 290
    {
290 291
    private:
291 292

	
292 293
      // References to the NetworkSimplex class
293 294
      const IntVector  &_source;
294 295
      const IntVector  &_target;
295 296
      const CostVector &_cost;
296 297
      const IntVector  &_state;
297 298
      const CostVector &_pi;
298 299
      int &_in_arc;
299 300
      int _arc_num;
300 301

	
301 302
      // Pivot rule data
302 303
      int _block_size;
303 304
      int _next_arc;
304 305

	
305 306
    public:
306 307

	
307 308
      // Constructor
308 309
      BlockSearchPivotRule(NetworkSimplex &ns) :
309 310
        _source(ns._source), _target(ns._target),
310 311
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
311 312
        _in_arc(ns.in_arc), _arc_num(ns._arc_num), _next_arc(0)
312 313
      {
313 314
        // The main parameters of the pivot rule
314 315
        const double BLOCK_SIZE_FACTOR = 2.0;
315 316
        const int MIN_BLOCK_SIZE = 10;
316 317

	
317 318
        _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_arc_num)),
318 319
                                MIN_BLOCK_SIZE );
319 320
      }
320 321

	
321 322
      // Find next entering arc
322 323
      bool findEnteringArc() {
323 324
        Cost c, min = 0;
324 325
        int cnt = _block_size;
325 326
        int e, min_arc = _next_arc;
326 327
        for (e = _next_arc; e < _arc_num; ++e) {
327 328
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
328 329
          if (c < min) {
329 330
            min = c;
330 331
            min_arc = e;
331 332
          }
332 333
          if (--cnt == 0) {
333 334
            if (min < 0) break;
334 335
            cnt = _block_size;
335 336
          }
336 337
        }
337 338
        if (min == 0 || cnt > 0) {
338 339
          for (e = 0; e < _next_arc; ++e) {
339 340
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
340 341
            if (c < min) {
341 342
              min = c;
342 343
              min_arc = e;
343 344
            }
344 345
            if (--cnt == 0) {
345 346
              if (min < 0) break;
346 347
              cnt = _block_size;
347 348
            }
348 349
          }
349 350
        }
350 351
        if (min >= 0) return false;
351 352
        _in_arc = min_arc;
352 353
        _next_arc = e;
353 354
        return true;
354 355
      }
355 356

	
356 357
    }; //class BlockSearchPivotRule
357 358

	
358 359

	
359 360
    // Implementation of the Candidate List pivot rule
360 361
    class CandidateListPivotRule
361 362
    {
362 363
    private:
363 364

	
364 365
      // References to the NetworkSimplex class
365 366
      const IntVector  &_source;
366 367
      const IntVector  &_target;
367 368
      const CostVector &_cost;
368 369
      const IntVector  &_state;
369 370
      const CostVector &_pi;
370 371
      int &_in_arc;
371 372
      int _arc_num;
372 373

	
373 374
      // Pivot rule data
374 375
      IntVector _candidates;
375 376
      int _list_length, _minor_limit;
376 377
      int _curr_length, _minor_count;
377 378
      int _next_arc;
378 379

	
379 380
    public:
380 381

	
381 382
      /// Constructor
382 383
      CandidateListPivotRule(NetworkSimplex &ns) :
383 384
        _source(ns._source), _target(ns._target),
384 385
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
385 386
        _in_arc(ns.in_arc), _arc_num(ns._arc_num), _next_arc(0)
386 387
      {
387 388
        // The main parameters of the pivot rule
388 389
        const double LIST_LENGTH_FACTOR = 1.0;
389 390
        const int MIN_LIST_LENGTH = 10;
390 391
        const double MINOR_LIMIT_FACTOR = 0.1;
391 392
        const int MIN_MINOR_LIMIT = 3;
392 393

	
393 394
        _list_length = std::max( int(LIST_LENGTH_FACTOR * sqrt(_arc_num)),
394 395
                                 MIN_LIST_LENGTH );
395 396
        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
396 397
                                 MIN_MINOR_LIMIT );
397 398
        _curr_length = _minor_count = 0;
398 399
        _candidates.resize(_list_length);
399 400
      }
400 401

	
401 402
      /// Find next entering arc
402 403
      bool findEnteringArc() {
403 404
        Cost min, c;
404 405
        int e, min_arc = _next_arc;
405 406
        if (_curr_length > 0 && _minor_count < _minor_limit) {
406 407
          // Minor iteration: select the best eligible arc from the
407 408
          // current candidate list
408 409
          ++_minor_count;
409 410
          min = 0;
410 411
          for (int i = 0; i < _curr_length; ++i) {
411 412
            e = _candidates[i];
412 413
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
413 414
            if (c < min) {
414 415
              min = c;
415 416
              min_arc = e;
416 417
            }
417 418
            if (c >= 0) {
418 419
              _candidates[i--] = _candidates[--_curr_length];
419 420
            }
420 421
          }
421 422
          if (min < 0) {
422 423
            _in_arc = min_arc;
423 424
            return true;
424 425
          }
425 426
        }
426 427

	
427 428
        // Major iteration: build a new candidate list
428 429
        min = 0;
429 430
        _curr_length = 0;
430 431
        for (e = _next_arc; e < _arc_num; ++e) {
431 432
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
432 433
          if (c < 0) {
433 434
            _candidates[_curr_length++] = e;
434 435
            if (c < min) {
435 436
              min = c;
436 437
              min_arc = e;
437 438
            }
438 439
            if (_curr_length == _list_length) break;
439 440
          }
440 441
        }
441 442
        if (_curr_length < _list_length) {
... ...
@@ -663,750 +664,752 @@
663 664
    /// \return <tt>(*this)</tt>
664 665
    template<typename CAP>
665 666
    NetworkSimplex& capacityMap(const CAP& map) {
666 667
      return upperMap(map);
667 668
    }
668 669

	
669 670
    /// \brief Set the lower and upper bounds on the arcs.
670 671
    ///
671 672
    /// This function sets the lower and upper bounds on the arcs.
672 673
    /// If neither this function nor \ref lowerMap() is used before
673 674
    /// calling \ref run(), the lower bounds will be set to zero
674 675
    /// on all arcs.
675 676
    /// If none of the functions \ref upperMap(), \ref capacityMap()
676 677
    /// and \ref boundMaps() is used before calling \ref run(),
677 678
    /// the upper bounds (capacities) will be set to
678 679
    /// \c std::numeric_limits<Flow>::max() on all arcs.
679 680
    ///
680 681
    /// \param lower An arc map storing the lower bounds.
681 682
    /// \param upper An arc map storing the upper bounds.
682 683
    ///
683 684
    /// The \c Value type of the maps must be convertible to the
684 685
    /// \c Flow type of the algorithm.
685 686
    ///
686 687
    /// \note This function is just a shortcut of calling \ref lowerMap()
687 688
    /// and \ref upperMap() separately.
688 689
    ///
689 690
    /// \return <tt>(*this)</tt>
690 691
    template <typename LOWER, typename UPPER>
691 692
    NetworkSimplex& boundMaps(const LOWER& lower, const UPPER& upper) {
692 693
      return lowerMap(lower).upperMap(upper);
693 694
    }
694 695

	
695 696
    /// \brief Set the costs of the arcs.
696 697
    ///
697 698
    /// This function sets the costs of the arcs.
698 699
    /// If it is not used before calling \ref run(), the costs
699 700
    /// will be set to \c 1 on all arcs.
700 701
    ///
701 702
    /// \param map An arc map storing the costs.
702 703
    /// Its \c Value type must be convertible to the \c Cost type
703 704
    /// of the algorithm.
704 705
    ///
705 706
    /// \return <tt>(*this)</tt>
706 707
    template<typename COST>
707 708
    NetworkSimplex& costMap(const COST& map) {
708 709
      delete _pcost;
709 710
      _pcost = new CostArcMap(_graph);
710 711
      for (ArcIt a(_graph); a != INVALID; ++a) {
711 712
        (*_pcost)[a] = map[a];
712 713
      }
713 714
      return *this;
714 715
    }
715 716

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

	
739 740
    /// \brief Set single source and target nodes and a supply value.
740 741
    ///
741 742
    /// This function sets a single source node and a single target node
742 743
    /// and the required flow value.
743 744
    /// If neither this function nor \ref supplyMap() is used before
744 745
    /// calling \ref run(), the supply of each node will be set to zero.
745 746
    /// (It makes sense only if non-zero lower bounds are given.)
746 747
    ///
747 748
    /// \param s The source node.
748 749
    /// \param t The target node.
749 750
    /// \param k The required amount of flow from node \c s to node \c t
750 751
    /// (i.e. the supply of \c s and the demand of \c t).
751 752
    ///
752 753
    /// \return <tt>(*this)</tt>
753 754
    NetworkSimplex& stSupply(const Node& s, const Node& t, Flow k) {
754 755
      delete _psupply;
755 756
      _psupply = NULL;
756 757
      _pstsup = true;
757 758
      _psource = s;
758 759
      _ptarget = t;
759 760
      _pstflow = k;
760 761
      return *this;
761 762
    }
762 763

	
763 764
    /// \brief Set the flow map.
764 765
    ///
765 766
    /// This function sets the flow map.
766 767
    /// If it is not used before calling \ref run(), an instance will
767 768
    /// be allocated automatically. The destructor deallocates this
768 769
    /// automatically allocated map, of course.
769 770
    ///
770 771
    /// \return <tt>(*this)</tt>
771 772
    NetworkSimplex& flowMap(FlowMap& map) {
772 773
      if (_local_flow) {
773 774
        delete _flow_map;
774 775
        _local_flow = false;
775 776
      }
776 777
      _flow_map = &map;
777 778
      return *this;
778 779
    }
779 780

	
780 781
    /// \brief Set the potential map.
781 782
    ///
782 783
    /// This function sets the potential map, which is used for storing
783 784
    /// the dual solution.
784 785
    /// If it is not used before calling \ref run(), an instance will
785 786
    /// be allocated automatically. The destructor deallocates this
786 787
    /// automatically allocated map, of course.
787 788
    ///
788 789
    /// \return <tt>(*this)</tt>
789 790
    NetworkSimplex& potentialMap(PotentialMap& map) {
790 791
      if (_local_potential) {
791 792
        delete _potential_map;
792 793
        _local_potential = false;
793 794
      }
794 795
      _potential_map = &map;
795 796
      return *this;
796 797
    }
797 798

	
798 799
    /// \name Execution Control
799 800
    /// The algorithm can be executed using \ref run().
800 801

	
801 802
    /// @{
802 803

	
803 804
    /// \brief Run the algorithm.
804 805
    ///
805 806
    /// This function runs the algorithm.
806 807
    /// The paramters can be specified using \ref lowerMap(),
807 808
    /// \ref upperMap(), \ref capacityMap(), \ref boundMaps(),
808 809
    /// \ref costMap(), \ref supplyMap() and \ref stSupply()
809 810
    /// functions. For example,
810 811
    /// \code
811 812
    ///   NetworkSimplex<ListDigraph> ns(graph);
812 813
    ///   ns.boundMaps(lower, upper).costMap(cost)
813 814
    ///     .supplyMap(sup).run();
814 815
    /// \endcode
815 816
    ///
816 817
    /// This function can be called more than once. All the parameters
817 818
    /// that have been given are kept for the next call, unless
818 819
    /// \ref reset() is called, thus only the modified parameters
819 820
    /// have to be set again. See \ref reset() for examples.
820 821
    ///
821 822
    /// \param pivot_rule The pivot rule that will be used during the
822 823
    /// algorithm. For more information see \ref PivotRule.
823 824
    ///
824 825
    /// \return \c true if a feasible flow can be found.
825 826
    bool run(PivotRule pivot_rule = BLOCK_SEARCH) {
826 827
      return init() && start(pivot_rule);
827 828
    }
828 829

	
829 830
    /// \brief Reset all the parameters that have been given before.
830 831
    ///
831 832
    /// This function resets all the paramaters that have been given
832 833
    /// using \ref lowerMap(), \ref upperMap(), \ref capacityMap(),
833 834
    /// \ref boundMaps(), \ref costMap(), \ref supplyMap() and
834 835
    /// \ref stSupply() functions before.
835 836
    ///
836 837
    /// It is useful for multiple run() calls. If this function is not
837 838
    /// used, all the parameters given before are kept for the next
838 839
    /// \ref run() call.
839 840
    ///
840 841
    /// For example,
841 842
    /// \code
842 843
    ///   NetworkSimplex<ListDigraph> ns(graph);
843 844
    ///
844 845
    ///   // First run
845 846
    ///   ns.lowerMap(lower).capacityMap(cap).costMap(cost)
846 847
    ///     .supplyMap(sup).run();
847 848
    ///
848 849
    ///   // Run again with modified cost map (reset() is not called,
849 850
    ///   // so only the cost map have to be set again)
850 851
    ///   cost[e] += 100;
851 852
    ///   ns.costMap(cost).run();
852 853
    ///
853 854
    ///   // Run again from scratch using reset()
854 855
    ///   // (the lower bounds will be set to zero on all arcs)
855 856
    ///   ns.reset();
856 857
    ///   ns.capacityMap(cap).costMap(cost)
857 858
    ///     .supplyMap(sup).run();
858 859
    /// \endcode
859 860
    ///
860 861
    /// \return <tt>(*this)</tt>
861 862
    NetworkSimplex& reset() {
862 863
      delete _plower;
863 864
      delete _pupper;
864 865
      delete _pcost;
865 866
      delete _psupply;
866 867
      _plower = NULL;
867 868
      _pupper = NULL;
868 869
      _pcost = NULL;
869 870
      _psupply = NULL;
870 871
      _pstsup = false;
871 872
      return *this;
872 873
    }
873 874

	
874 875
    /// @}
875 876

	
876 877
    /// \name Query Functions
877 878
    /// The results of the algorithm can be obtained using these
878 879
    /// functions.\n
879 880
    /// The \ref run() function must be called before using them.
880 881

	
881 882
    /// @{
882 883

	
883 884
    /// \brief Return the total cost of the found flow.
884 885
    ///
885 886
    /// This function returns the total cost of the found flow.
886 887
    /// The complexity of the function is O(e).
887 888
    ///
888 889
    /// \note The return type of the function can be specified as a
889 890
    /// template parameter. For example,
890 891
    /// \code
891 892
    ///   ns.totalCost<double>();
892 893
    /// \endcode
893 894
    /// It is useful if the total cost cannot be stored in the \c Cost
894 895
    /// type of the algorithm, which is the default return type of the
895 896
    /// function.
896 897
    ///
897 898
    /// \pre \ref run() must be called before using this function.
898 899
    template <typename Num>
899 900
    Num totalCost() const {
900 901
      Num c = 0;
901 902
      if (_pcost) {
902 903
        for (ArcIt e(_graph); e != INVALID; ++e)
903 904
          c += (*_flow_map)[e] * (*_pcost)[e];
904 905
      } else {
905 906
        for (ArcIt e(_graph); e != INVALID; ++e)
906 907
          c += (*_flow_map)[e];
907 908
      }
908 909
      return c;
909 910
    }
910 911

	
911 912
#ifndef DOXYGEN
912 913
    Cost totalCost() const {
913 914
      return totalCost<Cost>();
914 915
    }
915 916
#endif
916 917

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

	
926 927
    /// \brief Return a const reference to the flow map.
927 928
    ///
928 929
    /// This function returns a const reference to an arc map storing
929 930
    /// the found flow.
930 931
    ///
931 932
    /// \pre \ref run() must be called before using this function.
932 933
    const FlowMap& flowMap() const {
933 934
      return *_flow_map;
934 935
    }
935 936

	
936 937
    /// \brief Return the potential (dual value) of the given node.
937 938
    ///
938 939
    /// This function returns the potential (dual value) of the
939 940
    /// given node.
940 941
    ///
941 942
    /// \pre \ref run() must be called before using this function.
942 943
    Cost potential(const Node& n) const {
943 944
      return (*_potential_map)[n];
944 945
    }
945 946

	
946 947
    /// \brief Return a const reference to the potential map
947 948
    /// (the dual solution).
948 949
    ///
949 950
    /// This function returns a const reference to a node map storing
950 951
    /// the found potentials, which form the dual solution of the
951 952
    /// \ref min_cost_flow "minimum cost flow" problem.
952 953
    ///
953 954
    /// \pre \ref run() must be called before using this function.
954 955
    const PotentialMap& potentialMap() const {
955 956
      return *_potential_map;
956 957
    }
957 958

	
958 959
    /// @}
959 960

	
960 961
  private:
961 962

	
962 963
    // Initialize internal data structures
963 964
    bool init() {
964 965
      // Initialize result maps
965 966
      if (!_flow_map) {
966 967
        _flow_map = new FlowMap(_graph);
967 968
        _local_flow = true;
968 969
      }
969 970
      if (!_potential_map) {
970 971
        _potential_map = new PotentialMap(_graph);
971 972
        _local_potential = true;
972 973
      }
973 974

	
974 975
      // Initialize vectors
975 976
      _node_num = countNodes(_graph);
976 977
      _arc_num = countArcs(_graph);
977 978
      int all_node_num = _node_num + 1;
978 979
      int all_arc_num = _arc_num + _node_num;
979 980
      if (_node_num == 0) return false;
980 981

	
981 982
      _arc_ref.resize(_arc_num);
982 983
      _source.resize(all_arc_num);
983 984
      _target.resize(all_arc_num);
984 985

	
985 986
      _cap.resize(all_arc_num);
986 987
      _cost.resize(all_arc_num);
987 988
      _supply.resize(all_node_num);
988 989
      _flow.resize(all_arc_num);
989 990
      _pi.resize(all_node_num);
990 991

	
991 992
      _parent.resize(all_node_num);
992 993
      _pred.resize(all_node_num);
993 994
      _forward.resize(all_node_num);
994 995
      _thread.resize(all_node_num);
995 996
      _rev_thread.resize(all_node_num);
996 997
      _succ_num.resize(all_node_num);
997 998
      _last_succ.resize(all_node_num);
998 999
      _state.resize(all_arc_num);
999 1000

	
1000 1001
      // Initialize node related data
1001 1002
      bool valid_supply = true;
1002 1003
      if (!_pstsup && !_psupply) {
1003 1004
        _pstsup = true;
1004 1005
        _psource = _ptarget = NodeIt(_graph);
1005 1006
        _pstflow = 0;
1006 1007
      }
1007 1008
      if (_psupply) {
1008 1009
        Flow sum = 0;
1009 1010
        int i = 0;
1010 1011
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1011 1012
          _node_id[n] = i;
1012 1013
          _supply[i] = (*_psupply)[n];
1013 1014
          sum += _supply[i];
1014 1015
        }
1015 1016
        valid_supply = (sum == 0);
1016 1017
      } else {
1017 1018
        int i = 0;
1018 1019
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1019 1020
          _node_id[n] = i;
1020 1021
          _supply[i] = 0;
1021 1022
        }
1022 1023
        _supply[_node_id[_psource]] =  _pstflow;
1023 1024
        _supply[_node_id[_ptarget]]   = -_pstflow;
1024 1025
      }
1025 1026
      if (!valid_supply) return false;
1026 1027

	
1027 1028
      // Set data for the artificial root node
1028 1029
      _root = _node_num;
1029 1030
      _parent[_root] = -1;
1030 1031
      _pred[_root] = -1;
1031 1032
      _thread[_root] = 0;
1032 1033
      _rev_thread[0] = _root;
1033 1034
      _succ_num[_root] = all_node_num;
1034 1035
      _last_succ[_root] = _root - 1;
1035 1036
      _supply[_root] = 0;
1036 1037
      _pi[_root] = 0;
1037 1038

	
1038 1039
      // Store the arcs in a mixed order
1039 1040
      int k = std::max(int(sqrt(_arc_num)), 10);
1040 1041
      int i = 0;
1041 1042
      for (ArcIt e(_graph); e != INVALID; ++e) {
1042 1043
        _arc_ref[i] = e;
1043 1044
        if ((i += k) >= _arc_num) i = (i % k) + 1;
1044 1045
      }
1045 1046

	
1046 1047
      // Initialize arc maps
1047
      Flow max_cap = std::numeric_limits<Flow>::max();
1048
      Cost max_cost = std::numeric_limits<Cost>::max() / 4;
1048
      Flow inf_cap =
1049
        std::numeric_limits<Flow>::has_infinity ?
1050
        std::numeric_limits<Flow>::infinity() :
1051
        std::numeric_limits<Flow>::max();
1049 1052
      if (_pupper && _pcost) {
1050 1053
        for (int i = 0; i != _arc_num; ++i) {
1051 1054
          Arc e = _arc_ref[i];
1052 1055
          _source[i] = _node_id[_graph.source(e)];
1053 1056
          _target[i] = _node_id[_graph.target(e)];
1054 1057
          _cap[i] = (*_pupper)[e];
1055 1058
          _cost[i] = (*_pcost)[e];
1056 1059
          _flow[i] = 0;
1057 1060
          _state[i] = STATE_LOWER;
1058 1061
        }
1059 1062
      } else {
1060 1063
        for (int i = 0; i != _arc_num; ++i) {
1061 1064
          Arc e = _arc_ref[i];
1062 1065
          _source[i] = _node_id[_graph.source(e)];
1063 1066
          _target[i] = _node_id[_graph.target(e)];
1064 1067
          _flow[i] = 0;
1065 1068
          _state[i] = STATE_LOWER;
1066 1069
        }
1067 1070
        if (_pupper) {
1068 1071
          for (int i = 0; i != _arc_num; ++i)
1069 1072
            _cap[i] = (*_pupper)[_arc_ref[i]];
1070 1073
        } else {
1071 1074
          for (int i = 0; i != _arc_num; ++i)
1072
            _cap[i] = max_cap;
1075
            _cap[i] = inf_cap;
1073 1076
        }
1074 1077
        if (_pcost) {
1075 1078
          for (int i = 0; i != _arc_num; ++i)
1076 1079
            _cost[i] = (*_pcost)[_arc_ref[i]];
1077 1080
        } else {
1078 1081
          for (int i = 0; i != _arc_num; ++i)
1079 1082
            _cost[i] = 1;
1080 1083
        }
1081 1084
      }
1082 1085

	
1086
      // Initialize artifical cost
1087
      Cost art_cost;
1088
      if (std::numeric_limits<Cost>::is_exact) {
1089
        art_cost = std::numeric_limits<Cost>::max() / 4 + 1;
1090
      } else {
1091
        art_cost = std::numeric_limits<Cost>::min();
1092
        for (int i = 0; i != _arc_num; ++i) {
1093
          if (_cost[i] > art_cost) art_cost = _cost[i];
1094
        }
1095
        art_cost = (art_cost + 1) * _node_num;
1096
      }
1097

	
1083 1098
      // Remove non-zero lower bounds
1084 1099
      if (_plower) {
1085 1100
        for (int i = 0; i != _arc_num; ++i) {
1086 1101
          Flow c = (*_plower)[_arc_ref[i]];
1087 1102
          if (c != 0) {
1088 1103
            _cap[i] -= c;
1089 1104
            _supply[_source[i]] -= c;
1090 1105
            _supply[_target[i]] += c;
1091 1106
          }
1092 1107
        }
1093 1108
      }
1094 1109

	
1095 1110
      // Add artificial arcs and initialize the spanning tree data structure
1096 1111
      for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1097 1112
        _thread[u] = u + 1;
1098 1113
        _rev_thread[u + 1] = u;
1099 1114
        _succ_num[u] = 1;
1100 1115
        _last_succ[u] = u;
1101 1116
        _parent[u] = _root;
1102 1117
        _pred[u] = e;
1103
        _cost[e] = max_cost;
1104
        _cap[e] = max_cap;
1118
        _cost[e] = art_cost;
1119
        _cap[e] = inf_cap;
1105 1120
        _state[e] = STATE_TREE;
1106 1121
        if (_supply[u] >= 0) {
1107 1122
          _flow[e] = _supply[u];
1108 1123
          _forward[u] = true;
1109
          _pi[u] = -max_cost;
1124
          _pi[u] = -art_cost;
1110 1125
        } else {
1111 1126
          _flow[e] = -_supply[u];
1112 1127
          _forward[u] = false;
1113
          _pi[u] = max_cost;
1128
          _pi[u] = art_cost;
1114 1129
        }
1115 1130
      }
1116 1131

	
1117 1132
      return true;
1118 1133
    }
1119 1134

	
1120 1135
    // Find the join node
1121 1136
    void findJoinNode() {
1122 1137
      int u = _source[in_arc];
1123 1138
      int v = _target[in_arc];
1124 1139
      while (u != v) {
1125 1140
        if (_succ_num[u] < _succ_num[v]) {
1126 1141
          u = _parent[u];
1127 1142
        } else {
1128 1143
          v = _parent[v];
1129 1144
        }
1130 1145
      }
1131 1146
      join = u;
1132 1147
    }
1133 1148

	
1134 1149
    // Find the leaving arc of the cycle and returns true if the
1135 1150
    // leaving arc is not the same as the entering arc
1136 1151
    bool findLeavingArc() {
1137 1152
      // Initialize first and second nodes according to the direction
1138 1153
      // of the cycle
1139 1154
      if (_state[in_arc] == STATE_LOWER) {
1140 1155
        first  = _source[in_arc];
1141 1156
        second = _target[in_arc];
1142 1157
      } else {
1143 1158
        first  = _target[in_arc];
1144 1159
        second = _source[in_arc];
1145 1160
      }
1146 1161
      delta = _cap[in_arc];
1147 1162
      int result = 0;
1148 1163
      Flow d;
1149 1164
      int e;
1150 1165

	
1151 1166
      // Search the cycle along the path form the first node to the root
1152 1167
      for (int u = first; u != join; u = _parent[u]) {
1153 1168
        e = _pred[u];
1154 1169
        d = _forward[u] ? _flow[e] : _cap[e] - _flow[e];
1155 1170
        if (d < delta) {
1156 1171
          delta = d;
1157 1172
          u_out = u;
1158 1173
          result = 1;
1159 1174
        }
1160 1175
      }
1161 1176
      // Search the cycle along the path form the second node to the root
1162 1177
      for (int u = second; u != join; u = _parent[u]) {
1163 1178
        e = _pred[u];
1164 1179
        d = _forward[u] ? _cap[e] - _flow[e] : _flow[e];
1165 1180
        if (d <= delta) {
1166 1181
          delta = d;
1167 1182
          u_out = u;
1168 1183
          result = 2;
1169 1184
        }
1170 1185
      }
1171 1186

	
1172 1187
      if (result == 1) {
1173 1188
        u_in = first;
1174 1189
        v_in = second;
1175 1190
      } else {
1176 1191
        u_in = second;
1177 1192
        v_in = first;
1178 1193
      }
1179 1194
      return result != 0;
1180 1195
    }
1181 1196

	
1182 1197
    // Change _flow and _state vectors
1183 1198
    void changeFlow(bool change) {
1184 1199
      // Augment along the cycle
1185 1200
      if (delta > 0) {
1186 1201
        Flow val = _state[in_arc] * delta;
1187 1202
        _flow[in_arc] += val;
1188 1203
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
1189 1204
          _flow[_pred[u]] += _forward[u] ? -val : val;
1190 1205
        }
1191 1206
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
1192 1207
          _flow[_pred[u]] += _forward[u] ? val : -val;
1193 1208
        }
1194 1209
      }
1195 1210
      // Update the state of the entering and leaving arcs
1196 1211
      if (change) {
1197 1212
        _state[in_arc] = STATE_TREE;
1198 1213
        _state[_pred[u_out]] =
1199 1214
          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
1200 1215
      } else {
1201 1216
        _state[in_arc] = -_state[in_arc];
1202 1217
      }
1203 1218
    }
1204 1219

	
1205 1220
    // Update the tree structure
1206 1221
    void updateTreeStructure() {
1207 1222
      int u, w;
1208 1223
      int old_rev_thread = _rev_thread[u_out];
1209 1224
      int old_succ_num = _succ_num[u_out];
1210 1225
      int old_last_succ = _last_succ[u_out];
1211 1226
      v_out = _parent[u_out];
1212 1227

	
1213 1228
      u = _last_succ[u_in];  // the last successor of u_in
1214 1229
      right = _thread[u];    // the node after it
1215 1230

	
1216 1231
      // Handle the case when old_rev_thread equals to v_in
1217 1232
      // (it also means that join and v_out coincide)
1218 1233
      if (old_rev_thread == v_in) {
1219 1234
        last = _thread[_last_succ[u_out]];
1220 1235
      } else {
1221 1236
        last = _thread[v_in];
1222 1237
      }
1223 1238

	
1224 1239
      // Update _thread and _parent along the stem nodes (i.e. the nodes
1225 1240
      // between u_in and u_out, whose parent have to be changed)
1226 1241
      _thread[v_in] = stem = u_in;
1227 1242
      _dirty_revs.clear();
1228 1243
      _dirty_revs.push_back(v_in);
1229 1244
      par_stem = v_in;
1230 1245
      while (stem != u_out) {
1231 1246
        // Insert the next stem node into the thread list
1232 1247
        new_stem = _parent[stem];
1233 1248
        _thread[u] = new_stem;
1234 1249
        _dirty_revs.push_back(u);
1235 1250

	
1236 1251
        // Remove the subtree of stem from the thread list
1237 1252
        w = _rev_thread[stem];
1238 1253
        _thread[w] = right;
1239 1254
        _rev_thread[right] = w;
1240 1255

	
1241 1256
        // Change the parent node and shift stem nodes
1242 1257
        _parent[stem] = par_stem;
1243 1258
        par_stem = stem;
1244 1259
        stem = new_stem;
1245 1260

	
1246 1261
        // Update u and right
1247 1262
        u = _last_succ[stem] == _last_succ[par_stem] ?
1248 1263
          _rev_thread[par_stem] : _last_succ[stem];
1249 1264
        right = _thread[u];
1250 1265
      }
1251 1266
      _parent[u_out] = par_stem;
1252 1267
      _thread[u] = last;
1253 1268
      _rev_thread[last] = u;
1254 1269
      _last_succ[u_out] = u;
1255 1270

	
1256 1271
      // Remove the subtree of u_out from the thread list except for
1257 1272
      // the case when old_rev_thread equals to v_in
1258 1273
      // (it also means that join and v_out coincide)
1259 1274
      if (old_rev_thread != v_in) {
1260 1275
        _thread[old_rev_thread] = right;
1261 1276
        _rev_thread[right] = old_rev_thread;
1262 1277
      }
1263 1278

	
1264 1279
      // Update _rev_thread using the new _thread values
1265 1280
      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
1266 1281
        u = _dirty_revs[i];
1267 1282
        _rev_thread[_thread[u]] = u;
1268 1283
      }
1269 1284

	
1270 1285
      // Update _pred, _forward, _last_succ and _succ_num for the
1271 1286
      // stem nodes from u_out to u_in
1272 1287
      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
1273 1288
      u = u_out;
1274 1289
      while (u != u_in) {
1275 1290
        w = _parent[u];
1276 1291
        _pred[u] = _pred[w];
1277 1292
        _forward[u] = !_forward[w];
1278 1293
        tmp_sc += _succ_num[u] - _succ_num[w];
1279 1294
        _succ_num[u] = tmp_sc;
1280 1295
        _last_succ[w] = tmp_ls;
1281 1296
        u = w;
1282 1297
      }
1283 1298
      _pred[u_in] = in_arc;
1284 1299
      _forward[u_in] = (u_in == _source[in_arc]);
1285 1300
      _succ_num[u_in] = old_succ_num;
1286 1301

	
1287 1302
      // Set limits for updating _last_succ form v_in and v_out
1288 1303
      // towards the root
1289 1304
      int up_limit_in = -1;
1290 1305
      int up_limit_out = -1;
1291 1306
      if (_last_succ[join] == v_in) {
1292 1307
        up_limit_out = join;
1293 1308
      } else {
1294 1309
        up_limit_in = join;
1295 1310
      }
1296 1311

	
1297 1312
      // Update _last_succ from v_in towards the root
1298 1313
      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
1299 1314
           u = _parent[u]) {
1300 1315
        _last_succ[u] = _last_succ[u_out];
1301 1316
      }
1302 1317
      // Update _last_succ from v_out towards the root
1303 1318
      if (join != old_rev_thread && v_in != old_rev_thread) {
1304 1319
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1305 1320
             u = _parent[u]) {
1306 1321
          _last_succ[u] = old_rev_thread;
1307 1322
        }
1308 1323
      } else {
1309 1324
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1310 1325
             u = _parent[u]) {
1311 1326
          _last_succ[u] = _last_succ[u_out];
1312 1327
        }
1313 1328
      }
1314 1329

	
1315 1330
      // Update _succ_num from v_in to join
1316 1331
      for (u = v_in; u != join; u = _parent[u]) {
1317 1332
        _succ_num[u] += old_succ_num;
1318 1333
      }
1319 1334
      // Update _succ_num from v_out to join
1320 1335
      for (u = v_out; u != join; u = _parent[u]) {
1321 1336
        _succ_num[u] -= old_succ_num;
1322 1337
      }
1323 1338
    }
1324 1339

	
1325 1340
    // Update potentials
1326 1341
    void updatePotential() {
1327 1342
      Cost sigma = _forward[u_in] ?
1328 1343
        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
1329 1344
        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
1330
      if (_succ_num[u_in] > _node_num / 2) {
1331
        // Update in the upper subtree (which contains the root)
1332
        int before = _rev_thread[u_in];
1333
        int after = _thread[_last_succ[u_in]];
1334
        _thread[before] = after;
1335
        _pi[_root] -= sigma;
1336
        for (int u = _thread[_root]; u != _root; u = _thread[u]) {
1337
          _pi[u] -= sigma;
1338
        }
1339
        _thread[before] = u_in;
1340
      } else {
1341
        // Update in the lower subtree (which has been moved)
1345
      // Update potentials in the subtree, which has been moved
1342 1346
        int end = _thread[_last_succ[u_in]];
1343 1347
        for (int u = u_in; u != end; u = _thread[u]) {
1344 1348
          _pi[u] += sigma;
1345 1349
        }
1346 1350
      }
1347
    }
1348 1351

	
1349 1352
    // Execute the algorithm
1350 1353
    bool start(PivotRule pivot_rule) {
1351 1354
      // Select the pivot rule implementation
1352 1355
      switch (pivot_rule) {
1353 1356
        case FIRST_ELIGIBLE:
1354 1357
          return start<FirstEligiblePivotRule>();
1355 1358
        case BEST_ELIGIBLE:
1356 1359
          return start<BestEligiblePivotRule>();
1357 1360
        case BLOCK_SEARCH:
1358 1361
          return start<BlockSearchPivotRule>();
1359 1362
        case CANDIDATE_LIST:
1360 1363
          return start<CandidateListPivotRule>();
1361 1364
        case ALTERING_LIST:
1362 1365
          return start<AlteringListPivotRule>();
1363 1366
      }
1364 1367
      return false;
1365 1368
    }
1366 1369

	
1367 1370
    template <typename PivotRuleImpl>
1368 1371
    bool start() {
1369 1372
      PivotRuleImpl pivot(*this);
1370 1373

	
1371 1374
      // Execute the Network Simplex algorithm
1372 1375
      while (pivot.findEnteringArc()) {
1373 1376
        findJoinNode();
1374 1377
        bool change = findLeavingArc();
1375 1378
        changeFlow(change);
1376 1379
        if (change) {
1377 1380
          updateTreeStructure();
1378 1381
          updatePotential();
1379 1382
        }
1380 1383
      }
1381 1384

	
1382 1385
      // Check if the flow amount equals zero on all the artificial arcs
1383 1386
      for (int e = _arc_num; e != _arc_num + _node_num; ++e) {
1384 1387
        if (_flow[e] > 0) return false;
1385 1388
      }
1386 1389

	
1387 1390
      // Copy flow values to _flow_map
1388 1391
      if (_plower) {
1389 1392
        for (int i = 0; i != _arc_num; ++i) {
1390 1393
          Arc e = _arc_ref[i];
1391 1394
          _flow_map->set(e, (*_plower)[e] + _flow[i]);
1392 1395
        }
1393 1396
      } else {
1394 1397
        for (int i = 0; i != _arc_num; ++i) {
1395 1398
          _flow_map->set(_arc_ref[i], _flow[i]);
1396 1399
        }
1397 1400
      }
1398 1401
      // Copy potential values to _potential_map
1399 1402
      for (NodeIt n(_graph); n != INVALID; ++n) {
1400 1403
        _potential_map->set(n, _pi[_node_id[n]]);
1401 1404
      }
1402 1405

	
1403 1406
      return true;
1404 1407
    }
1405 1408

	
1406 1409
  }; //class NetworkSimplex
1407 1410

	
1408 1411
  ///@}
1409 1412

	
1410 1413
} //namespace lemon
1411 1414

	
1412 1415
#endif //LEMON_NETWORK_SIMPLEX_H
0 comments (0 inline)