gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Support multiple run() calls in NetworkSimplex (#234)
0 2 0
default
2 files changed with 90 insertions and 31 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

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

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

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

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

	
34 34
namespace lemon {
35 35

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

	
39 39
  /// \brief Implementation of the primal Network Simplex algorithm
40 40
  /// for finding a \ref min_cost_flow "minimum cost flow".
41 41
  ///
42 42
  /// \ref NetworkSimplex implements the primal Network Simplex algorithm
43 43
  /// for finding a \ref min_cost_flow "minimum cost flow".
44
  /// This algorithm is a specialized version of the linear programming
45
  /// simplex method directly for the minimum cost flow problem.
46
  /// It is one of the most efficient solution methods.
47
  ///
48
  /// In general this class is the fastest implementation available
49
  /// in LEMON for the minimum cost flow problem.
44 50
  ///
45 51
  /// \tparam GR The digraph type the algorithm runs on.
46 52
  /// \tparam V The value type used in the algorithm.
47 53
  /// By default it is \c int.
48 54
  ///
49
  /// \warning \c V must be a signed integer type.
55
  /// \warning The value type must be a signed integer type.
50 56
  ///
51 57
  /// \note %NetworkSimplex provides five different pivot rule
52 58
  /// implementations. For more information see \ref PivotRule.
53 59
  template <typename GR, typename V = int>
54 60
  class NetworkSimplex
55 61
  {
56 62
  public:
57 63

	
58 64
    /// The value type of the algorithm
59 65
    typedef V Value;
60 66
    /// The type of the flow map
61 67
    typedef typename GR::template ArcMap<Value> FlowMap;
62 68
    /// The type of the potential map
63 69
    typedef typename GR::template NodeMap<Value> PotentialMap;
64 70

	
65 71
  public:
66 72

	
67 73
    /// \brief Enum type for selecting the pivot rule.
68 74
    ///
69 75
    /// Enum type for selecting the pivot rule for the \ref run()
70 76
    /// function.
71 77
    ///
72 78
    /// \ref NetworkSimplex provides five different pivot rule
73 79
    /// implementations that significantly affect the running time
74 80
    /// of the algorithm.
75 81
    /// By default \ref BLOCK_SEARCH "Block Search" is used, which
76 82
    /// proved to be the most efficient and the most robust on various
77 83
    /// test inputs according to our benchmark tests.
78 84
    /// However another pivot rule can be selected using the \ref run()
79 85
    /// function with the proper parameter.
80 86
    enum PivotRule {
81 87

	
82 88
      /// The First Eligible pivot rule.
83 89
      /// The next eligible arc is selected in a wraparound fashion
84 90
      /// in every iteration.
85 91
      FIRST_ELIGIBLE,
86 92

	
87 93
      /// The Best Eligible pivot rule.
88 94
      /// The best eligible arc is selected in every iteration.
89 95
      BEST_ELIGIBLE,
90 96

	
91 97
      /// The Block Search pivot rule.
92 98
      /// A specified number of arcs are examined in every iteration
93 99
      /// in a wraparound fashion and the best eligible arc is selected
94 100
      /// from this block.
95 101
      BLOCK_SEARCH,
96 102

	
97 103
      /// The Candidate List pivot rule.
98 104
      /// In a major iteration a candidate list is built from eligible arcs
99 105
      /// in a wraparound fashion and in the following minor iterations
100 106
      /// the best eligible arc is selected from this list.
101 107
      CANDIDATE_LIST,
102 108

	
103 109
      /// The Altering Candidate List pivot rule.
104 110
      /// It is a modified version of the Candidate List method.
105 111
      /// It keeps only the several best eligible arcs from the former
106 112
      /// candidate list and extends this list in every iteration.
107 113
      ALTERING_LIST
108 114
    };
109 115

	
110 116
  private:
111 117

	
112 118
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
113 119

	
114 120
    typedef typename GR::template ArcMap<Value> ValueArcMap;
115 121
    typedef typename GR::template NodeMap<Value> ValueNodeMap;
116 122

	
117 123
    typedef std::vector<Arc> ArcVector;
118 124
    typedef std::vector<Node> NodeVector;
119 125
    typedef std::vector<int> IntVector;
120 126
    typedef std::vector<bool> BoolVector;
121 127
    typedef std::vector<Value> ValueVector;
122 128

	
123 129
    // State constants for arcs
124 130
    enum ArcStateEnum {
125 131
      STATE_UPPER = -1,
126 132
      STATE_TREE  =  0,
127 133
      STATE_LOWER =  1
128 134
    };
129 135

	
130 136
  private:
131 137

	
132 138
    // Data related to the underlying digraph
133 139
    const GR &_graph;
134 140
    int _node_num;
135 141
    int _arc_num;
136 142

	
137 143
    // Parameters of the problem
138 144
    ValueArcMap *_plower;
139 145
    ValueArcMap *_pupper;
140 146
    ValueArcMap *_pcost;
141 147
    ValueNodeMap *_psupply;
142 148
    bool _pstsup;
143 149
    Node _psource, _ptarget;
144 150
    Value _pstflow;
145 151

	
... ...
@@ -696,447 +702,501 @@
696 702
        (*_pcost)[a] = map[a];
697 703
      }
698 704
      return *this;
699 705
    }
700 706

	
701 707
    /// \brief Set the supply values of the nodes.
702 708
    ///
703 709
    /// This function sets the supply values of the nodes.
704 710
    /// If neither this function nor \ref stSupply() is used before
705 711
    /// calling \ref run(), the supply of each node will be set to zero.
706 712
    /// (It makes sense only if non-zero lower bounds are given.)
707 713
    ///
708 714
    /// \param map A node map storing the supply values.
709 715
    /// Its \c Value type must be convertible to the \c Value type
710 716
    /// of the algorithm.
711 717
    ///
712 718
    /// \return <tt>(*this)</tt>
713 719
    template<typename SUP>
714 720
    NetworkSimplex& supplyMap(const SUP& map) {
715 721
      delete _psupply;
716 722
      _pstsup = false;
717 723
      _psupply = new ValueNodeMap(_graph);
718 724
      for (NodeIt n(_graph); n != INVALID; ++n) {
719 725
        (*_psupply)[n] = map[n];
720 726
      }
721 727
      return *this;
722 728
    }
723 729

	
724 730
    /// \brief Set single source and target nodes and a supply value.
725 731
    ///
726 732
    /// This function sets a single source node and a single target node
727 733
    /// and the required flow value.
728 734
    /// If neither this function nor \ref supplyMap() is used before
729 735
    /// calling \ref run(), the supply of each node will be set to zero.
730 736
    /// (It makes sense only if non-zero lower bounds are given.)
731 737
    ///
732 738
    /// \param s The source node.
733 739
    /// \param t The target node.
734 740
    /// \param k The required amount of flow from node \c s to node \c t
735 741
    /// (i.e. the supply of \c s and the demand of \c t).
736 742
    ///
737 743
    /// \return <tt>(*this)</tt>
738 744
    NetworkSimplex& stSupply(const Node& s, const Node& t, Value k) {
739 745
      delete _psupply;
740 746
      _psupply = NULL;
741 747
      _pstsup = true;
742 748
      _psource = s;
743 749
      _ptarget = t;
744 750
      _pstflow = k;
745 751
      return *this;
746 752
    }
747 753

	
748 754
    /// \brief Set the flow map.
749 755
    ///
750 756
    /// This function sets the flow map.
751 757
    /// If it is not used before calling \ref run(), an instance will
752 758
    /// be allocated automatically. The destructor deallocates this
753 759
    /// automatically allocated map, of course.
754 760
    ///
755 761
    /// \return <tt>(*this)</tt>
756 762
    NetworkSimplex& flowMap(FlowMap& map) {
757 763
      if (_local_flow) {
758 764
        delete _flow_map;
759 765
        _local_flow = false;
760 766
      }
761 767
      _flow_map = &map;
762 768
      return *this;
763 769
    }
764 770

	
765 771
    /// \brief Set the potential map.
766 772
    ///
767 773
    /// This function sets the potential map, which is used for storing
768 774
    /// the dual solution.
769 775
    /// If it is not used before calling \ref run(), an instance will
770 776
    /// be allocated automatically. The destructor deallocates this
771 777
    /// automatically allocated map, of course.
772 778
    ///
773 779
    /// \return <tt>(*this)</tt>
774 780
    NetworkSimplex& potentialMap(PotentialMap& map) {
775 781
      if (_local_potential) {
776 782
        delete _potential_map;
777 783
        _local_potential = false;
778 784
      }
779 785
      _potential_map = &map;
780 786
      return *this;
781 787
    }
782 788

	
783 789
    /// \name Execution Control
784 790
    /// The algorithm can be executed using \ref run().
785 791

	
786 792
    /// @{
787 793

	
788 794
    /// \brief Run the algorithm.
789 795
    ///
790 796
    /// This function runs the algorithm.
791 797
    /// The paramters can be specified using \ref lowerMap(),
792
    /// \ref upperMap(), \ref capacityMap(), \ref boundMaps(), 
798
    /// \ref upperMap(), \ref capacityMap(), \ref boundMaps(),
793 799
    /// \ref costMap(), \ref supplyMap() and \ref stSupply()
794 800
    /// functions. For example,
795 801
    /// \code
796 802
    ///   NetworkSimplex<ListDigraph> ns(graph);
797 803
    ///   ns.boundMaps(lower, upper).costMap(cost)
798 804
    ///     .supplyMap(sup).run();
799 805
    /// \endcode
800 806
    ///
807
    /// This function can be called more than once. All the parameters
808
    /// that have been given are kept for the next call, unless
809
    /// \ref reset() is called, thus only the modified parameters
810
    /// have to be set again. See \ref reset() for examples.
811
    ///
801 812
    /// \param pivot_rule The pivot rule that will be used during the
802 813
    /// algorithm. For more information see \ref PivotRule.
803 814
    ///
804 815
    /// \return \c true if a feasible flow can be found.
805 816
    bool run(PivotRule pivot_rule = BLOCK_SEARCH) {
806 817
      return init() && start(pivot_rule);
807 818
    }
808 819

	
820
    /// \brief Reset all the parameters that have been given before.
821
    ///
822
    /// This function resets all the paramaters that have been given
823
    /// using \ref lowerMap(), \ref upperMap(), \ref capacityMap(),
824
    /// \ref boundMaps(), \ref costMap(), \ref supplyMap() and
825
    /// \ref stSupply() functions before.
826
    ///
827
    /// It is useful for multiple run() calls. If this function is not
828
    /// used, all the parameters given before are kept for the next
829
    /// \ref run() call.
830
    ///
831
    /// For example,
832
    /// \code
833
    ///   NetworkSimplex<ListDigraph> ns(graph);
834
    ///
835
    ///   // First run
836
    ///   ns.lowerMap(lower).capacityMap(cap).costMap(cost)
837
    ///     .supplyMap(sup).run();
838
    ///
839
    ///   // Run again with modified cost map (reset() is not called,
840
    ///   // so only the cost map have to be set again)
841
    ///   cost[e] += 100;
842
    ///   ns.costMap(cost).run();
843
    ///
844
    ///   // Run again from scratch using reset()
845
    ///   // (the lower bounds will be set to zero on all arcs)
846
    ///   ns.reset();
847
    ///   ns.capacityMap(cap).costMap(cost)
848
    ///     .supplyMap(sup).run();
849
    /// \endcode
850
    ///
851
    /// \return <tt>(*this)</tt>
852
    NetworkSimplex& reset() {
853
      delete _plower;
854
      delete _pupper;
855
      delete _pcost;
856
      delete _psupply;
857
      _plower = NULL;
858
      _pupper = NULL;
859
      _pcost = NULL;
860
      _psupply = NULL;
861
      _pstsup = false;
862
      return *this;
863
    }
864

	
809 865
    /// @}
810 866

	
811 867
    /// \name Query Functions
812 868
    /// The results of the algorithm can be obtained using these
813 869
    /// functions.\n
814 870
    /// The \ref run() function must be called before using them.
815 871

	
816 872
    /// @{
817 873

	
818 874
    /// \brief Return the total cost of the found flow.
819 875
    ///
820 876
    /// This function returns the total cost of the found flow.
821 877
    /// The complexity of the function is \f$ O(e) \f$.
822 878
    ///
823 879
    /// \note The return type of the function can be specified as a
824 880
    /// template parameter. For example,
825 881
    /// \code
826 882
    ///   ns.totalCost<double>();
827 883
    /// \endcode
828 884
    /// It is useful if the total cost cannot be stored in the \c Value
829 885
    /// type of the algorithm, which is the default return type of the
830 886
    /// function.
831 887
    ///
832 888
    /// \pre \ref run() must be called before using this function.
833 889
    template <typename Num>
834 890
    Num totalCost() const {
835 891
      Num c = 0;
836 892
      if (_pcost) {
837 893
        for (ArcIt e(_graph); e != INVALID; ++e)
838 894
          c += (*_flow_map)[e] * (*_pcost)[e];
839 895
      } else {
840 896
        for (ArcIt e(_graph); e != INVALID; ++e)
841 897
          c += (*_flow_map)[e];
842 898
      }
843 899
      return c;
844 900
    }
845 901

	
846 902
#ifndef DOXYGEN
847 903
    Value totalCost() const {
848 904
      return totalCost<Value>();
849 905
    }
850 906
#endif
851 907

	
852 908
    /// \brief Return the flow on the given arc.
853 909
    ///
854 910
    /// This function returns the flow on the given arc.
855 911
    ///
856 912
    /// \pre \ref run() must be called before using this function.
857 913
    Value flow(const Arc& a) const {
858 914
      return (*_flow_map)[a];
859 915
    }
860 916

	
861 917
    /// \brief Return a const reference to the flow map.
862 918
    ///
863 919
    /// This function returns a const reference to an arc map storing
864 920
    /// the found flow.
865 921
    ///
866 922
    /// \pre \ref run() must be called before using this function.
867 923
    const FlowMap& flowMap() const {
868 924
      return *_flow_map;
869 925
    }
870 926

	
871 927
    /// \brief Return the potential (dual value) of the given node.
872 928
    ///
873 929
    /// This function returns the potential (dual value) of the
874 930
    /// given node.
875 931
    ///
876 932
    /// \pre \ref run() must be called before using this function.
877 933
    Value potential(const Node& n) const {
878 934
      return (*_potential_map)[n];
879 935
    }
880 936

	
881 937
    /// \brief Return a const reference to the potential map
882 938
    /// (the dual solution).
883 939
    ///
884 940
    /// This function returns a const reference to a node map storing
885 941
    /// the found potentials, which form the dual solution of the
886 942
    /// \ref min_cost_flow "minimum cost flow" problem.
887 943
    ///
888 944
    /// \pre \ref run() must be called before using this function.
889 945
    const PotentialMap& potentialMap() const {
890 946
      return *_potential_map;
891 947
    }
892 948

	
893 949
    /// @}
894 950

	
895 951
  private:
896 952

	
897 953
    // Initialize internal data structures
898 954
    bool init() {
899 955
      // Initialize result maps
900 956
      if (!_flow_map) {
901 957
        _flow_map = new FlowMap(_graph);
902 958
        _local_flow = true;
903 959
      }
904 960
      if (!_potential_map) {
905 961
        _potential_map = new PotentialMap(_graph);
906 962
        _local_potential = true;
907 963
      }
908 964

	
909 965
      // Initialize vectors
910 966
      _node_num = countNodes(_graph);
911 967
      _arc_num = countArcs(_graph);
912 968
      int all_node_num = _node_num + 1;
913 969
      int all_arc_num = _arc_num + _node_num;
914 970
      if (_node_num == 0) return false;
915 971

	
916 972
      _arc_ref.resize(_arc_num);
917 973
      _source.resize(all_arc_num);
918 974
      _target.resize(all_arc_num);
919 975

	
920 976
      _cap.resize(all_arc_num);
921 977
      _cost.resize(all_arc_num);
922 978
      _supply.resize(all_node_num);
923
      _flow.resize(all_arc_num, 0);
924
      _pi.resize(all_node_num, 0);
979
      _flow.resize(all_arc_num);
980
      _pi.resize(all_node_num);
925 981

	
926 982
      _parent.resize(all_node_num);
927 983
      _pred.resize(all_node_num);
928 984
      _forward.resize(all_node_num);
929 985
      _thread.resize(all_node_num);
930 986
      _rev_thread.resize(all_node_num);
931 987
      _succ_num.resize(all_node_num);
932 988
      _last_succ.resize(all_node_num);
933
      _state.resize(all_arc_num, STATE_LOWER);
989
      _state.resize(all_arc_num);
934 990

	
935 991
      // Initialize node related data
936 992
      bool valid_supply = true;
937 993
      if (!_pstsup && !_psupply) {
938 994
        _pstsup = true;
939 995
        _psource = _ptarget = NodeIt(_graph);
940 996
        _pstflow = 0;
941 997
      }
942 998
      if (_psupply) {
943 999
        Value sum = 0;
944 1000
        int i = 0;
945 1001
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
946 1002
          _node_id[n] = i;
947 1003
          _supply[i] = (*_psupply)[n];
948 1004
          sum += _supply[i];
949 1005
        }
950 1006
        valid_supply = (sum == 0);
951 1007
      } else {
952 1008
        int i = 0;
953 1009
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
954 1010
          _node_id[n] = i;
955 1011
          _supply[i] = 0;
956 1012
        }
957 1013
        _supply[_node_id[_psource]] =  _pstflow;
958 1014
        _supply[_node_id[_ptarget]]   = -_pstflow;
959 1015
      }
