gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Bug fix in NetworkSimplex (#234)
0 1 0
default
1 file changed with 7 insertions and 6 deletions:
↑ Collapse diff ↑
Ignore white space 768 line context
... ...
@@ -763,820 +763,821 @@
763 763
    template <typename LOWER, typename UPPER>
764 764
    NetworkSimplex& boundMaps(const LOWER& lower, const UPPER& upper) {
765 765
      return lowerMap(lower).upperMap(upper);
766 766
    }
767 767

	
768 768
    /// \brief Set the costs of the arcs.
769 769
    ///
770 770
    /// This function sets the costs of the arcs.
771 771
    /// If it is not used before calling \ref run(), the costs
772 772
    /// will be set to \c 1 on all arcs.
773 773
    ///
774 774
    /// \param map An arc map storing the costs.
775 775
    /// Its \c Value type must be convertible to the \c Cost type
776 776
    /// of the algorithm.
777 777
    ///
778 778
    /// \return <tt>(*this)</tt>
779 779
    template<typename COST>
780 780
    NetworkSimplex& costMap(const COST& map) {
781 781
      delete _pcost;
782 782
      _pcost = new CostArcMap(_graph);
783 783
      for (ArcIt a(_graph); a != INVALID; ++a) {
784 784
        (*_pcost)[a] = map[a];
785 785
      }
786 786
      return *this;
787 787
    }
788 788

	
789 789
    /// \brief Set the supply values of the nodes.
790 790
    ///
791 791
    /// This function sets the supply values of the nodes.
792 792
    /// If neither this function nor \ref stSupply() is used before
793 793
    /// calling \ref run(), the supply of each node will be set to zero.
794 794
    /// (It makes sense only if non-zero lower bounds are given.)
795 795
    ///
796 796
    /// \param map A node map storing the supply values.
797 797
    /// Its \c Value type must be convertible to the \c Flow type
798 798
    /// of the algorithm.
799 799
    ///
800 800
    /// \return <tt>(*this)</tt>
801 801
    template<typename SUP>
802 802
    NetworkSimplex& supplyMap(const SUP& map) {
803 803
      delete _psupply;
804 804
      _pstsup = false;
805 805
      _psupply = new FlowNodeMap(_graph);
806 806
      for (NodeIt n(_graph); n != INVALID; ++n) {
807 807
        (*_psupply)[n] = map[n];
808 808
      }
809 809
      return *this;
810 810
    }
811 811

	
812 812
    /// \brief Set single source and target nodes and a supply value.
813 813
    ///
814 814
    /// This function sets a single source node and a single target node
815 815
    /// and the required flow value.
816 816
    /// If neither this function nor \ref supplyMap() is used before
817 817
    /// calling \ref run(), the supply of each node will be set to zero.
818 818
    /// (It makes sense only if non-zero lower bounds are given.)
819 819
    ///
820 820
    /// \param s The source node.
821 821
    /// \param t The target node.
822 822
    /// \param k The required amount of flow from node \c s to node \c t
823 823
    /// (i.e. the supply of \c s and the demand of \c t).
824 824
    ///
825 825
    /// \return <tt>(*this)</tt>
826 826
    NetworkSimplex& stSupply(const Node& s, const Node& t, Flow k) {
827 827
      delete _psupply;
828 828
      _psupply = NULL;
829 829
      _pstsup = true;
830 830
      _psource = s;
831 831
      _ptarget = t;
832 832
      _pstflow = k;
833 833
      return *this;
834 834
    }
835 835
    
836 836
    /// \brief Set the problem type.
837 837
    ///
838 838
    /// This function sets the problem type for the algorithm.
839 839
    /// If it is not used before calling \ref run(), the \ref GEQ problem
840 840
    /// type will be used.
841 841
    ///
842 842
    /// For more information see \ref ProblemType.
843 843
    ///
844 844
    /// \return <tt>(*this)</tt>
845 845
    NetworkSimplex& problemType(ProblemType problem_type) {
846 846
      _ptype = problem_type;
847 847
      return *this;
848 848
    }
849 849

	
850 850
    /// \brief Set the flow map.
851 851
    ///
852 852
    /// This function sets the flow map.
853 853
    /// If it is not used before calling \ref run(), an instance will
854 854
    /// be allocated automatically. The destructor deallocates this
855 855
    /// automatically allocated map, of course.
856 856
    ///
857 857
    /// \return <tt>(*this)</tt>
858 858
    NetworkSimplex& flowMap(FlowMap& map) {
859 859
      if (_local_flow) {
860 860
        delete _flow_map;
861 861
        _local_flow = false;
862 862
      }
863 863
      _flow_map = &map;
864 864
      return *this;
865 865
    }
866 866

	
867 867
    /// \brief Set the potential map.
868 868
    ///
869 869
    /// This function sets the potential map, which is used for storing
870 870
    /// the dual solution.
871 871
    /// If it is not used before calling \ref run(), an instance will
872 872
    /// be allocated automatically. The destructor deallocates this
873 873
    /// automatically allocated map, of course.
874 874
    ///
875 875
    /// \return <tt>(*this)</tt>
876 876
    NetworkSimplex& potentialMap(PotentialMap& map) {
877 877
      if (_local_potential) {
878 878
        delete _potential_map;
879 879
        _local_potential = false;
880 880
      }
881 881
      _potential_map = &map;
882 882
      return *this;
883 883
    }
884 884
    
885 885
    /// @}
886 886

	
887 887
    /// \name Execution Control
888 888
    /// The algorithm can be executed using \ref run().
889 889

	
890 890
    /// @{
891 891

	
892 892
    /// \brief Run the algorithm.
893 893
    ///
894 894
    /// This function runs the algorithm.
895 895
    /// The paramters can be specified using functions \ref lowerMap(),
896 896
    /// \ref upperMap(), \ref capacityMap(), \ref boundMaps(),
897 897
    /// \ref costMap(), \ref supplyMap(), \ref stSupply(), 
898 898
    /// \ref problemType(), \ref flowMap() and \ref potentialMap().
899 899
    /// For example,
900 900
    /// \code
901 901
    ///   NetworkSimplex<ListDigraph> ns(graph);
902 902
    ///   ns.boundMaps(lower, upper).costMap(cost)
903 903
    ///     .supplyMap(sup).run();
904 904
    /// \endcode
905 905
    ///
906 906
    /// This function can be called more than once. All the parameters
907 907
    /// that have been given are kept for the next call, unless
908 908
    /// \ref reset() is called, thus only the modified parameters
909 909
    /// have to be set again. See \ref reset() for examples.
910 910
    ///
911 911
    /// \param pivot_rule The pivot rule that will be used during the
912 912
    /// algorithm. For more information see \ref PivotRule.
913 913
    ///
914 914
    /// \return \c true if a feasible flow can be found.
915 915
    bool run(PivotRule pivot_rule = BLOCK_SEARCH) {
916 916
      return init() && start(pivot_rule);
917 917
    }
918 918

	
919 919
    /// \brief Reset all the parameters that have been given before.
920 920
    ///
921 921
    /// This function resets all the paramaters that have been given
922 922
    /// before using functions \ref lowerMap(), \ref upperMap(),
923 923
    /// \ref capacityMap(), \ref boundMaps(), \ref costMap(),
924 924
    /// \ref supplyMap(), \ref stSupply(), \ref problemType(), 
925 925
    /// \ref flowMap() and \ref potentialMap().
926 926
    ///
927 927
    /// It is useful for multiple run() calls. If this function is not
928 928
    /// used, all the parameters given before are kept for the next
929 929
    /// \ref run() call.
930 930
    ///
931 931
    /// For example,
932 932
    /// \code
933 933
    ///   NetworkSimplex<ListDigraph> ns(graph);
934 934
    ///
935 935
    ///   // First run
936 936
    ///   ns.lowerMap(lower).capacityMap(cap).costMap(cost)
937 937
    ///     .supplyMap(sup).run();
938 938
    ///
939 939
    ///   // Run again with modified cost map (reset() is not called,
940 940
    ///   // so only the cost map have to be set again)
941 941
    ///   cost[e] += 100;
942 942
    ///   ns.costMap(cost).run();
943 943
    ///
944 944
    ///   // Run again from scratch using reset()
945 945
    ///   // (the lower bounds will be set to zero on all arcs)
946 946
    ///   ns.reset();
947 947
    ///   ns.capacityMap(cap).costMap(cost)
948 948
    ///     .supplyMap(sup).run();
949 949
    /// \endcode
950 950
    ///
951 951
    /// \return <tt>(*this)</tt>
952 952
    NetworkSimplex& reset() {
953 953
      delete _plower;
954 954
      delete _pupper;
955 955
      delete _pcost;
956 956
      delete _psupply;
957 957
      _plower = NULL;
958 958
      _pupper = NULL;
959 959
      _pcost = NULL;
960 960
      _psupply = NULL;
961 961
      _pstsup = false;
962 962
      _ptype = GEQ;
963 963
      if (_local_flow) delete _flow_map;
964 964
      if (_local_potential) delete _potential_map;
965 965
      _flow_map = NULL;
966 966
      _potential_map = NULL;
967 967
      _local_flow = false;
968 968
      _local_potential = false;
969 969

	
970 970
      return *this;
971 971
    }
972 972

	
973 973
    /// @}
974 974

	
975 975
    /// \name Query Functions
976 976
    /// The results of the algorithm can be obtained using these
977 977
    /// functions.\n
978 978
    /// The \ref run() function must be called before using them.
979 979

	
980 980
    /// @{
981 981

	
982 982
    /// \brief Return the total cost of the found flow.
983 983
    ///
984 984
    /// This function returns the total cost of the found flow.
985 985
    /// The complexity of the function is O(e).
986 986
    ///
987 987
    /// \note The return type of the function can be specified as a
988 988
    /// template parameter. For example,
989 989
    /// \code
990 990
    ///   ns.totalCost<double>();
991 991
    /// \endcode
992 992
    /// It is useful if the total cost cannot be stored in the \c Cost
993 993
    /// type of the algorithm, which is the default return type of the
994 994
    /// function.
995 995
    ///
996 996
    /// \pre \ref run() must be called before using this function.
997 997
    template <typename Num>
998 998
    Num totalCost() const {
999 999
      Num c = 0;
1000 1000
      if (_pcost) {
1001 1001
        for (ArcIt e(_graph); e != INVALID; ++e)
1002 1002
          c += (*_flow_map)[e] * (*_pcost)[e];
1003 1003
      } else {
1004 1004
        for (ArcIt e(_graph); e != INVALID; ++e)
1005 1005
          c += (*_flow_map)[e];
1006 1006
      }
1007 1007
      return c;
1008 1008
    }
1009 1009

	
1010 1010
#ifndef DOXYGEN
1011 1011
    Cost totalCost() const {
1012 1012
      return totalCost<Cost>();
1013 1013
    }
1014 1014
#endif
1015 1015

	
1016 1016
    /// \brief Return the flow on the given arc.
1017 1017
    ///
1018 1018
    /// This function returns the flow on the given arc.
1019 1019
    ///
1020 1020
    /// \pre \ref run() must be called before using this function.
1021 1021
    Flow flow(const Arc& a) const {
1022 1022
      return (*_flow_map)[a];
1023 1023
    }
1024 1024

	
1025 1025
    /// \brief Return a const reference to the flow map.
1026 1026
    ///
1027 1027
    /// This function returns a const reference to an arc map storing
1028 1028
    /// the found flow.
1029 1029
    ///
1030 1030
    /// \pre \ref run() must be called before using this function.
1031 1031
    const FlowMap& flowMap() const {
1032 1032
      return *_flow_map;
1033 1033
    }
1034 1034

	
1035 1035
    /// \brief Return the potential (dual value) of the given node.
1036 1036
    ///
1037 1037
    /// This function returns the potential (dual value) of the
1038 1038
    /// given node.
1039 1039
    ///
1040 1040
    /// \pre \ref run() must be called before using this function.
1041 1041
    Cost potential(const Node& n) const {
1042 1042
      return (*_potential_map)[n];
1043 1043
    }
1044 1044

	
1045 1045
    /// \brief Return a const reference to the potential map
1046 1046
    /// (the dual solution).
1047 1047
    ///
1048 1048
    /// This function returns a const reference to a node map storing
1049 1049
    /// the found potentials, which form the dual solution of the
1050 1050
    /// \ref min_cost_flow "minimum cost flow" problem.
1051 1051
    ///
1052 1052
    /// \pre \ref run() must be called before using this function.
1053 1053
    const PotentialMap& potentialMap() const {
1054 1054
      return *_potential_map;
1055 1055
    }
1056 1056

	
1057 1057
    /// @}
1058 1058

	
1059 1059
  private:
1060 1060

	
1061 1061
    // Initialize internal data structures
1062 1062
    bool init() {
1063 1063
      // Initialize result maps
1064 1064
      if (!_flow_map) {
1065 1065
        _flow_map = new FlowMap(_graph);
1066 1066
        _local_flow = true;
1067 1067
      }
1068 1068
      if (!_potential_map) {
1069 1069
        _potential_map = new PotentialMap(_graph);
1070 1070
        _local_potential = true;
1071 1071
      }
1072 1072

	
1073 1073
      // Initialize vectors
1074 1074
      _node_num = countNodes(_graph);
1075 1075
      _arc_num = countArcs(_graph);
1076 1076
      int all_node_num = _node_num + 1;
1077 1077
      int all_arc_num = _arc_num + _node_num;
1078 1078
      if (_node_num == 0) return false;
1079 1079

	
1080 1080
      _arc_ref.resize(_arc_num);
1081 1081
      _source.resize(all_arc_num);
1082 1082
      _target.resize(all_arc_num);
1083 1083

	
1084 1084
      _cap.resize(all_arc_num);
1085 1085
      _cost.resize(all_arc_num);
1086 1086
      _supply.resize(all_node_num);
1087 1087
      _flow.resize(all_arc_num);
1088 1088
      _pi.resize(all_node_num);
1089 1089

	
1090 1090
      _parent.resize(all_node_num);
1091 1091
      _pred.resize(all_node_num);
1092 1092
      _forward.resize(all_node_num);
1093 1093
      _thread.resize(all_node_num);
1094 1094
      _rev_thread.resize(all_node_num);
1095 1095
      _succ_num.resize(all_node_num);
1096 1096
      _last_succ.resize(all_node_num);
1097 1097
      _state.resize(all_arc_num);
1098 1098

	
1099 1099
      // Initialize node related data
1100 1100
      bool valid_supply = true;
1101 1101
      Flow sum_supply = 0;
1102 1102
      if (!_pstsup && !_psupply) {
1103 1103
        _pstsup = true;
1104 1104
        _psource = _ptarget = NodeIt(_graph);
1105 1105
        _pstflow = 0;
1106 1106
      }
1107 1107
      if (_psupply) {
1108 1108
        int i = 0;
1109 1109
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1110 1110
          _node_id[n] = i;
1111 1111
          _supply[i] = (*_psupply)[n];
1112 1112
          sum_supply += _supply[i];
1113 1113
        }
1114 1114
        valid_supply = (_ptype == GEQ && sum_supply <= 0) ||
1115 1115
                       (_ptype == LEQ && sum_supply >= 0);
1116 1116
      } else {
1117 1117
        int i = 0;
1118 1118
        for (NodeIt n(_graph); n != INVALID; ++n, ++i) {
1119 1119
          _node_id[n] = i;
1120 1120
          _supply[i] = 0;
1121 1121
        }
1122 1122
        _supply[_node_id[_psource]] =  _pstflow;
1123 1123
        _supply[_node_id[_ptarget]] = -_pstflow;
1124 1124
      }
1125 1125
      if (!valid_supply) return false;
1126 1126

	
1127 1127
      // Infinite capacity value
1128 1128
      Flow inf_cap =
1129 1129
        std::numeric_limits<Flow>::has_infinity ?
1130 1130
        std::numeric_limits<Flow>::infinity() :
1131 1131
        std::numeric_limits<Flow>::max();
1132 1132

	
1133 1133
      // Initialize artifical cost
1134 1134
      Cost art_cost;
1135 1135
      if (std::numeric_limits<Cost>::is_exact) {
1136 1136
        art_cost = std::numeric_limits<Cost>::max() / 4 + 1;
1137 1137
      } else {
1138 1138
        art_cost = std::numeric_limits<Cost>::min();
1139 1139
        for (int i = 0; i != _arc_num; ++i) {
1140 1140
          if (_cost[i] > art_cost) art_cost = _cost[i];
1141 1141
        }
1142 1142
        art_cost = (art_cost + 1) * _node_num;
1143 1143
      }
1144 1144

	
1145 1145
      // Run Circulation to check if a feasible solution exists
1146 1146
      typedef ConstMap<Arc, Flow> ConstArcMap;
1147
      ConstArcMap zero_arc_map(0), inf_arc_map(inf_cap);
1147 1148
      FlowNodeMap *csup = NULL;
1148 1149
      bool local_csup = false;
1149 1150
      if (_psupply) {
1150 1151
        csup = _psupply;
1151 1152
      } else {
1152 1153
        csup = new FlowNodeMap(_graph, 0);
1153 1154
        (*csup)[_psource] =  _pstflow;
1154 1155
        (*csup)[_ptarget] = -_pstflow;
1155 1156
        local_csup = true;
1156 1157
      }
1157 1158
      bool circ_result = false;
1158 1159
      if (_ptype == GEQ || (_ptype == LEQ && sum_supply == 0)) {
1159 1160
        // GEQ problem type
1160 1161
        if (_plower) {
1161 1162
          if (_pupper) {
1162 1163
            Circulation<GR, FlowArcMap, FlowArcMap, FlowNodeMap>
1163 1164
              circ(_graph, *_plower, *_pupper, *csup);
1164 1165
            circ_result = circ.run();
1165 1166
          } else {
1166 1167
            Circulation<GR, FlowArcMap, ConstArcMap, FlowNodeMap>
1167
              circ(_graph, *_plower, ConstArcMap(inf_cap), *csup);
1168
              circ(_graph, *_plower, inf_arc_map, *csup);
1168 1169
            circ_result = circ.run();
1169 1170
          }
1170 1171
        } else {
1171 1172
          if (_pupper) {
1172 1173
            Circulation<GR, ConstArcMap, FlowArcMap, FlowNodeMap>
1173
              circ(_graph, ConstArcMap(0), *_pupper, *csup);
1174
              circ(_graph, zero_arc_map, *_pupper, *csup);
1174 1175
            circ_result = circ.run();
1175 1176
          } else {
1176 1177
            Circulation<GR, ConstArcMap, ConstArcMap, FlowNodeMap>
1177
              circ(_graph, ConstArcMap(0), ConstArcMap(inf_cap), *csup);
1178
              circ(_graph, zero_arc_map, inf_arc_map, *csup);
1178 1179
            circ_result = circ.run();
1179 1180
          }
1180 1181
        }
1181 1182
      } else {
1182 1183
        // LEQ problem type
1183 1184
        typedef ReverseDigraph<const GR> RevGraph;
1184 1185
        typedef NegMap<FlowNodeMap> NegNodeMap;
1185 1186
        RevGraph rgraph(_graph);
1186 1187
        NegNodeMap neg_csup(*csup);
1187 1188
        if (_plower) {
1188 1189
          if (_pupper) {
1189 1190
            Circulation<RevGraph, FlowArcMap, FlowArcMap, NegNodeMap>
1190 1191
              circ(rgraph, *_plower, *_pupper, neg_csup);
1191 1192
            circ_result = circ.run();
1192 1193
          } else {
1193 1194
            Circulation<RevGraph, FlowArcMap, ConstArcMap, NegNodeMap>
1194
              circ(rgraph, *_plower, ConstArcMap(inf_cap), neg_csup);
1195
              circ(rgraph, *_plower, inf_arc_map, neg_csup);
1195 1196
            circ_result = circ.run();
1196 1197
          }
1197 1198
        } else {
1198 1199
          if (_pupper) {
1199 1200
            Circulation<RevGraph, ConstArcMap, FlowArcMap, NegNodeMap>
1200
              circ(rgraph, ConstArcMap(0), *_pupper, neg_csup);
1201
              circ(rgraph, zero_arc_map, *_pupper, neg_csup);
1201 1202
            circ_result = circ.run();
1202 1203
          } else {
1203 1204
            Circulation<RevGraph, ConstArcMap, ConstArcMap, NegNodeMap>
1204
              circ(rgraph, ConstArcMap(0), ConstArcMap(inf_cap), neg_csup);
1205
              circ(rgraph, zero_arc_map, inf_arc_map, neg_csup);
1205 1206
            circ_result = circ.run();
1206 1207
          }
1207 1208
        }
1208 1209
      }
1209 1210
      if (local_csup) delete csup;
1210 1211
      if (!circ_result) return false;
1211 1212

	
1212 1213
      // Set data for the artificial root node
1213 1214
      _root = _node_num;
1214 1215
      _parent[_root] = -1;
1215 1216
      _pred[_root] = -1;
1216 1217
      _thread[_root] = 0;
1217 1218
      _rev_thread[0] = _root;
1218 1219
      _succ_num[_root] = all_node_num;
1219 1220
      _last_succ[_root] = _root - 1;
1220 1221
      _supply[_root] = -sum_supply;
1221 1222
      if (sum_supply < 0) {
1222 1223
        _pi[_root] = -art_cost;
1223 1224
      } else {
1224 1225
        _pi[_root] = art_cost;
1225 1226
      }
1226 1227

	
1227 1228
      // Store the arcs in a mixed order
1228 1229
      int k = std::max(int(sqrt(_arc_num)), 10);
1229 1230
      int i = 0;
1230 1231
      for (ArcIt e(_graph); e != INVALID; ++e) {
1231 1232
        _arc_ref[i] = e;
1232 1233
        if ((i += k) >= _arc_num) i = (i % k) + 1;
1233 1234
      }
1234 1235

	
1235 1236
      // Initialize arc maps
1236 1237
      if (_pupper && _pcost) {
1237 1238
        for (int i = 0; i != _arc_num; ++i) {
1238 1239
          Arc e = _arc_ref[i];
1239 1240
          _source[i] = _node_id[_graph.source(e)];
1240 1241
          _target[i] = _node_id[_graph.target(e)];
1241 1242
          _cap[i] = (*_pupper)[e];
1242 1243
          _cost[i] = (*_pcost)[e];
1243 1244
          _flow[i] = 0;
1244 1245
          _state[i] = STATE_LOWER;
1245 1246
        }
1246 1247
      } else {
1247 1248
        for (int i = 0; i != _arc_num; ++i) {
1248 1249
          Arc e = _arc_ref[i];
1249 1250
          _source[i] = _node_id[_graph.source(e)];
1250 1251
          _target[i] = _node_id[_graph.target(e)];
1251 1252
          _flow[i] = 0;
1252 1253
          _state[i] = STATE_LOWER;
1253 1254
        }
1254 1255
        if (_pupper) {
1255 1256
          for (int i = 0; i != _arc_num; ++i)
1256 1257
            _cap[i] = (*_pupper)[_arc_ref[i]];
1257 1258
        } else {
1258 1259
          for (int i = 0; i != _arc_num; ++i)
1259 1260
            _cap[i] = inf_cap;
1260 1261
        }
1261 1262
        if (_pcost) {
1262 1263
          for (int i = 0; i != _arc_num; ++i)
1263 1264
            _cost[i] = (*_pcost)[_arc_ref[i]];
1264 1265
        } else {
1265 1266
          for (int i = 0; i != _arc_num; ++i)
1266 1267
            _cost[i] = 1;
1267 1268
        }
1268 1269
      }
1269 1270
      
1270 1271
      // Remove non-zero lower bounds
1271 1272
      if (_plower) {
1272 1273
        for (int i = 0; i != _arc_num; ++i) {
1273 1274
          Flow c = (*_plower)[_arc_ref[i]];
1274 1275
          if (c != 0) {
1275 1276
            _cap[i] -= c;
1276 1277
            _supply[_source[i]] -= c;
1277 1278
            _supply[_target[i]] += c;
1278 1279
          }
1279 1280
        }
1280 1281
      }
1281 1282

	
1282 1283
      // Add artificial arcs and initialize the spanning tree data structure
1283 1284
      for (int u = 0, e = _arc_num; u != _node_num; ++u, ++e) {
1284 1285
        _thread[u] = u + 1;
1285 1286
        _rev_thread[u + 1] = u;
1286 1287
        _succ_num[u] = 1;
1287 1288
        _last_succ[u] = u;
1288 1289
        _parent[u] = _root;
1289 1290
        _pred[u] = e;
1290 1291
        _cost[e] = art_cost;
1291 1292
        _cap[e] = inf_cap;
1292 1293
        _state[e] = STATE_TREE;
1293 1294
        if (_supply[u] > 0 || (_supply[u] == 0 && sum_supply <= 0)) {
1294 1295
          _flow[e] = _supply[u];
1295 1296
          _forward[u] = true;
1296 1297
          _pi[u] = -art_cost + _pi[_root];
1297 1298
        } else {
1298 1299
          _flow[e] = -_supply[u];
1299 1300
          _forward[u] = false;
1300 1301
          _pi[u] = art_cost + _pi[_root];
1301 1302
        }
1302 1303
      }
1303 1304

	
1304 1305
      return true;
1305 1306
    }
