gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 3 0
merge default
1 file changed with 32 insertions and 18 deletions:
↑ Collapse diff ↑
Ignore white space 6 line context
... ...
@@ -766,820 +766,821 @@
766 766
    template <typename LOWER, typename UPPER>
767 767
    NetworkSimplex& boundMaps(const LOWER& lower, const UPPER& upper) {
768 768
      return lowerMap(lower).upperMap(upper);
769 769
    }
770 770

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

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

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

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

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

	
890 890
    /// \name Execution Control
891 891
    /// The algorithm can be executed using \ref run().
892 892

	
893 893
    /// @{
894 894

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

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

	
973 973
      return *this;
974 974
    }
975 975

	
976 976
    /// @}
977 977

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

	
983 983
    /// @{
984 984

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

	
1013 1013
#ifndef DOXYGEN
1014 1014
    Cost totalCost() const {
1015 1015
      return totalCost<Cost>();
1016 1016
    }
1017 1017
#endif
1018 1018

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

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

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

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

	
1060 1060
    /// @}
1061 1061

	
1062 1062
  private:
1063 1063

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

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

	
1083 1083
      _arc_ref.resize(_arc_num);
1084 1084
      _source.resize(all_arc_num);
1085 1085
      _target.resize(all_arc_num);
1086 1086

	
1087 1087
      _cap.resize(all_arc_num);
1088 1088
      _cost.resize(all_arc_num);
1089 1089
      _supply.resize(all_node_num);
1090 1090
      _flow.resize(all_arc_num);
1091 1091
      _pi.resize(all_node_num);
1092 1092

	
1093 1093
      _parent.resize(all_node_num);
1094 1094
      _pred.resize(all_node_num);
1095 1095
      _forward.resize(all_node_num);
1096 1096
      _thread.resize(all_node_num);
1097 1097
      _rev_thread.resize(all_node_num);
1098 1098
      _succ_num.resize(all_node_num);
1099 1099
      _last_succ.resize(all_node_num);
1100 1100
      _state.resize(all_arc_num);
1101 1101

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

	
1130 1130
      // Infinite capacity value
1131 1131
      Flow inf_cap =
1132 1132
        std::numeric_limits<Flow>::has_infinity ?
1133 1133
        std::numeric_limits<Flow>::infinity() :
1134 1134
        std::numeric_limits<Flow>::max();
1135 1135

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

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

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

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

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

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

	
1307 1308
      return true;
1308 1309
    }
1309 1310

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

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

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

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

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

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

	
1403 1404
      u = _last_succ[u_in];  // the last successor of u_in
1404 1405
      right = _thread[u];    // the node after it
1405 1406

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

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

	
1426 1427
        // Remove the subtree of stem from the thread list
1427 1428
        w = _rev_thread[stem];
1428 1429
        _thread[w] = right;
1429 1430
        _rev_thread[right] = w;
1430 1431

	
1431 1432
        // Change the parent node and shift stem nodes
1432 1433
        _parent[stem] = par_stem;
1433 1434
        par_stem = stem;
1434 1435
        stem = new_stem;
1435 1436

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

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

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

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

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

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

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

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

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

	
1545 1546
    template <typename PivotRuleImpl>
1546 1547
    bool start() {
1547 1548
      PivotRuleImpl pivot(*this);
1548 1549

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

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

	
1576 1577
      return true;
1577 1578
    }
1578 1579

	
1579 1580
  }; //class NetworkSimplex
1580 1581

	
1581 1582
  ///@}
1582 1583

	
1583 1584
} //namespace lemon
1584 1585

	
1585 1586
#endif //LEMON_NETWORK_SIMPLEX_H
Ignore white space 768 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 sup4 sup5\n"
37 37
  "    1    20   27    0   20   30\n"
38 38
  "    2    -4    0    0   -8   -3\n"
39 39
  "    3     0    0    0    0    0\n"
40 40
  "    4     0    0    0    0    0\n"
41 41
  "    5     9    0    0    6   11\n"
42 42
  "    6    -6    0    0   -5   -6\n"