960 1016
      if (!valid_supply) return false;
961 1017

	
962 1018
      // Set data for the artificial root node
963 1019
      _root = _node_num;
964 1020
      _parent[_root] = -1;
965 1021
      _pred[_root] = -1;
966 1022
      _thread[_root] = 0;
967 1023
      _rev_thread[0] = _root;
968 1024
      _succ_num[_root] = all_node_num;
969 1025
      _last_succ[_root] = _root - 1;
970 1026
      _supply[_root] = 0;
971 1027
      _pi[_root] = 0;
972 1028

	
973 1029
      // Store the arcs in a mixed order
974 1030
      int k = std::max(int(sqrt(_arc_num)), 10);
975 1031
      int i = 0;
976 1032
      for (ArcIt e(_graph); e != INVALID; ++e) {
977 1033
        _arc_ref[i] = e;
978 1034
        if ((i += k) >= _arc_num) i = (i % k) + 1;
979 1035
      }
980 1036

	
981 1037
      // Initialize arc maps
982 1038
      if (_pupper && _pcost) {
983 1039
        for (int i = 0; i != _arc_num; ++i) {
984 1040
          Arc e = _arc_ref[i];
985 1041
          _source[i] = _node_id[_graph.source(e)];
986 1042
          _target[i] = _node_id[_graph.target(e)];
987 1043
          _cap[i] = (*_pupper)[e];
988 1044
          _cost[i] = (*_pcost)[e];
1045
          _flow[i] = 0;
1046
          _state[i] = STATE_LOWER;
989 1047
        }
990 1048
      } else {
991 1049
        for (int i = 0; i != _arc_num; ++i) {
992 1050
          Arc e = _arc_ref[i];
993 1051
          _source[i] = _node_id[_graph.source(e)];
994 1052
          _target[i] = _node_id[_graph.target(e)];
1053
          _flow[i] = 0;
1054
          _state[i] = STATE_LOWER;
995 1055
        }
996 1056
        if (_pupper) {
997 1057
          for (int i = 0; i != _arc_num; ++i)
998 1058
            _cap[i] = (*_pupper)[_arc_ref[i]];
999 1059
        } else {
1000 1060
          Value val = std::numeric_limits<Value>::max();
1001 1061
          for (int i = 0; i != _arc_num; ++i)
1002 1062
            _cap[i] = val;
1003 1063
        }
1004 1064
        if (_pcost) {
1005 1065
          for (int i = 0; i != _arc_num; ++i)
1006 1066
            _cost[i] = (*_pcost)[_arc_ref[i]];
1007 1067
        } else {
1008 1068
          for (int i = 0; i != _arc_num; ++i)
1009 1069
            _cost[i] = 1;
1010 1070
        }
1011 1071
      }