1306 1307

	
1307 1308
    // Find the join node
1308 1309
    void findJoinNode() {
1309 1310
      int u = _source[in_arc];
1310 1311
      int v = _target[in_arc];
1311 1312
      while (u != v) {
1312 1313
        if (_succ_num[u] < _succ_num[v]) {
1313 1314
          u = _parent[u];
1314 1315
        } else {
1315 1316
          v = _parent[v];
1316 1317
        }
1317 1318
      }
1318 1319
      join = u;
1319 1320
    }
1320 1321

	
1321 1322
    // Find the leaving arc of the cycle and returns true if the
1322 1323
    // leaving arc is not the same as the entering arc
1323 1324
    bool findLeavingArc() {
1324 1325
      // Initialize first and second nodes according to the direction
1325 1326
      // of the cycle
1326 1327
      if (_state[in_arc] == STATE_LOWER) {
1327 1328
        first  = _source[in_arc];
1328 1329
        second = _target[in_arc];
1329 1330
      } else {
1330 1331
        first  = _target[in_arc];
1331 1332
        second = _source[in_arc];
1332 1333
      }
1333 1334
      delta = _cap[in_arc];
1334 1335
      int result = 0;
1335 1336
      Flow d;
1336 1337
      int e;
1337 1338

	
1338 1339
      // Search the cycle along the path form the first node to the root
1339 1340
      for (int u = first; u != join; u = _parent[u]) {
1340 1341
        e = _pred[u];
1341 1342
        d = _forward[u] ? _flow[e] : _cap[e] - _flow[e];
1342 1343
        if (d < delta) {
1343 1344
          delta = d;
1344 1345
          u_out = u;
1345 1346
          result = 1;
1346 1347
        }
1347 1348
      }
1348 1349
      // Search the cycle along the path form the second node to the root
1349 1350
      for (int u = second; u != join; u = _parent[u]) {
1350 1351
        e = _pred[u];
1351 1352
        d = _forward[u] ? _cap[e] - _flow[e] : _flow[e];
1352 1353
        if (d <= delta) {
1353 1354
          delta = d;
1354 1355
          u_out = u;
1355 1356
          result = 2;
1356 1357
        }
1357 1358
      }
1358 1359

	
1359 1360
      if (result == 1) {
1360 1361
        u_in = first;
1361 1362
        v_in = second;
1362 1363
      } else {
1363 1364
        u_in = second;
1364 1365
        v_in = first;
1365 1366
      }
1366 1367
      return result != 0;
1367 1368
    }
