gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Improve arc mixing in NS and enable it by default (#391)
0 1 0
default
1 file changed with 7 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
... ...
@@ -447,685 +447,686 @@
447 447
        _minor_limit = std::max( int(MINOR_LIMIT_FACTOR * _list_length),
448 448
                                 MIN_MINOR_LIMIT );
449 449
        _curr_length = _minor_count = 0;
450 450
        _candidates.resize(_list_length);
451 451
      }
452 452

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

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

	
503 503
      search_end:
504 504
        _minor_count = 1;
505 505
        _next_arc = e;
506 506
        return true;
507 507
      }
508 508

	
509 509
    }; //class CandidateListPivotRule
510 510

	
511 511

	
512 512
    // Implementation of the Altering Candidate List pivot rule
513 513
    class AlteringListPivotRule
514 514
    {
515 515
    private:
516 516

	
517 517
      // References to the NetworkSimplex class
518 518
      const IntVector  &_source;
519 519
      const IntVector  &_target;
520 520
      const CostVector &_cost;
521 521
      const CharVector &_state;
522 522
      const CostVector &_pi;
523 523
      int &_in_arc;
524 524
      int _search_arc_num;
525 525

	
526 526
      // Pivot rule data
527 527
      int _block_size, _head_length, _curr_length;
528 528
      int _next_arc;
529 529
      IntVector _candidates;
530 530
      CostVector _cand_cost;
531 531

	
532 532
      // Functor class to compare arcs during sort of the candidate list
533 533
      class SortFunc
534 534
      {
535 535
      private:
536 536
        const CostVector &_map;
537 537
      public:
538 538
        SortFunc(const CostVector &map) : _map(map) {}
539 539
        bool operator()(int left, int right) {
540 540
          return _map[left] > _map[right];
541 541
        }
542 542
      };
543 543

	
544 544
      SortFunc _sort_func;
545 545

	
546 546
    public:
547 547

	
548 548
      // Constructor
549 549
      AlteringListPivotRule(NetworkSimplex &ns) :
550 550
        _source(ns._source), _target(ns._target),
551 551
        _cost(ns._cost), _state(ns._state), _pi(ns._pi),
552 552
        _in_arc(ns.in_arc), _search_arc_num(ns._search_arc_num),
553 553
        _next_arc(0), _cand_cost(ns._search_arc_num), _sort_func(_cand_cost)
554 554
      {
555 555
        // The main parameters of the pivot rule
556 556
        const double BLOCK_SIZE_FACTOR = 1.0;
557 557
        const int MIN_BLOCK_SIZE = 10;
558 558
        const double HEAD_LENGTH_FACTOR = 0.1;
559 559
        const int MIN_HEAD_LENGTH = 3;
560 560

	
561 561
        _block_size = std::max( int(BLOCK_SIZE_FACTOR *
562 562
                                    std::sqrt(double(_search_arc_num))),
563 563
                                MIN_BLOCK_SIZE );
564 564
        _head_length = std::max( int(HEAD_LENGTH_FACTOR * _block_size),
565 565
                                 MIN_HEAD_LENGTH );
566 566
        _candidates.resize(_head_length + _block_size);
567 567
        _curr_length = 0;
568 568
      }
569 569

	
570 570
      // Find next entering arc
571 571
      bool findEnteringArc() {
572 572
        // Check the current candidate list
573 573
        int e;
574 574
        Cost c;
575 575
        for (int i = 0; i != _curr_length; ++i) {
576 576
          e = _candidates[i];
577 577
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
578 578
          if (c < 0) {
579 579
            _cand_cost[e] = c;
580 580
          } else {
581 581
            _candidates[i--] = _candidates[--_curr_length];
582 582
          }
583 583
        }
584 584

	
585 585
        // Extend the list
586 586
        int cnt = _block_size;
587 587
        int limit = _head_length;
588 588

	
589 589
        for (e = _next_arc; e != _search_arc_num; ++e) {
590 590
          c = _state[e] * (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
591 591
          if (c < 0) {
592 592
            _cand_cost[e] = c;
593 593
            _candidates[_curr_length++] = e;
594 594
          }
595 595
          if (--cnt == 0) {
596 596
            if (_curr_length > limit) goto search_end;
597 597
            limit = 0;
598 598
            cnt = _block_size;
599 599
          }
600 600
        }
601 601
        for (e = 0; e != _next_arc; ++e) {
602 602
          _cand_cost[e] = _state[e] *
603 603
            (_cost[e] + _pi[_source[e]] - _pi[_target[e]]);
604 604
          if (_cand_cost[e] < 0) {
605 605
            _candidates[_curr_length++] = e;
606 606
          }
607 607
          if (--cnt == 0) {
608 608
            if (_curr_length > limit) goto search_end;
609 609
            limit = 0;
610 610
            cnt = _block_size;
611 611
          }
612 612
        }
613 613
        if (_curr_length == 0) return false;
614 614

	
615 615
      search_end:
616 616

	
617 617
        // Make heap of the candidate list (approximating a partial sort)
618 618
        make_heap( _candidates.begin(), _candidates.begin() + _curr_length,
619 619
                   _sort_func );
620 620

	
621 621
        // Pop the first element of the heap
622 622
        _in_arc = _candidates[0];
623 623
        _next_arc = e;
624 624
        pop_heap( _candidates.begin(), _candidates.begin() + _curr_length,
625 625
                  _sort_func );
626 626
        _curr_length = std::min(_head_length, _curr_length - 1);
627 627
        return true;
628 628
      }
629 629

	
630 630
    }; //class AlteringListPivotRule
631 631

	
632 632
  public:
633 633

	
634 634
    /// \brief Constructor.
635 635
    ///
636 636
    /// The constructor of the class.
637 637
    ///
638 638
    /// \param graph The digraph the algorithm runs on.
639
    /// \param arc_mixing Indicate if the arcs have to be stored in a
639
    /// \param arc_mixing Indicate if the arcs will be stored in a
640 640
    /// mixed order in the internal data structure.
641
    /// In special cases, it could lead to better overall performance,
642
    /// but it is usually slower. Therefore it is disabled by default.
643
    NetworkSimplex(const GR& graph, bool arc_mixing = false) :
641
    /// In general, it leads to similar performance as using the original
642
    /// arc order, but it makes the algorithm more robust and in special
643
    /// cases, even significantly faster. Therefore, it is enabled by default.
644
    NetworkSimplex(const GR& graph, bool arc_mixing = true) :
644 645
      _graph(graph), _node_id(graph), _arc_id(graph),
645 646
      _arc_mixing(arc_mixing),
646 647
      MAX(std::numeric_limits<Value>::max()),
647 648
      INF(std::numeric_limits<Value>::has_infinity ?
648 649
          std::numeric_limits<Value>::infinity() : MAX)
649 650
    {
650 651
      // Check the number types
651 652
      LEMON_ASSERT(std::numeric_limits<Value>::is_signed,
652 653
        "The flow type of NetworkSimplex must be signed");
653 654
      LEMON_ASSERT(std::numeric_limits<Cost>::is_signed,
654 655
        "The cost type of NetworkSimplex must be signed");
655 656

	
656 657
      // Reset data structures
657 658
      reset();
658 659
    }
659 660

	
660 661
    /// \name Parameters
661 662
    /// The parameters of the algorithm can be specified using these
662 663
    /// functions.
663 664

	
664 665
    /// @{
665 666

	
666 667
    /// \brief Set the lower bounds on the arcs.
667 668
    ///
668 669
    /// This function sets the lower bounds on the arcs.
669 670
    /// If it is not used before calling \ref run(), the lower bounds
670 671
    /// will be set to zero on all arcs.
671 672
    ///
672 673
    /// \param map An arc map storing the lower bounds.
673 674
    /// Its \c Value type must be convertible to the \c Value type
674 675
    /// of the algorithm.
675 676
    ///
676 677
    /// \return <tt>(*this)</tt>
677 678
    template <typename LowerMap>
678 679
    NetworkSimplex& lowerMap(const LowerMap& map) {
679 680
      _have_lower = true;
680 681
      for (ArcIt a(_graph); a != INVALID; ++a) {
681 682
        _lower[_arc_id[a]] = map[a];
682 683
      }
683 684
      return *this;
684 685
    }
685 686

	
686 687
    /// \brief Set the upper bounds (capacities) on the arcs.
687 688
    ///
688 689
    /// This function sets the upper bounds (capacities) on the arcs.
689 690
    /// If it is not used before calling \ref run(), the upper bounds
690 691
    /// will be set to \ref INF on all arcs (i.e. the flow value will be
691 692
    /// unbounded from above).
692 693
    ///
693 694
    /// \param map An arc map storing the upper bounds.
694 695
    /// Its \c Value type must be convertible to the \c Value type
695 696
    /// of the algorithm.
696 697
    ///
697 698
    /// \return <tt>(*this)</tt>
698 699
    template<typename UpperMap>
699 700
    NetworkSimplex& upperMap(const UpperMap& map) {
700 701
      for (ArcIt a(_graph); a != INVALID; ++a) {
701 702
        _upper[_arc_id[a]] = map[a];
702 703
      }
703 704
      return *this;
704 705
    }
705 706

	
706 707
    /// \brief Set the costs of the arcs.
707 708
    ///
708 709
    /// This function sets the costs of the arcs.
709 710
    /// If it is not used before calling \ref run(), the costs
710 711
    /// will be set to \c 1 on all arcs.
711 712
    ///
712 713
    /// \param map An arc map storing the costs.
713 714
    /// Its \c Value type must be convertible to the \c Cost type
714 715
    /// of the algorithm.
715 716
    ///
716 717
    /// \return <tt>(*this)</tt>
717 718
    template<typename CostMap>
718 719
    NetworkSimplex& costMap(const CostMap& map) {
719 720
      for (ArcIt a(_graph); a != INVALID; ++a) {
720 721
        _cost[_arc_id[a]] = map[a];
721 722
      }
722 723
      return *this;
723 724
    }
724 725

	
725 726
    /// \brief Set the supply values of the nodes.
726 727
    ///
727 728
    /// This function sets the supply values of the nodes.
728 729
    /// If neither this function nor \ref stSupply() is used before
729 730
    /// calling \ref run(), the supply of each node will be set to zero.
730 731
    ///
731 732
    /// \param map A node map storing the supply values.
732 733
    /// Its \c Value type must be convertible to the \c Value type
733 734
    /// of the algorithm.
734 735
    ///
735 736
    /// \return <tt>(*this)</tt>
736 737
    template<typename SupplyMap>
737 738
    NetworkSimplex& supplyMap(const SupplyMap& map) {
738 739
      for (NodeIt n(_graph); n != INVALID; ++n) {
739 740
        _supply[_node_id[n]] = map[n];
740 741
      }
741 742
      return *this;
742 743
    }
743 744

	
744 745
    /// \brief Set single source and target nodes and a supply value.
745 746
    ///
746 747
    /// This function sets a single source node and a single target node
747 748
    /// and the required flow value.
748 749
    /// If neither this function nor \ref supplyMap() is used before
749 750
    /// calling \ref run(), the supply of each node will be set to zero.
750 751
    ///
751 752
    /// Using this function has the same effect as using \ref supplyMap()
752 753
    /// with such a map in which \c k is assigned to \c s, \c -k is
753 754
    /// assigned to \c t and all other nodes have zero supply value.
754 755
    ///
755 756
    /// \param s The source node.
756 757
    /// \param t The target node.
757 758
    /// \param k The required amount of flow from node \c s to node \c t
758 759
    /// (i.e. the supply of \c s and the demand of \c t).
759 760
    ///
760 761
    /// \return <tt>(*this)</tt>
761 762
    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
762 763
      for (int i = 0; i != _node_num; ++i) {
763 764
        _supply[i] = 0;
764 765
      }
765 766
      _supply[_node_id[s]] =  k;
766 767
      _supply[_node_id[t]] = -k;
767 768
      return *this;
768 769
    }