43 43
  "    7     0    0    0    0    0\n"
44 44
  "    8     0    0    0    0    3\n"
45 45
  "    9     3    0    0    0    0\n"
46 46
  "   10    -2    0    0   -7   -2\n"
47 47
  "   11     0    0    0  -10    0\n"
48 48
  "   12   -20  -27    0  -30  -20\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
enum ProblemType {
80 80
  EQ,
81 81
  GEQ,
82 82
  LEQ
83 83
};
84 84

	
85 85
// Check the interface of an MCF algorithm
86 86
template <typename GR, typename Flow, typename Cost>
87 87
class McfClassConcept
88 88
{
89 89
public:
90 90

	
91 91
  template <typename MCF>
92 92
  struct Constraints {
93 93
    void constraints() {
94 94
      checkConcept<concepts::Digraph, GR>();
95 95

	
96 96
      MCF mcf(g);
97 97

	
98 98
      b = mcf.reset()
99 99
             .lowerMap(lower)
100 100
             .upperMap(upper)
101 101
             .capacityMap(upper)
102 102
             .boundMaps(lower, upper)
103 103
             .costMap(cost)
104 104
             .supplyMap(sup)
105 105
             .stSupply(n, n, k)
106 106
             .flowMap(flow)
107 107
             .potentialMap(pot)
108 108
             .run();
109 109
      
110 110
      const MCF& const_mcf = mcf;
111 111

	
112 112
      const typename MCF::FlowMap &fm = const_mcf.flowMap();
113 113
      const typename MCF::PotentialMap &pm = const_mcf.potentialMap();
114 114

	
115 115
      v = const_mcf.totalCost();
116 116
      double x = const_mcf.template totalCost<double>();
117 117
      v = const_mcf.flow(a);
118 118
      v = const_mcf.potential(n);
119 119

	
120 120
      ignore_unused_variable_warning(fm);
121 121
      ignore_unused_variable_warning(pm);
122 122
      ignore_unused_variable_warning(x);
123 123
    }
124 124

	
125 125
    typedef typename GR::Node Node;
126 126
    typedef typename GR::Arc Arc;
127 127
    typedef concepts::ReadMap<Node, Flow> NM;
128 128
    typedef concepts::ReadMap<Arc, Flow> FAM;
129 129
    typedef concepts::ReadMap<Arc, Cost> CAM;
130 130

	
131 131
    const GR &g;
132 132
    const FAM &lower;
133 133
    const FAM &upper;
134 134
    const CAM &cost;
135 135
    const NM &sup;
136 136
    const Node &n;
137 137
    const Arc &a;
138 138
    const Flow &k;
139 139
    Flow v;
140 140
    bool b;
141 141

	
142 142
    typename MCF::FlowMap &flow;
143 143
    typename MCF::PotentialMap &pot;
144 144
  };
145 145

	
146 146
};
147 147

	
148 148

	
149 149
// Check the feasibility of the given flow (primal soluiton)
150 150
template < typename GR, typename LM, typename UM,
151 151
           typename SM, typename FM >
152 152
bool checkFlow( const GR& gr, const LM& lower, const UM& upper,
153 153
                const SM& supply, const FM& flow,
154 154
                ProblemType type = EQ )
155 155
{
156 156
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
157 157

	
158 158
  for (ArcIt e(gr); e != INVALID; ++e) {
159 159
    if (flow[e] < lower[e] || flow[e] > upper[e]) return false;
160 160
  }
161 161

	
162 162
  for (NodeIt n(gr); n != INVALID; ++n) {
163 163
    typename SM::Value sum = 0;
164 164
    for (OutArcIt e(gr, n); e != INVALID; ++e)
165 165
      sum += flow[e];
166 166
    for (InArcIt e(gr, n); e != INVALID; ++e)
167 167
      sum -= flow[e];
168 168
    bool b = (type ==  EQ && sum == supply[n]) ||
169 169
             (type == GEQ && sum >= supply[n]) ||
170 170
             (type == LEQ && sum <= supply[n]);
171 171
    if (!b) return false;
172 172
  }
173 173

	
174 174
  return true;
175 175
}
176 176

	
177 177
// Check the feasibility of the given potentials (dual soluiton)
178 178
// using the "Complementary Slackness" optimality condition
179 179
template < typename GR, typename LM, typename UM,
180 180
           typename CM, typename SM, typename FM, typename PM >