1368 1369

	
1369 1370
    // Change _flow and _state vectors
1370 1371
    void changeFlow(bool change) {
1371 1372
      // Augment along the cycle
1372 1373
      if (delta > 0) {
1373 1374
        Flow val = _state[in_arc] * delta;
1374 1375
        _flow[in_arc] += val;
1375 1376
        for (int u = _source[in_arc]; u != join; u = _parent[u]) {
1376 1377
          _flow[_pred[u]] += _forward[u] ? -val : val;
1377 1378
        }
1378 1379
        for (int u = _target[in_arc]; u != join; u = _parent[u]) {
1379 1380
          _flow[_pred[u]] += _forward[u] ? val : -val;
1380 1381
        }
1381 1382
      }
1382 1383
      // Update the state of the entering and leaving arcs
1383 1384
      if (change) {
1384 1385
        _state[in_arc] = STATE_TREE;
1385 1386
        _state[_pred[u_out]] =
1386 1387
          (_flow[_pred[u_out]] == 0) ? STATE_LOWER : STATE_UPPER;
1387 1388
      } else {
1388 1389
        _state[in_arc] = -_state[in_arc];
1389 1390
      }
1390 1391
    }
1391 1392

	
1392 1393
    // Update the tree structure
1393 1394
    void updateTreeStructure() {
1394 1395
      int u, w;
1395 1396
      int old_rev_thread = _rev_thread[u_out];
1396 1397
      int old_succ_num = _succ_num[u_out];
1397 1398
      int old_last_succ = _last_succ[u_out];
1398 1399
      v_out = _parent[u_out];
1399 1400

	
1400 1401
      u = _last_succ[u_in];  // the last successor of u_in
1401 1402
      right = _thread[u];    // the node after it
1402 1403

	
1403 1404
      // Handle the case when old_rev_thread equals to v_in
1404 1405
      // (it also means that join and v_out coincide)
1405 1406
      if (old_rev_thread == v_in) {
1406 1407
        last = _thread[_last_succ[u_out]];
1407 1408
      } else {
1408 1409
        last = _thread[v_in];
1409 1410
      }
1410 1411

	
1411 1412
      // Update _thread and _parent along the stem nodes (i.e. the nodes
1412 1413
      // between u_in and u_out, whose parent have to be changed)
1413 1414
      _thread[v_in] = stem = u_in;
1414 1415
      _dirty_revs.clear();
1415 1416
      _dirty_revs.push_back(v_in);
1416 1417
      par_stem = v_in;
1417 1418
      while (stem != u_out) {
1418 1419
        // Insert the next stem node into the thread list
1419 1420
        new_stem = _parent[stem];
1420 1421
        _thread[u] = new_stem;
1421 1422
        _dirty_revs.push_back(u);
1422 1423

	
1423 1424
        // Remove the subtree of stem from the thread list
1424 1425
        w = _rev_thread[stem];
1425 1426
        _thread[w] = right;
1426 1427
        _rev_thread[right] = w;
1427 1428

	
1428 1429
        // Change the parent node and shift stem nodes
1429 1430
        _parent[stem] = par_stem;
1430 1431
        par_stem = stem;
1431 1432
        stem = new_stem;
1432 1433

	
1433 1434
        // Update u and right
1434 1435
        u = _last_succ[stem] == _last_succ[par_stem] ?
1435 1436
          _rev_thread[par_stem] : _last_succ[stem];
1436 1437
        right = _thread[u];
1437 1438
      }
1438 1439
      _parent[u_out] = par_stem;
1439 1440
      _thread[u] = last;
1440 1441
      _rev_thread[last] = u;
1441 1442
      _last_succ[u_out] = u;
1442 1443

	
1443 1444
      // Remove the subtree of u_out from the thread list except for
1444 1445
      // the case when old_rev_thread equals to v_in
1445 1446
      // (it also means that join and v_out coincide)
1446 1447
      if (old_rev_thread != v_in) {
1447 1448
        _thread[old_rev_thread] = right;
1448 1449
        _rev_thread[right] = old_rev_thread;
1449 1450
      }
1450 1451

	
1451 1452
      // Update _rev_thread using the new _thread values
1452 1453
      for (int i = 0; i < int(_dirty_revs.size()); ++i) {
1453 1454
        u = _dirty_revs[i];
1454 1455
        _rev_thread[_thread[u]] = u;
1455 1456
      }
1456 1457

	
1457 1458
      // Update _pred, _forward, _last_succ and _succ_num for the
1458 1459
      // stem nodes from u_out to u_in
1459 1460
      int tmp_sc = 0, tmp_ls = _last_succ[u_out];
1460 1461
      u = u_out;
1461 1462
      while (u != u_in) {
1462 1463
        w = _parent[u];
1463 1464
        _pred[u] = _pred[w];
1464 1465
        _forward[u] = !_forward[w];
1465 1466
        tmp_sc += _succ_num[u] - _succ_num[w];
1466 1467
        _succ_num[u] = tmp_sc;
1467 1468
        _last_succ[w] = tmp_ls;
1468 1469
        u = w;
1469 1470
      }
1470 1471
      _pred[u_in] = in_arc;
1471 1472
      _forward[u_in] = (u_in == _source[in_arc]);
1472 1473
      _succ_num[u_in] = old_succ_num;
1473 1474

	
1474 1475
      // Set limits for updating _last_succ form v_in and v_out
1475 1476
      // towards the root
1476 1477
      int up_limit_in = -1;
1477 1478
      int up_limit_out = -1;
1478 1479
      if (_last_succ[join] == v_in) {
1479 1480
        up_limit_out = join;
1480 1481
      } else {
1481 1482
        up_limit_in = join;
1482 1483
      }
1483 1484

	
1484 1485
      // Update _last_succ from v_in towards the root
1485 1486
      for (u = v_in; u != up_limit_in && _last_succ[u] == v_in;
1486 1487
           u = _parent[u]) {
1487 1488
        _last_succ[u] = _last_succ[u_out];
1488 1489
      }
1489 1490
      // Update _last_succ from v_out towards the root
1490 1491
      if (join != old_rev_thread && v_in != old_rev_thread) {
1491 1492
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1492 1493
             u = _parent[u]) {
1493 1494
          _last_succ[u] = old_rev_thread;
1494 1495
        }
1495 1496
      } else {
1496 1497
        for (u = v_out; u != up_limit_out && _last_succ[u] == old_last_succ;
1497 1498
             u = _parent[u]) {
1498 1499
          _last_succ[u] = _last_succ[u_out];
1499 1500
        }
1500 1501
      }
