gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Add a parameter to control arc mixing in NS (#298)
0 1 0
default
1 file changed with 24 insertions and 9 deletions:
↑ Collapse diff ↑
Ignore white space 786432 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 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 372
            _in_arc = e;
373 373
          }
374 374
          if (--cnt == 0) {
375 375
            if (min < 0) goto search_end;
376 376
            cnt = _block_size;
377 377
          }
378 378
        }
379 379
        for (e = 0; e < _next_arc; ++e) {
380 380
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
381 381
          if (c < min) {
382 382
            min = c;
383 383
            _in_arc = e;
384 384
          }
385 385
          if (--cnt == 0) {
386 386
            if (min < 0) goto search_end;
387 387
            cnt = _block_size;
388 388
          }
389 389
        }
390 390
        if (min >= 0) return false;
391 391

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

	
397 397
    }; //class BlockSearchPivotRule
398 398

	
399 399

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

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

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

	
420 420
    public:
421 421

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

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

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

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

	
500 500
    }; //class CandidateListPivotRule
501 501

	
502 502

	
503 503
    // Implementation of the Altering Candidate List pivot rule
504 504
    class AlteringListPivotRule
505 505
    {
506 506
    private:
507 507

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

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

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

	
535 535
      SortFunc _sort_func;
536 536

	
537 537
    public:
538 538

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

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

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

	
574 574
        // Extend the list
575 575
        int cnt = _block_size;
576 576
        int limit = _head_length;
577 577

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

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

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

	
619 619
    }; //class AlteringListPivotRule
620 620

	
621 621
  public:
622 622

	
623 623
    /// \brief Constructor.
624 624
    ///
625 625
    /// The constructor of the class.
626 626
    ///
627 627
    /// \param graph The digraph the algorithm runs on.
628
    NetworkSimplex(const GR& graph) :
628
    /// \param arc_mixing Indicate if the arcs have to be stored in a
629
    /// mixed order in the internal data structure. 
630
    /// In special cases, it could lead to better overall performance,
631
    /// but it is usually slower. Therefore it is disabled by default.
632
    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
629 633
      _graph(graph), _node_id(graph), _arc_id(graph),
630 634
      INF(std::numeric_limits<Value>::has_infinity ?
631 635
          std::numeric_limits<Value>::infinity() :
632 636
          std::numeric_limits<Value>::max())
633 637
    {
634 638
      // Check the value types
635 639
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
636 640
        "The flow type of NetworkSimplex must be signed");
637 641
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
638 642
        "The cost type of NetworkSimplex must be signed");
639 643
        
640 644
      // Resize vectors
641 645
      _node_num = countNodes(_graph);
642 646
      _arc_num = countArcs(_graph);
643 647
      int all_node_num = _node_num + 1;
644 648
      int max_arc_num = _arc_num + 2 * _node_num;
645 649

	
646 650
      _source.resize(max_arc_num);
647 651
      _target.resize(max_arc_num);
648 652

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

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

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

	
693 708
    /// \name Parameters
694 709
    /// The parameters of the algorithm can be specified using these
695 710
    /// functions.
696 711

	
697 712
    /// @{
698 713

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

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

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

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

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

	
819 834
    /// @}
820 835

	
821 836
    /// \name Execution Control
822 837
    /// The algorithm can be executed using \ref run().
823 838

	
824 839
    /// @{
825 840

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

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

	
910 925
    /// @}
911 926

	
912 927
    /// \name Query Functions
913 928
    /// The results of the algorithm can be obtained using these
914 929
    /// functions.\n
915 930
    /// The \ref run() function must be called before using them.
916 931

	
917 932
    /// @{
918 933

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

	
944 959
#ifndef DOXYGEN
945 960
    Cost totalCost() const {
946 961
      return totalCost<Cost>();
947 962
    }
948 963
#endif
949 964

	
950 965
    /// \brief Return the flow on the given arc.
951 966
    ///
952 967
    /// This function returns the flow on the given arc.
953 968
    ///
954 969
    /// \pre \ref run() must be called before using this function.
955 970
    Value flow(const Arc& a) const {
956 971
      return _flow[_arc_id[a]];
957 972
    }
958 973

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

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

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

	
998 1013
    /// @}
999 1014

	
1000 1015
  private:
1001 1016

	
1002 1017
    // Initialize internal data structures
