gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Internal restructuring and renamings in NetworkSimplex (#234)
0 1 0
default
1 file changed with 105 insertions and 118 deletions:
↑ Collapse diff ↑
Ignore white space 48 line context
... ...
@@ -7,48 +7,49 @@
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

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

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

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

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

	
33 34
namespace lemon {
34 35

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

	
38 39
  /// \brief Implementation of the primal network simplex algorithm
39 40
  /// for finding a \ref min_cost_flow "minimum cost flow".
40 41
  ///
41 42
  /// \ref NetworkSimplex implements the primal network simplex algorithm
42 43
  /// for finding a \ref min_cost_flow "minimum cost flow".
43 44
  ///
44 45
  /// \tparam Digraph The digraph type the algorithm runs on.
45 46
  /// \tparam LowerMap The type of the lower bound map.
46 47
  /// \tparam CapacityMap The type of the capacity (upper bound) map.
47 48
  /// \tparam CostMap The type of the cost (length) map.
48 49
  /// \tparam SupplyMap The type of the supply map.
49 50
  ///
50 51
  /// \warning
51 52
  /// - Arc capacities and costs should be \e non-negative \e integers.
52 53
  /// - Supply values should be \e signed \e integers.
53 54
  /// - The value types of the maps should be convertible to each other.
54 55
  /// - \c CostMap::Value must be signed type.
... ...
@@ -99,239 +100,230 @@
99 100

	
100 101
  public:
101 102

	
102 103
    /// Enum type for selecting the pivot rule used by \ref run()
103 104
    enum PivotRuleEnum {
104 105
      FIRST_ELIGIBLE_PIVOT,
105 106
      BEST_ELIGIBLE_PIVOT,
106 107
      BLOCK_SEARCH_PIVOT,
107 108
      CANDIDATE_LIST_PIVOT,
108 109
      ALTERING_LIST_PIVOT
109 110
    };
110 111

	
111 112
  private:
112 113

	
113 114
    // State constants for arcs
114 115
    enum ArcStateEnum {
115 116
      STATE_UPPER = -1,
116 117
      STATE_TREE  =  0,
117 118
      STATE_LOWER =  1
118 119
    };
119 120

	
120 121
  private:
121 122

	
122 123
    // References for the original data
123
    const Digraph &_orig_graph;
124
    const Digraph &_graph;
124 125
    const LowerMap *_orig_lower;
125 126
    const CapacityMap &_orig_cap;
126 127
    const CostMap &_orig_cost;
127 128
    const SupplyMap *_orig_supply;
128 129
    Node _orig_source;
129 130
    Node _orig_target;
130 131
    Capacity _orig_flow_value;
131 132

	
132 133
    // Result maps
133
    FlowMap *_flow_result;
134
    PotentialMap *_potential_result;
134
    FlowMap *_flow_map;
135
    PotentialMap *_potential_map;
135 136
    bool _local_flow;
136 137
    bool _local_potential;
137 138

	
138
    // Data structures for storing the graph
139
    ArcVector _arc;
140
    NodeVector _node;
141
    IntNodeMap _node_id;
142
    IntVector _source;
143
    IntVector _target;
144

	
145 139
    // The number of nodes and arcs in the original graph
146 140
    int _node_num;
147 141
    int _arc_num;
148 142

	
143
    // Data structures for storing the graph
144
    IntNodeMap _node_id;
145
    ArcVector _arc_ref;
146
    IntVector _source;
147
    IntVector _target;
148

	
149 149
    // Node and arc maps
150 150
    CapacityVector _cap;
151 151
    CostVector _cost;
152 152
    CostVector _supply;
153 153
    CapacityVector _flow;
154 154
    CostVector _pi;
155 155

	
156
    // Node and arc maps for the spanning tree structure
156
    // Data for storing the spanning tree structure
157 157
    IntVector _depth;
158 158
    IntVector _parent;
159 159
    IntVector _pred;
160 160
    IntVector _thread;
161 161
    BoolVector _forward;
162 162
    IntVector _state;
163

	
164
    // The root node
165 163
    int _root;
166 164

	
167
    // The entering arc in the current pivot iteration
168
    int _in_arc;
169

	
170 165
    // Temporary data used in the current pivot iteration
171
    int join, u_in, v_in, u_out, v_out;
172
    int right, first, second, last;
166
    int in_arc, join, u_in, v_in, u_out, v_out;
167
    int first, second, right, last;
173 168
    int stem, par_stem, new_stem;
174 169
    Capacity delta;
175 170

	
176 171
  private:
177 172

	
178 173
    /// \brief Implementation of the "First Eligible" pivot rule for the
179 174
    /// \ref NetworkSimplex "network simplex" algorithm.
180 175
    ///
181 176
    /// This class implements the "First Eligible" pivot rule
182 177
    /// for the \ref NetworkSimplex "network simplex" algorithm.
183 178
    ///
184 179
    /// For more information see \ref NetworkSimplex::run().
185 180
    class FirstEligiblePivotRule
186 181
    {
187 182
    private:
188 183

	
189 184
      // References to the NetworkSimplex class
190
      const ArcVector &_arc;
191 185
      const IntVector  &_source;
192 186
      const IntVector  &_target;
193 187
      const CostVector &_cost;
194 188
      const IntVector  &_state;
195 189
      const CostVector &_pi;
196 190
      int &_in_arc;
197 191
      int _arc_num;
198 192

	
199 193
      // Pivot rule data
200 194
      int _next_arc;
201 195

	
202 196
    public:
203 197

	
204 198
      /// Constructor
205 199
      FirstEligiblePivotRule(NetworkSimplex &ns) :
206
        _arc(ns._arc), _source(ns._source), _target(ns._target),
200
        _source(ns._source), _target(ns._target),
207 201
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
208
        _in_arc(ns._in_arc), _arc_num(ns._arc_num), _next_arc(0)
202
        _in_arc(ns.in_arc), _arc_num(ns._arc_num), _next_arc(0)
209 203
      {}
210 204

	
211 205
      /// Find next entering arc
212 206
      bool findEnteringArc() {
213 207
        Cost c;
214 208
        for (int e = _next_arc; e < _arc_num; ++e) {
215 209
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
216 210
          if (c < 0) {
217 211
            _in_arc = e;
218 212
            _next_arc = e + 1;
219 213
            return true;
220 214
          }
221 215
        }
222 216
        for (int e = 0; e < _next_arc; ++e) {
223 217
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
224 218
          if (c < 0) {
225 219
            _in_arc = e;
226 220
            _next_arc = e + 1;
227 221
            return true;
228 222
          }
229 223
        }
230 224
        return false;
231 225
      }
232 226

	
233 227
    }; //class FirstEligiblePivotRule
234 228

	
235 229

	
236 230
    /// \brief Implementation of the "Best Eligible" pivot rule for the
237 231
    /// \ref NetworkSimplex "network simplex" algorithm.
238 232
    ///
239 233
    /// This class implements the "Best Eligible" pivot rule
240 234
    /// for the \ref NetworkSimplex "network simplex" algorithm.
241 235
    ///
242 236
    /// For more information see \ref NetworkSimplex::run().
243 237
    class BestEligiblePivotRule
244 238
    {
245 239
    private:
246 240

	
247 241
      // References to the NetworkSimplex class
248
      const ArcVector &_arc;
249 242
      const IntVector  &_source;
250 243
      const IntVector  &_target;
251 244
      const CostVector &_cost;
252 245
      const IntVector  &_state;
253 246
      const CostVector &_pi;
254 247
      int &_in_arc;
255 248
      int _arc_num;
256 249

	
257 250
    public:
258 251

	
259 252
      /// Constructor
260 253
      BestEligiblePivotRule(NetworkSimplex &ns) :
261
        _arc(ns._arc), _source(ns._source), _target(ns._target),
254
        _source(ns._source), _target(ns._target),
262 255
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
263
        _in_arc(ns._in_arc), _arc_num(ns._arc_num)
256
        _in_arc(ns.in_arc), _arc_num(ns._arc_num)
264 257
      {}
265 258

	
266 259
      /// Find next entering arc
267 260
      bool findEnteringArc() {
268 261
        Cost c, min = 0;
269 262
        for (int e = 0; e < _arc_num; ++e) {
270 263
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
271 264
          if (c < min) {
272 265
            min = c;
273 266
            _in_arc = e;
274 267
          }
275 268
        }
276 269
        return min < 0;
277 270
      }
278 271

	
279 272
    }; //class BestEligiblePivotRule
280 273

	
281 274

	
282 275
    /// \brief Implementation of the "Block Search" pivot rule for the
283 276
    /// \ref NetworkSimplex "network simplex" algorithm.
284 277
    ///
285 278
    /// This class implements the "Block Search" pivot rule
286 279
    /// for the \ref NetworkSimplex "network simplex" algorithm.
287 280
    ///
288 281
    /// For more information see \ref NetworkSimplex::run().
289 282
    class BlockSearchPivotRule
290 283
    {
291 284
    private:
292 285

	
293 286
      // References to the NetworkSimplex class
294
      const ArcVector &_arc;
295 287
      const IntVector  &_source;
296 288
      const IntVector  &_target;
297 289
      const CostVector &_cost;
298 290
      const IntVector  &_state;
299 291
      const CostVector &_pi;
300 292
      int &_in_arc;
301 293
      int _arc_num;
302 294

	
303 295
      // Pivot rule data
304 296
      int _block_size;
305 297
      int _next_arc;
306 298

	
307 299
    public:
308 300

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

	
319 311
        _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_arc_num)),
320 312
                                MIN_BLOCK_SIZE );
