gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Small improvements in NS pivot rules (#298)
0 1 0
default
1 file changed with 47 insertions and 55 deletions:
↑ Collapse diff ↑
Ignore white space 1536 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_algs
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_algs
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 75
    /// The type of the flow amounts, capacity bounds and supply values
76 76
    typedef V Value;
77 77
    /// The type of the arc costs
78 78
    typedef C Cost;
79 79

	
80 80
  public:
81 81

	
82 82
    /// \brief Problem type constants for the \c run() function.
83 83
    ///
84 84
    /// Enum type containing the problem type constants that can be
85 85
    /// returned by the \ref run() function of the algorithm.
86 86
    enum ProblemType {
87 87
      /// The problem has no feasible solution (flow).
88 88
      INFEASIBLE,
89 89
      /// The problem has optimal solution (i.e. it is feasible and
90 90
      /// bounded), and the algorithm has found optimal flow and node
91 91
      /// potentials (primal and dual solutions).
92 92
      OPTIMAL,
93 93
      /// The objective function of the problem is unbounded, i.e.
94 94
      /// there is a directed cycle having negative total cost and
95 95
      /// infinite upper bound.
96 96
      UNBOUNDED
97 97
    };
98 98
    
99 99
    /// \brief Constants for selecting the type of the supply constraints.
100 100
    ///
101 101
    /// Enum type containing constants for selecting the supply type,
102 102
    /// i.e. the direction of the inequalities in the supply/demand
103 103
    /// constraints of the \ref min_cost_flow "minimum cost flow problem".
104 104
    ///
105 105
    /// The default supply type is \c GEQ, the \c LEQ type can be
106 106
    /// selected using \ref supplyType().
107 107
    /// The equality form is a special case of both supply types.
108 108
    enum SupplyType {
109 109
      /// This option means that there are <em>"greater or equal"</em>
110 110
      /// supply/demand constraints in the definition of the problem.
111 111
      GEQ,
112 112
      /// This option means that there are <em>"less or equal"</em>
113 113
      /// supply/demand constraints in the definition of the problem.
114 114
      LEQ
115 115
    };
116 116
    
117 117
    /// \brief Constants for selecting the pivot rule.
118 118
    ///
119 119
    /// Enum type containing constants for selecting the pivot rule for
120 120
    /// the \ref run() function.
121 121
    ///
122 122
    /// \ref NetworkSimplex provides five different pivot rule
123 123
    /// implementations that significantly affect the running time
124 124
    /// of the algorithm.
125 125
    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
126 126
    /// proved to be the most efficient and the most robust on various
127 127
    /// test inputs according to our benchmark tests.
128 128
    /// However another pivot rule can be selected using the \ref run()
129 129
    /// function with the proper parameter.
130 130
    enum PivotRule {
131 131

	
132 132
      /// The First Eligible pivot rule.
133 133
      /// The next eligible arc is selected in a wraparound fashion
134 134
      /// in every iteration.
135 135
      FIRST_ELIGIBLE,
136 136

	
137 137
      /// The Best Eligible pivot rule.
138 138
      /// The best eligible arc is selected in every iteration.
139 139
      BEST_ELIGIBLE,
140 140

	
141 141
      /// The Block Search pivot rule.
142 142
      /// A specified number of arcs are examined in every iteration
143 143
      /// in a wraparound fashion and the best eligible arc is selected
144 144
      /// from this block.
145 145
      BLOCK_SEARCH,
146 146

	
147 147
      /// The Candidate List pivot rule.
148 148
      /// In a major iteration a candidate list is built from eligible arcs
149 149
      /// in a wraparound fashion and in the following minor iterations
150 150
      /// the best eligible arc is selected from this list.
151 151
      CANDIDATE_LIST,
152 152

	
153 153
      /// The Altering Candidate List pivot rule.
154 154
      /// It is a modified version of the Candidate List method.
155 155
      /// It keeps only the several best eligible arcs from the former
156 156
      /// candidate list and extends this list in every iteration.
157 157
      ALTERING_LIST
158 158
    };
159 159
    
160 160
  private:
161 161

	
162 162
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
163 163

	
164 164
    typedef std::vector<Arc> ArcVector;
165 165
    typedef std::vector<Node> NodeVector;
166 166
    typedef std::vector<int> IntVector;
167 167
    typedef std::vector<bool> BoolVector;
168 168
    typedef std::vector<Value> ValueVector;
169 169
    typedef std::vector<Cost> CostVector;
170 170

	
171 171
    // State constants for arcs
172 172
    enum ArcStateEnum {
173 173
      STATE_UPPER = -1,
174 174
      STATE_TREE  =  0,
175 175
      STATE_LOWER =  1
176 176
    };
177 177

	
178 178
  private:
179 179

	
180 180
    // Data related to the underlying digraph
181 181
    const GR &_graph;
182 182
    int _node_num;
183 183
    int _arc_num;
184 184
    int _all_arc_num;
185 185
    int _search_arc_num;
186 186

	
187 187
    // Parameters of the problem
188 188
    bool _have_lower;
189 189
    SupplyType _stype;
190 190
    Value _sum_supply;
191 191

	
192 192
    // Data structures for storing the digraph
193 193
    IntNodeMap _node_id;
194 194
    IntArcMap _arc_id;
195 195
    IntVector _source;
196 196
    IntVector _target;
197 197

	
198 198
    // Node and arc data
199 199
    ValueVector _lower;
200 200
    ValueVector _upper;
201 201
    ValueVector _cap;
202 202
    CostVector _cost;
203 203
    ValueVector _supply;
204 204
    ValueVector _flow;
205 205
    CostVector _pi;
206 206

	
207 207
    // Data for storing the spanning tree structure
208 208
    IntVector _parent;
209 209
    IntVector _pred;
210 210
    IntVector _thread;
211 211
    IntVector _rev_thread;
212 212
    IntVector _succ_num;
213 213
    IntVector _last_succ;
214 214
    IntVector _dirty_revs;
215 215
    BoolVector _forward;
216 216
    IntVector _state;
217 217
    int _root;
218 218

	
219 219
    // Temporary data used in the current pivot iteration
220 220
    int in_arc, join, u_in, v_in, u_out, v_out;
221 221
    int first, second, right, last;
222 222
    int stem, par_stem, new_stem;
223 223
    Value delta;
224 224

	
225 225
  public:
226 226
  
227 227
    /// \brief Constant for infinite upper bounds (capacities).
228 228
    ///
229 229
    /// Constant for infinite upper bounds (capacities).
230 230
    /// It is \c std::numeric_limits<Value>::infinity() if available,
231 231
    /// \c std::numeric_limits<Value>::max() otherwise.
232 232
    const Value INF;
233 233

	
234 234
  private:
235 235

	
236 236
    // Implementation of the First Eligible pivot rule
237 237
    class FirstEligiblePivotRule
238 238
    {
239 239
    private:
240 240

	
241 241
      // References to the NetworkSimplex class
242 242
      const IntVector  &_source;
243 243
      const IntVector  &_target;
244 244
      const CostVector &_cost;
245 245
      const IntVector  &_state;
246 246
      const CostVector &_pi;
247 247
      int &_in_arc;
248 248
      int _search_arc_num;
249 249

	
250 250
      // Pivot rule data
251 251
      int _next_arc;
252 252

	
253 253
    public:
254 254

	
255 255
      // Constructor
256 256
      FirstEligiblePivotRule(NetworkSimplex &ns) :
257 257
        _source(ns._source), _target(ns._target),
258 258
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
259 259
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
260 260
        _next_arc(0)
261 261
      {}
262 262

	
263 263
      // Find next entering arc
264 264
      bool findEnteringArc() {
265 265
        Cost c;
266 266
        for (int e = _next_arc; e < _search_arc_num; ++e) {
267 267
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
268 268
          if (c < 0) {
269 269
            _in_arc = e;
270 270
            _next_arc = e + 1;
271 271
            return true;
272 272
          }
273 273
        }
274 274
        for (int e = 0; e < _next_arc; ++e) {
275 275
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
276 276
          if (c < 0) {
277 277
            _in_arc = e;
278 278
            _next_arc = e + 1;
279 279
            return true;
280 280
          }
281 281
        }
282 282
        return false;
283 283
      }
284 284

	
285 285
    }; //class FirstEligiblePivotRule
286 286

	
287 287

	
288 288
    // Implementation of the Best Eligible pivot rule
289 289
    class BestEligiblePivotRule
290 290
    {
291 291
    private:
292 292

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

	
302 302
    public:
303 303

	
304 304
      // Constructor
305 305
      BestEligiblePivotRule(NetworkSimplex &ns) :
306 306
        _source(ns._source), _target(ns._target),
307 307
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
308 308
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num)
309 309
      {}
310 310

	
311 311
      // Find next entering arc
312 312
      bool findEnteringArc() {
313 313
        Cost c, min = 0;
314 314
        for (int e = 0; e < _search_arc_num; ++e) {
315 315
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
316 316
          if (c < min) {
317 317
            min = c;
318 318
            _in_arc = e;
319 319
          }
320 320
        }
321 321
        return min < 0;
322 322
      }
323 323

	
324 324
    }; //class BestEligiblePivotRule