769 770

	
770 771
    /// \brief Set the type of the supply constraints.
771 772
    ///
772 773
    /// This function sets the type of the supply/demand constraints.
773 774
    /// If it is not used before calling \ref run(), the \ref GEQ supply
774 775
    /// type will be used.
775 776
    ///
776 777
    /// For more information, see \ref SupplyType.
777 778
    ///
778 779
    /// \return <tt>(*this)</tt>
779 780
    NetworkSimplex& supplyType(SupplyType supply_type) {
780 781
      _stype = supply_type;
781 782
      return *this;
782 783
    }
783 784

	
784 785
    /// @}
785 786

	
786 787
    /// \name Execution Control
787 788
    /// The algorithm can be executed using \ref run().
788 789

	
789 790
    /// @{
790 791

	
791 792
    /// \brief Run the algorithm.
792 793
    ///
793 794
    /// This function runs the algorithm.
794 795
    /// The paramters can be specified using functions \ref lowerMap(),
795 796
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
796 797
    /// \ref supplyType().
797 798
    /// For example,
798 799
    /// \code
799 800
    ///   NetworkSimplex<ListDigraph> ns(graph);
800 801
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
801 802
    ///     .supplyMap(sup).run();
802 803
    /// \endcode
803 804
    ///
804 805
    /// This function can be called more than once. All the given parameters