321 313
      }
322 314

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

	
358 350
    }; //class BlockSearchPivotRule
359 351

	
360 352

	
361 353
    /// \brief Implementation of the "Candidate List" pivot rule for the
362 354
    /// \ref NetworkSimplex "network simplex" algorithm.
363 355
    ///
364 356
    /// This class implements the "Candidate List" pivot rule
365 357
    /// for the \ref NetworkSimplex "network simplex" algorithm.
366 358
    ///
367 359
    /// For more information see \ref NetworkSimplex::run().
368 360
    class CandidateListPivotRule
369 361
    {
370 362
    private:
371 363

	
372 364
      // References to the NetworkSimplex class
373
      const ArcVector &_arc;
374 365
      const IntVector  &_source;
375 366
      const IntVector  &_target;
376 367
      const CostVector &_cost;
377 368
      const IntVector  &_state;
378 369
      const CostVector &_pi;
379 370
      int &_in_arc;
380 371
      int _arc_num;
381 372

	
382 373
      // Pivot rule data
383 374
      IntVector _candidates;
384 375
      int _list_length, _minor_limit;
385 376
      int _curr_length, _minor_count;
386 377
      int _next_arc;
387 378

	
388 379
    public:
389 380

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

	
402 393
        _list_length = std::max( int(LIST_LENGTH_FACTOR * sqrt(_arc_num)),
403 394
                                 MIN_LIST_LENGTH );
404 395
        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
405 396
                                 MIN_MINOR_LIMIT );