1012 1072

	
1013 1073
      // Remove non-zero lower bounds
1014 1074
      if (_plower) {
1015 1075
        for (int i = 0; i != _arc_num; ++i) {
1016 1076
          Value c = (*_plower)[_arc_ref[i]];
1017 1077
          if (c != 0) {
1018 1078
            _cap[i] -= c;
1019 1079
            _supply[_source[i]] -= c;
1020 1080
            _supply[_target[i]] += c;
1021 1081
          }
1022 1082
        }
1023 1083
      }
1024 1084

	
1025 1085
      // Add artificial arcs and initialize the spanning tree data structure
1026 1086
      Value max_cap = std::numeric_limits<Value>::max();
1027 1087
      Value max_cost = std::numeric_limits<Value>::max() / 4;
1028 1088
      for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1029 1089
        _thread[u] = u + 1;
1030 1090
        _rev_thread[u + 1] = u;
1031 1091
        _succ_num[u] = 1;
1032 1092
        _last_succ[u] = u;
1033 1093
        _parent[u] = _root;
1034 1094
        _pred[u] = e;
1095
        _cost[e] = max_cost;
1096
        _cap[e] = max_cap;
1097
        _state[e] = STATE_TREE;
1035 1098
        if (_supply[u] >= 0) {
1036 1099
          _flow[e] = _supply[u];
1037 1100
          _forward[u] = true;
1038 1101
          _pi[u] = -max_cost;
1039 1102
        } else {
1040 1103
          _flow[e] = -_supply[u];
1041 1104
          _forward[u] = false;
1042 1105
          _pi[u] = max_cost;
1043 1106
        }
