gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Less map copying in NetworkSimplex (#234) - The graph is copied in the constructor instead of the init() function. It must not be modified after the class is constructed. - The maps are copied once (instead of twice). - Remove FlowMap, PotentialMap typedefs and flowMap(), pontentialMap() setter functions. - flowMap() and potentialMap() query functions copy the values into the given map (reference) instead of returning a const reference to a previously constructed map.
0 2 0
default
2 files changed with 184 insertions and 318 deletions:
↑ Collapse diff ↑
Ignore white space 256 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
  /// Moreover it supports both directions of the supply/demand inequality
51 51
  /// constraints. For more information see \ref SupplyType.
52 52
  ///
53 53
  /// Most of the parameters of the problem (except for the digraph)
54 54
  /// can be given using separate functions, and the algorithm can be
55 55
  /// executed using the \ref run() function. If some parameters are not
56 56
  /// specified, then default values will be used.
57 57
  ///
58 58
  /// \tparam GR The digraph type the algorithm runs on.
59 59
  /// \tparam V The value type used for flow amounts, capacity bounds
60 60
  /// and supply values in the algorithm. By default it is \c int.
61 61
  /// \tparam C The value type used for costs and potentials in the
62 62
  /// algorithm. By default it is the same as \c V.
63 63
  ///
64 64
  /// \warning Both value types must be signed and all input data must
65 65
  /// be integer.
66 66
  ///
67 67
  /// \note %NetworkSimplex provides five different pivot rule
68 68
  /// implementations, from which the most efficient one is used
69 69
  /// by default. For more information see \ref PivotRule.
70 70
  template <typename GR, typename V = int, typename C = V>
71 71
  class NetworkSimplex
72 72
  {
73 73
  public:
74 74

	
75
    /// The flow type of the algorithm
75
    /// The type of the flow amounts, capacity bounds and supply values
76 76
    typedef V Value;
77
    /// The cost type of the algorithm
77
    /// The type of the arc costs
78 78
    typedef C Cost;
79
#ifdef DOXYGEN
80
    /// The type of the flow map
81
    typedef GR::ArcMap<Value> FlowMap;
82
    /// The type of the potential map
83
    typedef GR::NodeMap<Cost> PotentialMap;
84
#else
85
    /// The type of the flow map
86
    typedef typename GR::template ArcMap<Value> FlowMap;
87
    /// The type of the potential map
88
    typedef typename GR::template NodeMap<Cost> PotentialMap;
89
#endif
90 79

	
91 80
  public:
92 81

	
93 82
    /// \brief Problem type constants for the \c run() function.
94 83
    ///
95 84
    /// Enum type containing the problem type constants that can be
96 85
    /// returned by the \ref run() function of the algorithm.
97 86
    enum ProblemType {
98 87
      /// The problem has no feasible solution (flow).
99 88
      INFEASIBLE,
100 89
      /// The problem has optimal solution (i.e. it is feasible and
101 90
      /// bounded), and the algorithm has found optimal flow and node
102 91
      /// potentials (primal and dual solutions).
103 92
      OPTIMAL,
104 93
      /// The objective function of the problem is unbounded, i.e.
105 94
      /// there is a directed cycle having negative total cost and
106 95
      /// infinite upper bound.
107 96
      UNBOUNDED
108 97
    };
109 98
    
110 99
    /// \brief Constants for selecting the type of the supply constraints.
111 100
    ///
112 101
    /// Enum type containing constants for selecting the supply type,
113 102
    /// i.e. the direction of the inequalities in the supply/demand
114 103
    /// constraints of the \ref min_cost_flow "minimum cost flow problem".
115 104
    ///
116 105
    /// The default supply type is \c GEQ, since this form is supported
117 106
    /// by other minimum cost flow algorithms and the \ref Circulation
118 107
    /// algorithm, as well.
119 108
    /// The \c LEQ problem type can be selected using the \ref supplyType()
120 109
    /// function.
121 110
    ///
122 111
    /// Note that the equality form is a special case of both supply types.
123 112
    enum SupplyType {
124 113

	
125 114
      /// This option means that there are <em>"greater or equal"</em>
126 115
      /// supply/demand constraints in the definition, i.e. the exact
127 116
      /// formulation of the problem is the following.
128 117
      /**
129 118
          \f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
130 119
          \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \geq
131 120
              sup(u) \quad \forall u\in V \f]
132 121
          \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
133 122
      */
134 123
      /// It means that the total demand must be greater or equal to the 
135 124
      /// total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
136 125
      /// negative) and all the supplies have to be carried out from 
137 126
      /// the supply nodes, but there could be demands that are not 
138 127
      /// satisfied.
139 128
      GEQ,
140 129
      /// It is just an alias for the \c GEQ option.
141 130
      CARRY_SUPPLIES = GEQ,
142 131

	
143 132
      /// This option means that there are <em>"less or equal"</em>
144 133
      /// supply/demand constraints in the definition, i.e. the exact
145 134
      /// formulation of the problem is the following.
146 135
      /**
147 136
          \f[ \min\sum_{uv\in A} f(uv) \cdot cost(uv) \f]
148 137
          \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu) \leq
149 138
              sup(u) \quad \forall u\in V \f]
150 139
          \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A \f]
151 140
      */
152 141
      /// It means that the total demand must be less or equal to the 
153 142
      /// total supply (i.e. \f$\sum_{u\in V} sup(u)\f$ must be zero or
154 143
      /// positive) and all the demands have to be satisfied, but there
155 144
      /// could be supplies that are not carried out from the supply
156 145
      /// nodes.
157 146
      LEQ,
158 147
      /// It is just an alias for the \c LEQ option.
159 148
      SATISFY_DEMANDS = LEQ
160 149
    };
161 150
    
162 151
    /// \brief Constants for selecting the pivot rule.
163 152
    ///
164 153
    /// Enum type containing constants for selecting the pivot rule for
165 154
    /// the \ref run() function.
166 155
    ///
167 156
    /// \ref NetworkSimplex provides five different pivot rule
168 157
    /// implementations that significantly affect the running time
169 158
    /// of the algorithm.
170 159
    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
171 160
    /// proved to be the most efficient and the most robust on various
172 161
    /// test inputs according to our benchmark tests.
173 162
    /// However another pivot rule can be selected using the \ref run()
174 163
    /// function with the proper parameter.
175 164
    enum PivotRule {
176 165

	
177 166
      /// The First Eligible pivot rule.
178 167
      /// The next eligible arc is selected in a wraparound fashion
179 168
      /// in every iteration.
180 169
      FIRST_ELIGIBLE,
181 170

	
182 171
      /// The Best Eligible pivot rule.
183 172
      /// The best eligible arc is selected in every iteration.
184 173
      BEST_ELIGIBLE,
185 174

	
186 175
      /// The Block Search pivot rule.
187 176
      /// A specified number of arcs are examined in every iteration
188 177
      /// in a wraparound fashion and the best eligible arc is selected
189 178
      /// from this block.
190 179
      BLOCK_SEARCH,
191 180

	
192 181
      /// The Candidate List pivot rule.
193 182
      /// In a major iteration a candidate list is built from eligible arcs
194 183
      /// in a wraparound fashion and in the following minor iterations
195 184
      /// the best eligible arc is selected from this list.
196 185
      CANDIDATE_LIST,
197 186

	
198 187
      /// The Altering Candidate List pivot rule.
199 188
      /// It is a modified version of the Candidate List method.
200 189
      /// It keeps only the several best eligible arcs from the former
201 190
      /// candidate list and extends this list in every iteration.
202 191
      ALTERING_LIST
203 192
    };
204 193
    
205 194
  private:
206 195

	
207 196
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
208 197

	
209
    typedef typename GR::template ArcMap<Value> ValueArcMap;
210
    typedef typename GR::template ArcMap<Cost> CostArcMap;
211
    typedef typename GR::template NodeMap<Value> ValueNodeMap;
212

	
213 198
    typedef std::vector<Arc> ArcVector;
214 199
    typedef std::vector<Node> NodeVector;
215 200
    typedef std::vector<int> IntVector;
216 201
    typedef std::vector<bool> BoolVector;
217
    typedef std::vector<Value> FlowVector;
202
    typedef std::vector<Value> ValueVector;
218 203
    typedef std::vector<Cost> CostVector;
219 204

	
220 205
    // State constants for arcs
221 206
    enum ArcStateEnum {
222 207
      STATE_UPPER = -1,
223 208
      STATE_TREE  =  0,
224 209
      STATE_LOWER =  1
225 210
    };
226 211

	
227 212
  private:
228 213

	
229 214
    // Data related to the underlying digraph
230 215
    const GR &_graph;
231 216
    int _node_num;
232 217
    int _arc_num;
233 218

	
234 219
    // Parameters of the problem
235
    ValueArcMap *_plower;
236
    ValueArcMap *_pupper;
237
    CostArcMap *_pcost;
238
    ValueNodeMap *_psupply;
239
    bool _pstsup;
240
    Node _psource, _ptarget;
241
    Value _pstflow;
220
    bool _have_lower;
242 221
    SupplyType _stype;
243
    
244 222
    Value _sum_supply;
245 223

	
246
    // Result maps
247
    FlowMap *_flow_map;
248
    PotentialMap *_potential_map;
249
    bool _local_flow;
250
    bool _local_potential;
251

	
252 224
    // Data structures for storing the digraph
253 225
    IntNodeMap _node_id;
254
    ArcVector _arc_ref;
226
    IntArcMap _arc_id;
255 227
    IntVector _source;
256 228
    IntVector _target;
257 229

	
258 230
    // Node and arc data
259
    FlowVector _cap;
231
    ValueVector _lower;
232
    ValueVector _upper;
233
    ValueVector _cap;
260 234
    CostVector _cost;
261
    FlowVector _supply;
262
    FlowVector _flow;
235
    ValueVector _supply;
236
    ValueVector _flow;
263 237
    CostVector _pi;
264 238

	
265 239
    // Data for storing the spanning tree structure
266 240
    IntVector _parent;
267 241
    IntVector _pred;
268 242
    IntVector _thread;
269 243
    IntVector _rev_thread;
270 244
    IntVector _succ_num;
271 245
    IntVector _last_succ;
272 246
    IntVector _dirty_revs;
273 247
    BoolVector _forward;
274 248
    IntVector _state;
275 249
    int _root;
276 250

	
277 251
    // Temporary data used in the current pivot iteration
278 252
    int in_arc, join, u_in, v_in, u_out, v_out;
279 253
    int first, second, right, last;
280 254
    int stem, par_stem, new_stem;
281 255
    Value delta;
282 256

	
283 257
  public:
284 258
  
285 259
    /// \brief Constant for infinite upper bounds (capacities).
286 260
    ///
287 261
    /// Constant for infinite upper bounds (capacities).
288 262
    /// It is \c std::numeric_limits<Value>::infinity() if available,
289 263
    /// \c std::numeric_limits<Value>::max() otherwise.
290 264
    const Value INF;
291 265

	
292 266
  private:
293 267

	
294 268
    // Implementation of the First Eligible pivot rule
295 269
    class FirstEligiblePivotRule
296 270
    {
297 271
    private:
298 272

	
299 273
      // References to the NetworkSimplex class
300 274
      const IntVector  &_source;
301 275
      const IntVector  &_target;
302 276
      const CostVector &_cost;
303 277
      const IntVector  &_state;
304 278
      const CostVector &_pi;
305 279
      int &_in_arc;
306 280
      int _arc_num;
307 281

	
308 282
      // Pivot rule data
309 283
      int _next_arc;
310 284

	
311 285
    public:
312 286

	
313 287
      // Constructor
314 288
      FirstEligiblePivotRule(NetworkSimplex &ns) :
315 289
        _source(ns._source), _target(ns._target),
316 290
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
317 291
        _in_arc(ns.in_arc), _arc_num(ns._arc_num), _next_arc(0)
318 292
      {}
319 293

	
320 294
      // Find next entering arc
321 295
      bool findEnteringArc() {
322 296
        Cost c;
323 297
        for (int e = _next_arc; e < _arc_num; ++e) {
324 298
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
325 299
          if (c < 0) {
326 300
            _in_arc = e;
327 301
            _next_arc = e + 1;
328 302
            return true;
329 303
          }
330 304
        }
331 305
        for (int e = 0; e < _next_arc; ++e) {
332 306
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
333 307
          if (c < 0) {
334 308
            _in_arc = e;
335 309
            _next_arc = e + 1;
336 310
            return true;
337 311
          }
338 312
        }
339 313
        return false;
340 314
      }
341 315

	
342 316
    }; //class FirstEligiblePivotRule
343 317

	
344 318

	
345 319
    // Implementation of the Best Eligible pivot rule
346 320
    class BestEligiblePivotRule
347 321
    {
348 322
    private:
349 323

	
350 324
      // References to the NetworkSimplex class
351 325
      const IntVector  &_source;
352 326
      const IntVector  &_target;
353 327
      const CostVector &_cost;
354 328
      const IntVector  &_state;
355 329
      const CostVector &_pi;
356 330
      int &_in_arc;
357 331
      int _arc_num;
358 332

	
359 333
    public:
360 334

	
361 335
      // Constructor
362 336
      BestEligiblePivotRule(NetworkSimplex &ns) :
363 337
        _source(ns._source), _target(ns._target),
364 338
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
365 339
        _in_arc(ns.in_arc), _arc_num(ns._arc_num)
366 340
      {}
367 341

	
368 342
      // Find next entering arc
369 343
      bool findEnteringArc() {
370 344
        Cost c, min = 0;
371 345
        for (int e = 0; e < _arc_num; ++e) {
372 346
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
373 347
          if (c < min) {
374 348
            min = c;
375 349
            _in_arc = e;
376 350
          }
377 351
        }
378 352
        return min < 0;
379 353
      }
380 354

	
381 355
    }; //class BestEligiblePivotRule
382 356

	
383 357

	
384 358
    // Implementation of the Block Search pivot rule
385 359
    class BlockSearchPivotRule
386 360
    {
387 361
    private:
388 362

	
389 363
      // References to the NetworkSimplex class
390 364
      const IntVector  &_source;
... ...
@@ -564,797 +538,696 @@
564 538
    class AlteringListPivotRule
565 539
    {
566 540
    private:
567 541

	
568 542
      // References to the NetworkSimplex class
569 543
      const IntVector  &_source;
570 544
      const IntVector  &_target;
571 545
      const CostVector &_cost;
572 546
      const IntVector  &_state;
573 547
      const CostVector &_pi;
574 548
      int &_in_arc;
575 549
      int _arc_num;
576 550

	
577 551
      // Pivot rule data
578 552
      int _block_size, _head_length, _curr_length;
579 553
      int _next_arc;
580 554
      IntVector _candidates;
581 555
      CostVector _cand_cost;
582 556

	
583 557
      // Functor class to compare arcs during sort of the candidate list
584 558
      class SortFunc
585 559
      {
586 560
      private:
587 561
        const CostVector &_map;
588 562
      public:
589 563
        SortFunc(const CostVector &map) : _map(map) {}
590 564
        bool operator()(int left, int right) {
591 565
          return _map[left] > _map[right];
592 566
        }
593 567
      };
594 568

	
595 569
      SortFunc _sort_func;
596 570

	
597 571
    public:
598 572

	
599 573
      // Constructor
600 574
      AlteringListPivotRule(NetworkSimplex &ns) :
601 575
        _source(ns._source), _target(ns._target),
602 576
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
603 577
        _in_arc(ns.in_arc), _arc_num(ns._arc_num),
604 578
        _next_arc(0), _cand_cost(ns._arc_num), _sort_func(_cand_cost)
605 579
      {
606 580
        // The main parameters of the pivot rule
607 581
        const double BLOCK_SIZE_FACTOR = 1.5;
608 582
        const int MIN_BLOCK_SIZE = 10;
609 583
        const double HEAD_LENGTH_FACTOR = 0.1;
610 584
        const int MIN_HEAD_LENGTH = 3;
611 585

	
612 586
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
613 587
                                    std::sqrt(double(_arc_num))),
614 588
                                MIN_BLOCK_SIZE );
615 589
        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
616 590
                                 MIN_HEAD_LENGTH );
617 591
        _candidates.resize(_head_length + _block_size);
618 592
        _curr_length = 0;
619 593
      }
620 594

	
621 595
      // Find next entering arc
622 596
      bool findEnteringArc() {
623 597
        // Check the current candidate list
624 598
        int e;
625 599
        for (int i = 0; i < _curr_length; ++i) {
626 600
          e = _candidates[i];
627 601
          _cand_cost[e] = _state[e] *
628 602
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
629 603
          if (_cand_cost[e] >= 0) {
630 604
            _candidates[i--] = _candidates[--_curr_length];
631 605
          }
632 606
        }
633 607

	
634 608
        // Extend the list
635 609
        int cnt = _block_size;
636 610
        int last_arc = 0;
637 611
        int limit = _head_length;
638 612

	
639 613
        for (int e = _next_arc; e < _arc_num; ++e) {
640 614
          _cand_cost[e] = _state[e] *
641 615
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
642 616
          if (_cand_cost[e] < 0) {
643 617
            _candidates[_curr_length++] = e;
644 618
            last_arc = e;
645 619
          }
646 620
          if (--cnt == 0) {
647 621
            if (_curr_length > limit) break;
648 622
            limit = 0;
649 623
            cnt = _block_size;
650 624
          }
651 625
        }
652 626
        if (_curr_length <= limit) {
653 627
          for (int e = 0; e < _next_arc; ++e) {
654 628
            _cand_cost[e] = _state[e] *
655 629
              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
656 630
            if (_cand_cost[e] < 0) {
657 631
              _candidates[_curr_length++] = e;
658 632
              last_arc = e;
659 633
            }
660 634
            if (--cnt == 0) {
661 635
              if (_curr_length > limit) break;
662 636
              limit = 0;
663 637
              cnt = _block_size;
664 638
            }
665 639
          }
666 640
        }
667 641
        if (_curr_length == 0) return false;
668 642
        _next_arc = last_arc + 1;
669 643

	
670 644
        // Make heap of the candidate list (approximating a partial sort)
671 645
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
672 646
                   _sort_func );
673 647

	
674 648
        // Pop the first element of the heap
675 649
        _in_arc = _candidates[0];
676 650
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
677 651
                  _sort_func );