805 806
    /// are kept for the next call, unless \ref resetParams() or \ref reset()
806 807
    /// is used, thus only the modified parameters have to be set again.
807 808
    /// If the underlying digraph was also modified after the construction
808 809
    /// of the class (or the last \ref reset() call), then the \ref reset()
809 810
    /// function must be called.
810 811
    ///
811 812
    /// \param pivot_rule The pivot rule that will be used during the
812 813
    /// algorithm. For more information, see \ref PivotRule.
813 814
    ///
814 815
    /// \return \c INFEASIBLE if no feasible flow exists,
815 816
    /// \n \c OPTIMAL if the problem has optimal solution
816 817
    /// (i.e. it is feasible and bounded), and the algorithm has found
817 818
    /// optimal flow and node potentials (primal and dual solutions),
818 819
    /// \n \c UNBOUNDED if the objective function of the problem is
819 820
    /// unbounded, i.e. there is a directed cycle having negative total
820 821
    /// cost and infinite upper bound.
821 822
    ///
822 823
    /// \see ProblemType, PivotRule
823 824
    /// \see resetParams(), reset()
824 825
    ProblemType run(PivotRule pivot_rule = BLOCK_SEARCH) {
825 826
      if (!init()) return INFEASIBLE;
826 827
      return start(pivot_rule);
827 828
    }