181 181
bool checkPotential( const GR& gr, const LM& lower, const UM& upper,
182 182
                     const CM& cost, const SM& supply, const FM& flow, 
183 183
                     const PM& pi )
184 184
{
185 185
  TEMPLATE_DIGRAPH_TYPEDEFS(GR);
186 186

	
187 187
  bool opt = true;
188 188
  for (ArcIt e(gr); opt && e != INVALID; ++e) {
189 189
    typename CM::Value red_cost =
190 190
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
191 191
    opt = red_cost == 0 ||
192 192
          (red_cost > 0 && flow[e] == lower[e]) ||
193 193
          (red_cost < 0 && flow[e] == upper[e]);
194 194
  }
195 195
  
196 196
  for (NodeIt n(gr); opt && n != INVALID; ++n) {
197 197
    typename SM::Value sum = 0;
198 198
    for (OutArcIt e(gr, n); e != INVALID; ++e)
199 199
      sum += flow[e];
200 200
    for (InArcIt e(gr, n); e != INVALID; ++e)
201 201
      sum -= flow[e];
202 202
    opt = (sum == supply[n]) || (pi[n] == 0);
203 203
  }
204 204
  
205 205
  return opt;
206 206
}
207 207

	
208 208
// Run a minimum cost flow algorithm and check the results
209 209
template < typename MCF, typename GR,
210 210
           typename LM, typename UM,
211 211
           typename CM, typename SM >
212 212
void checkMcf( const MCF& mcf, bool mcf_result,
213 213
               const GR& gr, const LM& lower, const UM& upper,
214 214
               const CM& cost, const SM& supply,
215 215
               bool result, typename CM::Value total,
216 216
               const std::string &test_id = "",
217 217
               ProblemType type = EQ )
