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 192 line context
... ...
@@ -543,197 +543,198 @@
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];
... ...
@@ -837,199 +838,199 @@
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
    ///
0 comments (0 inline)