828 829

	
829 830
    /// \brief Reset all the parameters that have been given before.
830 831
    ///
831 832
    /// This function resets all the paramaters that have been given
832 833
    /// before using functions \ref lowerMap(), \ref upperMap(),
833 834
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), \ref supplyType().
834 835
    ///
835 836
    /// It is useful for multiple \ref run() calls. Basically, all the given
836 837
    /// parameters are kept for the next \ref run() call, unless
837 838
    /// \ref resetParams() or \ref reset() is used.
838 839
    /// If the underlying digraph was also modified after the construction
839 840
    /// of the class or the last \ref reset() call, then the \ref reset()
840 841
    /// function must be used, otherwise \ref resetParams() is sufficient.
841 842
    ///
842 843
    /// For example,
843 844
    /// \code
844 845
    ///   NetworkSimplex<ListDigraph> ns(graph);
845 846
    ///
846 847
    ///   // First run
847 848
    ///   ns.lowerMap(lower).upperMap(upper).costMap(cost)
848 849
    ///     .supplyMap(sup).run();
849 850
    ///
850 851
    ///   // Run again with modified cost map (resetParams() is not called,
851 852
    ///   // so only the cost map have to be set again)
852 853
    ///   cost[e] += 100;
853 854
    ///   ns.costMap(cost).run();
854 855
    ///
855 856
    ///   // Run again from scratch using resetParams()
856 857
    ///   // (the lower bounds will be set to zero on all arcs)
857 858
    ///   ns.resetParams();
858 859
    ///   ns.upperMap(capacity).costMap(cost)