218 218
{
219 219
  check(mcf_result == result, "Wrong result " + test_id);
220 220
  if (result) {
221 221
    check(checkFlow(gr, lower, upper, supply, mcf.flowMap(), type),
222 222
          "The flow is not feasible " + test_id);
223 223
    check(mcf.totalCost() == total, "The flow is not optimal " + test_id);
224 224
    check(checkPotential(gr, lower, upper, cost, supply, mcf.flowMap(),
225 225
                         mcf.potentialMap()),
226 226
          "Wrong potentials " + test_id);
227 227
  }
228 228
}
229 229

	
230 230
int main()
231 231
{
232 232
  // Check the interfaces
233 233
  {
234 234
    typedef int Flow;
235 235
    typedef int Cost;
236
    // TODO: This typedef should be enabled if the standard maps are
237
    // reference maps in the graph concepts (See #190).
238
/**/
239
    //typedef concepts::Digraph GR;
240
    typedef ListDigraph GR;
241
/**/
236
    typedef concepts::Digraph GR;
242 237
    checkConcept< McfClassConcept<GR, Flow, Cost>,
243 238
                  NetworkSimplex<GR, Flow, Cost> >();
244 239
  }
245 240

	
246 241
  // Run various MCF tests
247 242
  typedef ListDigraph Digraph;
248 243
  DIGRAPH_TYPEDEFS(ListDigraph);
249 244

	
250 245
  // Read the test digraph
251 246
  Digraph gr;
252 247
  Digraph::ArcMap<int> c(gr), l1(gr), l2(gr), u(gr);
253 248
  Digraph::NodeMap<int> s1(gr), s2(gr), s3(gr), s4(gr), s5(gr);
254 249
  ConstMap<Arc, int> cc(1), cu(std::numeric_limits<int>::max());
255 250
  Node v, w;
256 251

	
257 252
  std::istringstream input(test_lgf);
258 253
  DigraphReader<Digraph>(gr, input)
259 254
    .arcMap("cost", c)
260 255
    .arcMap("cap", u)
261 256
    .arcMap("low1", l1)
262 257
    .arcMap("low2", l2)
263 258
    .nodeMap("sup1", s1)
264 259
    .nodeMap("sup2", s2)
265 260
    .nodeMap("sup3", s3)
266 261
    .nodeMap("sup4", s4)
267 262
    .nodeMap("sup5", s5)
268 263
    .node("source", v)
269 264
    .node("target", w)
270 265
    .run();
271 266

	
272 267
  // A. Test NetworkSimplex with the default pivot rule
273 268
  {
274 269
    NetworkSimplex<Digraph> mcf(gr);
275 270

	
276 271
    // Check the equality form
277 272
    mcf.upperMap(u).costMap(c);
278 273
    checkMcf(mcf, mcf.supplyMap(s1).run(),
279 274
             gr, l1, u, c, s1, true,  5240, "#A1");
280 275
    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
281 276
             gr, l1, u, c, s2, true,  7620, "#A2");
282 277
    mcf.lowerMap(l2);
283 278
    checkMcf(mcf, mcf.supplyMap(s1).run(),
284 279
             gr, l2, u, c, s1, true,  5970, "#A3");
285 280
    checkMcf(mcf, mcf.stSupply(v, w, 27).run(),
286 281
             gr, l2, u, c, s2, true,  8010, "#A4");
287 282
    mcf.reset();
288 283
    checkMcf(mcf, mcf.supplyMap(s1).run(),
289 284
             gr, l1, cu, cc, s1, true,  74, "#A5");
290 285
    checkMcf(mcf, mcf.lowerMap(l2).stSupply(v, w, 27).run(),
291 286
             gr, l2, cu, cc, s2, true,  94, "#A6");
292 287
    mcf.reset();
293 288
    checkMcf(mcf, mcf.run(),
294 289
             gr, l1, cu, cc, s3, true,   0, "#A7");
295 290
    checkMcf(mcf, mcf.boundMaps(l2, u).run(),
296 291
             gr, l2, u, cc, s3, false,   0, "#A8");
297 292

	
298 293
    // Check the GEQ form
299 294
    mcf.reset().upperMap(u).costMap(c).supplyMap(s4);
300 295
    checkMcf(mcf, mcf.run(),
301 296
             gr, l1, u, c, s4, true,  3530, "#A9", GEQ);
302 297
    mcf.problemType(mcf.GEQ);
303 298
    checkMcf(mcf, mcf.lowerMap(l2).run(),
304 299
             gr, l2, u, c, s4, true,  4540, "#A10", GEQ);
305 300
    mcf.problemType(mcf.CARRY_SUPPLIES).supplyMap(s5);
306 301
    checkMcf(mcf, mcf.run(),
307 302
             gr, l2, u, c, s5, false,    0, "#A11", GEQ);
308 303

	
309 304
    // Check the LEQ form
310 305
    mcf.reset().problemType(mcf.LEQ);
311 306
    mcf.upperMap(u).costMap(c).supplyMap(s5);
312 307
    checkMcf(mcf, mcf.run(),
313 308
             gr, l1, u, c, s5, true,  5080, "#A12", LEQ);
314 309
    checkMcf(mcf, mcf.lowerMap(l2).run(),
315 310
             gr, l2, u, c, s5, true,  5930, "#A13", LEQ);
316 311
    mcf.problemType(mcf.SATISFY_DEMANDS).supplyMap(s4);
317 312
    checkMcf(mcf, mcf.run(),
318 313
             gr, l2, u, c, s4, false,    0, "#A14", LEQ);
319 314
  }
320 315

	
321 316
  // B. Test NetworkSimplex with each pivot rule
322 317
  {
323 318
    NetworkSimplex<Digraph> mcf(gr);
324 319
    mcf.supplyMap(s1).costMap(c).capacityMap(u).lowerMap(l2);
325 320

	
326 321
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::FIRST_ELIGIBLE),
327 322
             gr, l2, u, c, s1, true,  5970, "#B1");