325 325

	
326 326

	
327 327
    // Implementation of the Block Search pivot rule
328 328
    class BlockSearchPivotRule
329 329
    {
330 330
    private:
331 331

	
332 332
      // References to the NetworkSimplex class
333 333
      const IntVector  &_source;
334 334
      const IntVector  &_target;
335 335
      const CostVector &_cost;
336 336
      const IntVector  &_state;
337 337
      const CostVector &_pi;
338 338
      int &_in_arc;
339 339
      int _search_arc_num;
340 340

	
341 341
      // Pivot rule data
342 342
      int _block_size;
343 343
      int _next_arc;
344 344

	
345 345
    public:
346 346

	
347 347
      // Constructor
348 348
      BlockSearchPivotRule(NetworkSimplex &ns) :
349 349
        _source(ns._source), _target(ns._target),
350 350
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
351 351
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
352 352
        _next_arc(0)
353 353
      {
354 354
        // The main parameters of the pivot rule
355 355
        const double BLOCK_SIZE_FACTOR = 0.5;
356 356
        const int MIN_BLOCK_SIZE = 10;
357 357

	
358 358
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
359 359
                                    std::sqrt(double(_search_arc_num))),
360 360
                                MIN_BLOCK_SIZE );
361 361
      }
362 362

	
363 363
      // Find next entering arc