859 860
    ///     .supplyMap(sup).run();
860 861
    /// \endcode
861 862
    ///
862 863
    /// \return <tt>(*this)</tt>
863 864
    ///
864 865
    /// \see reset(), run()
865 866
    NetworkSimplex& resetParams() {
866 867
      for (int i = 0; i != _node_num; ++i) {
867 868
        _supply[i] = 0;
868 869
      }
869 870
      for (int i = 0; i != _arc_num; ++i) {
870 871
        _lower[i] = 0;
871 872
        _upper[i] = INF;
872 873
        _cost[i] = 1;
873 874
      }
874 875
      _have_lower = false;
875 876
      _stype = GEQ;
876 877
      return *this;
877 878
    }
878 879

	
879 880
    /// \brief Reset the internal data structures and all the parameters
880 881
    /// that have been given before.
881 882
    ///
882 883
    /// This function resets the internal data structures and all the
883 884
    /// paramaters that have been given before using functions \ref lowerMap(),
884 885
    /// \ref upperMap(), \ref costMap(), \ref supplyMap(), \ref stSupply(),
885 886
    /// \ref supplyType().
886 887
    ///
887 888
    /// It is useful for multiple \ref run() calls. Basically, all the given
888 889
    /// parameters are kept for the next \ref run() call, unless
889 890
    /// \ref resetParams() or \ref reset() is used.
890 891
    /// If the underlying digraph was also modified after the construction
891 892
    /// of the class or the last \ref reset() call, then the \ref reset()
892 893
    /// function must be used, otherwise \ref resetParams() is sufficient.
893 894
    ///
894 895
    /// See \ref resetParams() for examples.
895 896
    ///
896 897
    /// \return <tt>(*this)</tt>
897 898
    ///
898 899
    /// \see resetParams(), run()
899 900
    NetworkSimplex& reset() {
900 901
      // Resize vectors
901 902
      _node_num = countNodes(_graph);
902 903
      _arc_num = countArcs(_graph);
903 904
      int all_node_num = _node_num + 1;
904 905
      int max_arc_num = _arc_num + 2 * _node_num;
905 906

	
906 907
      _source.resize(max_arc_num);
907 908
      _target.resize(max_arc_num);
908 909

	
909 910
      _lower.resize(_arc_num);
910 911
      _upper.resize(_arc_num);
911 912
      _cap.resize(max_arc_num);
912 913
      _cost.resize(max_arc_num);
913 914
      _supply.resize(all_node_num);
914 915
      _flow.resize(max_arc_num);
915 916
      _pi.resize(all_node_num);
916 917

	
917 918
      _parent.resize(all_node_num);
918 919
      _pred.resize(all_node_num);
919 920
      _pred_dir.resize(all_node_num);
920 921
      _thread.resize(all_node_num);
921 922
      _rev_thread.resize(all_node_num);
922 923
      _succ_num.resize(all_node_num);
923 924
      _last_succ.resize(all_node_num);
924 925
      _state.resize(max_arc_num);
925 926

	
926 927
      // Copy the graph
927 928
      int i = 0;
928 929
      for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
929 930
        _node_id[n] = i;
930 931
      }
931 932
      if (_arc_mixing) {
932 933
        // Store the arcs in a mixed order
933
        int k = std::max(int(std::sqrt(double(_arc_num))), 10);
934
        const int skip = std::max(_arc_num / _node_num, 3);
934 935
        int i = 0, j = 0;
935 936
        for (ArcIt a(_graph); a != INVALID; ++a) {
936 937
          _arc_id[a] = i;
937 938
          _source[i] = _node_id[_graph.source(a)];
938 939
          _target[i] = _node_id[_graph.target(a)];
939
          if ((i += k) >= _arc_num) i = ++j;
940
          if ((i += skip) >= _arc_num) i = ++j;
940 941
        }
941 942
      } else {
942 943
        // Store the arcs in the original order
943 944
        int i = 0;
944 945
        for (ArcIt a(_graph); a != INVALID; ++a, ++i) {
945 946
          _arc_id[a] = i;
946 947
          _source[i] = _node_id[_graph.source(a)];
947 948
          _target[i] = _node_id[_graph.target(a)];
948 949
        }
949 950
      }