1003 1018
    bool init() {
1004 1019
      if (_node_num == 0) return false;
1005 1020

	
1006 1021
      // Check the sum of supply values
1007 1022
      _sum_supply = 0;
1008 1023
      for (int i = 0; i != _node_num; ++i) {
1009 1024
        _sum_supply += _supply[i];
1010 1025
      }
1011 1026
      if ( !((_stype == GEQ && _sum_supply <= 0) ||
1012 1027
             (_stype == LEQ && _sum_supply >= 0)) ) return false;
1013 1028

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

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

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

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

	
1175 1190
      return true;
1176 1191
    }
1177 1192

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

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

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

	
1232 1247
      if (result == 1) {
1233 1248
        u_in = first;
1234 1249
        v_in = second;
1235 1250
      } else {
1236 1251
        u_in = second;
1237 1252
        v_in = first;
1238 1253
      }
1239 1254
      return result != 0;
1240 1255
    }
1241 1256

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

	
1265 1280
    // Update the tree structure
1266 1281
    void updateTreeStructure() {
1267 1282
      int u, w;
1268 1283
      int old_rev_thread = _rev_thread[u_out];
1269 1284
      int old_succ_num = _succ_num[u_out];
1270 1285
      int old_last_succ = _last_succ[u_out];
1271 1286
      v_out = _parent[u_out];
1272 1287

	
1273 1288
      u = _last_succ[u_in];  // the last successor of u_in
1274 1289
      right = _thread[u];    // the node after it
1275 1290

	
1276 1291
      // Handle the case when old_rev_thread equals to v_in
1277 1292
      // (it also means that join and v_out coincide)
1278 1293
      if (old_rev_thread == v_in) {
1279 1294
        last = _thread[_last_succ[u_out]];
1280 1295
      } else {
1281 1296
        last = _thread[v_in];
1282 1297
      }
1283 1298

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

	
1296 1311
        // Remove the subtree of stem from the thread list
1297 1312
        w = _rev_thread[stem];
1298 1313
        _thread[w] = right;
1299 1314
        _rev_thread[right] = w;
1300 1315

	
1301 1316
        // Change the parent node and shift stem nodes
1302 1317
        _parent[stem] = par_stem;
1303 1318
        par_stem = stem;
1304 1319
        stem = new_stem;
1305 1320

	
1306 1321
        // Update u and right
1307 1322
        u = _last_succ[stem] == _last_succ[par_stem] ?
1308 1323
          _rev_thread[par_stem] : _last_succ[stem];
1309 1324
        right = _thread[u];
1310 1325
      }
1311 1326
      _parent[u_out] = par_stem;
1312 1327
      _thread[u] = last;
1313 1328
      _rev_thread[last] = u;
1314 1329
      _last_succ[u_out] = u;
1315 1330

	
1316 1331
      // Remove the subtree of u_out from the thread list except for
1317 1332
      // the case when old_rev_thread equals to v_in
1318 1333
      // (it also means that join and v_out coincide)
1319 1334
      if (old_rev_thread != v_in) {
1320 1335
        _thread[old_rev_thread] = right;
1321 1336
        _rev_thread[right] = old_rev_thread;
1322 1337
      }
1323 1338

	
1324 1339
      // Update _rev_thread using the new _thread values
1325 1340
      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
1326 1341
        u = _dirty_revs[i];
1327 1342
        _rev_thread[_thread[u]] = u;
1328 1343
      }
1329 1344

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

	
1347 1362
      // Set limits for updating _last_succ form v_in and v_out
1348 1363
      // towards the root
1349 1364
      int up_limit_in = -1;
1350 1365
      int up_limit_out = -1;
1351 1366
      if (_last_succ[join] == v_in) {
1352 1367
        up_limit_out = join;
1353 1368
      } else {
1354 1369
        up_limit_in = join;
1355 1370
      }
1356 1371

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

	
1375 1390
      // Update _succ_num from v_in to join
1376 1391
      for (u = v_in; u != join; u = _parent[u]) {
1377 1392
        _succ_num[u] += old_succ_num;
1378 1393
      }
1379 1394
      // Update _succ_num from v_out to join
1380 1395
      for (u = v_out; u != join; u = _parent[u]) {
1381 1396
        _succ_num[u] -= old_succ_num;
1382 1397
      }
1383 1398
    }
1384 1399

	
1385 1400
    // Update potentials