678 652
        _curr_length = std::min(_head_length, _curr_length - 1);
679 653
        return true;
680 654
      }
681 655

	
682 656
    }; //class AlteringListPivotRule
683 657

	
684 658
  public:
685 659

	
686 660
    /// \brief Constructor.
687 661
    ///
688 662
    /// The constructor of the class.
689 663
    ///
690 664
    /// \param graph The digraph the algorithm runs on.
691 665
    NetworkSimplex(const GR& graph) :
692
      _graph(graph),
693
      _plower(NULL), _pupper(NULL), _pcost(NULL),
694
      _psupply(NULL), _pstsup(false), _stype(GEQ),
695
      _flow_map(NULL), _potential_map(NULL),
696
      _local_flow(false), _local_potential(false),
697
      _node_id(graph),
666
      _graph(graph), _node_id(graph), _arc_id(graph),
698 667
      INF(std::numeric_limits<Value>::has_infinity ?
699 668
          std::numeric_limits<Value>::infinity() :
700 669
          std::numeric_limits<Value>::max())
701 670
    {
702 671
      // Check the value types
703 672
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
704 673
        "The flow type of NetworkSimplex must be signed");
705 674
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
706 675
        "The cost type of NetworkSimplex must be signed");
707
    }
676
        
677
      // Resize vectors