364 364
      bool findEnteringArc() {
365 365
        Cost c, min = 0;
366 366
        int cnt = _block_size;
367
        int e, min_arc = _next_arc;
367
        int e;
368 368
        for (e = _next_arc; e < _search_arc_num; ++e) {
369 369
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
370 370
          if (c < min) {
371 371
            min = c;
372
            min_arc = e;
372
            _in_arc = e;
373 373
          }
374 374
          if (--cnt == 0) {
375
            if (min < 0) break;
375
            if (min < 0) goto search_end;
376 376
            cnt = _block_size;
377 377
          }
378 378
        }
379
        if (min == 0 || cnt > 0) {
380
          for (e = 0; e < _next_arc; ++e) {
381
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
382
            if (c < min) {
383
              min = c;
384
              min_arc = e;
385
            }
386
            if (--cnt == 0) {
387
              if (min < 0) break;
388
              cnt = _block_size;
389
            }
379
        for (e = 0; e < _next_arc; ++e) {
380
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
381
          if (c < min) {
382
            min = c;
383
            _in_arc = e;
384
          }
385
          if (--cnt == 0) {
386
            if (min < 0) goto search_end;
387
            cnt = _block_size;
390 388
          }
391 389
        }
392 390
        if (min >= 0) return false;
393
        _in_arc = min_arc;
391

	
392
      search_end:
394 393
        _next_arc = e;
395 394
        return true;
396 395
      }
397 396

	
398 397
    }; //class BlockSearchPivotRule
399 398

	
400 399

	
401 400
    // Implementation of the Candidate List pivot rule
402 401
    class CandidateListPivotRule
403 402
    {
404 403
    private:
405 404

	
406 405
      // References to the NetworkSimplex class
407 406
      const IntVector  &_source;
408 407
      const IntVector  &_target;
409 408
      const CostVector &_cost;
410 409
      const IntVector  &_state;
411 410
      const CostVector &_pi;
412 411
      int &_in_arc;
413 412
      int _search_arc_num;
414 413

	
415 414
      // Pivot rule data
416 415
      IntVector _candidates;
417 416
      int _list_length, _minor_limit;
418 417
      int _curr_length, _minor_count;
419 418
      int _next_arc;
420 419

	
421 420
    public:
422 421

	
423 422
      /// Constructor
424 423
      CandidateListPivotRule(NetworkSimplex &ns) :
425 424
        _source(ns._source), _target(ns._target),
426 425
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
427 426
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
428 427
        _next_arc(0)
429 428
      {
430 429
        // The main parameters of the pivot rule
431
        const double LIST_LENGTH_FACTOR = 1.0;
430
        const double LIST_LENGTH_FACTOR = 0.25;
432 431
        const int MIN_LIST_LENGTH = 10;
433 432
        const double MINOR_LIMIT_FACTOR = 0.1;
434 433
        const int MIN_MINOR_LIMIT = 3;
435 434

	
436 435
        _list_length = std::max( int(LIST_LENGTH_FACTOR *
437 436
                                     std::sqrt(double(_search_arc_num))),
438 437
                                 MIN_LIST_LENGTH );
439 438
        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
440 439
                                 MIN_MINOR_LIMIT );
441 440
        _curr_length = _minor_count = 0;
442 441
        _candidates.resize(_list_length);
443 442
      }
444 443

	
445 444
      /// Find next entering arc
446 445
      bool findEnteringArc() {
447 446
        Cost min, c;
448
        int e, min_arc = _next_arc;
447
        int e;
449 448
        if (_curr_length > 0 && _minor_count < _minor_limit) {
450 449
          // Minor iteration: select the best eligible arc from the
451 450
          // current candidate list
452 451
          ++_minor_count;
453 452
          min = 0;
454 453
          for (int i = 0; i < _curr_length; ++i) {
455 454
            e = _candidates[i];
456 455
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
457 456
            if (c < min) {
458 457
              min = c;
459
              min_arc = e;
458
              _in_arc = e;
460 459
            }
461
            if (c >= 0) {
460
            else if (c >= 0) {
462 461
              _candidates[i--] = _candidates[--_curr_length];
463 462
            }
464 463
          }
465
          if (min < 0) {
466
            _in_arc = min_arc;
467
            return true;
468
          }
464
          if (min < 0) return true;
469 465
        }
470 466

	
471 467
        // Major iteration: build a new candidate list
472 468
        min = 0;
473 469
        _curr_length = 0;
474 470
        for (e = _next_arc; e < _search_arc_num; ++e) {
475 471
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
476 472
          if (c < 0) {
477 473
            _candidates[_curr_length++] = e;
478 474
            if (c < min) {
479 475
              min = c;
480
              min_arc = e;
476
              _in_arc = e;
481 477
            }
482
            if (_curr_length == _list_length) break;
478
            if (_curr_length == _list_length) goto search_end;
483 479
          }
484 480
        }
485
        if (_curr_length < _list_length) {
486
          for (e = 0; e < _next_arc; ++e) {
487
            c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
488
            if (c < 0) {
489
              _candidates[_curr_length++] = e;
490
              if (c < min) {
491
                min = c;
492
                min_arc = e;
493
              }
494
              if (_curr_length == _list_length) break;
481
        for (e = 0; e < _next_arc; ++e) {
482
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
483
          if (c < 0) {
484
            _candidates[_curr_length++] = e;
485
            if (c < min) {
486
              min = c;
487
              _in_arc = e;
495 488
            }
489
            if (_curr_length == _list_length) goto search_end;
496 490
          }
497 491
        }
498 492
        if (_curr_length == 0) return false;
493
      
494
      search_end:        
499 495
        _minor_count = 1;
500
        _in_arc = min_arc;
501 496
        _next_arc = e;
502 497
        return true;
503 498
      }
504 499

	
505 500
    }; //class CandidateListPivotRule
506 501

	
507 502

	
508 503
    // Implementation of the Altering Candidate List pivot rule
509 504
    class AlteringListPivotRule
510 505
    {
511 506
    private:
512 507

	
513 508
      // References to the NetworkSimplex class
514 509
      const IntVector  &_source;
515 510
      const IntVector  &_target;
516 511
      const CostVector &_cost;
517 512
      const IntVector  &_state;
518 513
      const CostVector &_pi;
519 514
      int &_in_arc;
520 515
      int _search_arc_num;
521 516

	
522 517
      // Pivot rule data
523 518
      int _block_size, _head_length, _curr_length;
524 519
      int _next_arc;
525 520
      IntVector _candidates;
526 521
      CostVector _cand_cost;
527 522

	
528 523
      // Functor class to compare arcs during sort of the candidate list
529 524
      class SortFunc
530 525
      {
531 526
      private:
532 527
        const CostVector &_map;
533 528
      public:
534 529
        SortFunc(const CostVector &map) : _map(map) {}
535 530
        bool operator()(int left, int right) {
536 531
          return _map[left] > _map[right];
537 532
        }
538 533
      };
539 534

	
540 535
      SortFunc _sort_func;
541 536

	
542 537
    public:
543 538

	
544 539
      // Constructor
545 540
      AlteringListPivotRule(NetworkSimplex &ns) :
546 541
        _source(ns._source), _target(ns._target),
547 542
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
548 543
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
549 544
        _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
550 545
      {
551 546
        // The main parameters of the pivot rule
552
        const double BLOCK_SIZE_FACTOR = 1.5;
547
        const double BLOCK_SIZE_FACTOR = 1.0;
553 548
        const int MIN_BLOCK_SIZE = 10;
554 549
        const double HEAD_LENGTH_FACTOR = 0.1;
555 550
        const int MIN_HEAD_LENGTH = 3;
556 551

	
557 552
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
558 553
                                    std::sqrt(double(_search_arc_num))),
559 554
                                MIN_BLOCK_SIZE );
560 555
        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
561 556
                                 MIN_HEAD_LENGTH );
562 557
        _candidates.resize(_head_length + _block_size);
563 558
        _curr_length = 0;
564 559
      }
565 560

	
566 561
      // Find next entering arc
567 562
      bool findEnteringArc() {
568 563
        // Check the current candidate list
569 564
        int e;
570 565
        for (int i = 0; i < _curr_length; ++i) {
571 566
          e = _candidates[i];
572 567
          _cand_cost[e] = _state[e] *
573 568
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
574 569
          if (_cand_cost[e] >= 0) {
575 570
            _candidates[i--] = _candidates[--_curr_length];
576 571
          }
577 572
        }
578 573

	
579 574
        // Extend the list
580 575
        int cnt = _block_size;
581
        int last_arc = 0;
582 576
        int limit = _head_length;
583 577

	
584
        for (int e = _next_arc; e < _search_arc_num; ++e) {
578
        for (e = _next_arc; e < _search_arc_num; ++e) {
585 579
          _cand_cost[e] = _state[e] *
586 580
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
587 581
          if (_cand_cost[e] < 0) {
588 582
            _candidates[_curr_length++] = e;
589
            last_arc = e;
590 583
          }
591 584
          if (--cnt == 0) {
592
            if (_curr_length > limit) break;
585
            if (_curr_length > limit) goto search_end;
593 586
            limit = 0;
594 587
            cnt = _block_size;
595 588
          }
596 589
        }
597
        if (_curr_length <= limit) {
598
          for (int e = 0; e < _next_arc; ++e) {
599
            _cand_cost[e] = _state[e] *
600
              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
601
            if (_cand_cost[e] < 0) {
602
              _candidates[_curr_length++] = e;
603
              last_arc = e;
604
            }
605
            if (--cnt == 0) {
606
              if (_curr_length > limit) break;
607
              limit = 0;
608
              cnt = _block_size;
609
            }
590
        for (e = 0; e < _next_arc; ++e) {
591
          _cand_cost[e] = _state[e] *
592
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
593
          if (_cand_cost[e] < 0) {
594
            _candidates[_curr_length++] = e;
595
          }
596
          if (--cnt == 0) {
597
            if (_curr_length > limit) goto search_end;
598
            limit = 0;
599
            cnt = _block_size;
610 600
          }
611 601
        }
612 602
        if (_curr_length == 0) return false;
613
        _next_arc = last_arc + 1;
603
        
604
      search_end:
614 605

	
615 606
        // Make heap of the candidate list (approximating a partial sort)
616 607
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
617 608
                   _sort_func );
618 609

	
619 610
        // Pop the first element of the heap
620 611
        _in_arc = _candidates[0];
612
        _next_arc = e;
621 613
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
622 614
                  _sort_func );
623 615
        _curr_length = std::min(_head_length, _curr_length - 1);
624 616
        return true;
625 617
      }
626 618

	
627 619
    }; //class AlteringListPivotRule
628 620

	
629 621
  public:
630 622

	
631 623
    /// \brief Constructor.
632 624
    ///
633 625
    /// The constructor of the class.
634 626
    ///
635 627
    /// \param graph The digraph the algorithm runs on.
636 628
    NetworkSimplex(const GR& graph) :
637 629
      _graph(graph), _node_id(graph), _arc_id(graph),
638 630
      INF(std::numeric_limits<Value>::has_infinity ?
639 631
          std::numeric_limits<Value>::infinity() :
640 632
          std::numeric_limits<Value>::max())
641 633
    {
642 634
      // Check the value types
643 635
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
644 636
        "The flow type of NetworkSimplex must be signed");
645 637
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
646 638
        "The cost type of NetworkSimplex must be signed");
647 639
        
648 640
      // Resize vectors
649 641
      _node_num = countNodes(_graph);
650 642
      _arc_num = countArcs(_graph);
651 643
      int all_node_num = _node_num + 1;
652 644
      int max_arc_num = _arc_num + 2 * _node_num;
653 645

	
654 646
      _source.resize(max_arc_num);
655 647
      _target.resize(max_arc_num);
656 648

	
657 649
      _lower.resize(_arc_num);
658 650
      _upper.resize(_arc_num);
659 651
      _cap.resize(max_arc_num);
660 652
      _cost.resize(max_arc_num);
661 653
      _supply.resize(all_node_num);
662 654
      _flow.resize(max_arc_num);
663 655
      _pi.resize(all_node_num);
664 656

	
665 657
      _parent.resize(all_node_num);
666 658
      _pred.resize(all_node_num);
667 659
      _forward.resize(all_node_num);
668 660
      _thread.resize(all_node_num);
669 661
      _rev_thread.resize(all_node_num);
670 662
      _succ_num.resize(all_node_num);
671 663
      _last_succ.resize(all_node_num);
672 664
      _state.resize(max_arc_num);
673 665

	
674 666
      // Copy the graph (store the arcs in a mixed order)
675 667
      int i = 0;
676 668
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
677 669
        _node_id[n] = i;
678 670
      }
