Changes in / [1014:bc726f4892c7:1011:9a6c9d4ee77b] in lemon-main
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/cycle_canceling.h
r1013 r1003 36 36 #include <lemon/bellman_ford.h> 37 37 #include <lemon/howard_mmc.h> 38 #include <lemon/hartmann_orlin_mmc.h>39 38 40 39 namespace lemon { … … 929 928 // Execute the "Minimum Mean Cycle Canceling" method 930 929 void startMinMeanCycleCanceling() { 931 typedef Path<StaticDigraph> SPath;930 typedef SimplePath<StaticDigraph> SPath; 932 931 typedef typename SPath::ArcIt SPathArcIt; 933 932 typedef typename HowardMmc<StaticDigraph, CostArcMap> 934 ::template SetPath<SPath>::Create HwMmc; 935 typedef typename HartmannOrlinMmc<StaticDigraph, CostArcMap> 936 ::template SetPath<SPath>::Create HoMmc; 937 938 const double HW_ITER_LIMIT_FACTOR = 1.0; 939 const int HW_ITER_LIMIT_MIN_VALUE = 5; 940 941 const int hw_iter_limit = 942 std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num), 943 HW_ITER_LIMIT_MIN_VALUE); 933 ::template SetPath<SPath>::Create MMC; 944 934 945 935 SPath cycle; 946 HwMmc hw_mmc(_sgr, _cost_map);947 hw_mmc.cycle(cycle);936 MMC mmc(_sgr, _cost_map); 937 mmc.cycle(cycle); 948 938 buildResidualNetwork(); 949 while (true) { 950 951 typename HwMmc::TerminationCause hw_tc = 952 hw_mmc.findCycleMean(hw_iter_limit); 953 if (hw_tc == HwMmc::ITERATION_LIMIT) { 954 // Howard's algorithm reached the iteration limit, start a 955 // strongly polynomial algorithm instead 956 HoMmc ho_mmc(_sgr, _cost_map); 957 ho_mmc.cycle(cycle); 958 // Find a minimum mean cycle (Hartmann-Orlin algorithm) 959 if (!(ho_mmc.findCycleMean() && ho_mmc.cycleCost() < 0)) break; 960 ho_mmc.findCycle(); 961 } else { 962 // Find a minimum mean cycle (Howard algorithm) 963 if (!(hw_tc == HwMmc::OPTIMAL && hw_mmc.cycleCost() < 0)) break; 964 hw_mmc.findCycle(); 965 } 966 939 while (mmc.findCycleMean() && mmc.cycleCost() < 0) { 940 // Find the cycle 941 mmc.findCycle(); 942 967 943 // Compute delta value 968 944 Value delta = INF; … … 989 965 const double LIMIT_FACTOR = 1.0; 990 966 const int MIN_LIMIT = 5; 991 const double HW_ITER_LIMIT_FACTOR = 1.0;992 const int HW_ITER_LIMIT_MIN_VALUE = 5;993 994 const int hw_iter_limit =995 std::max(static_cast<int>(HW_ITER_LIMIT_FACTOR * _node_num),996 HW_ITER_LIMIT_MIN_VALUE);997 967 998 968 // Contruct auxiliary data vectors … … 1168 1138 } 1169 1139 } else { 1170 typedef HowardMmc<StaticDigraph, CostArcMap> HwMmc; 1171 typedef HartmannOrlinMmc<StaticDigraph, CostArcMap> HoMmc; 1140 typedef HowardMmc<StaticDigraph, CostArcMap> MMC; 1172 1141 typedef typename BellmanFord<StaticDigraph, CostArcMap> 1173 1142 ::template SetDistMap<CostNodeMap>::Create BF; 1174 1143 1175 1144 // Set epsilon to the minimum cycle mean 1176 Cost cycle_cost = 0;1177 int cycle_size = 1;1178 1145 buildResidualNetwork(); 1179 HwMmc hw_mmc(_sgr, _cost_map); 1180 if (hw_mmc.findCycleMean(hw_iter_limit) == HwMmc::ITERATION_LIMIT) { 1181 // Howard's algorithm reached the iteration limit, start a 1182 // strongly polynomial algorithm instead 1183 HoMmc ho_mmc(_sgr, _cost_map); 1184 ho_mmc.findCycleMean(); 1185 epsilon = -ho_mmc.cycleMean(); 1186 cycle_cost = ho_mmc.cycleCost(); 1187 cycle_size = ho_mmc.cycleSize(); 1188 } else { 1189 // Set epsilon 1190 epsilon = -hw_mmc.cycleMean(); 1191 cycle_cost = hw_mmc.cycleCost(); 1192 cycle_size = hw_mmc.cycleSize(); 1193 } 1146 MMC mmc(_sgr, _cost_map); 1147 mmc.findCycleMean(); 1148 epsilon = -mmc.cycleMean(); 1149 Cost cycle_cost = mmc.cycleCost(); 1150 int cycle_size = mmc.cycleSize(); 1194 1151 1195 1152 // Compute feasible potentials for the current epsilon -
lemon/howard_mmc.h
r1012 r1002 150 150 typedef TR Traits; 151 151 152 /// \brief Constants for the causes of search termination.153 ///154 /// Enum type containing constants for the different causes of search155 /// termination. The \ref findCycleMean() function returns one of156 /// these values.157 enum TerminationCause {158 159 /// No directed cycle can be found in the digraph.160 NO_CYCLE = 0,161 162 /// Optimal solution (minimum cycle mean) is found.163 OPTIMAL = 1,164 165 /// The iteration count limit is reached.166 ITERATION_LIMIT167 };168 169 152 private: 170 153 … … 342 325 } 343 326 344 /// \brief Find the minimum cycle mean (or an upper bound).327 /// \brief Find the minimum cycle mean. 345 328 /// 346 329 /// This function finds the minimum mean cost of the directed 347 /// cycles in the digraph (or an upper bound for it). 348 /// 349 /// By default, the function finds the exact minimum cycle mean, 350 /// but an optional limit can also be specified for the number of 351 /// iterations performed during the search process. 352 /// The return value indicates if the optimal solution is found 353 /// or the iteration limit is reached. In the latter case, an 354 /// approximate solution is provided, which corresponds to a directed 355 /// cycle whose mean cost is relatively small, but not necessarily 356 /// minimal. 357 /// 358 /// \param limit The maximum allowed number of iterations during 359 /// the search process. Its default value implies that the algorithm 360 /// runs until it finds the exact optimal solution. 361 /// 362 /// \return The termination cause of the search process. 363 /// For more information, see \ref TerminationCause. 364 TerminationCause findCycleMean(int limit = std::numeric_limits<int>::max()) { 330 /// cycles in the digraph. 331 /// 332 /// \return \c true if a directed cycle exists in the digraph. 333 bool findCycleMean() { 365 334 // Initialize and find strongly connected components 366 335 init(); … … 368 337 369 338 // Find the minimum cycle mean in the components 370 int iter_count = 0;371 bool iter_limit_reached = false;372 339 for (int comp = 0; comp < _comp_num; ++comp) { 373 340 // Find the minimum mean cycle in the current component 374 341 if (!buildPolicyGraph(comp)) continue; 375 342 while (true) { 376 if (++iter_count > limit) {377 iter_limit_reached = true;378 break;379 }380 343 findPolicyCycle(); 381 344 if (!computeNodeDistances()) break; 382 345 } 383 384 346 // Update the best cycle (global minimum mean cycle) 385 347 if ( _curr_found && (!_best_found || … … 390 352 _best_node = _curr_node; 391 353 } 392 393 if (iter_limit_reached) break; 394 } 395 396 if (iter_limit_reached) { 397 return ITERATION_LIMIT; 398 } else { 399 return _best_found ? OPTIMAL : NO_CYCLE; 400 } 354 } 355 return _best_found; 401 356 } 402 357 -
test/min_mean_cycle_test.cc
r1012 r877 111 111 int cost, int size) { 112 112 MMC alg(gr, lm); 113 check(alg.findCycleMean(), "Wrong result");113 alg.findCycleMean(); 114 114 check(alg.cycleMean() == static_cast<double>(cost) / size, 115 115 "Wrong cycle mean"); … … 211 211 checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l3, c3, 0, 1); 212 212 checkMmcAlg<HowardMmc<GR, IntArcMap> >(gr, l4, c4, -1, 1); 213 214 // Howard with iteration limit215 HowardMmc<GR, IntArcMap> mmc(gr, l1);216 check((mmc.findCycleMean(2) == HowardMmc<GR, IntArcMap>::ITERATION_LIMIT),217 "Wrong termination cause");218 check((mmc.findCycleMean(4) == HowardMmc<GR, IntArcMap>::OPTIMAL),219 "Wrong termination cause");220 213 } 221 214
Note: See TracChangeset
for help on using the changeset viewer.