678
      _node_num = countNodes(_graph);
679
      _arc_num = countArcs(_graph);
680
      int all_node_num = _node_num + 1;
681
      int all_arc_num = _arc_num + _node_num;
708 682

	
709
    /// Destructor.
710
    ~NetworkSimplex() {
711
      if (_local_flow) delete _flow_map;
712
      if (_local_potential) delete _potential_map;
683
      _source.resize(all_arc_num);
684
      _target.resize(all_arc_num);
685

	
686
      _lower.resize(all_arc_num);
687
      _upper.resize(all_arc_num);
688
      _cap.resize(all_arc_num);
689
      _cost.resize(all_arc_num);
690
      _supply.resize(all_node_num);
691
      _flow.resize(all_arc_num);
692
      _pi.resize(all_node_num);
693

	
694
      _parent.resize(all_node_num);
695
      _pred.resize(all_node_num);
696
      _forward.resize(all_node_num);
697
      _thread.resize(all_node_num);
698
      _rev_thread.resize(all_node_num);
699
      _succ_num.resize(all_node_num);
700
      _last_succ.resize(all_node_num);
701
      _state.resize(all_arc_num);
702

	
703
      // Copy the graph (store the arcs in a mixed order)
704
      int i = 0;
705
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
706
        _node_id[n] = i;
707
      }
708
      int k = std::max(int(std::sqrt(double(_arc_num))), 10);
709
      i = 0;
710
      for (ArcIt a(_graph); a != INVALID; ++a) {
711
        _arc_id[a] = i;
712
        _source[i] = _node_id[_graph.source(a)];
713
        _target[i] = _node_id[_graph.target(a)];
714
        if ((i += k) >= _arc_num) i = (i % k) + 1;
715
      }
716
      
717
      // Initialize maps
718
      for (int i = 0; i != _node_num; ++i) {
719
        _supply[i] = 0;
720
      }
721
      for (int i = 0; i != _arc_num; ++i) {
722
        _lower[i] = 0;
723
        _upper[i] = INF;
724
        _cost[i] = 1;
725
      }
726
      _have_lower = false;
727
      _stype = GEQ;
713 728
    }
714 729

	
715 730
    /// \name Parameters
716 731
    /// The parameters of the algorithm can be specified using these
717 732
    /// functions.
718 733

	
719 734
    /// @{
720 735

	
721 736
    /// \brief Set the lower bounds on the arcs.
722 737
    ///
723 738
    /// This function sets the lower bounds on the arcs.
724 739
    /// If it is not used before calling \ref run(), the lower bounds
725 740
    /// will be set to zero on all arcs.
726 741
    ///
727 742
    /// \param map An arc map storing the lower bounds.
728 743
    /// Its \c Value type must be convertible to the \c Value type
729 744
    /// of the algorithm.
730 745
    ///
731 746
    /// \return <tt>(*this)</tt>
732 747
    template <typename LowerMap>
733 748
    NetworkSimplex& lowerMap(const LowerMap& map) {
734
      delete _plower;
735
      _plower = new ValueArcMap(_graph);
749
      _have_lower = true;
736 750
      for (ArcIt a(_graph); a != INVALID; ++a) {
737
        (*_plower)[a] = map[a];
751
        _lower[_arc_id[a]] = map[a];
738 752
      }
739 753
      return *this;
740 754
    }
741 755

	
742 756
    /// \brief Set the upper bounds (capacities) on the arcs.
743 757
    ///
744 758
    /// This function sets the upper bounds (capacities) on the arcs.
745 759
    /// If it is not used before calling \ref run(), the upper bounds
746 760
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
747 761
    /// unbounded from above on each arc).
748 762
    ///
749 763
    /// \param map An arc map storing the upper bounds.
750 764
    /// Its \c Value type must be convertible to the \c Value type
751 765
    /// of the algorithm.
752 766
    ///
753 767
    /// \return <tt>(*this)</tt>
754 768
    template<typename UpperMap>
755 769
    NetworkSimplex& upperMap(const UpperMap& map) {
756
      delete _pupper;
757
      _pupper = new ValueArcMap(_graph);
758 770
      for (ArcIt a(_graph); a != INVALID; ++a) {
759
        (*_pupper)[a] = map[a];
771
        _upper[_arc_id[a]] = map[a];
760 772
      }
761 773
      return *this;
762 774
    }
763 775

	
764 776
    /// \brief Set the costs of the arcs.
765 777
    ///
766 778
    /// This function sets the costs of the arcs.
767 779
    /// If it is not used before calling \ref run(), the costs
768 780
    /// will be set to \c 1 on all arcs.
769 781
    ///
770 782
    /// \param map An arc map storing the costs.
771 783
    /// Its \c Value type must be convertible to the \c Cost type
772 784
    /// of the algorithm.
773 785
    ///
774 786
    /// \return <tt>(*this)</tt>
775 787
    template<typename CostMap>
776 788
    NetworkSimplex& costMap(const CostMap& map) {
777
      delete _pcost;
778
      _pcost = new CostArcMap(_graph);
779 789
      for (ArcIt a(_graph); a != INVALID; ++a) {
780
        (*_pcost)[a] = map[a];
790
        _cost[_arc_id[a]] = map[a];
781 791
      }
782 792
      return *this;
783 793
    }
784 794

	
785 795
    /// \brief Set the supply values of the nodes.
786 796
    ///
787 797
    /// This function sets the supply values of the nodes.
788 798
    /// If neither this function nor \ref stSupply() is used before
789 799
    /// calling \ref run(), the supply of each node will be set to zero.
790 800
    /// (It makes sense only if non-zero lower bounds are given.)
791 801
    ///
792 802
    /// \param map A node map storing the supply values.
793 803
    /// Its \c Value type must be convertible to the \c Value type
794 804
    /// of the algorithm.
795 805
    ///
796 806
    /// \return <tt>(*this)</tt>
797 807
    template<typename SupplyMap>
798 808
    NetworkSimplex& supplyMap(const SupplyMap& map) {
799
      delete _psupply;
800
      _pstsup = false;
801
      _psupply = new ValueNodeMap(_graph);
802 809
      for (NodeIt n(_graph); n != INVALID; ++n) {
803
        (*_psupply)[n] = map[n];
810
        _supply[_node_id[n]] = map[n];
804 811
      }
805 812
      return *this;
806 813
    }
807 814

	
808 815
    /// \brief Set single source and target nodes and a supply value.
809 816
    ///
810 817
    /// This function sets a single source node and a single target node
811 818
    /// and the required flow value.
812 819
    /// If neither this function nor \ref supplyMap() is used before
813 820
    /// calling \ref run(), the supply of each node will be set to zero.
814 821
    /// (It makes sense only if non-zero lower bounds are given.)
815 822
    ///
816 823
    /// Using this function has the same effect as using \ref supplyMap()
817 824
    /// with such a map in which \c k is assigned to \c s, \c -k is
818 825
    /// assigned to \c t and all other nodes have zero supply value.
819 826
    ///
820 827
    /// \param s The source node.
821 828
    /// \param t The target node.
822 829
    /// \param k The required amount of flow from node \c s to node \c t
823 830
    /// (i.e. the supply of \c s and the demand of \c t).
824 831
    ///
825 832
    /// \return <tt>(*this)</tt>
826 833
    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
827
      delete _psupply;
828
      _psupply = NULL;
829
      _pstsup = true;
830
      _psource = s;
831
      _ptarget = t;
832
      _pstflow = k;
834
      for (int i = 0; i != _node_num; ++i) {
835
        _supply[i] = 0;
836
      }
837
      _supply[_node_id[s]] =  k;
838
      _supply[_node_id[t]] = -k;
833 839
      return *this;
834 840
    }
835 841
    
836 842
    /// \brief Set the type of the supply constraints.
837 843
    ///
838 844
    /// This function sets the type of the supply/demand constraints.
839 845
    /// If it is not used before calling \ref run(), the \ref GEQ supply
840 846
    /// type will be used.
841 847
    ///
842 848
    /// For more information see \ref SupplyType.
843 849
    ///
844 850
    /// \return <tt>(*this)</tt>
845 851
    NetworkSimplex& supplyType(SupplyType supply_type) {
846 852
      _stype = supply_type;
847 853
      return *this;
848 854
    }
849 855

	
850
    /// \brief Set the flow map.
851
    ///
852
    /// This function sets the flow map.
853
    /// If it is not used before calling \ref run(), an instance will
854
    /// be allocated automatically. The destructor deallocates this
855
    /// automatically allocated map, of course.
856
    ///
857
    /// \return <tt>(*this)</tt>
858
    NetworkSimplex& flowMap(FlowMap& map) {
859
      if (_local_flow) {
860
        delete _flow_map;
861
        _local_flow = false;
862
      }
863
      _flow_map = &map;
864
      return *this;
865
    }
866

	
867
    /// \brief Set the potential map.
868
    ///
869
    /// This function sets the potential map, which is used for storing
870
    /// the dual solution.
871
    /// If it is not used before calling \ref run(), an instance will