679 671
      int k = std::max(int(std::sqrt(double(_arc_num))), 10);
680 672
      i = 0;
681 673
      for (ArcIt a(_graph); a != INVALID; ++a) {
682 674
        _arc_id[a] = i;
683 675
        _source[i] = _node_id[_graph.source(a)];
684 676
        _target[i] = _node_id[_graph.target(a)];
685 677
        if ((i += k) >= _arc_num) i = (i % k) + 1;
686 678
      }
687 679
      
688 680
      // Initialize maps
689 681
      for (int i = 0; i != _node_num; ++i) {
690 682
        _supply[i] = 0;
691 683
      }
692 684
      for (int i = 0; i != _arc_num; ++i) {
693 685
        _lower[i] = 0;
694 686
        _upper[i] = INF;
695 687
        _cost[i] = 1;
696 688
      }
697 689
      _have_lower = false;
698 690
      _stype = GEQ;
699 691
    }
700 692

	
701 693
    /// \name Parameters
702 694
    /// The parameters of the algorithm can be specified using these
703 695
    /// functions.
704 696

	
705 697
    /// @{
706 698

	
707 699
    /// \brief Set the lower bounds on the arcs.
708 700
    ///
709 701
    /// This function sets the lower bounds on the arcs.
710 702
    /// If it is not used before calling \ref run(), the lower bounds
711 703
    /// will be set to zero on all arcs.
712 704
    ///
713 705
    /// \param map An arc map storing the lower bounds.
714 706
    /// Its \c Value type must be convertible to the \c Value type
715 707
    /// of the algorithm.
716 708
    ///
717 709
    /// \return <tt>(*this)</tt>
718 710
    template <typename LowerMap>
719 711
    NetworkSimplex& lowerMap(const LowerMap& map) {
720 712
      _have_lower = true;
721 713
      for (ArcIt a(_graph); a != INVALID; ++a) {
722 714
        _lower[_arc_id[a]] = map[a];
723 715
      }
724 716
      return *this;
725 717
    }
726 718

	
727 719
    /// \brief Set the upper bounds (capacities) on the arcs.
728 720
    ///
729 721
    /// This function sets the upper bounds (capacities) on the arcs.
730 722
    /// If it is not used before calling \ref run(), the upper bounds
731 723
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
732 724
    /// unbounded from above on each arc).
733 725
    ///
734 726
    /// \param map An arc map storing the upper bounds.
735 727
    /// Its \c Value type must be convertible to the \c Value type
736 728
    /// of the algorithm.
737 729
    ///
738 730
    /// \return <tt>(*this)</tt>
739 731
    template<typename UpperMap>
740 732
    NetworkSimplex& upperMap(const UpperMap& map) {
741 733
      for (ArcIt a(_graph); a != INVALID; ++a) {
742 734
        _upper[_arc_id[a]] = map[a];
743 735
      }
744 736
      return *this;
745 737
    }
746 738

	
747 739
    /// \brief Set the costs of the arcs.
748 740
    ///
749 741
    /// This function sets the costs of the arcs.
750 742
    /// If it is not used before calling \ref run(), the costs
751 743
    /// will be set to \c 1 on all arcs.
752 744
    ///
753 745
    /// \param map An arc map storing the costs.
754 746
    /// Its \c Value type must be convertible to the \c Cost type
755 747
    /// of the algorithm.
756 748
    ///
757 749
    /// \return <tt>(*this)</tt>
758 750
    template<typename CostMap>
759 751
    NetworkSimplex& costMap(const CostMap& map) {
760 752
      for (ArcIt a(_graph); a != INVALID; ++a) {
761 753
        _cost[_arc_id[a]] = map[a];
762 754
      }
763 755
      return *this;
764 756
    }