950 951

	
951 952
      // Reset parameters
952 953
      resetParams();
953 954
      return *this;
954 955
    }
955 956

	
956 957
    /// @}
957 958

	
958 959
    /// \name Query Functions
959 960
    /// The results of the algorithm can be obtained using these
960 961
    /// functions.\n
961 962
    /// The \ref run() function must be called before using them.
962 963

	
963 964
    /// @{
964 965

	
965 966
    /// \brief Return the total cost of the found flow.
966 967
    ///
967 968
    /// This function returns the total cost of the found flow.
968 969
    /// Its complexity is O(e).
969 970
    ///
970 971
    /// \note The return type of the function can be specified as a
971 972
    /// template parameter. For example,
972 973
    /// \code
973 974
    ///   ns.totalCost<double>();
974 975
    /// \endcode
975 976
    /// It is useful if the total cost cannot be stored in the \c Cost
976 977
    /// type of the algorithm, which is the default return type of the
977 978
    /// function.
978 979
    ///
979 980
    /// \pre \ref run() must be called before using this function.
980 981
    template <typename Number>
981 982
    Number totalCost() const {
982 983
      Number c = 0;
983 984
      for (ArcIt a(_graph); a != INVALID; ++a) {
984 985
        int i = _arc_id[a];
985 986
        c += Number(_flow[i]) * Number(_cost[i]);
986 987
      }
987 988
      return c;
988 989
    }
989 990

	
990 991
#ifndef DOXYGEN
991 992
    Cost totalCost() const {
992 993
      return totalCost<Cost>();
993 994
    }
994 995
#endif
995 996

	
996 997
    /// \brief Return the flow on the given arc.
997 998
    ///
998 999
    /// This function returns the flow on the given arc.
999 1000
    ///
1000 1001
    /// \pre \ref run() must be called before using this function.
1001 1002
    Value flow(const Arc& a) const {
1002 1003
      return _flow[_arc_id[a]];
1003 1004
    }
1004 1005

	
1005 1006
    /// \brief Return the flow map (the primal solution).
1006 1007
    ///
1007 1008
    /// This function copies the flow value on each arc into the given
1008 1009
    /// map. The \c Value type of the algorithm must be convertible to
1009 1010
    /// the \c Value type of the map.
1010 1011
    ///
1011 1012
    /// \pre \ref run() must be called before using this function.
1012 1013
    template <typename FlowMap>
1013 1014
    void flowMap(FlowMap &map) const {
1014 1015
      for (ArcIt a(_graph); a != INVALID; ++a) {
1015 1016
        map.set(a, _flow[_arc_id[a]]);
1016 1017
      }
1017 1018
    }
1018 1019

	
1019 1020
    /// \brief Return the potential (dual value) of the given node.
1020 1021
    ///
1021 1022
    /// This function returns the potential (dual value) of the
1022 1023
    /// given node.
1023 1024
    ///
1024 1025
    /// \pre \ref run() must be called before using this function.
1025 1026
    Cost potential(const Node& n) const {
1026 1027
      return _pi[_node_id[n]];
1027 1028
    }
1028 1029

	
1029 1030
    /// \brief Return the potential map (the dual solution).
1030 1031
    ///
1031 1032
    /// This function copies the potential (dual value) of each node
1032 1033
    /// into the given map.
1033 1034
    /// The \c Cost type of the algorithm must be convertible to the
1034 1035
    /// \c Value type of the map.
1035 1036
    ///
1036 1037
    /// \pre \ref run() must be called before using this function.
1037 1038
    template <typename PotentialMap>
1038 1039
    void potentialMap(PotentialMap &map) const {
1039 1040
      for (NodeIt n(_graph); n != INVALID; ++n) {
1040 1041
        map.set(n, _pi[_node_id[n]]);
1041 1042
      }
1042 1043
    }
1043 1044

	
1044 1045
    /// @}
1045 1046

	
1046 1047
  private:
1047 1048

	
1048 1049
    // Initialize internal data structures