872
    /// be allocated automatically. The destructor deallocates this
873
    /// automatically allocated map, of course.
874
    ///
875
    /// \return <tt>(*this)</tt>
876
    NetworkSimplex& potentialMap(PotentialMap& map) {
877
      if (_local_potential) {
878
        delete _potential_map;
879
        _local_potential = false;
880
      }
881
      _potential_map = &map;
882
      return *this;
883
    }
884
    
885 856
    /// @}
886 857

	
887 858
    /// \name Execution Control
888 859
    /// The algorithm can be executed using \ref run().
889 860

	
890 861
    /// @{
891 862

	
892 863
    /// \brief Run the algorithm.
893 864
    ///
894 865
    /// This function runs the algorithm.
895 866
    /// The paramters can be specified using functions \ref lowerMap(),
896 867
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 
897
    /// \ref supplyType(), \ref flowMap() and \ref potentialMap().
868
    /// \ref supplyType().
898 869
    /// For example,
899 870
    /// \code
900 871
    ///   NetworkSimplex<ListDigraph> ns(graph);
901 872
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
902 873
    ///     .supplyMap(sup).run();
903 874
    /// \endcode
904 875
    ///
905 876
    /// This function can be called more than once. All the parameters
906 877
    /// that have been given are kept for the next call, unless
907 878
    /// \ref reset() is called, thus only the modified parameters
908 879
    /// have to be set again. See \ref reset() for examples.
880
    /// However the underlying digraph must not be modified after this
881
    /// class have been constructed, since it copies and extends the graph.
909 882
    ///
910 883
    /// \param pivot_rule The pivot rule that will be used during the
911 884
    /// algorithm. For more information see \ref PivotRule.
912 885
    ///
913 886
    /// \return \c INFEASIBLE if no feasible flow exists,
914 887
    /// \n \c OPTIMAL if the problem has optimal solution
915 888
    /// (i.e. it is feasible and bounded), and the algorithm has found
916 889
    /// optimal flow and node potentials (primal and dual solutions),
917 890
    /// \n \c UNBOUNDED if the objective function of the problem is
918 891
    /// unbounded, i.e. there is a directed cycle having negative total
919 892
    /// cost and infinite upper bound.
920 893
    ///
921 894
    /// \see ProblemType, PivotRule
922 895
    ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
923 896
      if (!init()) return INFEASIBLE;
924 897
      return start(pivot_rule);
925 898
    }
926 899

	
927 900
    /// \brief Reset all the parameters that have been given before.
928 901
    ///
929 902
    /// This function resets all the paramaters that have been given
930 903
    /// before using functions \ref lowerMap(), \ref upperMap(),
931
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType(),
932
    /// \ref flowMap() and \ref potentialMap().
904
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
933 905
    ///
934 906
    /// It is useful for multiple run() calls. If this function is not
935 907
    /// used, all the parameters given before are kept for the next
936 908
    /// \ref run() call.
909
    /// However the underlying digraph must not be modified after this
910
    /// class have been constructed, since it copies and extends the graph.
937 911
    ///
938 912
    /// For example,
939 913
    /// \code
940 914
    ///   NetworkSimplex<ListDigraph> ns(graph);
941 915
    ///
942 916
    ///   // First run
943 917
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
944 918
    ///     .supplyMap(sup).run();
945 919
    ///
946 920
    ///   // Run again with modified cost map (reset() is not called,
947 921
    ///   // so only the cost map have to be set again)
948 922
    ///   cost[e] += 100;
949 923
    ///   ns.costMap(cost).run();
950 924
    ///
951 925
    ///   // Run again from scratch using reset()
952 926
    ///   // (the lower bounds will be set to zero on all arcs)
953 927
    ///   ns.reset();
954 928
    ///   ns.upperMap(capacity).costMap(cost)
955 929
    ///     .supplyMap(sup).run();
956 930
    /// \endcode
957 931
    ///
958 932
    /// \return <tt>(*this)</tt>
959 933
    NetworkSimplex& reset() {
960
      delete _plower;
961
      delete _pupper;
962
      delete _pcost;
963
      delete _psupply;
964
      _plower = NULL;
965
      _pupper = NULL;
966
      _pcost = NULL;
967
      _psupply = NULL;
968
      _pstsup = false;
934
      for (int i = 0; i != _node_num; ++i) {
935
        _supply[i] = 0;
936
      }
937
      for (int i = 0; i != _arc_num; ++i) {
938
        _lower[i] = 0;
939
        _upper[i] = INF;
940
        _cost[i] = 1;
941
      }
942
      _have_lower = false;
969 943
      _stype = GEQ;
970
      if (_local_flow) delete _flow_map;
971
      if (_local_potential) delete _potential_map;
972
      _flow_map = NULL;
973
      _potential_map = NULL;
974
      _local_flow = false;
975
      _local_potential = false;
976

	
977 944
      return *this;
978 945
    }
979 946

	
980 947
    /// @}
981 948

	
982 949
    /// \name Query Functions
983 950
    /// The results of the algorithm can be obtained using these
984 951
    /// functions.\n
985 952
    /// The \ref run() function must be called before using them.
986 953

	
987 954
    /// @{
988 955

	
989 956
    /// \brief Return the total cost of the found flow.
990 957
    ///
991 958
    /// This function returns the total cost of the found flow.
992 959
    /// Its complexity is O(e).
993 960
    ///
994 961
    /// \note The return type of the function can be specified as a
995 962
    /// template parameter. For example,
996 963
    /// \code
997 964
    ///   ns.totalCost<double>();
998 965
    /// \endcode
999 966
    /// It is useful if the total cost cannot be stored in the \c Cost
1000 967
    /// type of the algorithm, which is the default return type of the
1001 968
    /// function.
1002 969
    ///
1003 970
    /// \pre \ref run() must be called before using this function.
1004
    template <typename Value>