765 757

	
766 758
    /// \brief Set the supply values of the nodes.
767 759
    ///
768 760
    /// This function sets the supply values of the nodes.
769 761
    /// If neither this function nor \ref stSupply() is used before
770 762
    /// calling \ref run(), the supply of each node will be set to zero.
771 763
    /// (It makes sense only if non-zero lower bounds are given.)
772 764
    ///
773 765
    /// \param map A node map storing the supply values.
774 766
    /// Its \c Value type must be convertible to the \c Value type
775 767
    /// of the algorithm.
776 768
    ///
777 769
    /// \return <tt>(*this)</tt>
778 770
    template<typename SupplyMap>
779 771
    NetworkSimplex& supplyMap(const SupplyMap& map) {
780 772
      for (NodeIt n(_graph); n != INVALID; ++n) {
781 773
        _supply[_node_id[n]] = map[n];
782 774
      }
783 775
      return *this;
784 776
    }
785 777

	
786 778
    /// \brief Set single source and target nodes and a supply value.
787 779
    ///
788 780
    /// This function sets a single source node and a single target node
789 781
    /// and the required flow value.
790 782
    /// If neither this function nor \ref supplyMap() is used before
791 783
    /// calling \ref run(), the supply of each node will be set to zero.
792 784
    /// (It makes sense only if non-zero lower bounds are given.)
793 785
    ///
794 786
    /// Using this function has the same effect as using \ref supplyMap()
795 787
    /// with such a map in which \c k is assigned to \c s, \c -k is
796 788
    /// assigned to \c t and all other nodes have zero supply value.
797 789
    ///
798 790
    /// \param s The source node.
799 791
    /// \param t The target node.
800 792
    /// \param k The required amount of flow from node \c s to node \c t
801 793
    /// (i.e. the supply of \c s and the demand of \c t).
802 794
    ///
803 795
    /// \return <tt>(*this)</tt>
804 796
    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
805 797
      for (int i = 0; i != _node_num; ++i) {
806 798
        _supply[i] = 0;
807 799
      }
808 800
      _supply[_node_id[s]] =  k;
809 801
      _supply[_node_id[t]] = -k;
810 802
      return *this;
811 803
    }
812 804
    
813 805
    /// \brief Set the type of the supply constraints.
814 806
    ///
815 807
    /// This function sets the type of the supply/demand constraints.
816 808
    /// If it is not used before calling \ref run(), the \ref GEQ supply
817 809
    /// type will be used.
818 810
    ///
819 811
    /// For more information see \ref SupplyType.
820 812
    ///
821 813
    /// \return <tt>(*this)</tt>
822 814
    NetworkSimplex& supplyType(SupplyType supply_type) {
823 815
      _stype = supply_type;
824 816
      return *this;
825 817
    }
826 818

	
827 819
    /// @}
828 820

	
829 821
    /// \name Execution Control
830 822
    /// The algorithm can be executed using \ref run().
831 823

	
832 824
    /// @{
833 825

	
834 826
    /// \brief Run the algorithm.
835 827
    ///
836 828
    /// This function runs the algorithm.
837 829
    /// The paramters can be specified using functions \ref lowerMap(),
838 830
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(), 
839 831
    /// \ref supplyType().
840 832
    /// For example,
841 833
    /// \code
842 834
    ///   NetworkSimplex<ListDigraph> ns(graph);
843 835
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
844 836
    ///     .supplyMap(sup).run();
845 837
    /// \endcode
846 838
    ///
847 839
    /// This function can be called more than once. All the parameters
848 840
    /// that have been given are kept for the next call, unless
849 841
    /// \ref reset() is called, thus only the modified parameters
850 842
    /// have to be set again. See \ref reset() for examples.
851 843
    /// However the underlying digraph must not be modified after this
852 844
    /// class have been constructed, since it copies and extends the graph.
853 845
    ///
854 846
    /// \param pivot_rule The pivot rule that will be used during the
855 847
    /// algorithm. For more information see \ref PivotRule.
856 848
    ///
857 849
    /// \return \c INFEASIBLE if no feasible flow exists,
858 850
    /// \n \c OPTIMAL if the problem has optimal solution
859 851
    /// (i.e. it is feasible and bounded), and the algorithm has found
860 852
    /// optimal flow and node potentials (primal and dual solutions),
861 853
    /// \n \c UNBOUNDED if the objective function of the problem is
862 854
    /// unbounded, i.e. there is a directed cycle having negative total
863 855
    /// cost and infinite upper bound.
864 856
    ///
865 857
    /// \see ProblemType, PivotRule
866 858
    ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
867 859
      if (!init()) return INFEASIBLE;
868 860
      return start(pivot_rule);
869 861
    }
870 862

	
871 863
    /// \brief Reset all the parameters that have been given before.
872 864
    ///
873 865
    /// This function resets all the paramaters that have been given
874 866
    /// before using functions \ref lowerMap(), \ref upperMap(),
875 867
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
876 868
    ///
877 869
    /// It is useful for multiple run() calls. If this function is not
878 870
    /// used, all the parameters given before are kept for the next
879 871
    /// \ref run() call.
880 872
    /// However the underlying digraph must not be modified after this
881 873
    /// class have been constructed, since it copies and extends the graph.
882 874
    ///
883 875
    /// For example,
884 876
    /// \code
885 877
    ///   NetworkSimplex<ListDigraph> ns(graph);
886 878
    ///
887 879
    ///   // First run
888 880
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
889 881
    ///     .supplyMap(sup).run();
890 882
    ///
891 883
    ///   // Run again with modified cost map (reset() is not called,
892 884
    ///   // so only the cost map have to be set again)
893 885
    ///   cost[e] += 100;
894 886
    ///   ns.costMap(cost).run();
895 887
    ///
896 888
    ///   // Run again from scratch using reset()
897 889
    ///   // (the lower bounds will be set to zero on all arcs)
898 890
    ///   ns.reset();
899 891
    ///   ns.upperMap(capacity).costMap(cost)
900 892
    ///     .supplyMap(sup).run();
901 893
    /// \endcode
902 894
    ///
903 895
    /// \return <tt>(*this)</tt>
904 896
    NetworkSimplex& reset() {
905 897
      for (int i = 0; i != _node_num; ++i) {
906 898
        _supply[i] = 0;
907 899
      }
908 900
      for (int i = 0; i != _arc_num; ++i) {
909 901
        _lower[i] = 0;
910 902
        _upper[i] = INF;
911 903
        _cost[i] = 1;
912 904
      }
913 905
      _have_lower = false;
914 906
      _stype = GEQ;
915 907
      return *this;
916 908
    }
917 909

	
918 910
    /// @}
919 911

	
920 912
    /// \name Query Functions
921 913
    /// The results of the algorithm can be obtained using these
922 914
    /// functions.\n