1044
        _cost[e] = max_cost;
1045
        _cap[e] = max_cap;
1046
        _state[e] = STATE_TREE;
1047 1107
      }
1048 1108

	
1049 1109
      return true;
1050 1110
    }
1051 1111

	
1052 1112
    // Find the join node
1053 1113
    void findJoinNode() {
1054 1114
      int u = _source[in_arc];
1055 1115
      int v = _target[in_arc];
1056 1116
      while (u != v) {
1057 1117
        if (_succ_num[u] < _succ_num[v]) {
1058 1118
          u = _parent[u];
1059 1119
        } else {
1060 1120
          v = _parent[v];
1061 1121
        }
1062 1122
      }
1063 1123
      join = u;
1064 1124
    }
1065 1125

	
1066 1126
    // Find the leaving arc of the cycle and returns true if the
1067 1127
    // leaving arc is not the same as the entering arc
1068 1128
    bool findLeavingArc() {
1069 1129
      // Initialize first and second nodes according to the direction
1070 1130
      // of the cycle
1071 1131
      if (_state[in_arc] == STATE_LOWER) {
1072 1132
        first  = _source[in_arc];
1073 1133
        second = _target[in_arc];
1074 1134
      } else {
1075 1135
        first  = _target[in_arc];
1076 1136
        second = _source[in_arc];
1077 1137
      }
1078 1138
      delta = _cap[in_arc];
1079 1139
      int result = 0;
1080 1140
      Value d;
1081 1141
      int e;
1082 1142

	
1083 1143
      // Search the cycle along the path form the first node to the root
1084 1144
      for (int u = first; u != join; u = _parent[u]) {
1085 1145
        e = _pred[u];
1086 1146
        d = _forward[u] ? _flow[e] : _cap[e] - _flow[e];
1087 1147
        if (d < delta) {
1088 1148
          delta = d;
1089 1149
          u_out = u;
1090 1150
          result = 1;
1091 1151
        }
1092 1152
      }
1093 1153
      // Search the cycle along the path form the second node to the root
1094 1154
      for (int u = second; u != join; u = _parent[u]) {
1095 1155
        e = _pred[u];
1096 1156
        d = _forward[u] ? _cap[e] - _flow[e] : _flow[e];
1097 1157
        if (d <= delta) {
1098 1158
          delta = d;
1099 1159
          u_out = u;
1100 1160
          result = 2;
1101 1161
        }
1102 1162
      }
1103 1163

	
1104 1164
      if (result == 1) {
1105 1165
        u_in = first;
1106 1166
        v_in = second;
1107 1167
      } else {
1108 1168
        u_in = second;
1109 1169
        v_in = first;
1110 1170
      }
1111 1171
      return result != 0;
1112 1172
    }