328 323
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BEST_ELIGIBLE),
329 324
             gr, l2, u, c, s1, true,  5970, "#B2");
330 325
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::BLOCK_SEARCH),
331 326
             gr, l2, u, c, s1, true,  5970, "#B3");
332 327
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::CANDIDATE_LIST),
333 328
             gr, l2, u, c, s1, true,  5970, "#B4");
334 329
    checkMcf(mcf, mcf.run(NetworkSimplex<Digraph>::ALTERING_LIST),
335 330
             gr, l2, u, c, s1, true,  5970, "#B5");
336 331
  }
337 332

	
338 333
  return 0;
339 334
}
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
///\ingroup tools
20 20
///\file
21 21
///\brief DIMACS problem solver.
22 22
///
23 23
/// This program solves various problems given in DIMACS format.
24 24
///
25 25
/// See
26 26
/// \code
27 27
///   dimacs-solver --help
28 28
/// \endcode
29 29
/// for more info on usage.
30 30

	
31 31
#include <iostream>
32 32
#include <fstream>
33 33
#include <cstring>
34 34

	
35 35
#include <lemon/smart_graph.h>
36 36
#include <lemon/dimacs.h>
37 37
#include <lemon/lgf_writer.h>
38 38
#include <lemon/time_measure.h>
39 39

	
40 40
#include <lemon/arg_parser.h>
41 41
#include <lemon/error.h>
42 42

	
43 43
#include <lemon/dijkstra.h>
44 44
#include <lemon/preflow.h>
45 45
#include <lemon/matching.h>
46 46
#include <lemon/network_simplex.h>
47 47

	
48 48
using namespace lemon;
49 49
typedef SmartDigraph Digraph;
50 50
DIGRAPH_TYPEDEFS(Digraph);
51 51
typedef SmartGraph Graph;
52 52

	
53 53
template<class Value>
54 54
void solve_sp(ArgParser &ap, std::istream &is, std::ostream &,
55 55
              DimacsDescriptor &desc)
56 56
{
57 57
  bool report = !ap.given("q");
58 58
  Digraph g;
59 59
  Node s;
60 60
  Digraph::ArcMap<Value> len(g);
61 61
  Timer t;
62 62
  t.restart();
63 63
  readDimacsSp(is, g, len, s, desc);
64 64
  if(report) std::cerr << "Read the file: " << t << '\n';
65 65
  t.restart();
66 66
  Dijkstra<Digraph, Digraph::ArcMap<Value> > dij(g,len);
67 67
  if(report) std::cerr << "Setup Dijkstra class: " << t << '\n';
68 68
  t.restart();
69 69
  dij.run(s);
70 70
  if(report) std::cerr << "Run Dijkstra: " << t << '\n';
71 71
}
72 72

	
73 73
template<class Value>
74 74
void solve_max(ArgParser &ap, std::istream &is, std::ostream &,
75 75
               Value infty, DimacsDescriptor &desc)
76 76
{
77 77
  bool report = !ap.given("q");
78 78
  Digraph g;
79 79
  Node s,t;
80 80
  Digraph::ArcMap<Value> cap(g);
81 81
  Timer ti;
82 82
  ti.restart();
83 83
  readDimacsMax(is, g, cap, s, t, infty, desc);
84 84
  if(report) std::cerr << "Read the file: " << ti << '\n';
85 85
  ti.restart();
86 86
  Preflow<Digraph, Digraph::ArcMap<Value> > pre(g,cap,s,t);
87 87
  if(report) std::cerr << "Setup Preflow class: " << ti << '\n';
88 88
  ti.restart();
89 89
  pre.run();
90 90
  if(report) std::cerr << "Run Preflow: " << ti << '\n';
91 91
  if(report) std::cerr << "\nMax flow value: " << pre.flowValue() << '\n';  
92 92
}
93 93

	
94 94
template<class Value>
95 95
void solve_min(ArgParser &ap, std::istream &is, std::ostream &,
96
               DimacsDescriptor &desc)
96
               Value infty, DimacsDescriptor &desc)