1005
    Value totalCost() const {
1006
      Value c = 0;
1007
      if (_pcost) {
1008
        for (ArcIt e(_graph); e != INVALID; ++e)
1009
          c += (*_flow_map)[e] * (*_pcost)[e];
1010
      } else {
1011
        for (ArcIt e(_graph); e != INVALID; ++e)
1012
          c += (*_flow_map)[e];
971
    template <typename Number>
972
    Number totalCost() const {
973
      Number c = 0;
974
      for (ArcIt a(_graph); a != INVALID; ++a) {
975
        int i = _arc_id[a];
976
        c += Number(_flow[i]) * Number(_cost[i]);
1013 977
      }
1014 978
      return c;
1015 979
    }
1016 980

	
1017 981
#ifndef DOXYGEN
1018 982
    Cost totalCost() const {
1019 983
      return totalCost<Cost>();
1020 984
    }
1021 985
#endif
1022 986

	
1023 987
    /// \brief Return the flow on the given arc.
1024 988
    ///
1025 989
    /// This function returns the flow on the given arc.
1026 990
    ///
1027 991
    /// \pre \ref run() must be called before using this function.
1028 992
    Value flow(const Arc& a) const {
1029
      return (*_flow_map)[a];
993
      return _flow[_arc_id[a]];
1030 994
    }
1031 995

	
1032
    /// \brief Return a const reference to the flow map.
996
    /// \brief Return the flow map (the primal solution).
1033 997
    ///
1034
    /// This function returns a const reference to an arc map storing
1035
    /// the found flow.
998
    /// This function copies the flow value on each arc into the given
999
    /// map. The \c Value type of the algorithm must be convertible to
1000
    /// the \c Value type of the map.
1036 1001
    ///
1037 1002
    /// \pre \ref run() must be called before using this function.
1038
    const FlowMap& flowMap() const {
1039
      return *_flow_map;
1003
    template <typename FlowMap>
1004
    void flowMap(FlowMap &map) const {
1005
      for (ArcIt a(_graph); a != INVALID; ++a) {
1006
        map.set(a, _flow[_arc_id[a]]);
1007
      }
1040 1008
    }
1041 1009

	
1042 1010
    /// \brief Return the potential (dual value) of the given node.
1043 1011
    ///
1044 1012
    /// This function returns the potential (dual value) of the
1045 1013
    /// given node.
1046 1014
    ///
1047 1015
    /// \pre \ref run() must be called before using this function.
1048 1016
    Cost potential(const Node& n) const {
1049
      return (*_potential_map)[n];
1017
      return _pi[_node_id[n]];
1050 1018
    }
1051 1019

	
1052
    /// \brief Return a const reference to the potential map
1053
    /// (the dual solution).
1020
    /// \brief Return the potential map (the dual solution).
1054 1021
    ///
1055
    /// This function returns a const reference to a node map storing
1056
    /// the found potentials, which form the dual solution of the
1057
    /// \ref min_cost_flow "minimum cost flow problem".
1022
    /// This function copies the potential (dual value) of each node
1023
    /// into the given map.
1024
    /// The \c Cost type of the algorithm must be convertible to the
1025
    /// \c Value type of the map.
1058 1026
    ///
1059 1027
    /// \pre \ref run() must be called before using this function.
1060
    const PotentialMap& potentialMap() const {
1061
      return *_potential_map;
1028
    template <typename PotentialMap>
1029
    void potentialMap(PotentialMap &map) const {
1030
      for (NodeIt n(_graph); n != INVALID; ++n) {
1031
        map.set(n, _pi[_node_id[n]]);
1032
      }
1062 1033
    }
1063 1034

	
1064 1035
    /// @}
1065 1036

	
1066 1037
  private:
1067 1038

	
1068 1039
    // Initialize internal data structures
1069 1040
    bool init() {
1070
      // Initialize result maps
1071
      if (!_flow_map) {
1072
        _flow_map = new FlowMap(_graph);
1073
        _local_flow = true;
1074
      }
1075
      if (!_potential_map) {
1076
        _potential_map = new PotentialMap(_graph);
1077
        _local_potential = true;
1078
      }
1079

	
1080
      // Initialize vectors
1081
      _node_num = countNodes(_graph);
1082
      _arc_num = countArcs(_graph);
1083
      int all_node_num = _node_num + 1;
1084
      int all_arc_num = _arc_num + _node_num;
1085 1041
      if (_node_num == 0) return false;
1086 1042

	
1087
      _arc_ref.resize(_arc_num);
1088
      _source.resize(all_arc_num);
1089
      _target.resize(all_arc_num);
1043
      // Check the sum of supply values
1044
      _sum_supply = 0;
1045
      for (int i = 0; i != _node_num; ++i) {
1046
        _sum_supply += _supply[i];
1047
      }
1048
      if ( !(_stype == GEQ && _sum_supply <= 0 ||
1049
             _stype == LEQ && _sum_supply >= 0) ) return false;
1090 1050

	
1091
      _cap.resize(all_arc_num);
1092
      _cost.resize(all_arc_num);
1093
      _supply.resize(all_node_num);
1094
      _flow.resize(all_arc_num);
1095
      _pi.resize(all_node_num);
1096

	
1097
      _parent.resize(all_node_num);
1098
      _pred.resize(all_node_num);
1099
      _forward.resize(all_node_num);
1100
      _thread.resize(all_node_num);
1101
      _rev_thread.resize(all_node_num);
1102
      _succ_num.resize(all_node_num);
1103
      _last_succ.resize(all_node_num);
1104
      _state.resize(all_arc_num);
1105

	
1106
      // Initialize node related data
1107
      bool valid_supply = true;
1108
      _sum_supply = 0;
1109
      if (!_pstsup && !_psupply) {
1110
        _pstsup = true;
1111
        _psource = _ptarget = NodeIt(_graph);
1112
        _pstflow = 0;
1051
      // Remove non-zero lower bounds
1052
      if (_have_lower) {
1053
        for (int i = 0; i != _arc_num; ++i) {
1054
          Value c = _lower[i];
1055
          if (c >= 0) {
1056
            _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
1057
          } else {
1058
            _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
1059
          }
1060
          _supply[_source[i]] -= c;
1061
          _supply[_target[i]] += c;
1062
        }
1063
      } else {
1064
        for (int i = 0; i != _arc_num; ++i) {
1065
          _cap[i] = _upper[i];
1066
        }
1113 1067
      }
1114
      if (_psupply) {
1115
        int i = 0;
1116
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1117
          _node_id[n] = i;
1118
          _supply[i] = (*_psupply)[n];
1119
          _sum_supply += _supply[i];
1120
        }
1121
        valid_supply = (_stype == GEQ && _sum_supply <= 0) ||
1122
                       (_stype == LEQ && _sum_supply >= 0);
1123
      } else {
1124
        int i = 0;
1125
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1126
          _node_id[n] = i;
1127
          _supply[i] = 0;
1128
        }
1129
        _supply[_node_id[_psource]] =  _pstflow;
1130
        _supply[_node_id[_ptarget]] = -_pstflow;
1131
      }
1132
      if (!valid_supply) return false;
1133 1068

	
1134 1069
      // Initialize artifical cost
1135 1070
      Cost ART_COST;
1136 1071
      if (std::numeric_limits<Cost>::is_exact) {
1137 1072
        ART_COST = std::numeric_limits<Cost>::max() / 4 + 1;
1138 1073
      } else {
1139 1074
        ART_COST = std::numeric_limits<Cost>::min();
1140 1075
        for (int i = 0; i != _arc_num; ++i) {
1141 1076
          if (_cost[i] > ART_COST) ART_COST = _cost[i];
1142 1077
        }
1143 1078
        ART_COST = (ART_COST + 1) * _node_num;
1144 1079
      }
1145 1080

	
1081
      // Initialize arc maps
1082
      for (int i = 0; i != _arc_num; ++i) {
1083
        _flow[i] = 0;
1084
        _state[i] = STATE_LOWER;
1085
      }
1086
      
1146 1087
      // Set data for the artificial root node
1147 1088
      _root = _node_num;
1148 1089
      _parent[_root] = -1;
1149 1090
      _pred[_root] = -1;
1150 1091
      _thread[_root] = 0;
1151 1092
      _rev_thread[0] = _root;
1152
      _succ_num[_root] = all_node_num;
1093
      _succ_num[_root] = _node_num + 1;
1153 1094
      _last_succ[_root] = _root - 1;
1154 1095
      _supply[_root] = -_sum_supply;
1155
      if (_sum_supply < 0) {
1156
        _pi[_root] = -ART_COST;
1157
      } else {
1158
        _pi[_root] = ART_COST;
1159
      }
1160

	
1161
      // Store the arcs in a mixed order
1162
      int k = std::max(int(std::sqrt(double(_arc_num))), 10);
1163
      int i = 0;
1164
      for (ArcIt e(_graph); e != INVALID; ++e) {
1165
        _arc_ref[i] = e;
1166
        if ((i += k) >= _arc_num) i = (i % k) + 1;
1167
      }
1168

	
1169
      // Initialize arc maps
1170
      if (_pupper && _pcost) {
1171
        for (int i = 0; i != _arc_num; ++i) {
1172
          Arc e = _arc_ref[i];
1173
          _source[i] = _node_id[_graph.source(e)];
1174
          _target[i] = _node_id[_graph.target(e)];
1175
          _cap[i] = (*_pupper)[e];
1176
          _cost[i] = (*_pcost)[e];
1177
          _flow[i] = 0;
1178
          _state[i] = STATE_LOWER;
1179
        }
1180
      } else {
1181
        for (int i = 0; i != _arc_num; ++i) {
1182
          Arc e = _arc_ref[i];
1183
          _source[i] = _node_id[_graph.source(e)];
1184
          _target[i] = _node_id[_graph.target(e)];
1185
          _flow[i] = 0;
1186
          _state[i] = STATE_LOWER;
1187
        }
1188
        if (_pupper) {
1189
          for (int i = 0; i != _arc_num; ++i)
1190
            _cap[i] = (*_pupper)[_arc_ref[i]];
1191
        } else {
1192
          for (int i = 0; i != _arc_num; ++i)
1193
            _cap[i] = INF;
1194
        }
1195
        if (_pcost) {
1196
          for (int i = 0; i != _arc_num; ++i)
1197
            _cost[i] = (*_pcost)[_arc_ref[i]];
1198
        } else {
1199
          for (int i = 0; i != _arc_num; ++i)
1200
            _cost[i] = 1;
1201
        }
1202
      }
1203
      
1204
      // Remove non-zero lower bounds
1205
      if (_plower) {
1206
        for (int i = 0; i != _arc_num; ++i) {
1207
          Value c = (*_plower)[_arc_ref[i]];
1208
          if (c > 0) {
1209
            if (_cap[i] < INF) _cap[i] -= c;
1210
            _supply[_source[i]] -= c;
1211
            _supply[_target[i]] += c;
1212
          }
1213
          else if (c < 0) {
1214
            if (_cap[i] < INF + c) {
1215
              _cap[i] -= c;
1216
            } else {
1217
              _cap[i] = INF;
1218
            }
1219
            _supply[_source[i]] -= c;
1220
            _supply[_target[i]] += c;
1221
          }
1222
        }
1223
      }
1096
      _pi[_root] = _sum_supply < 0 ? -ART_COST : ART_COST;
1224 1097

	
1225 1098
      // Add artificial arcs and initialize the spanning tree data structure
1226 1099
      for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1100
        _parent[u] = _root;
1101
        _pred[u] = e;
1227 1102
        _thread[u] = u + 1;
1228 1103
        _rev_thread[u + 1] = u;
1229 1104
        _succ_num[u] = 1;
1230 1105
        _last_succ[u] = u;
1231
        _parent[u] = _root;
1232
        _pred[u] = e;
1233 1106
        _cost[e] = ART_COST;
1234 1107
        _cap[e] = INF;
1235 1108
        _state[e] = STATE_TREE;
1236 1109
        if (_supply[u] > 0 || (_supply[u] == 0 && _sum_supply <= 0)) {
1237 1110
          _flow[e] = _supply[u];
1238 1111
          _forward[u] = true;
1239 1112
          _pi[u] = -ART_COST + _pi[_root];
1240 1113
        } else {
1241 1114
          _flow[e] = -_supply[u];
1242 1115
          _forward[u] = false;
1243 1116
          _pi[u] = ART_COST + _pi[_root];
1244 1117
        }
1245 1118
      }
1246 1119

	
1247 1120
      return true;
1248 1121
    }
1249 1122

	
1250 1123
    // Find the join node
1251 1124
    void findJoinNode() {
1252 1125
      int u = _source[in_arc];
1253 1126
      int v = _target[in_arc];
1254 1127
      while (u != v) {
1255 1128
        if (_succ_num[u] < _succ_num[v]) {
1256 1129
          u = _parent[u];
1257 1130
        } else {
1258 1131
          v = _parent[v];
1259 1132
        }
1260 1133
      }
1261 1134
      join = u;
1262 1135
    }
1263 1136

	
1264 1137
    // Find the leaving arc of the cycle and returns true if the
1265 1138
    // leaving arc is not the same as the entering arc
1266 1139
    bool findLeavingArc() {
1267 1140
      // Initialize first and second nodes according to the direction
1268 1141
      // of the cycle
1269 1142
      if (_state[in_arc] == STATE_LOWER) {
1270 1143
        first  = _source[in_arc];
1271 1144
        second = _target[in_arc];
1272 1145
      } else {
1273 1146
        first  = _target[in_arc];
1274 1147
        second = _source[in_arc];
1275 1148
      }
1276 1149
      delta = _cap[in_arc];
1277 1150
      int result = 0;
1278 1151
      Value d;
1279 1152
      int e;
1280 1153

	
1281 1154
      // Search the cycle along the path form the first node to the root
1282 1155
      for (int u = first; u != join; u = _parent[u]) {
1283 1156
        e = _pred[u];
1284 1157
        d = _forward[u] ?
1285 1158
          _flow[e] : (_cap[e] == INF ? INF : _cap[e] - _flow[e]);
1286 1159
        if (d < delta) {
1287 1160
          delta = d;
1288 1161
          u_out = u;
1289 1162
          result = 1;
1290 1163
        }
1291 1164
      }
1292 1165
      // Search the cycle along the path form the second node to the root
1293 1166
      for (int u = second; u != join; u = _parent[u]) {
1294 1167
        e = _pred[u];
1295 1168
        d = _forward[u] ? 
1296 1169
          (_cap[e] == INF ? INF : _cap[e] - _flow[e]) : _flow[e];
1297 1170
        if (d <= delta) {
1298 1171
          delta = d;
1299 1172
          u_out = u;
1300 1173
          result = 2;
1301 1174
        }
1302 1175
      }
1303 1176

	
1304 1177
      if (result == 1) {
1305 1178
        u_in = first;
1306 1179
        v_in = second;
1307 1180
      } else {
1308 1181
        u_in = second;
1309 1182
        v_in = first;
1310 1183
      }
1311 1184
      return result != 0;
1312 1185
    }
1313 1186

	
1314 1187
    // Change _flow and _state vectors
1315 1188
    void changeFlow(bool change) {
1316 1189
      // Augment along the cycle
1317 1190
      if (delta > 0) {
1318 1191
        Value val = _state[in_arc] * delta;
1319 1192
        _flow[in_arc] += val;
1320 1193
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
1321 1194
          _flow[_pred[u]] += _forward[u] ? -val : val;
1322 1195
        }
1323 1196
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
1324 1197
          _flow[_pred[u]] += _forward[u] ? val : -val;
1325 1198
        }
1326 1199
      }
1327 1200
      // Update the state of the entering and leaving arcs
1328 1201
      if (change) {
1329 1202
        _state[in_arc] = STATE_TREE;
1330 1203
        _state[_pred[u_out]] =
1331 1204
          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
1332 1205
      } else {
1333 1206
        _state[in_arc] = -_state[in_arc];
1334 1207
      }
1335 1208
    }