1113 1173

	
1114 1174
    // Change _flow and _state vectors
1115 1175
    void changeFlow(bool change) {
1116 1176
      // Augment along the cycle
1117 1177
      if (delta > 0) {
1118 1178
        Value val = _state[in_arc] * delta;
1119 1179
        _flow[in_arc] += val;
1120 1180
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
1121 1181
          _flow[_pred[u]] += _forward[u] ? -val : val;
1122 1182
        }
1123 1183
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
1124 1184
          _flow[_pred[u]] += _forward[u] ? val : -val;
1125 1185
        }
1126 1186
      }
1127 1187
      // Update the state of the entering and leaving arcs
1128 1188
      if (change) {
1129 1189
        _state[in_arc] = STATE_TREE;
1130 1190
        _state[_pred[u_out]] =
1131 1191
          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
1132 1192
      } else {
1133 1193
        _state[in_arc] = -_state[in_arc];
1134 1194
      }
1135 1195
    }
1136 1196

	
1137 1197
    // Update the tree structure
1138 1198
    void updateTreeStructure() {
1139 1199
      int u, w;
1140 1200
      int old_rev_thread = _rev_thread[u_out];
1141 1201
      int old_succ_num = _succ_num[u_out];
1142 1202
      int old_last_succ = _last_succ[u_out];
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2009
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <iostream>
20 20
#include <fstream>
21 21

	
22 22
#include <lemon/list_graph.h>
23 23
#include <lemon/lgf_reader.h>
24 24

	
25 25
#include <lemon/network_simplex.h>
26 26

	
27 27
#include <lemon/concepts/digraph.h>
28 28
#include <lemon/concept_check.h>
29 29

	
30 30
#include "test_tools.h"
31 31

	
32 32
using namespace lemon;
33 33

	
34 34
char test_lgf[] =
35 35
  "@nodes\n"
36 36
  "label  sup1 sup2 sup3\n"
37 37
  "    1    20   27    0\n"
38 38
  "    2    -4    0    0\n"
39 39
  "    3     0    0    0\n"
40 40
  "    4     0    0    0\n"
41 41
  "    5     9    0    0\n"
42 42
  "    6    -6    0    0\n"
43 43
  "    7     0    0    0\n"
44 44
  "    8     0    0    0\n"
45 45
  "    9     3    0    0\n"
46 46
  "   10    -2    0    0\n"
47 47
  "   11     0    0    0\n"
48 48
  "   12   -20  -27    0\n"
49 49
  "\n"
50 50
  "@arcs\n"
51 51
  "       cost  cap low1 low2\n"
52 52
  " 1  2    70   11    0    8\n"
53 53
  " 1  3   150    3    0    1\n"
54 54
  " 1  4    80   15    0    2\n"
55 55
  " 2  8    80   12    0    0\n"
56 56
  " 3  5   140    5    0    3\n"
57 57
  " 4  6    60   10    0    1\n"
58 58
  " 4  7    80    2    0    0\n"
59 59
  " 4  8   110    3    0    0\n"
60 60
  " 5  7    60   14    0    0\n"
61 61
  " 5 11   120   12    0    0\n"
62 62
  " 6  3     0    3    0    0\n"
63 63
  " 6  9   140    4    0    0\n"
64 64
  " 6 10    90    8    0    0\n"
65 65
  " 7  1    30    5    0    0\n"
66 66
  " 8 12    60   16    0    4\n"
67 67
  " 9 12    50    6    0    0\n"
68 68
  "10 12    70   13    0    5\n"
69 69
  "10  2   100    7    0    0\n"
70 70
  "10  7    60   10    0    0\n"
71 71
  "11 10    20   14    0    6\n"
72 72
  "12 11    30   10    0    0\n"
73 73
  "\n"
74 74
  "@attributes\n"
75 75
  "source 1\n"
76 76
  "target 12\n";
77 77

	
78 78

	
79 79
// Check the interface of an MCF algorithm
80 80
template <typename GR, typename Value>
81 81
class McfClassConcept
82 82
{
83 83
public:
84 84

	
85 85
  template <typename MCF>
86 86
  struct Constraints {
87 87
    void constraints() {
88 88
      checkConcept<concepts::Digraph, GR>();
89 89

	
90 90
      MCF mcf(g);
91 91

	
92
      b = mcf.lowerMap(lower)
92
      b = mcf.reset()
93
             .lowerMap(lower)
93 94
             .upperMap(upper)
94 95
             .capacityMap(upper)
95 96
             .boundMaps(lower, upper)
96 97
             .costMap(cost)
97 98
             .supplyMap(sup)
98 99
             .stSupply(n, n, k)
99 100
             .run();
100 101

	
101 102
      const typename MCF::FlowMap &fm = mcf.flowMap();
102 103
      const typename MCF::PotentialMap &pm = mcf.potentialMap();
103 104

	
104 105
      v = mcf.totalCost();
105 106
      double x = mcf.template totalCost<double>();
106 107
      v = mcf.flow(a);
107 108
      v = mcf.potential(n);
108 109
      mcf.flowMap(flow);
109 110
      mcf.potentialMap(pot);
110 111

	
111 112
      ignore_unused_variable_warning(fm);
112 113
      ignore_unused_variable_warning(pm);
113 114
      ignore_unused_variable_warning(x);
114 115
    }
115 116

	
116 117
    typedef typename GR::Node Node;
117 118
    typedef typename GR::Arc Arc;
118 119
    typedef concepts::ReadMap<Node, Value> NM;
119 120
    typedef concepts::ReadMap<Arc, Value> AM;
120 121

	
121 122
    const GR &g;
122 123
    const AM &lower;
123 124
    const AM &upper;
124 125
    const AM &cost;
125 126
    const NM &sup;
126 127
    const Node &n;
127 128
    const Arc &a;
128 129
    const Value &k;
129 130
    Value v;
130 131
    bool b;
131 132

	
132 133
    typename MCF::FlowMap &flow;
133 134
    typename MCF::PotentialMap &pot;
134 135
  };
135 136

	
136 137
};
137 138

	
138 139

	
139 140
// Check the feasibility of the given flow (primal soluiton)
140 141
template < typename GR, typename LM, typename UM,
141 142
           typename SM, typename FM >
142 143
bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
143 144
                const SM& supply, const FM& flow )