1386 1401
    void updatePotential() {
1387 1402
      Cost sigma = _forward[u_in] ?
1388 1403
        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
1389 1404
        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
1390 1405
      // Update potentials in the subtree, which has been moved
1391 1406
      int end = _thread[_last_succ[u_in]];
1392 1407
      for (int u = u_in; u != end; u = _thread[u]) {
1393 1408
        _pi[u] += sigma;
1394 1409
      }
1395 1410
    }
1396 1411

	
1397 1412
    // Execute the algorithm
1398 1413
    ProblemType start(PivotRule pivot_rule) {
1399 1414
      // Select the pivot rule implementation
1400 1415
      switch (pivot_rule) {
1401 1416
        case FIRST_ELIGIBLE:
1402 1417
          return start<FirstEligiblePivotRule>();
1403 1418
        case BEST_ELIGIBLE:
1404 1419
          return start<BestEligiblePivotRule>();
1405 1420
        case BLOCK_SEARCH:
1406 1421
          return start<BlockSearchPivotRule>();
1407 1422
        case CANDIDATE_LIST:
1408 1423
          return start<CandidateListPivotRule>();
1409 1424
        case ALTERING_LIST:
1410 1425
          return start<AlteringListPivotRule>();
1411 1426
      }
1412 1427
      return INFEASIBLE; // avoid warning
1413 1428
    }
1414 1429

	
1415 1430
    template <typename PivotRuleImpl>
1416 1431
    ProblemType start() {
1417 1432
      PivotRuleImpl pivot(*this);
1418 1433

	
1419 1434
      // Execute the Network Simplex algorithm
1420 1435
      while (pivot.findEnteringArc()) {
1421 1436
        findJoinNode();
1422 1437
        bool change = findLeavingArc();
1423 1438
        if (delta >= INF) return UNBOUNDED;
1424 1439
        changeFlow(change);
1425 1440
        if (change) {
1426 1441
          updateTreeStructure();
1427 1442
          updatePotential();
1428 1443
        }
1429 1444
      }
1430 1445
      
1431 1446
      // Check feasibility
1432 1447
      for (int e = _search_arc_num; e != _all_arc_num; ++e) {
1433 1448
        if (_flow[e] != 0) return INFEASIBLE;
1434 1449
      }
1435 1450

	
1436 1451
      // Transform the solution and the supply map to the original form
1437 1452
      if (_have_lower) {
1438 1453
        for (int i = 0; i != _arc_num; ++i) {
1439 1454
          Value c = _lower[i];
1440 1455
          if (c != 0) {
1441 1456
            _flow[i] += c;
1442 1457
            _supply[_source[i]] += c;
1443 1458
            _supply[_target[i]] -= c;
1444 1459
          }
1445 1460
        }
1446 1461
      }
1447 1462
      
1448 1463
      // Shift potentials to meet the requirements of the GEQ/LEQ type
1449 1464
      // optimality conditions
1450 1465
      if (_sum_supply == 0) {
1451 1466
        if (_stype == GEQ) {
1452 1467
          Cost max_pot = std::numeric_limits<Cost>::min();
1453 1468
          for (int i = 0; i != _node_num; ++i) {
1454 1469
            if (_pi[i] > max_pot) max_pot = _pi[i];
1455 1470
          }
1456 1471
          if (max_pot > 0) {
1457 1472
            for (int i = 0; i != _node_num; ++i)
1458 1473
              _pi[i] -= max_pot;
1459 1474
          }
1460 1475
        } else {
1461 1476
          Cost min_pot = std::numeric_limits<Cost>::max();
1462 1477
          for (int i = 0; i != _node_num; ++i) {
1463 1478
            if (_pi[i] < min_pot) min_pot = _pi[i];
1464 1479
          }
1465 1480
          if (min_pot < 0) {
1466 1481
            for (int i = 0; i != _node_num; ++i)
1467 1482
              _pi[i] -= min_pot;
1468 1483
          }
1469 1484
        }
1470 1485
      }
1471 1486

	
1472 1487
      return OPTIMAL;
1473 1488
    }
1474 1489

	
1475 1490
  }; //class NetworkSimplex
1476 1491

	
1477 1492
  ///@}
1478 1493

	
1479 1494
} //namespace lemon
1480 1495

	
1481 1496
#endif //LEMON_NETWORK_SIMPLEX_H
0 comments (0 inline)