1501 1502

	
1502 1503
      // Update _succ_num from v_in to join
1503 1504
      for (u = v_in; u != join; u = _parent[u]) {
1504 1505
        _succ_num[u] += old_succ_num;
1505 1506
      }
1506 1507
      // Update _succ_num from v_out to join
1507 1508
      for (u = v_out; u != join; u = _parent[u]) {
1508 1509
        _succ_num[u] -= old_succ_num;
1509 1510
      }
1510 1511
    }
1511 1512

	
1512 1513
    // Update potentials
1513 1514
    void updatePotential() {
1514 1515
      Cost sigma = _forward[u_in] ?
1515 1516
        _pi[v_in] - _pi[u_in] - _cost[_pred[u_in]] :
1516 1517
        _pi[v_in] - _pi[u_in] + _cost[_pred[u_in]];
1517 1518
      // Update potentials in the subtree, which has been moved
1518 1519
      int end = _thread[_last_succ[u_in]];
1519 1520
      for (int u = u_in; u != end; u = _thread[u]) {
1520 1521
        _pi[u] += sigma;
1521 1522
      }
1522 1523
    }
1523 1524

	
1524 1525
    // Execute the algorithm
1525 1526
    bool start(PivotRule pivot_rule) {
1526 1527
      // Select the pivot rule implementation
1527 1528
      switch (pivot_rule) {
1528 1529
        case FIRST_ELIGIBLE:
1529 1530
          return start<FirstEligiblePivotRule>();
1530 1531
        case BEST_ELIGIBLE:
1531 1532
          return start<BestEligiblePivotRule>();
1532 1533
        case BLOCK_SEARCH:
1533 1534
          return start<BlockSearchPivotRule>();
1534 1535
        case CANDIDATE_LIST:
1535 1536
          return start<CandidateListPivotRule>();
1536 1537
        case ALTERING_LIST:
1537 1538
          return start<AlteringListPivotRule>();
1538 1539
      }
1539 1540
      return false;
1540 1541
    }