144 145
{
145 146
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
146 147

	
147 148
  for (ArcIt e(gr); e != INVALID; ++e) {
148 149
    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
149 150
  }
150 151

	
151 152
  for (NodeIt n(gr); n != INVALID; ++n) {
152 153
    typename SM::Value sum = 0;
153 154
    for (OutArcIt e(gr, n); e != INVALID; ++e)
154 155
      sum += flow[e];
155 156
    for (InArcIt e(gr, n); e != INVALID; ++e)
156 157
      sum -= flow[e];
157 158
    if (sum != supply[n]) return false;
158 159
  }
159 160

	
160 161
  return true;
161 162
}
162 163

	
163 164
// Check the feasibility of the given potentials (dual soluiton)
164 165
// using the "Complementary Slackness" optimality condition
165 166
template < typename GR, typename LM, typename UM,
166 167
           typename CM, typename FM, typename PM >
167 168
bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
168 169
                     const CM& cost, const FM& flow, const PM& pi )
169 170
{
170 171
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
171 172

	
172 173
  bool opt = true;
173 174
  for (ArcIt e(gr); opt && e != INVALID; ++e) {
174 175
    typename CM::Value red_cost =
175 176
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
176 177
    opt = red_cost == 0 ||
177 178
          (red_cost > 0 && flow[e] == lower[e]) ||
178 179
          (red_cost < 0 && flow[e] == upper[e]);
179 180
  }
180 181
  return opt;
181 182
}
182 183

	
183 184
// Run a minimum cost flow algorithm and check the results
184 185
template < typename MCF, typename GR,
185 186
           typename LM, typename UM,