97 97
{
98 98
  bool report = !ap.given("q");
99 99
  Digraph g;
100 100
  Digraph::ArcMap<Value> lower(g), cap(g), cost(g);
101 101
  Digraph::NodeMap<Value> sup(g);
102 102
  Timer ti;
103

	
103 104
  ti.restart();
104
  readDimacsMin(is, g, lower, cap, cost, sup, 0, desc);
105
  readDimacsMin(is, g, lower, cap, cost, sup, infty, desc);
106
  ti.stop();
107
  Value sum_sup = 0;
108
  for (Digraph::NodeIt n(g); n != INVALID; ++n) {
109
    sum_sup += sup[n];
110
  }
111
  if (report) {
112
    std::cerr << "Sum of supply values: " << sum_sup << "\n";
113
    if (sum_sup <= 0)
114
      std::cerr << "GEQ supply contraints are used for NetworkSimplex\n\n";
115
    else
116
      std::cerr << "LEQ supply contraints are used for NetworkSimplex\n\n";
117
  }
105 118
  if (report) std::cerr << "Read the file: " << ti << '\n';
119

	
106 120
  ti.restart();
107 121
  NetworkSimplex<Digraph, Value> ns(g);
108 122
  ns.lowerMap(lower).capacityMap(cap).costMap(cost).supplyMap(sup);
123
  if (sum_sup > 0) ns.problemType(ns.LEQ);
109 124
  if (report) std::cerr << "Setup NetworkSimplex class: " << ti << '\n';
110 125
  ti.restart();
111
  ns.run();
112
  if (report) std::cerr << "Run NetworkSimplex: " << ti << '\n';
113
  if (report) std::cerr << "\nMin flow cost: " << ns.totalCost() << '\n';
126
  bool res = ns.run();
127
  if (report) {
128
    std::cerr << "Run NetworkSimplex: " << ti << "\n\n";
129
    std::cerr << "Feasible flow: " << (res ? "found" : "not found") << '\n';
130
    if (res) std::cerr << "Min flow cost: " << ns.totalCost() << '\n';
131
  }
114 132
}
115 133

	
116 134
void solve_mat(ArgParser &ap, std::istream &is, std::ostream &,
117 135
              DimacsDescriptor &desc)
118 136
{
119 137
  bool report = !ap.given("q");
120 138
  Graph g;
121 139
  Timer ti;
122 140
  ti.restart();
123 141
  readDimacsMat(is, g, desc);
124 142
  if(report) std::cerr << "Read the file: " << ti << '\n';
125 143
  ti.restart();
126 144
  MaxMatching<Graph> mat(g);
127 145
  if(report) std::cerr << "Setup MaxMatching class: " << ti << '\n';
128 146
  ti.restart();
129 147
  mat.run();
130 148
  if(report) std::cerr << "Run MaxMatching: " << ti << '\n';
131 149
  if(report) std::cerr << "\nCardinality of max matching: "
132 150
                       << mat.matchingSize() << '\n';  
133 151
}
134 152

	
135 153

	
136 154
template<class Value>
137 155
void solve(ArgParser &ap, std::istream &is, std::ostream &os,
138 156
           DimacsDescriptor &desc)