1049 1050
    bool init() {
1050 1051
      if (_node_num == 0) return false;
1051 1052

	
1052 1053
      // Check the sum of supply values
1053 1054
      _sum_supply = 0;
1054 1055
      for (int i = 0; i != _node_num; ++i) {
1055 1056
        _sum_supply += _supply[i];
1056 1057
      }
1057 1058
      if ( !((_stype == GEQ && _sum_supply <= 0) ||
1058 1059
             (_stype == LEQ && _sum_supply >= 0)) ) return false;
1059 1060

	
1060 1061
      // Remove non-zero lower bounds
1061 1062
      if (_have_lower) {
1062 1063
        for (int i = 0; i != _arc_num; ++i) {
1063 1064
          Value c = _lower[i];
1064 1065
          if (c >= 0) {
1065 1066
            _cap[i] = _upper[i] < MAX ? _upper[i] - c : INF;
1066 1067
          } else {
1067 1068
            _cap[i] = _upper[i] < MAX + c ? _upper[i] - c : INF;
1068 1069
          }
1069 1070
          _supply[_source[i]] -= c;
1070 1071
          _supply[_target[i]] += c;
1071 1072
        }
1072 1073
      } else {
1073 1074
        for (int i = 0; i != _arc_num; ++i) {
1074 1075
          _cap[i] = _upper[i];
1075 1076
        }
1076 1077
      }
1077 1078

	
1078 1079
      // Initialize artifical cost
1079 1080
      Cost ART_COST;
1080 1081
      if (std::numeric_limits<Cost>::is_exact) {
1081 1082
        ART_COST = std::numeric_limits<Cost>::max() / 2 + 1;
1082 1083
      } else {
1083 1084
        ART_COST = 0;
1084 1085
        for (int i = 0; i != _arc_num; ++i) {
1085 1086
          if (_cost[i] > ART_COST) ART_COST = _cost[i];
1086 1087
        }
1087 1088
        ART_COST = (ART_COST + 1) * _node_num;
1088 1089
      }
1089 1090

	
1090 1091
      // Initialize arc maps
1091 1092
      for (int i = 0; i != _arc_num; ++i) {
1092 1093
        _flow[i] = 0;
1093 1094
        _state[i] = STATE_LOWER;
1094 1095
      }
1095 1096

	
1096 1097
      // Set data for the artificial root node
1097 1098
      _root = _node_num;
1098 1099
      _parent[_root] = -1;
1099 1100
      _pred[_root] = -1;
1100 1101
      _thread[_root] = 0;
1101 1102
      _rev_thread[0] = _root;
1102 1103
      _succ_num[_root] = _node_num + 1;
1103 1104
      _last_succ[_root] = _root - 1;
1104 1105
      _supply[_root] = -_sum_supply;
1105 1106
      _pi[_root] = 0;
1106 1107

	
1107 1108
      // Add artificial arcs and initialize the spanning tree data structure
1108 1109
      if (_sum_supply == 0) {
1109 1110
        // EQ supply constraints
1110 1111
        _search_arc_num = _arc_num;
1111 1112
        _all_arc_num = _arc_num + _node_num;
1112 1113
        for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1113 1114
          _parent[u] = _root;
1114 1115
          _pred[u] = e;
1115 1116
          _thread[u] = u + 1;
1116 1117
          _rev_thread[u + 1] = u;
1117 1118
          _succ_num[u] = 1;
1118 1119
          _last_succ[u] = u;
1119 1120
          _cap[e] = INF;
1120 1121
          _state[e] = STATE_TREE;
1121 1122
          if (_supply[u] >= 0) {
1122 1123
            _pred_dir[u] = DIR_UP;
1123 1124
            _pi[u] = 0;
1124 1125
            _source[e] = u;
1125 1126
            _target[e] = _root;
1126 1127
            _flow[e] = _supply[u];
1127 1128
            _cost[e] = 0;
1128 1129
          } else {
1129 1130
            _pred_dir[u] = DIR_DOWN;
1130 1131
            _pi[u] = ART_COST;
1131 1132
            _source[e] = _root;
0 comments (0 inline)