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 768 line context
... ...
@@ -244,818 +244,833 @@
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
0 comments (0 inline)