406 397
        _curr_length = _minor_count = 0;
407 398
        _candidates.resize(_list_length);
408 399
      }
409 400

	
410 401
      /// Find next entering arc
411 402
      bool findEnteringArc() {
412 403
        Cost min, c;
413 404
        int e, min_arc = _next_arc;
414 405
        if (_curr_length > 0 && _minor_count < _minor_limit) {
415 406
          // Minor iteration: select the best eligible arc from the
416 407
          // current candidate list
417 408
          ++_minor_count;
418 409
          min = 0;
... ...
@@ -461,286 +452,285 @@
461 452
          }
462 453
        }
463 454
        if (_curr_length == 0) return false;
464 455
        _minor_count = 1;
465 456
        _in_arc = min_arc;
466 457
        _next_arc = e;
467 458
        return true;
468 459
      }
469 460

	
470 461
    }; //class CandidateListPivotRule
471 462

	
472 463

	
473 464
    /// \brief Implementation of the "Altering Candidate List" pivot rule
474 465
    /// for the \ref NetworkSimplex "network simplex" algorithm.
475 466
    ///
476 467
    /// This class implements the "Altering Candidate List" pivot rule
477 468
    /// for the \ref NetworkSimplex "network simplex" algorithm.
478 469
    ///
479 470
    /// For more information see \ref NetworkSimplex::run().
480 471
    class AlteringListPivotRule
481 472
    {
482 473
    private:
483 474

	
484 475
      // References to the NetworkSimplex class
485
      const ArcVector &_arc;
486 476
      const IntVector  &_source;
487 477
      const IntVector  &_target;
488 478
      const CostVector &_cost;
489 479
      const IntVector  &_state;
490 480
      const CostVector &_pi;
491 481
      int &_in_arc;
492 482
      int _arc_num;
493 483

	
494 484
      // Pivot rule data
495 485
      int _block_size, _head_length, _curr_length;
496 486
      int _next_arc;
497 487
      IntVector _candidates;
498 488
      CostVector _cand_cost;
499 489

	
500 490
      // Functor class to compare arcs during sort of the candidate list
501 491
      class SortFunc
502 492
      {
503 493
      private:
504 494
        const CostVector &_map;
505 495
      public:
506 496
        SortFunc(const CostVector &map) : _map(map) {}
507 497
        bool operator()(int left, int right) {
508 498
          return _map[left] > _map[right];
509 499
        }
510 500
      };
511 501

	
512 502
      SortFunc _sort_func;
513 503

	
514 504
    public:
515 505

	
516 506
      /// Constructor
517 507
      AlteringListPivotRule(NetworkSimplex &ns) :
518
        _arc(ns._arc), _source(ns._source), _target(ns._target),
508
        _source(ns._source), _target(ns._target),
519 509
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
520
        _in_arc(ns._in_arc), _arc_num(ns._arc_num),
510
        _in_arc(ns.in_arc), _arc_num(ns._arc_num),
521 511
        _next_arc(0), _cand_cost(ns._arc_num), _sort_func(_cand_cost)
522 512
      {
523 513
        // The main parameters of the pivot rule
524 514
        const double BLOCK_SIZE_FACTOR = 1.5;
525 515
        const int MIN_BLOCK_SIZE = 10;
526 516
        const double HEAD_LENGTH_FACTOR = 0.1;
527 517
        const int MIN_HEAD_LENGTH = 3;
528 518

	
529 519
        _block_size = std::max( int(BLOCK_SIZE_FACTOR * sqrt(_arc_num)),
530 520
                                MIN_BLOCK_SIZE );
531 521
        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
532 522
                                 MIN_HEAD_LENGTH );
533 523
        _candidates.resize(_head_length + _block_size);
534 524
        _curr_length = 0;
535 525
      }
536 526

	
537 527
      /// Find next entering arc
538 528
      bool findEnteringArc() {
539 529
        // Check the current candidate list
540 530
        int e;
541 531
        for (int i = 0; i < _curr_length; ++i) {
542 532
          e = _candidates[i];
543 533
          _cand_cost[e] = _state[e] *
544 534
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
545 535
          if (_cand_cost[e] >= 0) {
546 536
            _candidates[i--] = _candidates[--_curr_length];
547 537
          }
548 538
        }
549 539

	
550 540
        // Extend the list
551 541
        int cnt = _block_size;
552
        int last_edge = 0;
542
        int last_arc = 0;
553 543
        int limit = _head_length;
554 544

	
555 545
        for (int e = _next_arc; e < _arc_num; ++e) {
556 546
          _cand_cost[e] = _state[e] *
557 547
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
558 548
          if (_cand_cost[e] < 0) {
559 549
            _candidates[_curr_length++] = e;
560
            last_edge = e;
550
            last_arc = e;
561 551
          }
562 552
          if (--cnt == 0) {
563 553
            if (_curr_length > limit) break;
564 554
            limit = 0;
565 555
            cnt = _block_size;
566 556
          }
567 557
        }
568 558
        if (_curr_length <= limit) {
569 559
          for (int e = 0; e < _next_arc; ++e) {
570 560
            _cand_cost[e] = _state[e] *
571 561
              (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
572 562
            if (_cand_cost[e] < 0) {
573 563
              _candidates[_curr_length++] = e;
574
              last_edge = e;
564
              last_arc = e;
575 565
            }
576 566
            if (--cnt == 0) {
577 567
              if (_curr_length > limit) break;
578 568
              limit = 0;
579 569
              cnt = _block_size;
580 570
            }
581 571
          }
582 572
        }
583 573
        if (_curr_length == 0) return false;
584
        _next_arc = last_edge + 1;
574
        _next_arc = last_arc + 1;
585 575

	
586 576
        // Make heap of the candidate list (approximating a partial sort)
587 577
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
588 578
                   _sort_func );
589 579

	
590 580
        // Pop the first element of the heap
591 581
        _in_arc = _candidates[0];
592 582
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
593 583
                  _sort_func );