1541 1542

	
1542 1543
    template <typename PivotRuleImpl>
1543 1544
    bool start() {
1544 1545
      PivotRuleImpl pivot(*this);
1545 1546

	
1546 1547
      // Execute the Network Simplex algorithm
1547 1548
      while (pivot.findEnteringArc()) {
1548 1549
        findJoinNode();
1549 1550
        bool change = findLeavingArc();
1550 1551
        changeFlow(change);
1551 1552
        if (change) {
1552 1553
          updateTreeStructure();
1553 1554
          updatePotential();
1554 1555
        }
1555 1556
      }
1556 1557

	
1557 1558
      // Copy flow values to _flow_map
1558 1559
      if (_plower) {
1559 1560
        for (int i = 0; i != _arc_num; ++i) {
1560 1561
          Arc e = _arc_ref[i];
1561 1562
          _flow_map->set(e, (*_plower)[e] + _flow[i]);
1562 1563
        }
1563 1564
      } else {
1564 1565
        for (int i = 0; i != _arc_num; ++i) {
1565 1566
          _flow_map->set(_arc_ref[i], _flow[i]);
1566 1567
        }
1567 1568
      }
1568 1569
      // Copy potential values to _potential_map
1569 1570
      for (NodeIt n(_graph); n != INVALID; ++n) {
1570 1571
        _potential_map->set(n, _pi[_node_id[n]]);
1571 1572
      }
1572 1573

	
1573 1574
      return true;
1574 1575
    }
1575 1576

	
1576 1577
  }; //class NetworkSimplex
1577 1578

	
1578 1579
  ///@}
1579 1580

	
1580 1581
} //namespace lemon
1581 1582

	
1582 1583
#endif //LEMON_NETWORK_SIMPLEX_H
0 comments (0 inline)