923 915
    /// The \ref run() function must be called before using them.
924 916

	
925 917
    /// @{
926 918

	
927 919
    /// \brief Return the total cost of the found flow.
928 920
    ///
929 921
    /// This function returns the total cost of the found flow.
930 922
    /// Its complexity is O(e).
931 923
    ///
932 924
    /// \note The return type of the function can be specified as a
933 925
    /// template parameter. For example,
934 926
    /// \code
935 927
    ///   ns.totalCost<double>();
936 928
    /// \endcode
937 929
    /// It is useful if the total cost cannot be stored in the \c Cost
938 930
    /// type of the algorithm, which is the default return type of the
939 931
    /// function.
940 932
    ///
941 933
    /// \pre \ref run() must be called before using this function.
942 934
    template <typename Number>
943 935
    Number totalCost() const {
944 936
      Number c = 0;
945 937
      for (ArcIt a(_graph); a != INVALID; ++a) {
946 938
        int i = _arc_id[a];
947 939
        c += Number(_flow[i]) * Number(_cost[i]);
948 940
      }
949 941
      return c;
950 942
    }
951 943

	
952 944
#ifndef DOXYGEN
953 945
    Cost totalCost() const {
954 946
      return totalCost<Cost>();
955 947
    }
956 948
#endif
957 949

	
958 950
    /// \brief Return the flow on the given arc.
959 951
    ///
960 952
    /// This function returns the flow on the given arc.
961 953
    ///
962 954
    /// \pre \ref run() must be called before using this function.
963 955
    Value flow(const Arc& a) const {
964 956
      return _flow[_arc_id[a]];
965 957
    }
966 958

	
967 959
    /// \brief Return the flow map (the primal solution).
968 960
    ///
969 961
    /// This function copies the flow value on each arc into the given
970 962
    /// map. The \c Value type of the algorithm must be convertible to
971 963
    /// the \c Value type of the map.
972 964
    ///
973 965
    /// \pre \ref run() must be called before using this function.
974 966
    template <typename FlowMap>
975 967
    void flowMap(FlowMap &map) const {
976 968
      for (ArcIt a(_graph); a != INVALID; ++a) {
977 969
        map.set(a, _flow[_arc_id[a]]);
978 970
      }
979 971
    }
980 972

	
981 973
    /// \brief Return the potential (dual value) of the given node.
982 974
    ///
983 975
    /// This function returns the potential (dual value) of the
984 976
    /// given node.
985 977
    ///
986 978
    /// \pre \ref run() must be called before using this function.
987 979
    Cost potential(const Node& n) const {
988 980
      return _pi[_node_id[n]];
989 981
    }
990 982

	
991 983
    /// \brief Return the potential map (the dual solution).
992 984
    ///
993 985
    /// This function copies the potential (dual value) of each node
994 986
    /// into the given map.
995 987
    /// The \c Cost type of the algorithm must be convertible to the
996 988
    /// \c Value type of the map.
997 989
    ///
998 990
    /// \pre \ref run() must be called before using this function.
999 991
    template <typename PotentialMap>
1000 992
    void potentialMap(PotentialMap &map) const {
1001 993
      for (NodeIt n(_graph); n != INVALID; ++n) {
1002 994
        map.set(n, _pi[_node_id[n]]);
1003 995
      }
1004 996
    }
1005 997

	
1006 998
    /// @}
1007 999

	
1008 1000
  private:
1009 1001

	
1010 1002
    // Initialize internal data structures
1011 1003
    bool init() {
1012 1004
      if (_node_num == 0) return false;
1013 1005

	
1014 1006
      // Check the sum of supply values
1015 1007
      _sum_supply = 0;
1016 1008
      for (int i = 0; i != _node_num; ++i) {
1017 1009
        _sum_supply += _supply[i];
1018 1010
      }
1019 1011
      if ( !((_stype == GEQ && _sum_supply <= 0) ||
1020 1012
             (_stype == LEQ && _sum_supply >= 0)) ) return false;
1021 1013

	
1022 1014
      // Remove non-zero lower bounds
1023 1015
      if (_have_lower) {
1024 1016
        for (int i = 0; i != _arc_num; ++i) {
1025 1017
          Value c = _lower[i];
1026 1018
          if (c >= 0) {
1027 1019
            _cap[i] = _upper[i] < INF ? _upper[i] - c : INF;
1028 1020
          } else {
1029 1021
            _cap[i] = _upper[i] < INF + c ? _upper[i] - c : INF;
1030 1022
          }
1031 1023
          _supply[_source[i]] -= c;
1032 1024
          _supply[_target[i]] += c;
1033 1025
        }
1034 1026
      } else {
1035 1027
        for (int i = 0; i != _arc_num; ++i) {
1036 1028
          _cap[i] = _upper[i];
1037 1029
        }
1038 1030
      }
1039 1031

	
1040 1032
      // Initialize artifical cost
1041 1033
      Cost ART_COST;
1042 1034
      if (std::numeric_limits<Cost>::is_exact) {
1043 1035
        ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
1044 1036
      } else {
1045 1037
        ART_COST = std::numeric_limits<Cost>::min();
1046 1038
        for (int i = 0; i != _arc_num; ++i) {
1047 1039
          if (_cost[i] > ART_COST) ART_COST = _cost[i];
1048 1040
        }
1049 1041
        ART_COST = (ART_COST + 1) * _node_num;
1050 1042
      }
1051 1043

	
1052 1044
      // Initialize arc maps
1053 1045
      for (int i = 0; i != _arc_num; ++i) {
1054 1046
        _flow[i] = 0;
1055 1047
        _state[i] = STATE_LOWER;
1056 1048
      }
1057 1049
      
1058 1050
      // Set data for the artificial root node
1059 1051
      _root = _node_num;
1060 1052
      _parent[_root] = -1;
1061 1053
      _pred[_root] = -1;
1062 1054
      _thread[_root] = 0;
1063 1055
      _rev_thread[0] = _root;
1064 1056
      _succ_num[_root] = _node_num + 1;
1065 1057
      _last_succ[_root] = _root - 1;
1066 1058
      _supply[_root] = -_sum_supply;
1067 1059
      _pi[_root] = 0;
1068 1060

	
1069 1061
      // Add artificial arcs and initialize the spanning tree data structure
1070 1062
      if (_sum_supply == 0) {
1071 1063
        // EQ supply constraints
1072 1064
        _search_arc_num = _arc_num;
1073 1065
        _all_arc_num = _arc_num + _node_num;
1074 1066
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1075 1067
          _parent[u] = _root;
1076 1068
          _pred[u] = e;
1077 1069
          _thread[u] = u + 1;
1078 1070
          _rev_thread[u + 1] = u;
1079 1071
          _succ_num[u] = 1;
1080 1072
          _last_succ[u] = u;
1081 1073
          _cap[e] = INF;
1082 1074
          _state[e] = STATE_TREE;
1083 1075
          if (_supply[u] >= 0) {
1084 1076
            _forward[u] = true;
1085 1077
            _pi[u] = 0;
1086 1078
            _source[e] = u;
1087 1079
            _target[e] = _root;
1088 1080
            _flow[e] = _supply[u];
1089 1081
            _cost[e] = 0;
1090 1082
          } else {
1091 1083
            _forward[u] = false;
1092 1084
            _pi[u] = ART_COST;
1093 1085
            _source[e] = _root;
1094 1086
            _target[e] = u;
1095 1087
            _flow[e] = -_supply[u];
1096 1088
            _cost[e] = ART_COST;
1097 1089
          }
1098 1090
        }
1099 1091
      }