186 187
           typename CM, typename SM >
187 188
void checkMcf( const MCF& mcf, bool mcf_result,
188 189
               const GR& gr, const LM& lower, const UM& upper,
189 190
               const CM& cost, const SM& supply,
190 191
               bool result, typename CM::Value total,
191 192
               const std::string &test_id = "" )
192 193
{
193 194
  check(mcf_result == result, "Wrong result " + test_id);
194 195
  if (result) {
195 196
    check(checkFlow(gr, lower, upper, supply, mcf.flowMap()),
196 197
          "The flow is not feasible " + test_id);
197 198
    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
198 199
    check(checkPotential(gr, lower, upper, cost, mcf.flowMap(),
199 200
                         mcf.potentialMap()),
200 201
          "Wrong potentials " + test_id);
201 202
  }
202 203
}
203 204

	
204 205
int main()
205 206
{
206 207
  // Check the interfaces
207 208
  {
208 209
    typedef int Value;
209 210
    // TODO: This typedef should be enabled if the standard maps are
210 211
    // reference maps in the graph concepts (See #190).
211 212
/**/
212 213
    //typedef concepts::Digraph GR;
213 214
    typedef ListDigraph GR;
214 215
/**/
215 216
    checkConcept< McfClassConcept<GR, Value>,
216 217
                  NetworkSimplex<GR, Value> >();
217 218
  }
218 219

	
219 220
  // Run various MCF tests
220 221
  typedef ListDigraph Digraph;
221 222
  DIGRAPH_TYPEDEFS(ListDigraph);
222 223

	
223 224
  // Read the test digraph
224 225
  Digraph gr;
225 226
  Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), u(gr);
226 227
  Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr);
227 228
  ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
228 229
  Node v, w;
229 230

	
230 231
  std::istringstream input(test_lgf);
231 232
  DigraphReader<Digraph>(gr, input)
232 233
    .arcMap("cost", c)