1336 1209

	
1337 1210
    // Update the tree structure
1338 1211
    void updateTreeStructure() {
1339 1212
      int u, w;
1340 1213
      int old_rev_thread = _rev_thread[u_out];
1341 1214
      int old_succ_num = _succ_num[u_out];
1342 1215
      int old_last_succ = _last_succ[u_out];
1343 1216
      v_out = _parent[u_out];
1344 1217

	
1345 1218
      u = _last_succ[u_in];  // the last successor of u_in
1346 1219
      right = _thread[u];    // the node after it
1347 1220

	
1348 1221
      // Handle the case when old_rev_thread equals to v_in
1349 1222
      // (it also means that join and v_out coincide)
1350 1223
      if (old_rev_thread == v_in) {
1351 1224
        last = _thread[_last_succ[u_out]];
1352 1225
      } else {
1353 1226
        last = _thread[v_in];
1354 1227
      }
1355 1228

	
1356 1229
      // Update _thread and _parent along the stem nodes (i.e. the nodes
1357 1230
      // between u_in and u_out, whose parent have to be changed)
1358 1231
      _thread[v_in] = stem = u_in;
1359 1232
      _dirty_revs.clear();
1360 1233
      _dirty_revs.push_back(v_in);
... ...
@@ -1392,154 +1265,150 @@
1392 1265
        _thread[old_rev_thread] = right;
1393 1266
        _rev_thread[right] = old_rev_thread;
1394 1267
      }
1395 1268

	
1396 1269
      // Update _rev_thread using the new _thread values
1397 1270
      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
1398 1271
        u = _dirty_revs[i];
1399 1272
        _rev_thread[_thread[u]] = u;
1400 1273
      }
1401 1274

	
1402 1275
      // Update _pred, _forward, _last_succ and _succ_num for the
1403 1276
      // stem nodes from u_out to u_in
1404 1277
      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
1405 1278
      u = u_out;
1406 1279
      while (u != u_in) {
1407 1280
        w = _parent[u];
1408 1281
        _pred[u] = _pred[w];
1409 1282
        _forward[u] = !_forward[w];
1410 1283
        tmp_sc += _succ_num[u] - _succ_num[w];
1411 1284
        _succ_num[u] = tmp_sc;
1412 1285
        _last_succ[w] = tmp_ls;
1413 1286
        u = w;
1414 1287
      }
1415 1288
      _pred[u_in] = in_arc;
1416 1289
      _forward[u_in] = (u_in == _source[in_arc]);
1417 1290
      _succ_num[u_in] = old_succ_num;
1418 1291

	
1419 1292
      // Set limits for updating _last_succ form v_in and v_out
1420 1293
      // towards the root
1421 1294
      int up_limit_in = -1;
1422 1295
      int up_limit_out = -1;
1423 1296
      if (_last_succ[join] == v_in) {
1424 1297
        up_limit_out = join;
1425 1298
      } else {
1426 1299
        up_limit_in = join;
1427 1300
      }
1428 1301

	
1429 1302
      // Update _last_succ from v_in towards the root
1430 1303
      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
1431 1304
           u = _parent[u]) {
1432 1305
        _last_succ[u] = _last_succ[u_out];
1433 1306
      }
1434 1307
      // Update _last_succ from v_out towards the root
1435 1308
      if (join != old_rev_thread && v_in != old_rev_thread) {
1436 1309
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1437 1310
             u = _parent[u]) {
1438 1311
          _last_succ[u] = old_rev_thread;
1439 1312
        }
1440 1313
      } else {
1441 1314
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1442 1315
             u = _parent[u]) {
1443 1316
          _last_succ[u] = _last_succ[u_out];
1444 1317
        }
1445 1318
      }
1446 1319

	
1447 1320
      // Update _succ_num from v_in to join
1448 1321
      for (u = v_in; u != join; u = _parent[u]) {
1449 1322
        _succ_num[u] += old_succ_num;
1450 1323
      }
1451 1324
      // Update _succ_num from v_out to join
1452 1325
      for (u = v_out; u != join; u = _parent[u]) {
1453 1326
        _succ_num[u] -= old_succ_num;
1454 1327
      }
1455 1328
    }
1456 1329

	
1457 1330
    // Update potentials
1458 1331
    void updatePotential() {
1459 1332
      Cost sigma = _forward[u_in] ?
1460 1333
        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
1461 1334
        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
1462 1335
      // Update potentials in the subtree, which has been moved
1463 1336
      int end = _thread[_last_succ[u_in]];
1464 1337
      for (int u = u_in; u != end; u = _thread[u]) {
1465 1338
        _pi[u] += sigma;
1466 1339
      }
1467 1340
    }
1468 1341

	
1469 1342
    // Execute the algorithm
1470 1343
    ProblemType start(PivotRule pivot_rule) {
1471 1344
      // Select the pivot rule implementation
1472 1345
      switch (pivot_rule) {
1473 1346
        case FIRST_ELIGIBLE:
1474 1347
          return start<FirstEligiblePivotRule>();
1475 1348
        case BEST_ELIGIBLE:
1476 1349
          return start<BestEligiblePivotRule>();
1477 1350
        case BLOCK_SEARCH:
1478 1351
          return start<BlockSearchPivotRule>();
1479 1352
        case CANDIDATE_LIST:
1480 1353
          return start<CandidateListPivotRule>();
1481 1354
        case ALTERING_LIST:
1482 1355
          return start<AlteringListPivotRule>();
1483 1356
      }
1484 1357
      return INFEASIBLE; // avoid warning
1485 1358
    }
1486 1359

	
1487 1360
    template <typename PivotRuleImpl>
1488 1361
    ProblemType start() {
1489 1362
      PivotRuleImpl pivot(*this);
1490 1363

	
1491 1364
      // Execute the Network Simplex algorithm
1492 1365
      while (pivot.findEnteringArc()) {
1493 1366
        findJoinNode();
1494 1367
        bool change = findLeavingArc();
1495 1368
        if (delta >= INF) return UNBOUNDED;
1496 1369
        changeFlow(change);
1497 1370
        if (change) {
1498 1371
          updateTreeStructure();
1499 1372
          updatePotential();
1500 1373
        }
1501 1374
      }
1502 1375
      
1503 1376
      // Check feasibility
1504 1377
      if (_sum_supply < 0) {
1505 1378
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1506 1379
          if (_supply[u] >= 0 && _flow[e] != 0) return INFEASIBLE;
1507 1380
        }
1508 1381
      }
1509 1382
      else if (_sum_supply > 0) {
1510 1383
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1511 1384
          if (_supply[u] <= 0 && _flow[e] != 0) return INFEASIBLE;
1512 1385
        }
1513 1386
      }
1514 1387
      else {
1515 1388
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1516 1389
          if (_flow[e] != 0) return INFEASIBLE;
1517 1390
        }
1518 1391
      }
1519 1392

	
1520
      // Copy flow values to _flow_map