139 157
{
140 158
  std::stringstream iss(static_cast<std::string>(ap["infcap"]));
141 159
  Value infty;
142 160
  iss >> infty;
143 161
  if(iss.fail())
144 162
    {
145 163
      std::cerr << "Cannot interpret '"
146 164
                << static_cast<std::string>(ap["infcap"]) << "' as infinite"
147 165
                << std::endl;
148 166
      exit(1);
149 167
    }
150 168
  
151 169
  switch(desc.type)
152 170
    {
153 171
    case DimacsDescriptor::MIN:
154
      solve_min<Value>(ap,is,os,desc);
172
      solve_min<Value>(ap,is,os,infty,desc);
155 173
      break;
156 174
    case DimacsDescriptor::MAX:
157 175
      solve_max<Value>(ap,is,os,infty,desc);
158 176
      break;
159 177
    case DimacsDescriptor::SP:
160 178
      solve_sp<Value>(ap,is,os,desc);
161 179
      break;
162 180
    case DimacsDescriptor::MAT:
163 181
      solve_mat(ap,is,os,desc);
164 182
      break;
165 183
    default:
166 184
      break;
167 185
    }
168 186
}
169 187

	
170 188
int main(int argc, const char *argv[]) {
171 189
  typedef SmartDigraph Digraph;
172 190

	
173 191
  typedef Digraph::Arc Arc;
174 192

	
175 193
  std::string inputName;
176 194
  std::string outputName;
177 195

	
178 196
  ArgParser ap(argc, argv);
179 197
  ap.other("[INFILE [OUTFILE]]",
180 198
           "If either the INFILE or OUTFILE file is missing the standard\n"
181 199
           "     input/output will be used instead.")
182 200
    .boolOption("q", "Do not print any report")
183 201
    .boolOption("int","Use 'int' for capacities, costs etc. (default)")
184 202
    .optionGroup("datatype","int")
185 203
#ifdef HAVE_LONG_LONG
186 204
    .boolOption("long","Use 'long long' for capacities, costs etc.")
187 205
    .optionGroup("datatype","long")
188 206
#endif
189 207
    .boolOption("double","Use 'double' for capacities, costs etc.")
190 208
    .optionGroup("datatype","double")
191 209
    .boolOption("ldouble","Use 'long double' for capacities, costs etc.")
192 210
    .optionGroup("datatype","ldouble")
193 211
    .onlyOneGroup("datatype")
194 212
    .stringOption("infcap","Value used for 'very high' capacities","0")
195 213
    .run();
196 214

	
197 215
  std::ifstream input;
198 216
  std::ofstream output;
199 217

	
200 218
  switch(ap.files().size())
201 219
    {
202 220
    case 2:
203 221
      output.open(ap.files()[1].c_str());
204 222
      if (!output) {
205 223
        throw IoError("Cannot open the file for writing", ap.files()[1]);
206 224
      }
207 225
    case 1:
208 226
      input.open(ap.files()[0].c_str());
209 227
      if (!input) {
210 228
        throw IoError("File cannot be found", ap.files()[0]);
211 229
      }
212 230
    case 0:
213 231
      break;
214 232
    default:
215 233
      std::cerr << ap.commandName() << ": too many arguments\n";
216 234
      return 1;
217 235
    }
218 236
  std::istream& is = (ap.files().size()<1 ? std::cin : input);
219 237
  std::ostream& os = (ap.files().size()<2 ? std::cout : output);
220 238

	
221 239
  DimacsDescriptor desc = dimacsType(is);
222 240
  
223 241
  if(!ap.given("q"))
224 242
    {
225 243
      std::cout << "Problem type: ";
226 244
      switch(desc.type)
227 245
        {
228 246
        case DimacsDescriptor::MIN:
229 247
          std::cout << "min";
230 248
          break;
231 249
        case DimacsDescriptor::MAX:
232 250
          std::cout << "max";
233 251
          break;
234 252
        case DimacsDescriptor::SP:
235 253
          std::cout << "sp";
236 254
        case DimacsDescriptor::MAT:
237 255
          std::cout << "mat";
238 256
          break;
239 257
        default:
240 258
          exit(1);
241 259
          break;
242 260
        }
243 261
      std::cout << "\nNum of nodes: " << desc.nodeNum;
244 262
      std::cout << "\nNum of arcs:  " << desc.edgeNum;
245 263
      std::cout << "\n\n";
246 264
    }
247 265
    
248 266
  if(ap.given("double"))
249 267
    solve<double>(ap,is,os,desc);
250 268
  else if(ap.given("ldouble"))
251 269
    solve<long double>(ap,is,os,desc);
252 270
#ifdef HAVE_LONG_LONG
253 271
  else if(ap.given("long"))
254 272
    solve<long long>(ap,is,os,desc);
255 273
#endif
256 274
  else solve<int>(ap,is,os,desc);
257 275

	
258 276
  return 0;
259 277
}
0 comments (0 inline)