1100 1092
      else if (_sum_supply > 0) {
1101 1093
        // LEQ supply constraints
1102 1094
        _search_arc_num = _arc_num + _node_num;
1103 1095
        int f = _arc_num + _node_num;
1104 1096
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1105 1097
          _parent[u] = _root;
1106 1098
          _thread[u] = u + 1;
1107 1099
          _rev_thread[u + 1] = u;
1108 1100
          _succ_num[u] = 1;
1109 1101
          _last_succ[u] = u;
1110 1102
          if (_supply[u] >= 0) {
1111 1103
            _forward[u] = true;
1112 1104
            _pi[u] = 0;
1113 1105
            _pred[u] = e;
1114 1106
            _source[e] = u;
1115 1107
            _target[e] = _root;
1116 1108
            _cap[e] = INF;
1117 1109
            _flow[e] = _supply[u];
1118 1110
            _cost[e] = 0;
1119 1111
            _state[e] = STATE_TREE;
1120 1112
          } else {
1121 1113
            _forward[u] = false;
1122 1114
            _pi[u] = ART_COST;
1123 1115
            _pred[u] = f;
1124 1116
            _source[f] = _root;
1125 1117
            _target[f] = u;
1126 1118
            _cap[f] = INF;
1127 1119
            _flow[f] = -_supply[u];
1128 1120
            _cost[f] = ART_COST;
1129 1121
            _state[f] = STATE_TREE;
1130 1122
            _source[e] = u;
1131 1123
            _target[e] = _root;
1132 1124
            _cap[e] = INF;
1133 1125
            _flow[e] = 0;
1134 1126
            _cost[e] = 0;
1135 1127
            _state[e] = STATE_LOWER;
1136 1128
            ++f;
1137 1129
          }
1138 1130
        }
1139 1131
        _all_arc_num = f;
1140 1132
      }
1141 1133
      else {
1142 1134
        // GEQ supply constraints
1143 1135
        _search_arc_num = _arc_num + _node_num;
1144 1136
        int f = _arc_num + _node_num;
1145 1137
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1146 1138
          _parent[u] = _root;
1147 1139
          _thread[u] = u + 1;
1148 1140
          _rev_thread[u + 1] = u;
1149 1141
          _succ_num[u] = 1;
1150 1142
          _last_succ[u] = u;
1151 1143
          if (_supply[u] <= 0) {
1152 1144
            _forward[u] = false;
1153 1145
            _pi[u] = 0;
1154 1146
            _pred[u] = e;
1155 1147
            _source[e] = _root;
1156 1148
            _target[e] = u;
1157 1149
            _cap[e] = INF;
1158 1150
            _flow[e] = -_supply[u];
1159 1151
            _cost[e] = 0;
1160 1152
            _state[e] = STATE_TREE;
1161 1153
          } else {
1162 1154
            _forward[u] = true;
1163 1155
            _pi[u] = -ART_COST;
1164 1156
            _pred[u] = f;
1165 1157
            _source[f] = u;
1166 1158
            _target[f] = _root;
1167 1159
            _cap[f] = INF;
1168 1160
            _flow[f] = _supply[u];
1169 1161
            _state[f] = STATE_TREE;
1170 1162
            _cost[f] = ART_COST;
1171 1163
            _source[e] = _root;
1172 1164
            _target[e] = u;
1173 1165
            _cap[e] = INF;
1174 1166
            _flow[e] = 0;
1175 1167
            _cost[e] = 0;
1176 1168
            _state[e] = STATE_LOWER;
1177 1169
            ++f;
1178 1170
          }
1179 1171
        }
1180 1172
        _all_arc_num = f;
1181 1173
      }
1182 1174

	
1183 1175
      return true;
1184 1176
    }
1185 1177

	
1186 1178
    // Find the join node
1187 1179
    void findJoinNode() {
1188 1180
      int u = _source[in_arc];
1189 1181
      int v = _target[in_arc];
1190 1182
      while (u != v) {
1191 1183
        if (_succ_num[u] < _succ_num[v]) {
1192 1184
          u = _parent[u];
1193 1185
        } else {
1194 1186
          v = _parent[v];
1195 1187
        }
1196 1188
      }
1197 1189
      join = u;
1198 1190
    }
1199 1191

	
1200 1192
    // Find the leaving arc of the cycle and returns true if the
1201 1193
    // leaving arc is not the same as the entering arc
1202 1194
    bool findLeavingArc() {
1203 1195
      // Initialize first and second nodes according to the direction
1204 1196
      // of the cycle
1205 1197
      if (_state[in_arc] == STATE_LOWER) {
1206 1198
        first  = _source[in_arc];
1207 1199
        second = _target[in_arc];
1208 1200
      } else {
1209 1201
        first  = _target[in_arc];
1210 1202
        second = _source[in_arc];
1211 1203
      }
1212 1204
      delta = _cap[in_arc];
1213 1205
      int result = 0;
1214 1206
      Value d;
1215 1207
      int e;
1216 1208

	
1217 1209
      // Search the cycle along the path form the first node to the root
1218 1210
      for (int u = first; u != join; u = _parent[u]) {
1219 1211
        e = _pred[u];
1220 1212
        d = _forward[u] ?
1221 1213
          _flow[e] : (_cap[e] == INF ? INF : _cap[e] - _flow[e]);
1222 1214
        if (d < delta) {
1223 1215
          delta = d;
1224 1216
          u_out = u;
1225 1217
          result = 1;
1226 1218
        }
1227 1219
      }
1228 1220
      // Search the cycle along the path form the second node to the root
1229 1221
      for (int u = second; u != join; u = _parent[u]) {
1230 1222
        e = _pred[u];
1231 1223
        d = _forward[u] ? 
1232 1224
          (_cap[e] == INF ? INF : _cap[e] - _flow[e]) : _flow[e];
1233 1225
        if (d <= delta) {
1234 1226
          delta = d;
1235 1227
          u_out = u;
1236 1228
          result = 2;
1237 1229
        }
1238 1230
      }
1239 1231

	
1240 1232
      if (result == 1) {
1241 1233
        u_in = first;
1242 1234
        v_in = second;
1243 1235
      } else {
1244 1236
        u_in = second;
1245 1237
        v_in = first;
1246 1238
      }
1247 1239
      return result != 0;
1248 1240
    }
