Changes in / [1011:9a6c9d4ee77b:1014:bc726f4892c7] in lemon-main
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/cycle_canceling.h
r1003 r1013 36 36 #include <lemon/bellman_ford.h> 37 37 #include <lemon/howard_mmc.h> 38 #include <lemon/hartmann_orlin_mmc.h> 38 39 39 40 namespace lemon { … … 928 929 // Execute the "Minimum Mean Cycle Canceling" method 929 930 void startMinMeanCycleCanceling() { 930 typedef SimplePath<StaticDigraph> SPath;931 typedef Path<StaticDigraph> SPath; 931 932 typedef typename SPath::ArcIt SPathArcIt; 932 933 typedef typename HowardMmc<StaticDigraph, CostArcMap> 933 ::template SetPath<SPath>::Create MMC; 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); 934 944 935 945 SPath cycle; 936 MMCmmc(_sgr, _cost_map);937 mmc.cycle(cycle);946 HwMmc hw_mmc(_sgr, _cost_map); 947 hw_mmc.cycle(cycle); 938 948 buildResidualNetwork(); 939 while (mmc.findCycleMean() && mmc.cycleCost() < 0) { 940 // Find the cycle 941 mmc.findCycle(); 942 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 943 967 // Compute delta value 944 968 Value delta = INF; … … 965 989 const double LIMIT_FACTOR = 1.0; 966 990 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); 967 997 968 998 // Contruct auxiliary data vectors … … 1138 1168 } 1139 1169 } else { 1140 typedef HowardMmc<StaticDigraph, CostArcMap> MMC; 1170 typedef HowardMmc<StaticDigraph, CostArcMap> HwMmc; 1171 typedef HartmannOrlinMmc<StaticDigraph, CostArcMap> HoMmc; 1141 1172 typedef typename BellmanFord<StaticDigraph, CostArcMap> 1142 1173 ::template SetDistMap<CostNodeMap>::Create BF; 1143 1174 1144 1175 // Set epsilon to the minimum cycle mean 1176 Cost cycle_cost = 0; 1177 int cycle_size = 1; 1145 1178 buildResidualNetwork(); 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(); 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 } 1151 1194 1152 1195 // Compute feasible potentials for the current epsilon -
lemon/howard_mmc.h
r1002 r1012 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 search 155 /// termination. The \ref findCycleMean() function returns one of 156 /// 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_LIMIT 167 }; 168 152 169 private: 153 170 … … 325 342 } 326 343 327 /// \brief Find the minimum cycle mean .344 /// \brief Find the minimum cycle mean (or an upper bound). 328 345 /// 329 346 /// This function finds the minimum mean cost of the directed 330 /// cycles in the digraph. 331 /// 332 /// \return \c true if a directed cycle exists in the digraph. 333 bool findCycleMean() { 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()) { 334 365 // Initialize and find strongly connected components 335 366 init(); … … 337 368 338 369 // Find the minimum cycle mean in the components 370 int iter_count = 0; 371 bool iter_limit_reached = false; 339 372 for (int comp = 0; comp < _comp_num; ++comp) { 340 373 // Find the minimum mean cycle in the current component 341 374 if (!buildPolicyGraph(comp)) continue; 342 375 while (true) { 376 if (++iter_count > limit) { 377 iter_limit_reached = true; 378 break; 379 } 343 380 findPolicyCycle(); 344 381 if (!computeNodeDistances()) break; 345 382 } 383 346 384 // Update the best cycle (global minimum mean cycle) 347 385 if ( _curr_found && (!_best_found || … … 352 390 _best_node = _curr_node; 353 391 } 354 } 355 return _best_found; 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 } 356 401 } 357 402 -
test/min_mean_cycle_test.cc
r877 r1012 111 111 int cost, int size) { 112 112 MMC alg(gr, lm); 113 alg.findCycleMean();113 check(alg.findCycleMean(), "Wrong result"); 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 limit 215 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"); 213 220 } 214 221
Note: See TracChangeset
for help on using the changeset viewer.