1521
      if (_plower) {
1393
      // Transform the solution and the supply map to the original form
1394
      if (_have_lower) {
1522 1395
        for (int i = 0; i != _arc_num; ++i) {
1523
          Arc e = _arc_ref[i];
1524
          _flow_map->set(e, (*_plower)[e] + _flow[i]);
1396
          Value c = _lower[i];
1397
          if (c != 0) {
1398
            _flow[i] += c;
1399
            _supply[_source[i]] += c;
1400
            _supply[_target[i]] -= c;
1401
          }
1525 1402
        }
1526
      } else {
1527
        for (int i = 0; i != _arc_num; ++i) {
1528
          _flow_map->set(_arc_ref[i], _flow[i]);
1529
        }
1530
      }
1531
      // Copy potential values to _potential_map
1532
      for (NodeIt n(_graph); n != INVALID; ++n) {
1533
        _potential_map->set(n, _pi[_node_id[n]]);
1534 1403
      }
1535 1404

	
1536 1405
      return OPTIMAL;
1537 1406
    }
1538 1407

	
1539 1408
  }; //class NetworkSimplex
1540 1409

	
1541 1410
  ///@}
1542 1411

	
1543 1412
} //namespace lemon
1544 1413

	
1545 1414
#endif //LEMON_NETWORK_SIMPLEX_H
Ignore white space 6 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
#include <iostream>
20 20
#include <fstream>
21 21
#include <limits>
22 22

	
23 23
#include <lemon/list_graph.h>
24 24
#include <lemon/lgf_reader.h>
25 25

	
26 26
#include <lemon/network_simplex.h>
27 27

	
28 28
#include <lemon/concepts/digraph.h>
29 29
#include <lemon/concept_check.h>
30 30

	
31 31
#include "test_tools.h"
32 32

	
33 33
using namespace lemon;
34 34

	
35 35
char test_lgf[] =
36 36
  "@nodes\n"
37 37
  "label  sup1 sup2 sup3 sup4 sup5 sup6\n"
38 38
  "    1    20   27    0   30   20   30\n"
39 39
  "    2    -4    0    0    0   -8   -3\n"
40 40
  "    3     0    0    0    0    0    0\n"
41 41
  "    4     0    0    0    0    0    0\n"
42 42
  "    5     9    0    0    0    6   11\n"
43 43
  "    6    -6    0    0    0   -5   -6\n"
44 44
  "    7     0    0    0    0    0    0\n"
45 45
  "    8     0    0    0    0    0    3\n"
46 46
  "    9     3    0    0    0    0    0\n"
47 47
  "   10    -2    0    0    0   -7   -2\n"
48 48
  "   11     0    0    0    0  -10    0\n"
49 49
  "   12   -20  -27    0  -30  -30  -20\n"
50 50
  "\n"                
51 51
  "@arcs\n"
52 52
  "       cost  cap low1 low2 low3\n"
53 53
  " 1  2    70   11    0    8    8\n"
54 54
  " 1  3   150    3    0    1    0\n"
55 55
  " 1  4    80   15    0    2    2\n"
56 56
  " 2  8    80   12    0    0    0\n"
57 57
  " 3  5   140    5    0    3    1\n"
58 58
  " 4  6    60   10    0    1    0\n"
59 59
  " 4  7    80    2    0    0    0\n"
60 60
  " 4  8   110    3    0    0    0\n"
61 61
  " 5  7    60   14    0    0    0\n"
62 62
  " 5 11   120   12    0    0    0\n"
63 63
  " 6  3     0    3    0    0    0\n"
64 64
  " 6  9   140    4    0    0    0\n"
65 65
  " 6 10    90    8    0    0    0\n"
66 66
  " 7  1    30    5    0    0   -5\n"
67 67
  " 8 12    60   16    0    4    3\n"
68 68
  " 9 12    50    6    0    0    0\n"
69 69
  "10 12    70   13    0    5    2\n"
70 70
  "10  2   100    7    0    0    0\n"
71 71
  "10  7    60   10    0    0   -3\n"
72 72
  "11 10    20   14    0    6  -20\n"
73 73
  "12 11    30   10    0    0  -10\n"
74 74
  "\n"
75 75
  "@attributes\n"
76 76
  "source 1\n"
77 77
  "target 12\n";
78 78

	
79 79

	
80 80
enum SupplyType {
81 81
  EQ,
82 82
  GEQ,
83 83
  LEQ
84 84
};
85 85

	
86 86
// Check the interface of an MCF algorithm
87
template <typename GR, typename Flow, typename Cost>
87
template <typename GR, typename Value, typename Cost>
88 88
class McfClassConcept
89 89
{
90 90
public:
91 91

	
92 92
  template <typename MCF>
93 93
  struct Constraints {
94 94
    void constraints() {
95 95
      checkConcept<concepts::Digraph, GR>();
96 96

	
97 97
      MCF mcf(g);
98
      const MCF& const_mcf = mcf;
98 99

	
99 100
      b = mcf.reset()
100 101
             .lowerMap(lower)
101 102
             .upperMap(upper)
102 103
             .costMap(cost)
103 104
             .supplyMap(sup)
104 105
             .stSupply(n, n, k)
105
             .flowMap(flow)
106
             .potentialMap(pot)
107 106
             .run();
108
      
109
      const MCF& const_mcf = mcf;
110

	
111
      const typename MCF::FlowMap &fm = const_mcf.flowMap();
112
      const typename MCF::PotentialMap &pm = const_mcf.potentialMap();
113 107

	
114 108
      c = const_mcf.totalCost();
115
      double x = const_mcf.template totalCost<double>();
109
      x = const_mcf.template totalCost<double>();
116 110
      v = const_mcf.flow(a);
117 111
      c = const_mcf.potential(n);
118
      
119
      v = const_mcf.INF;
120

	
121
      ignore_unused_variable_warning(fm);
122
      ignore_unused_variable_warning(pm);
123
      ignore_unused_variable_warning(x);
112
      const_mcf.flowMap(fm);
113
      const_mcf.potentialMap(pm);
124 114
    }
125 115

	
126 116
    typedef typename GR::Node Node;
127 117
    typedef typename GR::Arc Arc;
128
    typedef concepts::ReadMap<Node, Flow> NM;
129
    typedef concepts::ReadMap<Arc, Flow> FAM;
118
    typedef concepts::ReadMap<Node, Value> NM;
119
    typedef concepts::ReadMap<Arc, Value> VAM;
130 120
    typedef concepts::ReadMap<Arc, Cost> CAM;
121
    typedef concepts::WriteMap<Arc, Value> FlowMap;
122
    typedef concepts::WriteMap<Node, Cost> PotMap;
131 123

	
132 124
    const GR &g;
133
    const FAM &lower;
134
    const FAM &upper;
125
    const VAM &lower;
126
    const VAM &upper;
135 127
    const CAM &cost;
136 128
    const NM &sup;
137 129
    const Node &n;
138 130
    const Arc &a;
139
    const Flow &k;
140
    Flow v;
141
    Cost c;
131
    const Value &k;
132
    FlowMap fm;
133
    PotMap pm;
142 134
    bool b;
143

	
144
    typename MCF::FlowMap &flow;
145
    typename MCF::PotentialMap &pot;
135
    double x;
136
    typename MCF::Value v;
137
    typename MCF::Cost c;
146 138
  };
147 139

	
148 140
};
149 141

	
150 142

	
151 143
// Check the feasibility of the given flow (primal soluiton)
152 144
template < typename GR, typename LM, typename UM,
153 145
           typename SM, typename FM >
154 146
bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
155 147
                const SM& supply, const FM& flow,
156 148
                SupplyType type = EQ )
157 149
{
158 150
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
159 151

	
160 152
  for (ArcIt e(gr); e != INVALID; ++e) {
161 153
    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
162 154
  }
163 155

	
164 156
  for (NodeIt n(gr); n != INVALID; ++n) {
165 157
    typename SM::Value sum = 0;
166 158
    for (OutArcIt e(gr, n); e != INVALID; ++e)
167 159
      sum += flow[e];
168 160
    for (InArcIt e(gr, n); e != INVALID; ++e)
169 161
      sum -= flow[e];
170 162
    bool b = (type ==  EQ && sum == supply[n]) ||
171 163
             (type == GEQ && sum >= supply[n]) ||
172 164
             (type == LEQ && sum <= supply[n]);
173 165
    if (!b) return false;
174 166
  }
175 167

	
176 168
  return true;
177 169
}
178 170

	
179 171
// Check the feasibility of the given potentials (dual soluiton)
180 172
// using the "Complementary Slackness" optimality condition
181 173
template < typename GR, typename LM, typename UM,
182 174
           typename CM, typename SM, typename FM, typename PM >
183 175
bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
184 176
                     const CM& cost, const SM& supply, const FM& flow, 
185 177
                     const PM& pi )
186 178
{
187 179
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
188 180

	
189 181
  bool opt = true;
190 182
  for (ArcIt e(gr); opt && e != INVALID; ++e) {
191 183
    typename CM::Value red_cost =
192 184
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
193 185
    opt = red_cost == 0 ||
194 186
          (red_cost > 0 && flow[e] == lower[e]) ||
195 187
          (red_cost < 0 && flow[e] == upper[e]);
196 188
  }
197 189
  
198 190
  for (NodeIt n(gr); opt && n != INVALID; ++n) {
199 191
    typename SM::Value sum = 0;
200 192
    for (OutArcIt e(gr, n); e != INVALID; ++e)
201 193
      sum += flow[e];
202 194
    for (InArcIt e(gr, n); e != INVALID; ++e)
203 195
      sum -= flow[e];
204 196
    opt = (sum == supply[n]) || (pi[n] == 0);
205 197
  }
206 198
  
207 199
  return opt;
208 200
}
209 201

	
210 202
// Run a minimum cost flow algorithm and check the results
211 203
template < typename MCF, typename GR,
212 204
           typename LM, typename UM,