1249 1241

	
1250 1242
    // Change _flow and _state vectors
1251 1243
    void changeFlow(bool change) {
1252 1244
      // Augment along the cycle
1253 1245
      if (delta > 0) {
1254 1246
        Value val = _state[in_arc] * delta;
1255 1247
        _flow[in_arc] += val;
1256 1248
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
1257 1249
          _flow[_pred[u]] += _forward[u] ? -val : val;
1258 1250
        }
1259 1251
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
1260 1252
          _flow[_pred[u]] += _forward[u] ? val : -val;
1261 1253
        }
1262 1254
      }
1263 1255
      // Update the state of the entering and leaving arcs
1264 1256
      if (change) {
1265 1257
        _state[in_arc] = STATE_TREE;
1266 1258
        _state[_pred[u_out]] =
1267 1259
          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
1268 1260
      } else {
1269 1261
        _state[in_arc] = -_state[in_arc];
1270 1262
      }
1271 1263
    }
1272 1264

	
1273 1265
    // Update the tree structure
1274 1266
    void updateTreeStructure() {
1275 1267
      int u, w;
1276 1268
      int old_rev_thread = _rev_thread[u_out];
1277 1269
      int old_succ_num = _succ_num[u_out];
1278 1270
      int old_last_succ = _last_succ[u_out];
1279 1271
      v_out = _parent[u_out];
1280 1272

	
1281 1273
      u = _last_succ[u_in];  // the last successor of u_in
1282 1274
      right = _thread[u];    // the node after it
1283 1275

	
1284 1276
      // Handle the case when old_rev_thread equals to v_in
1285 1277
      // (it also means that join and v_out coincide)
1286 1278
      if (old_rev_thread == v_in) {
1287 1279
        last = _thread[_last_succ[u_out]];
1288 1280
      } else {
1289 1281
        last = _thread[v_in];
1290 1282
      }
1291 1283

	
1292 1284
      // Update _thread and _parent along the stem nodes (i.e. the nodes
1293 1285
      // between u_in and u_out, whose parent have to be changed)
1294 1286
      _thread[v_in] = stem = u_in;
1295 1287
      _dirty_revs.clear();
1296 1288
      _dirty_revs.push_back(v_in);
1297 1289
      par_stem = v_in;
1298 1290
      while (stem != u_out) {
1299 1291
        // Insert the next stem node into the thread list
1300 1292
        new_stem = _parent[stem];
1301 1293
        _thread[u] = new_stem;
1302 1294
        _dirty_revs.push_back(u);
1303 1295

	
1304 1296
        // Remove the subtree of stem from the thread list
1305 1297
        w = _rev_thread[stem];
1306 1298
        _thread[w] = right;
1307 1299
        _rev_thread[right] = w;
1308 1300

	
1309 1301
        // Change the parent node and shift stem nodes
1310 1302
        _parent[stem] = par_stem;
1311 1303
        par_stem = stem;
1312 1304
        stem = new_stem;
1313 1305

	
1314 1306
        // Update u and right
1315 1307
        u = _last_succ[stem] == _last_succ[par_stem] ?
1316 1308
          _rev_thread[par_stem] : _last_succ[stem];
1317 1309
        right = _thread[u];
1318 1310
      }
1319 1311
      _parent[u_out] = par_stem;
1320 1312
      _thread[u] = last;
1321 1313
      _rev_thread[last] = u;
1322 1314
      _last_succ[u_out] = u;
1323 1315

	
1324 1316
      // Remove the subtree of u_out from the thread list except for
1325 1317
      // the case when old_rev_thread equals to v_in
1326 1318
      // (it also means that join and v_out coincide)
1327 1319
      if (old_rev_thread != v_in) {
1328 1320
        _thread[old_rev_thread] = right;
1329 1321
        _rev_thread[right] = old_rev_thread;
1330 1322
      }
1331 1323

	
1332 1324
      // Update _rev_thread using the new _thread values
1333 1325
      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
1334 1326
        u = _dirty_revs[i];
1335 1327
        _rev_thread[_thread[u]] = u;
1336 1328
      }
1337 1329

	
1338 1330
      // Update _pred, _forward, _last_succ and _succ_num for the
1339 1331
      // stem nodes from u_out to u_in
1340 1332
      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
1341 1333
      u = u_out;
1342 1334
      while (u != u_in) {
1343 1335
        w = _parent[u];
1344 1336
        _pred[u] = _pred[w];
1345 1337
        _forward[u] = !_forward[w];
1346 1338
        tmp_sc += _succ_num[u] - _succ_num[w];
1347 1339
        _succ_num[u] = tmp_sc;
1348 1340
        _last_succ[w] = tmp_ls;
1349 1341
        u = w;
1350 1342
      }
1351 1343
      _pred[u_in] = in_arc;
1352 1344
      _forward[u_in] = (u_in == _source[in_arc]);
1353 1345
      _succ_num[u_in] = old_succ_num;
1354 1346

	
1355 1347
      // Set limits for updating _last_succ form v_in and v_out
1356 1348
      // towards the root
1357 1349
      int up_limit_in = -1;
1358 1350
      int up_limit_out = -1;
1359 1351
      if (_last_succ[join] == v_in) {
1360 1352
        up_limit_out = join;
1361 1353
      } else {
1362 1354
        up_limit_in = join;
1363 1355
      }
1364 1356

	
1365 1357
      // Update _last_succ from v_in towards the root
1366 1358
      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
1367 1359
           u = _parent[u]) {
1368 1360
        _last_succ[u] = _last_succ[u_out];
1369 1361
      }
1370 1362
      // Update _last_succ from v_out towards the root
1371 1363
      if (join != old_rev_thread && v_in != old_rev_thread) {
1372 1364
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1373 1365
             u = _parent[u]) {
1374 1366
          _last_succ[u] = old_rev_thread;
1375 1367
        }
1376 1368
      } else {
1377 1369
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1378 1370
             u = _parent[u]) {
1379 1371
          _last_succ[u] = _last_succ[u_out];
1380 1372
        }
1381 1373
      }
1382 1374

	
1383 1375
      // Update _succ_num from v_in to join
1384 1376
      for (u = v_in; u != join; u = _parent[u]) {
1385 1377
        _succ_num[u] += old_succ_num;
1386 1378
      }
1387 1379
      // Update _succ_num from v_out to join
1388 1380
      for (u = v_out; u != join; u = _parent[u]) {
0 comments (0 inline)