594 584
        _curr_length = std::min(_head_length, _curr_length - 1);
595 585
        return true;
596 586
      }
597 587

	
598 588
    }; //class AlteringListPivotRule
599 589

	
600 590
  public:
601 591

	
602 592
    /// \brief General constructor (with lower bounds).
603 593
    ///
604 594
    /// General constructor (with lower bounds).
605 595
    ///
606
    /// \param digraph The digraph the algorithm runs on.
596
    /// \param graph The digraph the algorithm runs on.
607 597
    /// \param lower The lower bounds of the arcs.
608 598
    /// \param capacity The capacities (upper bounds) of the arcs.
609 599
    /// \param cost The cost (length) values of the arcs.
610 600
    /// \param supply The supply values of the nodes (signed).
611
    NetworkSimplex( const Digraph &digraph,
601
    NetworkSimplex( const Digraph &graph,
612 602
                    const LowerMap &lower,
613 603
                    const CapacityMap &capacity,
614 604
                    const CostMap &cost,
615 605
                    const SupplyMap &supply ) :
616
      _orig_graph(digraph), _orig_lower(&lower), _orig_cap(capacity),
606
      _graph(graph), _orig_lower(&lower), _orig_cap(capacity),
617 607
      _orig_cost(cost), _orig_supply(&supply),
618
      _flow_result(NULL), _potential_result(NULL),
608
      _flow_map(NULL), _potential_map(NULL),
619 609
      _local_flow(false), _local_potential(false),
620
      _node_id(digraph)
610
      _node_id(graph)
621 611
    {}
622 612

	
623 613
    /// \brief General constructor (without lower bounds).
624 614
    ///
625 615
    /// General constructor (without lower bounds).
626 616
    ///
627
    /// \param digraph The digraph the algorithm runs on.
617
    /// \param graph The digraph the algorithm runs on.
628 618
    /// \param capacity The capacities (upper bounds) of the arcs.
629 619
    /// \param cost The cost (length) values of the arcs.
630 620
    /// \param supply The supply values of the nodes (signed).
631
    NetworkSimplex( const Digraph &digraph,
621
    NetworkSimplex( const Digraph &graph,
632 622
                    const CapacityMap &capacity,
633 623
                    const CostMap &cost,
634 624
                    const SupplyMap &supply ) :
635
      _orig_graph(digraph), _orig_lower(NULL), _orig_cap(capacity),
625
      _graph(graph), _orig_lower(NULL), _orig_cap(capacity),
636 626
      _orig_cost(cost), _orig_supply(&supply),
637
      _flow_result(NULL), _potential_result(NULL),
627
      _flow_map(NULL), _potential_map(NULL),
638 628
      _local_flow(false), _local_potential(false),
639
      _node_id(digraph)
629
      _node_id(graph)
640 630
    {}
641 631

	
642 632
    /// \brief Simple constructor (with lower bounds).
643 633
    ///
644 634
    /// Simple constructor (with lower bounds).
645 635
    ///
646
    /// \param digraph The digraph the algorithm runs on.
636
    /// \param graph The digraph the algorithm runs on.
647 637
    /// \param lower The lower bounds of the arcs.
648 638
    /// \param capacity The capacities (upper bounds) of the arcs.
649 639
    /// \param cost The cost (length) values of the arcs.
650 640
    /// \param s The source node.
651 641
    /// \param t The target node.
652 642
    /// \param flow_value The required amount of flow from node \c s
653 643
    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
654
    NetworkSimplex( const Digraph &digraph,
644
    NetworkSimplex( const Digraph &graph,
655 645
                    const LowerMap &lower,
656 646
                    const CapacityMap &capacity,
657 647
                    const CostMap &cost,
658 648
                    Node s, Node t,
659 649
                    Capacity flow_value ) :
660
      _orig_graph(digraph), _orig_lower(&lower), _orig_cap(capacity),
650
      _graph(graph), _orig_lower(&lower), _orig_cap(capacity),
661 651
      _orig_cost(cost), _orig_supply(NULL),
662 652
      _orig_source(s), _orig_target(t), _orig_flow_value(flow_value),
663
      _flow_result(NULL), _potential_result(NULL),
653
      _flow_map(NULL), _potential_map(NULL),
664 654
      _local_flow(false), _local_potential(false),
665
      _node_id(digraph)
655
      _node_id(graph)
666 656
    {}
667 657

	
668 658
    /// \brief Simple constructor (without lower bounds).
669 659
    ///
670 660
    /// Simple constructor (without lower bounds).
671 661
    ///
672
    /// \param digraph The digraph the algorithm runs on.
662
    /// \param graph The digraph the algorithm runs on.
673 663
    /// \param capacity The capacities (upper bounds) of the arcs.
674 664
    /// \param cost The cost (length) values of the arcs.
675 665
    /// \param s The source node.
676 666
    /// \param t The target node.
677 667
    /// \param flow_value The required amount of flow from node \c s
678 668
    /// to node \c t (i.e. the supply of \c s and the demand of \c t).
679
    NetworkSimplex( const Digraph &digraph,
669
    NetworkSimplex( const Digraph &graph,
680 670
                    const CapacityMap &capacity,
681 671
                    const CostMap &cost,
682 672
                    Node s, Node t,
683 673
                    Capacity flow_value ) :
684
      _orig_graph(digraph), _orig_lower(NULL), _orig_cap(capacity),
674
      _graph(graph), _orig_lower(NULL), _orig_cap(capacity),
685 675
      _orig_cost(cost), _orig_supply(NULL),
686 676
      _orig_source(s), _orig_target(t), _orig_flow_value(flow_value),
687
      _flow_result(NULL), _potential_result(NULL),
677
      _flow_map(NULL), _potential_map(NULL),
688 678
      _local_flow(false), _local_potential(false),
689
      _node_id(digraph)
679
      _node_id(graph)
690 680
    {}
691 681

	
692 682
    /// Destructor.
693 683
    ~NetworkSimplex() {
694
      if (_local_flow) delete _flow_result;
695
      if (_local_potential) delete _potential_result;
684
      if (_local_flow) delete _flow_map;
685
      if (_local_potential) delete _potential_map;
696 686
    }
697 687

	
698 688
    /// \brief Set the flow map.
699 689
    ///
700 690
    /// This function sets the flow map.
701 691
    ///
702 692
    /// \return <tt>(*this)</tt>
703 693
    NetworkSimplex& flowMap(FlowMap &map) {
704 694
      if (_local_flow) {
705
        delete _flow_result;
695
        delete _flow_map;
706 696
        _local_flow = false;
707 697
      }
708
      _flow_result = &map;
698
      _flow_map = &map;
709 699
      return *this;
710 700
    }
711 701

	
712 702
    /// \brief Set the potential map.
713 703
    ///
714 704
    /// This function sets the potential map.
715 705
    ///
716 706
    /// \return <tt>(*this)</tt>
717 707
    NetworkSimplex& potentialMap(PotentialMap &map) {
718 708
      if (_local_potential) {
719
        delete _potential_result;
709
        delete _potential_map;
720 710
        _local_potential = false;
721 711
      }
722
      _potential_result = &map;
712
      _potential_map = &map;
723 713
      return *this;
724 714
    }
725 715

	
726 716
    /// \name Execution control
727 717
    /// The algorithm can be executed using the
728 718
    /// \ref lemon::NetworkSimplex::run() "run()" function.
729 719
    /// @{
730 720

	
731 721
    /// \brief Run the algorithm.
732 722
    ///
733 723
    /// This function runs the algorithm.
734 724
    ///
735 725
    /// \param pivot_rule The pivot rule that is used during the
736 726
    /// algorithm.
737 727
    ///
738 728
    /// The available pivot rules:
739 729
    ///
740 730
    /// - FIRST_ELIGIBLE_PIVOT The next eligible arc is selected in
741 731
    /// a wraparound fashion in every iteration
742 732
    /// (\ref FirstEligiblePivotRule).
743 733
    ///
744 734
    /// - BEST_ELIGIBLE_PIVOT The best eligible arc is selected in
745 735
    /// every iteration (\ref BestEligiblePivotRule).
746 736
    ///
... ...
@@ -762,301 +752,298 @@
762 752
    /// pivot rule proved to be the fastest and the most robust on
763 753
    /// various test inputs. Thus it is the default option.
764 754
    ///
765 755
    /// \return \c true if a feasible flow can be found.
766 756
    bool run(PivotRuleEnum pivot_rule = BLOCK_SEARCH_PIVOT) {
767 757
      return init() && start(pivot_rule);
768 758
    }
769 759

	
770 760
    /// @}
771 761

	
772 762
    /// \name Query Functions
773 763
    /// The results of the algorithm can be obtained using these
774 764
    /// functions.\n
775 765
    /// \ref lemon::NetworkSimplex::run() "run()" must be called before
776 766
    /// using them.
777 767
    /// @{
778 768

	
779 769
    /// \brief Return a const reference to the flow map.
780 770
    ///
781 771
    /// This function returns a const reference to an arc map storing
782 772
    /// the found flow.
783 773
    ///
784 774
    /// \pre \ref run() must be called before using this function.
785 775
    const FlowMap& flowMap() const {
786
      return *_flow_result;
776
      return *_flow_map;
787 777
    }
788 778

	
789 779
    /// \brief Return a const reference to the potential map
790 780
    /// (the dual solution).
791 781
    ///
792 782
    /// This function returns a const reference to a node map storing
793 783
    /// the found potentials (the dual solution).
794 784
    ///
795 785
    /// \pre \ref run() must be called before using this function.
796 786
    const PotentialMap& potentialMap() const {
797
      return *_potential_result;
787
      return *_potential_map;
798 788
    }
799 789

	
800 790
    /// \brief Return the flow on the given arc.
801 791
    ///
802 792
    /// This function returns the flow on the given arc.
803 793
    ///
804 794
    /// \pre \ref run() must be called before using this function.
805 795
    Capacity flow(const Arc& arc) const {
806
      return (*_flow_result)[arc];
796
      return (*_flow_map)[arc];
807 797
    }
808 798

	
809 799
    /// \brief Return the potential of the given node.
810 800
    ///
811 801
    /// This function returns the potential of the given node.
812 802
    ///
813 803
    /// \pre \ref run() must be called before using this function.
814 804
    Cost potential(const Node& node) const {
815
      return (*_potential_result)[node];
805
      return (*_potential_map)[node];
816 806
    }
817 807

	
818 808
    /// \brief Return the total cost of the found flow.
819 809
    ///
820 810
    /// This function returns the total cost of the found flow.
821 811
    /// The complexity of the function is \f$ O(e) \f$.
822 812
    ///
823 813
    /// \pre \ref run() must be called before using this function.
824 814
    Cost totalCost() const {
825 815
      Cost c = 0;
826
      for (ArcIt e(_orig_graph); e != INVALID; ++e)
827
        c += (*_flow_result)[e] * _orig_cost[e];
816
      for (ArcIt e(_graph); e != INVALID; ++e)
817
        c += (*_flow_map)[e] * _orig_cost[e];
828 818
      return c;
829 819
    }
830 820

	
831 821
    /// @}
832 822

	
833 823
  private:
834 824

	
835 825
    // Initialize internal data structures
836 826
    bool init() {
837 827
      // Initialize result maps
838
      if (!_flow_result) {
839
        _flow_result = new FlowMap(_orig_graph);
828
      if (!_flow_map) {
829
        _flow_map = new FlowMap(_graph);
840 830
        _local_flow = true;
841 831
      }
842
      if (!_potential_result) {
843
        _potential_result = new PotentialMap(_orig_graph);
832
      if (!_potential_map) {
833
        _potential_map = new PotentialMap(_graph);
844 834
        _local_potential = true;
845 835
      }
846 836

	
847 837
      // Initialize vectors
848
      _node_num = countNodes(_orig_graph);
849
      _arc_num = countArcs(_orig_graph);
838
      _node_num = countNodes(_graph);
839
      _arc_num = countArcs(_graph);
850 840
      int all_node_num = _node_num + 1;
851
      int all_edge_num = _arc_num + _node_num;
841
      int all_arc_num = _arc_num + _node_num;
852 842

	
853
      _arc.resize(_arc_num);
854
      _node.reserve(_node_num);
855
      _source.resize(all_edge_num);
856
      _target.resize(all_edge_num);
843
      _arc_ref.resize(_arc_num);
844
      _source.resize(all_arc_num);
845
      _target.resize(all_arc_num);
857 846

	
858
      _cap.resize(all_edge_num);
859
      _cost.resize(all_edge_num);
847
      _cap.resize(all_arc_num);
848
      _cost.resize(all_arc_num);
860 849
      _supply.resize(all_node_num);
861
      _flow.resize(all_edge_num, 0);
850
      _flow.resize(all_arc_num, 0);
862 851
      _pi.resize(all_node_num, 0);
863 852

	
864 853
      _depth.resize(all_node_num);
865 854
      _parent.resize(all_node_num);
866 855
      _pred.resize(all_node_num);
856
      _forward.resize(all_node_num);
867 857
      _thread.resize(all_node_num);
868
      _forward.resize(all_node_num);
869
      _state.resize(all_edge_num, STATE_LOWER);
858
      _state.resize(all_arc_num, STATE_LOWER);
870 859

	
871 860
      // Initialize node related data
872 861
      bool valid_supply = true;
873 862
      if (_orig_supply) {
874 863
        Supply sum = 0;
875 864
        int i = 0;
876
        for (NodeIt n(_orig_graph); n != INVALID; ++n, ++i) {
877
          _node.push_back(n);
865
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
878 866
          _node_id[n] = i;
879 867
          _supply[i] = (*_orig_supply)[n];
880 868
          sum += _supply[i];
881 869
        }
882 870
        valid_supply = (sum == 0);
883 871
      } else {
884 872
        int i = 0;
885
        for (NodeIt n(_orig_graph); n != INVALID; ++n, ++i) {
886
          _node.push_back(n);
873
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
887 874
          _node_id[n] = i;
888 875
          _supply[i] = 0;
889 876
        }
890 877
        _supply[_node_id[_orig_source]] =  _orig_flow_value;
891 878
        _supply[_node_id[_orig_target]] = -_orig_flow_value;
892 879
      }
893 880
      if (!valid_supply) return false;
894 881

	
895 882
      // Set data for the artificial root node
896 883
      _root = _node_num;
897 884
      _depth[_root] = 0;
898 885
      _parent[_root] = -1;
899 886
      _pred[_root] = -1;
900 887
      _thread[_root] = 0;
901 888
      _supply[_root] = 0;
902 889
      _pi[_root] = 0;
903 890

	
904 891
      // Store the arcs in a mixed order
905 892
      int k = std::max(int(sqrt(_arc_num)), 10);
906 893
      int i = 0;
907
      for (ArcIt e(_orig_graph); e != INVALID; ++e) {
908
        _arc[i] = e;
894
      for (ArcIt e(_graph); e != INVALID; ++e) {
895
        _arc_ref[i] = e;
909 896
        if ((i += k) >= _arc_num) i = (i % k) + 1;
910 897
      }
911 898

	
912 899
      // Initialize arc maps
913 900
      for (int i = 0; i != _arc_num; ++i) {
914
        Arc e = _arc[i];
915
        _source[i] = _node_id[_orig_graph.source(e)];
916
        _target[i] = _node_id[_orig_graph.target(e)];
901
        Arc e = _arc_ref[i];
902
        _source[i] = _node_id[_graph.source(e)];
903
        _target[i] = _node_id[_graph.target(e)];
917 904
        _cost[i] = _orig_cost[e];
918 905
        _cap[i] = _orig_cap[e];
919 906
      }
920 907

	
921 908
      // Remove non-zero lower bounds
922 909
      if (_orig_lower) {
923 910
        for (int i = 0; i != _arc_num; ++i) {
924
          Capacity c = (*_orig_lower)[_arc[i]];
911
          Capacity c = (*_orig_lower)[_arc_ref[i]];
925 912
          if (c != 0) {
926 913
            _cap[i] -= c;
927 914
            _supply[_source[i]] -= c;
928 915
            _supply[_target[i]] += c;
929 916
          }
930 917
        }
931 918
      }
932 919

	
933 920
      // Add artificial arcs and initialize the spanning tree data structure
934 921
      Cost max_cost = std::numeric_limits<Cost>::max() / 4;
935 922
      Capacity max_cap = std::numeric_limits<Capacity>::max();
936 923
      for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
937 924
        _thread[u] = u + 1;
938 925
        _depth[u] = 1;
939 926
        _parent[u] = _root;
940 927
        _pred[u] = e;
941 928
        if (_supply[u] >= 0) {
942 929
          _flow[e] = _supply[u];
943 930
          _forward[u] = true;
944 931
          _pi[u] = -max_cost;
945 932
        } else {
946 933
          _flow[e] = -_supply[u];
947 934
          _forward[u] = false;
948 935
          _pi[u] = max_cost;
949 936
        }
950 937
        _cost[e] = max_cost;
951 938
        _cap[e] = max_cap;
952 939
        _state[e] = STATE_TREE;
953 940
      }
954 941

	
955 942
      return true;
956 943
    }
957 944

	
958 945
    // Find the join node
959 946
    void findJoinNode() {
960
      int u = _source[_in_arc];
961
      int v = _target[_in_arc];
947
      int u = _source[in_arc];
948
      int v = _target[in_arc];
962 949
      while (_depth[u] > _depth[v]) u = _parent[u];
963 950
      while (_depth[v] > _depth[u]) v = _parent[v];
964 951
      while (u != v) {
965 952
        u = _parent[u];
966 953
        v = _parent[v];
967 954
      }
968 955
      join = u;
969 956
    }
970 957

	
971 958
    // Find the leaving arc of the cycle and returns true if the
972 959
    // leaving arc is not the same as the entering arc
973 960
    bool findLeavingArc() {
974 961
      // Initialize first and second nodes according to the direction
975 962
      // of the cycle
976
      if (_state[_in_arc] == STATE_LOWER) {
977
        first  = _source[_in_arc];
978
        second = _target[_in_arc];
963
      if (_state[in_arc] == STATE_LOWER) {
964
        first  = _source[in_arc];
965
        second = _target[in_arc];
979 966
      } else {
980
        first  = _target[_in_arc];
981
        second = _source[_in_arc];
967
        first  = _target[in_arc];
968
        second = _source[in_arc];
982 969
      }
983
      delta = _cap[_in_arc];
970
      delta = _cap[in_arc];
984 971
      int result = 0;
985 972
      Capacity d;
986 973
      int e;
987 974

	
988 975
      // Search the cycle along the path form the first node to the root
989 976
      for (int u = first; u != join; u = _parent[u]) {
990 977
        e = _pred[u];
991 978
        d = _forward[u] ? _flow[e] : _cap[e] - _flow[e];
992 979
        if (d < delta) {
993 980
          delta = d;
994 981
          u_out = u;
995 982
          result = 1;
996 983
        }
997 984
      }
998 985
      // Search the cycle along the path form the second node to the root
999 986
      for (int u = second; u != join; u = _parent[u]) {
1000 987
        e = _pred[u];
1001 988
        d = _forward[u] ? _cap[e] - _flow[e] : _flow[e];
1002 989
        if (d <= delta) {
1003 990
          delta = d;
1004 991
          u_out = u;
1005 992
          result = 2;
1006 993
        }
1007 994
      }
1008 995

	
1009 996
      if (result == 1) {
1010 997
        u_in = first;
1011 998
        v_in = second;
1012 999
      } else {
1013 1000
        u_in = second;
1014 1001
        v_in = first;
1015 1002
      }
1016 1003
      return result != 0;
1017 1004
    }
1018 1005

	
1019 1006
    // Change _flow and _state vectors
1020 1007
    void changeFlow(bool change) {
1021 1008
      // Augment along the cycle
1022 1009
      if (delta > 0) {
1023
        Capacity val = _state[_in_arc] * delta;
1024
        _flow[_in_arc] += val;
1025
        for (int u = _source[_in_arc]; u != join; u = _parent[u]) {
1010
        Capacity val = _state[in_arc] * delta;
1011
        _flow[in_arc] += val;
1012
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
1026 1013
          _flow[_pred[u]] += _forward[u] ? -val : val;
1027 1014
        }
1028
        for (int u = _target[_in_arc]; u != join; u = _parent[u]) {
1015
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
1029 1016
          _flow[_pred[u]] += _forward[u] ? val : -val;
1030 1017
        }
1031 1018
      }
1032 1019
      // Update the state of the entering and leaving arcs
1033 1020
      if (change) {
1034
        _state[_in_arc] = STATE_TREE;
1021
        _state[in_arc] = STATE_TREE;
1035 1022
        _state[_pred[u_out]] =
1036 1023
          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
1037 1024
      } else {
1038
        _state[_in_arc] = -_state[_in_arc];
1025
        _state[in_arc] = -_state[in_arc];
1039 1026
      }
1040 1027
    }
1041 1028

	
1042 1029
    // Update _thread and _parent vectors
1043 1030
    void updateThreadParent() {
1044 1031
      int u;
1045 1032
      v_out = _parent[u_out];
1046 1033

	
1047 1034
      // Handle the case when join and v_out coincide
1048 1035
      bool par_first = false;
1049 1036
      if (join == v_out) {
1050 1037
        for (u = join; u != u_in && u != v_in; u = _thread[u]) ;
1051 1038
        if (u == v_in) {
1052 1039
          par_first = true;
1053 1040
          while (_thread[u] != u_out) u = _thread[u];
1054 1041
          first = u;
1055 1042
        }
1056 1043
      }
1057 1044

	
1058 1045
      // Find the last successor of u_in (u) and the node after it (right)
1059 1046
      // according to the thread index
1060 1047
      for (u = u_in; _depth[_thread[u]] > _depth[u_in]; u = _thread[u]) ;
1061 1048
      right = _thread[u];
1062 1049
      if (_thread[v_in] == u_out) {
... ...
@@ -1085,50 +1072,50 @@
1085 1072
        // according to the thread index
1086 1073
        for (u = stem; _depth[_thread[u]] > _depth[stem]; u = _thread[u]) ;
1087 1074
        right = _thread[u];
1088 1075
      }
1089 1076
      _parent[u_out] = par_stem;
1090 1077
      _thread[u] = last;
1091 1078

	
1092 1079
      if (join == v_out && par_first) {
1093 1080
        if (first != v_in) _thread[first] = right;
1094 1081
      } else {
1095 1082
        for (u = v_out; _thread[u] != u_out; u = _thread[u]) ;
1096 1083
        _thread[u] = right;
1097 1084
      }
1098 1085
    }
1099 1086

	
1100 1087
    // Update _pred and _forward vectors
1101 1088
    void updatePredArc() {
1102 1089
      int u = u_out, v;
1103 1090
      while (u != u_in) {
1104 1091
        v = _parent[u];
1105 1092
        _pred[u] = _pred[v];
1106 1093
        _forward[u] = !_forward[v];
1107 1094
        u = v;
1108 1095
      }
1109
      _pred[u_in] = _in_arc;
1110
      _forward[u_in] = (u_in == _source[_in_arc]);
1096
      _pred[u_in] = in_arc;
1097
      _forward[u_in] = (u_in == _source[in_arc]);
1111 1098
    }
1112 1099

	
1113 1100
    // Update _depth and _potential vectors
1114 1101
    void updateDepthPotential() {
1115 1102
      _depth[u_in] = _depth[v_in] + 1;
1116 1103
      Cost sigma = _forward[u_in] ?
1117 1104
        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
1118 1105
        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
1119 1106
      _pi[u_in] += sigma;
1120 1107
      for(int u = _thread[u_in]; _parent[u] != -1; u = _thread[u]) {
1121 1108
        _depth[u] = _depth[_parent[u]] + 1;
1122 1109
        if (_depth[u] <= _depth[u_in]) break;
1123 1110
        _pi[u] += sigma;
1124 1111
      }
1125 1112
    }
1126 1113

	
1127 1114
    // Execute the algorithm
1128 1115
    bool start(PivotRuleEnum pivot_rule) {
1129 1116
      // Select the pivot rule implementation
1130 1117
      switch (pivot_rule) {
1131 1118
        case FIRST_ELIGIBLE_PIVOT:
1132 1119
          return start<FirstEligiblePivotRule>();
1133 1120
        case BEST_ELIGIBLE_PIVOT:
1134 1121
          return start<BestEligiblePivotRule>();
... ...
@@ -1142,50 +1129,50 @@
1142 1129
      return false;
1143 1130
    }
1144 1131

	
1145 1132
    template<class PivotRuleImplementation>
1146 1133
    bool start() {
1147 1134
      PivotRuleImplementation pivot(*this);
1148 1135

	
1149 1136
      // Execute the network simplex algorithm
1150 1137
      while (pivot.findEnteringArc()) {
1151 1138
        findJoinNode();
1152 1139
        bool change = findLeavingArc();
1153 1140
        changeFlow(change);
1154 1141
        if (change) {
1155 1142
          updateThreadParent();
1156 1143
          updatePredArc();
1157 1144
          updateDepthPotential();
1158 1145
        }
1159 1146
      }
1160 1147

	
1161 1148
      // Check if the flow amount equals zero on all the artificial arcs
1162 1149
      for (int e = _arc_num; e != _arc_num + _node_num; ++e) {
1163 1150
        if (_flow[e] > 0) return false;
1164 1151
      }
1165 1152

	
1166
      // Copy flow values to _flow_result
1153
      // Copy flow values to _flow_map
1167 1154
      if (_orig_lower) {
1168 1155
        for (int i = 0; i != _arc_num; ++i) {
1169
          Arc e = _arc[i];
1170
          (*_flow_result)[e] = (*_orig_lower)[e] + _flow[i];
1156
          Arc e = _arc_ref[i];
1157
          _flow_map->set(e, (*_orig_lower)[e] + _flow[i]);
1171 1158
        }
1172 1159
      } else {
1173 1160
        for (int i = 0; i != _arc_num; ++i) {
1174
          (*_flow_result)[_arc[i]] = _flow[i];
1161
          _flow_map->set(_arc_ref[i], _flow[i]);
1175 1162
        }
1176 1163
      }
1177
      // Copy potential values to _potential_result
1178
      for (int i = 0; i != _node_num; ++i) {
1179
        (*_potential_result)[_node[i]] = _pi[i];
1164
      // Copy potential values to _potential_map
1165
      for (NodeIt n(_graph); n != INVALID; ++n) {
1166
        _potential_map->set(n, _pi[_node_id[n]]);
1180 1167
      }
1181 1168

	
1182 1169
      return true;
1183 1170
    }
1184 1171

	
1185 1172
  }; //class NetworkSimplex
1186 1173

	
1187 1174
  ///@}
1188 1175

	
1189 1176
} //namespace lemon
1190 1177

	
1191 1178
#endif //LEMON_NETWORK_SIMPLEX_H
0 comments (0 inline)