233 234
    .arcMap("cap", u)
234 235
    .arcMap("low1", l1)
235 236
    .arcMap("low2", l2)
236 237
    .nodeMap("sup1", s1)
237 238
    .nodeMap("sup2", s2)
238 239
    .nodeMap("sup3", s3)
239 240
    .node("source", v)
240 241
    .node("target", w)
241 242
    .run();
242 243

	
243 244
  // A. Test NetworkSimplex with the default pivot rule
244 245
  {
245
    NetworkSimplex<Digraph> mcf1(gr), mcf2(gr), mcf3(gr), mcf4(gr),
246
                            mcf5(gr), mcf6(gr), mcf7(gr), mcf8(gr);
246
    NetworkSimplex<Digraph> mcf(gr);
247 247

	
248
    checkMcf(mcf1, mcf1.upperMap(u).costMap(c).supplyMap(s1).run(),
248
    mcf.upperMap(u).costMap(c);
249
    checkMcf(mcf, mcf.supplyMap(s1).run(),
249 250
             gr, l1, u, c, s1, true,  5240, "#A1");
250
    checkMcf(mcf2, mcf2.upperMap(u).costMap(c).stSupply(v, w, 27).run(),
251
    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
251 252
             gr, l1, u, c, s2, true,  7620, "#A2");
252
    checkMcf(mcf3, mcf3.boundMaps(l2, u).costMap(c).supplyMap(s1).run(),
253
    mcf.lowerMap(l2);
254
    checkMcf(mcf, mcf.supplyMap(s1).run(),
253 255
             gr, l2, u, c, s1, true,  5970, "#A3");
254
    checkMcf(mcf4, mcf4.boundMaps(l2, u).costMap(c).stSupply(v, w, 27).run(),
256
    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
255 257
             gr, l2, u, c, s2, true,  8010, "#A4");
256
    checkMcf(mcf5, mcf5.supplyMap(s1).run(),
258
    mcf.reset();
259
    checkMcf(mcf, mcf.supplyMap(s1).run(),
257 260
             gr, l1, cu, cc, s1, true,  74, "#A5");
258
    checkMcf(mcf6, mcf6.stSupply(v, w, 27).lowerMap(l2).run(),
261
    checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
259 262
             gr, l2, cu, cc, s2, true,  94, "#A6");
260
    checkMcf(mcf7, mcf7.run(),
263
    mcf.reset();
264
    checkMcf(mcf, mcf.run(),
261 265
             gr, l1, cu, cc, s3, true,   0, "#A7");
262
    checkMcf(mcf8, mcf8.boundMaps(l2, u).run(),
266
    checkMcf(mcf, mcf.boundMaps(l2, u).run(),
263 267
             gr, l2, u, cc, s3, false,   0, "#A8");
264 268
  }
265 269

	
266 270
  // B. Test NetworkSimplex with each pivot rule
267 271
  {
268
    NetworkSimplex<Digraph> mcf1(gr), mcf2(gr), mcf3(gr), mcf4(gr), mcf5(gr);
269
    NetworkSimplex<Digraph>::PivotRule pr;
272
    NetworkSimplex<Digraph> mcf(gr);
273
    mcf.supplyMap(s1).costMap(c).capacityMap(u).lowerMap(l2);
270 274

	
271
    pr = NetworkSimplex<Digraph>::FIRST_ELIGIBLE;
272
    checkMcf(mcf1, mcf1.boundMaps(l2, u).costMap(c).supplyMap(s1).run(pr),
275
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::FIRST_ELIGIBLE),
273 276
             gr, l2, u, c, s1, true,  5970, "#B1");
274
    pr = NetworkSimplex<Digraph>::BEST_ELIGIBLE;
275
    checkMcf(mcf2, mcf2.boundMaps(l2, u).costMap(c).supplyMap(s1).run(pr),
277
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BEST_ELIGIBLE),
276 278
             gr, l2, u, c, s1, true,  5970, "#B2");
277
    pr = NetworkSimplex<Digraph>::BLOCK_SEARCH;
278
    checkMcf(mcf3, mcf3.boundMaps(l2, u).costMap(c).supplyMap(s1).run(pr),
279
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BLOCK_SEARCH),
279 280
             gr, l2, u, c, s1, true,  5970, "#B3");
280
    pr = NetworkSimplex<Digraph>::CANDIDATE_LIST;
281
    checkMcf(mcf4, mcf4.boundMaps(l2, u).costMap(c).supplyMap(s1).run(pr),
281
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::CANDIDATE_LIST),
282 282
             gr, l2, u, c, s1, true,  5970, "#B4");
283
    pr = NetworkSimplex<Digraph>::ALTERING_LIST;
284
    checkMcf(mcf5, mcf5.boundMaps(l2, u).costMap(c).supplyMap(s1).run(pr),
283
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::ALTERING_LIST),
285 284
             gr, l2, u, c, s1, true,  5970, "#B5");
286 285
  }
287 286

	
288 287
  return 0;
289 288
}
0 comments (0 inline)