213 205
           typename CM, typename SM,
214 206
           typename PT >
215 207
void checkMcf( const MCF& mcf, PT mcf_result,
216 208
               const GR& gr, const LM& lower, const UM& upper,
217 209
               const CM& cost, const SM& supply,
218 210
               PT result, bool optimal, typename CM::Value total,
219 211
               const std::string &test_id = "",
220 212
               SupplyType type = EQ )
221 213
{
222 214
  check(mcf_result == result, "Wrong result " + test_id);
223 215
  if (optimal) {
224
    check(checkFlow(gr, lower, upper, supply, mcf.flowMap(), type),
216
    typename GR::template ArcMap<typename SM::Value> flow(gr);
217
    typename GR::template NodeMap<typename CM::Value> pi(gr);
218
    mcf.flowMap(flow);
219
    mcf.potentialMap(pi);
220
    check(checkFlow(gr, lower, upper, supply, flow, type),
225 221
          "The flow is not feasible " + test_id);
226 222
    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
227
    check(checkPotential(gr, lower, upper, cost, supply, mcf.flowMap(),
228
                         mcf.potentialMap()),
223
    check(checkPotential(gr, lower, upper, cost, supply, flow, pi),
229 224
          "Wrong potentials " + test_id);
230 225
  }
231 226
}
232 227

	
233 228
int main()
234 229
{
235 230
  // Check the interfaces
236 231
  {
237
    typedef int Flow;
238
    typedef int Cost;
239 232
    typedef concepts::Digraph GR;
240
    checkConcept< McfClassConcept<GR, Flow, Cost>,
241
                  NetworkSimplex<GR, Flow, Cost> >();
233
    checkConcept< McfClassConcept<GR, int, int>,
234
                  NetworkSimplex<GR> >();
235
    checkConcept< McfClassConcept<GR, double, double>,
236
                  NetworkSimplex<GR, double> >();
237
    checkConcept< McfClassConcept<GR, int, double>,
238
                  NetworkSimplex<GR, int, double> >();
242 239
  }
243 240

	
244 241
  // Run various MCF tests
245 242
  typedef ListDigraph Digraph;
246 243
  DIGRAPH_TYPEDEFS(ListDigraph);
247 244

	
248 245
  // Read the test digraph
249 246
  Digraph gr;
250 247
  Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), l3(gr), u(gr);
251 248
  Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr), s6(gr);
252 249
  ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
253 250
  Node v, w;
254 251

	
255 252
  std::istringstream input(test_lgf);
256 253
  DigraphReader<Digraph>(gr, input)
257 254
    .arcMap("cost", c)
258 255
    .arcMap("cap", u)
259 256
    .arcMap("low1", l1)
260 257
    .arcMap("low2", l2)
261 258
    .arcMap("low3", l3)
262 259
    .nodeMap("sup1", s1)
263 260
    .nodeMap("sup2", s2)
264 261
    .nodeMap("sup3", s3)
265 262
    .nodeMap("sup4", s4)
266 263
    .nodeMap("sup5", s5)
267 264
    .nodeMap("sup6", s6)
268 265
    .node("source", v)
269 266
    .node("target", w)
270 267
    .run();
271 268
  
272 269
  // Build a test digraph for testing negative costs
273 270
  Digraph ngr;
274 271
  Node n1 = ngr.addNode();
275 272
  Node n2 = ngr.addNode();
276 273
  Node n3 = ngr.addNode();
277 274
  Node n4 = ngr.addNode();
278 275
  Node n5 = ngr.addNode();
279 276
  Node n6 = ngr.addNode();
280 277
  Node n7 = ngr.addNode();
281 278
  
282 279
  Arc a1 = ngr.addArc(n1, n2);
283 280
  Arc a2 = ngr.addArc(n1, n3);
284 281
  Arc a3 = ngr.addArc(n2, n4);
285 282
  Arc a4 = ngr.addArc(n3, n4);
286 283
  Arc a5 = ngr.addArc(n3, n2);
287 284
  Arc a6 = ngr.addArc(n5, n3);
288 285
  Arc a7 = ngr.addArc(n5, n6);
289 286
  Arc a8 = ngr.addArc(n6, n7);
290 287
  Arc a9 = ngr.addArc(n7, n5);
291 288
  
292 289
  Digraph::ArcMap<int> nc(ngr), nl1(ngr, 0), nl2(ngr, 0);
293 290
  ConstMap<Arc, int> nu1(std::numeric_limits<int>::max()), nu2(5000);
294 291
  Digraph::NodeMap<int> ns(ngr, 0);
295 292
  
296 293
  nl2[a7] =  1000;
297 294
  nl2[a8] = -1000;
298 295
  
299 296
  ns[n1] =  100;
300 297
  ns[n4] = -100;
301 298
  
302 299
  nc[a1] =  100;
303 300
  nc[a2] =   30;
304 301
  nc[a3] =   20;
305 302
  nc[a4] =   80;
306 303
  nc[a5] =   50;
307 304
  nc[a6] =   10;
308 305
  nc[a7] =   80;
309 306
  nc[a8] =   30;
310 307
  nc[a9] = -120;
311 308

	
312 309
  // A. Test NetworkSimplex with the default pivot rule
313 310
  {
314 311
    NetworkSimplex<Digraph> mcf(gr);
315 312

	
316 313
    // Check the equality form
317 314
    mcf.upperMap(u).costMap(c);
318 315
    checkMcf(mcf, mcf.supplyMap(s1).run(),
319 316
             gr, l1, u, c, s1, mcf.OPTIMAL, true,   5240, "#A1");
320 317
    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
321 318
             gr, l1, u, c, s2, mcf.OPTIMAL, true,   7620, "#A2");
322 319
    mcf.lowerMap(l2);
323 320
    checkMcf(mcf, mcf.supplyMap(s1).run(),
324 321
             gr, l2, u, c, s1, mcf.OPTIMAL, true,   5970, "#A3");
325 322
    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
326 323
             gr, l2, u, c, s2, mcf.OPTIMAL, true,   8010, "#A4");
327 324
    mcf.reset();
328 325
    checkMcf(mcf, mcf.supplyMap(s1).run(),
329 326
             gr, l1, cu, cc, s1, mcf.OPTIMAL, true,   74, "#A5");
330 327
    checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
331 328
             gr, l2, cu, cc, s2, mcf.OPTIMAL, true,   94, "#A6");
332 329
    mcf.reset();
333 330
    checkMcf(mcf, mcf.run(),
334 331
             gr, l1, cu, cc, s3, mcf.OPTIMAL, true,    0, "#A7");
335 332
    checkMcf(mcf, mcf.lowerMap(l2).upperMap(u).run(),
336 333
             gr, l2, u, cc, s3, mcf.INFEASIBLE, false, 0, "#A8");
337 334
    mcf.reset().lowerMap(l3).upperMap(u).costMap(c).supplyMap(s4);
338 335
    checkMcf(mcf, mcf.run(),
339 336
             gr, l3, u, c, s4, mcf.OPTIMAL, true,   6360, "#A9");
340 337

	
341 338
    // Check the GEQ form
342 339
    mcf.reset().upperMap(u).costMap(c).supplyMap(s5);
343 340
    checkMcf(mcf, mcf.run(),
344 341
             gr, l1, u, c, s5, mcf.OPTIMAL, true,   3530, "#A10", GEQ);
345 342
    mcf.supplyType(mcf.GEQ);
346 343
    checkMcf(mcf, mcf.lowerMap(l2).run(),
347 344
             gr, l2, u, c, s5, mcf.OPTIMAL, true,   4540, "#A11", GEQ);
348 345
    mcf.supplyType(mcf.CARRY_SUPPLIES).supplyMap(s6);
349 346
    checkMcf(mcf, mcf.run(),
350 347
             gr, l2, u, c, s6, mcf.INFEASIBLE, false,  0, "#A12", GEQ);
351 348

	
352 349
    // Check the LEQ form
353 350
    mcf.reset().supplyType(mcf.LEQ);
354 351
    mcf.upperMap(u).costMap(c).supplyMap(s6);
355 352
    checkMcf(mcf, mcf.run(),
356 353
             gr, l1, u, c, s6, mcf.OPTIMAL, true,   5080, "#A13", LEQ);
357 354
    checkMcf(mcf, mcf.lowerMap(l2).run(),
358 355
             gr, l2, u, c, s6, mcf.OPTIMAL, true,   5930, "#A14", LEQ);
359 356
    mcf.supplyType(mcf.SATISFY_DEMANDS).supplyMap(s5);
360 357
    checkMcf(mcf, mcf.run(),
361 358
             gr, l2, u, c, s5, mcf.INFEASIBLE, false,  0, "#A15", LEQ);
362 359

	
363 360
    // Check negative costs
364 361
    NetworkSimplex<Digraph> nmcf(ngr);
365 362
    nmcf.lowerMap(nl1).costMap(nc).supplyMap(ns);
366 363
    checkMcf(nmcf, nmcf.run(),
367 364
      ngr, nl1, nu1, nc, ns, nmcf.UNBOUNDED, false,    0, "#A16");
368 365
    checkMcf(nmcf, nmcf.upperMap(nu2).run(),
369 366
      ngr, nl1, nu2, nc, ns, nmcf.OPTIMAL, true,  -40000, "#A17");
0 comments (0 inline)