Changeset 2556:74c2c81055e1 in lemon-0.x for lemon/cycle_canceling.h
- Timestamp:
- 01/13/08 11:32:14 (16 years ago)
- Branch:
- default
- Phase:
- public
- Convert:
- svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@3437
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/cycle_canceling.h
r2553 r2556 35 35 #ifdef LIMITED_CYCLE_CANCELING 36 36 #include <lemon/bellman_ford.h> 37 /// \brief The maximum number of iterations for the first execution 38 /// of the \ref lemon::BellmanFord "Bellman-Ford" algorithm. 39 /// It should be at least 2. 40 #define STARTING_LIMIT 2 41 /// \brief The iteration limit for the 42 /// \ref lemon::BellmanFord "Bellman-Ford" algorithm is multiplied by 43 /// <tt>ALPHA_MUL / ALPHA_DIV</tt> in every round. 44 /// <tt>ALPHA_MUL / ALPHA_DIV</tt> must be greater than 1. 45 #define ALPHA_MUL 3 46 /// \brief The iteration limit for the 47 /// \ref lemon::BellmanFord "Bellman-Ford" algorithm is multiplied by 48 /// <tt>ALPHA_MUL / ALPHA_DIV</tt> in every round. 49 /// <tt>ALPHA_MUL / ALPHA_DIV</tt> must be greater than 1. 50 #define ALPHA_DIV 2 37 // The maximum number of iterations for the first execution of the 38 // Bellman-Ford algorithm. It should be at least 2. 39 #define STARTING_LIMIT 2 40 // The iteration limit for the Bellman-Ford algorithm is multiplied by 41 // <tt>ALPHA_MUL / ALPHA_DIV</tt> in every round. 42 // <tt>ALPHA_MUL / ALPHA_DIV</tt> must be greater than 1. 43 #define ALPHA_MUL 3 44 #define ALPHA_DIV 2 51 45 52 46 //#define _ONLY_ONE_CYCLE_ 53 47 //#define _NO_BACK_STEP_ 54 //#define _DEBUG_ITER_55 48 #endif 56 49 … … 60 53 #endif 61 54 55 //#define _DEBUG_ITER_ 56 62 57 namespace lemon { 63 58 … … 65 60 /// @{ 66 61 67 /// \brief Implementation of a cycle-canceling algorithm for finding68 /// a minimum cost flow.62 /// \brief Implementation of a cycle-canceling algorithm for 63 /// finding a minimum cost flow. 69 64 /// 70 /// \ref lemon::CycleCanceling "CycleCanceling" implements a71 /// cycle-canceling algorithm forfinding a minimum cost flow.65 /// \ref CycleCanceling implements a cycle-canceling algorithm for 66 /// finding a minimum cost flow. 72 67 /// 73 68 /// \param Graph The directed graph type the algorithm runs on. … … 78 73 /// 79 74 /// \warning 80 /// - Edge capacities and costs should be non negative integers.81 /// 75 /// - Edge capacities and costs should be non-negative integers. 76 /// However \c CostMap::Value should be signed type. 82 77 /// - Supply values should be signed integers. 83 78 /// - \c LowerMap::Value must be convertible to 84 /// 85 /// 79 /// \c CapacityMap::Value and \c CapacityMap::Value must be 80 /// convertible to \c SupplyMap::Value. 86 81 /// 87 82 /// \author Peter Kovacs … … 95 90 class CycleCanceling 96 91 { 97 typedef typename Graph::Node Node; 98 typedef typename Graph::NodeIt NodeIt; 99 typedef typename Graph::Edge Edge; 100 typedef typename Graph::EdgeIt EdgeIt; 101 typedef typename Graph::InEdgeIt InEdgeIt; 102 typedef typename Graph::OutEdgeIt OutEdgeIt; 92 GRAPH_TYPEDEFS(typename Graph); 103 93 104 94 typedef typename LowerMap::Value Lower; … … 106 96 typedef typename CostMap::Value Cost; 107 97 typedef typename SupplyMap::Value Supply; 108 typedef typename Graph::template EdgeMap<Capacity> Capacity RefMap;109 typedef typename Graph::template NodeMap<Supply> Supply RefMap;98 typedef typename Graph::template EdgeMap<Capacity> CapacityEdgeMap; 99 typedef typename Graph::template NodeMap<Supply> SupplyNodeMap; 110 100 111 101 typedef ResGraphAdaptor< const Graph, Capacity, 112 CapacityRefMap, CapacityRefMap > ResGraph;102 CapacityEdgeMap, CapacityEdgeMap > ResGraph; 113 103 typedef typename ResGraph::Node ResNode; 114 104 typedef typename ResGraph::NodeIt ResNodeIt; … … 118 108 public: 119 109 120 /// \briefThe type of the flow map.121 typedef CapacityRefMapFlowMap;110 /// The type of the flow map. 111 typedef typename Graph::template EdgeMap<Capacity> FlowMap; 122 112 123 113 protected: 124 114 125 /// \briefMap adaptor class for handling residual edge costs.115 /// Map adaptor class for handling residual edge costs. 126 116 class ResCostMap : public MapBase<ResEdge, Cost> 127 117 { … … 135 125 136 126 Cost operator[](const ResEdge &e) const { 137 127 return ResGraph::forward(e) ? cost_map[e] : -cost_map[e]; 138 128 } 139 129 … … 142 132 protected: 143 133 144 /// \briefThe directed graph the algorithm runs on.134 /// The directed graph the algorithm runs on. 145 135 const Graph &graph; 146 /// \briefThe original lower bound map.136 /// The original lower bound map. 147 137 const LowerMap *lower; 148 /// \briefThe modified capacity map.149 Capacity RefMap capacity;150 /// \briefThe cost map.138 /// The modified capacity map. 139 CapacityEdgeMap capacity; 140 /// The cost map. 151 141 const CostMap &cost; 152 /// \brief The modified supply map. 153 SupplyRefMap supply; 154 /// \brief The sum of supply values equals zero. 142 /// The modified supply map. 143 SupplyNodeMap supply; 155 144 bool valid_supply; 156 145 157 /// \briefThe current flow.146 /// The current flow. 158 147 FlowMap flow; 159 /// \briefThe residual graph.148 /// The residual graph. 160 149 ResGraph res_graph; 161 /// \briefThe residual cost map.150 /// The residual cost map. 162 151 ResCostMap res_cost; 163 152 … … 174 163 /// \param _supply The supply values of the nodes (signed). 175 164 CycleCanceling( const Graph &_graph, 176 177 178 179 165 const LowerMap &_lower, 166 const CapacityMap &_capacity, 167 const CostMap &_cost, 168 const SupplyMap &_supply ) : 180 169 graph(_graph), lower(&_lower), capacity(_graph), cost(_cost), 181 170 supply(_graph), flow(_graph, 0), 182 171 res_graph(_graph, capacity, flow), res_cost(cost) 183 172 { 184 // Removing non zero lower bounds173 // Removing non-zero lower bounds 185 174 capacity = subMap(_capacity, _lower); 186 175 Supply sum = 0; 187 176 for (NodeIt n(graph); n != INVALID; ++n) { 188 189 190 191 192 193 177 Supply s = _supply[n]; 178 for (InEdgeIt e(graph, n); e != INVALID; ++e) 179 s += _lower[e]; 180 for (OutEdgeIt e(graph, n); e != INVALID; ++e) 181 s -= _lower[e]; 182 sum += (supply[n] = s); 194 183 } 195 184 valid_supply = sum == 0; … … 205 194 /// \param _supply The supply values of the nodes (signed). 206 195 CycleCanceling( const Graph &_graph, 207 208 209 196 const CapacityMap &_capacity, 197 const CostMap &_cost, 198 const SupplyMap &_supply ) : 210 199 graph(_graph), lower(NULL), capacity(_capacity), cost(_cost), 211 200 supply(_supply), flow(_graph, 0), … … 218 207 } 219 208 220 221 209 /// \brief Simple constructor of the class (with lower bounds). 222 210 /// … … 230 218 /// \param _t The target node. 231 219 /// \param _flow_value The required amount of flow from node \c _s 232 /// to node \c _t (i.e. the supply of \c _s and the demand of 233 /// \c _t). 220 /// to node \c _t (i.e. the supply of \c _s and the demand of \c _t). 234 221 CycleCanceling( const Graph &_graph, 235 236 237 238 239 222 const LowerMap &_lower, 223 const CapacityMap &_capacity, 224 const CostMap &_cost, 225 Node _s, Node _t, 226 Supply _flow_value ) : 240 227 graph(_graph), lower(&_lower), capacity(_graph), cost(_cost), 241 228 supply(_graph), flow(_graph, 0), 242 229 res_graph(_graph, capacity, flow), res_cost(cost) 243 230 { 244 // Removing non zero lower bounds231 // Removing non-zero lower bounds 245 232 capacity = subMap(_capacity, _lower); 246 233 for (NodeIt n(graph); n != INVALID; ++n) { 247 248 249 250 251 252 253 254 234 Supply s = 0; 235 if (n == _s) s = _flow_value; 236 if (n == _t) s = -_flow_value; 237 for (InEdgeIt e(graph, n); e != INVALID; ++e) 238 s += _lower[e]; 239 for (OutEdgeIt e(graph, n); e != INVALID; ++e) 240 s -= _lower[e]; 241 supply[n] = s; 255 242 } 256 243 valid_supply = true; … … 267 254 /// \param _t The target node. 268 255 /// \param _flow_value The required amount of flow from node \c _s 269 /// to node \c _t (i.e. the supply of \c _s and the demand of 270 /// \c _t). 256 /// to node \c _t (i.e. the supply of \c _s and the demand of \c _t). 271 257 CycleCanceling( const Graph &_graph, 272 273 274 275 258 const CapacityMap &_capacity, 259 const CostMap &_cost, 260 Node _s, Node _t, 261 Supply _flow_value ) : 276 262 graph(_graph), lower(NULL), capacity(_capacity), cost(_cost), 277 263 supply(_graph, 0), flow(_graph, 0), … … 283 269 } 284 270 271 /// \brief Runs the algorithm. 272 /// 273 /// Runs the algorithm. 274 /// 275 /// \return \c true if a feasible flow can be found. 276 bool run() { 277 return init() && start(); 278 } 279 285 280 /// \brief Returns a const reference to the flow map. 286 281 /// … … 301 296 Cost c = 0; 302 297 for (EdgeIt e(graph); e != INVALID; ++e) 303 298 c += flow[e] * cost[e]; 304 299 return c; 305 300 } 306 301 307 /// \brief Runs the algorithm.308 ///309 /// Runs the algorithm.310 ///311 /// \return \c true if a feasible flow can be found.312 bool run() {313 return init() && start();314 }315 316 302 protected: 317 303 318 /// \briefInitializes the algorithm.304 /// Initializes the algorithm. 319 305 bool init() { 320 306 // Checking the sum of supply values … … 324 310 325 311 // Finding a feasible flow 326 Circulation< Graph, ConstMap<Edge, Capacity>, Capacity RefMap,327 328 329 312 Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap, 313 SupplyMap > 314 circulation( graph, constMap<Edge>((Capacity)0), capacity, 315 supply ); 330 316 circulation.flowMap(flow); 331 317 return circulation.run(); … … 334 320 #ifdef LIMITED_CYCLE_CANCELING 335 321 /// \brief Executes a cycle-canceling algorithm using 336 /// \ref lemon::BellmanFord "Bellman-Ford" algorithm with limited 337 /// iteration count. 322 /// \ref Bellman-Ford algorithm with limited iteration count. 338 323 bool start() { 339 324 typename BellmanFord<ResGraph, ResCostMap>::PredMap pred(res_graph); … … 348 333 bool optimal = false; 349 334 while (!optimal) { 350 351 352 353 354 355 335 BellmanFord<ResGraph, ResCostMap> bf(res_graph, res_cost); 336 bf.predMap(pred); 337 bf.init(0); 338 int iter_num = 0; 339 bool cycle_found = false; 340 while (!cycle_found) { 356 341 #ifdef _NO_BACK_STEP_ 357 358 342 int curr_iter_num = length_bound <= node_num ? 343 length_bound - iter_num : node_num - iter_num; 359 344 #else 360 361 362 #endif 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 #ifdef _DEBUG_ITER_ 402 403 #endif 404 405 406 345 int curr_iter_num = iter_num + length_bound <= node_num ? 346 length_bound : node_num - iter_num; 347 #endif 348 iter_num += curr_iter_num; 349 int real_iter_num = curr_iter_num; 350 for (int i = 0; i < curr_iter_num; ++i) { 351 if (bf.processNextWeakRound()) { 352 real_iter_num = i; 353 break; 354 } 355 } 356 if (real_iter_num < curr_iter_num) { 357 optimal = true; 358 break; 359 } else { 360 // Searching for node disjoint negative cycles 361 for (ResNodeIt n(res_graph); n != INVALID; ++n) 362 visited[n] = 0; 363 int id = 0; 364 for (ResNodeIt n(res_graph); n != INVALID; ++n) { 365 if (visited[n] > 0) continue; 366 visited[n] = ++id; 367 ResNode u = pred[n] == INVALID ? 368 INVALID : res_graph.source(pred[n]); 369 while (u != INVALID && visited[u] == 0) { 370 visited[u] = id; 371 u = pred[u] == INVALID ? 372 INVALID : res_graph.source(pred[u]); 373 } 374 if (u != INVALID && visited[u] == id) { 375 // Finding the negative cycle 376 cycle_found = true; 377 cycle.clear(); 378 ResEdge e = pred[u]; 379 cycle.push_back(e); 380 Capacity d = res_graph.rescap(e); 381 while (res_graph.source(e) != u) { 382 cycle.push_back(e = pred[res_graph.source(e)]); 383 if (res_graph.rescap(e) < d) 384 d = res_graph.rescap(e); 385 } 386 #ifdef _DEBUG_ITER_ 387 ++cycle_num; 388 #endif 389 // Augmenting along the cycle 390 for (int i = 0; i < cycle.size(); ++i) 391 res_graph.augment(cycle[i], d); 407 392 #ifdef _ONLY_ONE_CYCLE_ 408 409 #endif 410 411 412 413 414 415 416 393 break; 394 #endif 395 } 396 } 397 } 398 399 if (!cycle_found) 400 length_bound = length_bound * ALPHA_MUL / ALPHA_DIV; 401 } 417 402 } 418 403 419 404 #ifdef _DEBUG_ITER_ 420 405 std::cout << "Limited cycle-canceling algorithm finished. " 421 422 423 #endif 424 425 // Handling non zero lower bounds406 << "Found " << cycle_num << " negative cycles." 407 << std::endl; 408 #endif 409 410 // Handling non-zero lower bounds 426 411 if (lower) { 427 428 412 for (EdgeIt e(graph); e != INVALID; ++e) 413 flow[e] += (*lower)[e]; 429 414 } 430 415 return true; … … 434 419 #ifdef MIN_MEAN_CYCLE_CANCELING 435 420 /// \brief Executes the minimum mean cycle-canceling algorithm 436 /// using \ref lemon::MinMeanCycle "MinMeanCycle" class.421 /// using \ref MinMeanCycle. 437 422 bool start() { 438 423 typedef Path<ResGraph> ResPath; … … 445 430 mmc.cyclePath(cycle).init(); 446 431 if (mmc.findMinMean()) { 447 448 #ifdef _DEBUG_ITER_ 449 ++iter;450 #endif 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 432 while (mmc.cycleLength() < 0) { 433 #ifdef _DEBUG_ITER_ 434 ++cycle_num; 435 #endif 436 // Finding the cycle 437 mmc.findCycle(); 438 439 // Finding the largest flow amount that can be augmented 440 // along the cycle 441 Capacity delta = 0; 442 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) { 443 if (delta == 0 || res_graph.rescap(e) < delta) 444 delta = res_graph.rescap(e); 445 } 446 447 // Augmenting along the cycle 448 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) 449 res_graph.augment(e, delta); 450 451 // Finding the minimum cycle mean for the modified residual 452 // graph 453 mmc.reset(); 454 if (!mmc.findMinMean()) break; 455 } 471 456 } 472 457 473 458 #ifdef _DEBUG_ITER_ 474 459 std::cout << "Minimum mean cycle-canceling algorithm finished. " 475 476 477 #endif 478 479 // Handling non zero lower bounds460 << "Found " << cycle_num << " negative cycles." 461 << std::endl; 462 #endif 463 464 // Handling non-zero lower bounds 480 465 if (lower) { 481 482 466 for (EdgeIt e(graph); e != INVALID; ++e) 467 flow[e] += (*lower)[e]; 483 468 } 484 469 return true;
Note: See TracChangeset
for help on using the changeset viewer.