52 /// \tparam SupplyMap The type of the supply map. |
52 /// \tparam SupplyMap The type of the supply map. |
53 /// |
53 /// |
54 /// \warning |
54 /// \warning |
55 /// - Edge capacities and costs should be \e non-negative \e integers. |
55 /// - Edge capacities and costs should be \e non-negative \e integers. |
56 /// - Supply values should be \e signed \e integers. |
56 /// - Supply values should be \e signed \e integers. |
57 /// - \c LowerMap::Value must be convertible to \c CapacityMap::Value. |
57 /// - The value types of the maps should be convertible to each other. |
58 /// - \c CapacityMap::Value and \c SupplyMap::Value must be |
58 /// - \c CostMap::Value must be signed type. |
59 /// convertible to each other. |
|
60 /// - All value types must be convertible to \c CostMap::Value, which |
|
61 /// must be signed type. |
|
62 /// |
59 /// |
63 /// \note Edge costs are multiplied with the number of nodes during |
60 /// \note Edge costs are multiplied with the number of nodes during |
64 /// the algorithm so overflow problems may arise more easily than with |
61 /// the algorithm so overflow problems may arise more easily than with |
65 /// other minimum cost flow algorithms. |
62 /// other minimum cost flow algorithms. |
66 /// If it is available, <tt>long long int</tt> type is used instead of |
63 /// If it is available, <tt>long long int</tt> type is used instead of |
95 typedef typename Graph::template EdgeMap<LCost> LargeCostMap; |
92 typedef typename Graph::template EdgeMap<LCost> LargeCostMap; |
96 |
93 |
97 public: |
94 public: |
98 |
95 |
99 /// The type of the flow map. |
96 /// The type of the flow map. |
100 typedef CapacityEdgeMap FlowMap; |
97 typedef typename Graph::template EdgeMap<Capacity> FlowMap; |
101 /// The type of the potential map. |
98 /// The type of the potential map. |
102 typedef typename Graph::template NodeMap<LCost> PotentialMap; |
99 typedef typename Graph::template NodeMap<LCost> PotentialMap; |
103 |
100 |
104 private: |
101 private: |
105 |
102 |
106 /// \brief Map adaptor class for handling residual edge costs. |
103 /// \brief Map adaptor class for handling residual edge costs. |
107 /// |
104 /// |
108 /// \ref ResidualCostMap is a map adaptor class for handling |
105 /// \ref ResidualCostMap is a map adaptor class for handling |
109 /// residual edge costs. |
106 /// residual edge costs. |
110 class ResidualCostMap : public MapBase<ResEdge, LCost> |
107 template <typename Map> |
|
108 class ResidualCostMap : public MapBase<ResEdge, typename Map::Value> |
111 { |
109 { |
112 private: |
110 private: |
113 |
111 |
114 const LargeCostMap &_cost_map; |
112 const Map &_cost_map; |
115 |
113 |
116 public: |
114 public: |
117 |
115 |
118 ///\e |
116 ///\e |
119 ResidualCostMap(const LargeCostMap &cost_map) : |
117 ResidualCostMap(const Map &cost_map) : |
120 _cost_map(cost_map) {} |
118 _cost_map(cost_map) {} |
121 |
119 |
122 ///\e |
120 ///\e |
123 LCost operator[](const ResEdge &e) const { |
121 typename Map::Value operator[](const ResEdge &e) const { |
124 return ResGraph::forward(e) ? _cost_map[e] : -_cost_map[e]; |
122 return ResGraph::forward(e) ? _cost_map[e] : -_cost_map[e]; |
125 } |
123 } |
126 |
124 |
127 }; //class ResidualCostMap |
125 }; //class ResidualCostMap |
128 |
126 |
178 // The modified supply map |
176 // The modified supply map |
179 SupplyNodeMap _supply; |
177 SupplyNodeMap _supply; |
180 bool _valid_supply; |
178 bool _valid_supply; |
181 |
179 |
182 // Edge map of the current flow |
180 // Edge map of the current flow |
183 FlowMap _flow; |
181 FlowMap *_flow; |
|
182 bool _local_flow; |
184 // Node map of the current potentials |
183 // Node map of the current potentials |
185 PotentialMap _potential; |
184 PotentialMap *_potential; |
|
185 bool _local_potential; |
186 |
186 |
187 // The residual graph |
187 // The residual graph |
188 ResGraph _res_graph; |
188 ResGraph *_res_graph; |
189 // The residual cost map |
189 // The residual cost map |
190 ResidualCostMap _res_cost; |
190 ResidualCostMap<LargeCostMap> _res_cost; |
191 // The reduced cost map |
191 // The reduced cost map |
192 ReducedCostMap _red_cost; |
192 ReducedCostMap *_red_cost; |
193 // The excess map |
193 // The excess map |
194 SupplyNodeMap _excess; |
194 SupplyNodeMap _excess; |
195 // The epsilon parameter used for cost scaling |
195 // The epsilon parameter used for cost scaling |
196 LCost _epsilon; |
196 LCost _epsilon; |
197 |
197 |
198 public: |
198 public: |
199 |
199 |
200 /// \brief General constructor of the class (with lower bounds). |
200 /// \brief General constructor (with lower bounds). |
201 /// |
201 /// |
202 /// General constructor of the class (with lower bounds). |
202 /// General constructor (with lower bounds). |
203 /// |
203 /// |
204 /// \param graph The directed graph the algorithm runs on. |
204 /// \param graph The directed graph the algorithm runs on. |
205 /// \param lower The lower bounds of the edges. |
205 /// \param lower The lower bounds of the edges. |
206 /// \param capacity The capacities (upper bounds) of the edges. |
206 /// \param capacity The capacities (upper bounds) of the edges. |
207 /// \param cost The cost (length) values of the edges. |
207 /// \param cost The cost (length) values of the edges. |
210 const LowerMap &lower, |
210 const LowerMap &lower, |
211 const CapacityMap &capacity, |
211 const CapacityMap &capacity, |
212 const CostMap &cost, |
212 const CostMap &cost, |
213 const SupplyMap &supply ) : |
213 const SupplyMap &supply ) : |
214 _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost), |
214 _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost), |
215 _cost(graph), _supply(graph), _flow(graph, 0), _potential(graph, 0), |
215 _cost(graph), _supply(graph), _flow(0), _local_flow(false), |
216 _res_graph(graph, _capacity, _flow), _res_cost(_cost), |
216 _potential(0), _local_potential(false), _res_cost(_cost), |
217 _red_cost(graph, _cost, _potential), _excess(graph, 0) |
217 _excess(graph, 0) |
218 { |
218 { |
219 // Removing non-zero lower bounds |
219 // Removing non-zero lower bounds |
220 _capacity = subMap(capacity, lower); |
220 _capacity = subMap(capacity, lower); |
221 Supply sum = 0; |
221 Supply sum = 0; |
222 for (NodeIt n(_graph); n != INVALID; ++n) { |
222 for (NodeIt n(_graph); n != INVALID; ++n) { |
229 sum += s; |
229 sum += s; |
230 } |
230 } |
231 _valid_supply = sum == 0; |
231 _valid_supply = sum == 0; |
232 } |
232 } |
233 |
233 |
234 /// \brief General constructor of the class (without lower bounds). |
234 /// \brief General constructor (without lower bounds). |
235 /// |
235 /// |
236 /// General constructor of the class (without lower bounds). |
236 /// General constructor (without lower bounds). |
237 /// |
237 /// |
238 /// \param graph The directed graph the algorithm runs on. |
238 /// \param graph The directed graph the algorithm runs on. |
239 /// \param capacity The capacities (upper bounds) of the edges. |
239 /// \param capacity The capacities (upper bounds) of the edges. |
240 /// \param cost The cost (length) values of the edges. |
240 /// \param cost The cost (length) values of the edges. |
241 /// \param supply The supply values of the nodes (signed). |
241 /// \param supply The supply values of the nodes (signed). |
242 CostScaling( const Graph &graph, |
242 CostScaling( const Graph &graph, |
243 const CapacityMap &capacity, |
243 const CapacityMap &capacity, |
244 const CostMap &cost, |
244 const CostMap &cost, |
245 const SupplyMap &supply ) : |
245 const SupplyMap &supply ) : |
246 _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost), |
246 _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost), |
247 _cost(graph), _supply(supply), _flow(graph, 0), _potential(graph, 0), |
247 _cost(graph), _supply(supply), _flow(0), _local_flow(false), |
248 _res_graph(graph, _capacity, _flow), _res_cost(_cost), |
248 _potential(0), _local_potential(false), _res_cost(_cost), |
249 _red_cost(graph, _cost, _potential), _excess(graph, 0) |
249 _excess(graph, 0) |
250 { |
250 { |
251 // Checking the sum of supply values |
251 // Checking the sum of supply values |
252 Supply sum = 0; |
252 Supply sum = 0; |
253 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n]; |
253 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n]; |
254 _valid_supply = sum == 0; |
254 _valid_supply = sum == 0; |
255 } |
255 } |
256 |
256 |
257 /// \brief Simple constructor of the class (with lower bounds). |
257 /// \brief Simple constructor (with lower bounds). |
258 /// |
258 /// |
259 /// Simple constructor of the class (with lower bounds). |
259 /// Simple constructor (with lower bounds). |
260 /// |
260 /// |
261 /// \param graph The directed graph the algorithm runs on. |
261 /// \param graph The directed graph the algorithm runs on. |
262 /// \param lower The lower bounds of the edges. |
262 /// \param lower The lower bounds of the edges. |
263 /// \param capacity The capacities (upper bounds) of the edges. |
263 /// \param capacity The capacities (upper bounds) of the edges. |
264 /// \param cost The cost (length) values of the edges. |
264 /// \param cost The cost (length) values of the edges. |
271 const CapacityMap &capacity, |
271 const CapacityMap &capacity, |
272 const CostMap &cost, |
272 const CostMap &cost, |
273 Node s, Node t, |
273 Node s, Node t, |
274 Supply flow_value ) : |
274 Supply flow_value ) : |
275 _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost), |
275 _graph(graph), _lower(&lower), _capacity(graph), _orig_cost(cost), |
276 _cost(graph), _supply(graph), _flow(graph, 0), _potential(graph, 0), |
276 _cost(graph), _supply(graph), _flow(0), _local_flow(false), |
277 _res_graph(graph, _capacity, _flow), _res_cost(_cost), |
277 _potential(0), _local_potential(false), _res_cost(_cost), |
278 _red_cost(graph, _cost, _potential), _excess(graph, 0) |
278 _excess(graph, 0) |
279 { |
279 { |
280 // Removing nonzero lower bounds |
280 // Removing nonzero lower bounds |
281 _capacity = subMap(capacity, lower); |
281 _capacity = subMap(capacity, lower); |
282 for (NodeIt n(_graph); n != INVALID; ++n) { |
282 for (NodeIt n(_graph); n != INVALID; ++n) { |
283 Supply sum = 0; |
283 Supply sum = 0; |
307 const CapacityMap &capacity, |
307 const CapacityMap &capacity, |
308 const CostMap &cost, |
308 const CostMap &cost, |
309 Node s, Node t, |
309 Node s, Node t, |
310 Supply flow_value ) : |
310 Supply flow_value ) : |
311 _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost), |
311 _graph(graph), _lower(NULL), _capacity(capacity), _orig_cost(cost), |
312 _cost(graph), _supply(graph, 0), _flow(graph, 0), _potential(graph, 0), |
312 _cost(graph), _supply(graph, 0), _flow(0), _local_flow(false), |
313 _res_graph(graph, _capacity, _flow), _res_cost(_cost), |
313 _potential(0), _local_potential(false), _res_cost(_cost), |
314 _red_cost(graph, _cost, _potential), _excess(graph, 0) |
314 _excess(graph, 0) |
315 { |
315 { |
316 _supply[s] = flow_value; |
316 _supply[s] = flow_value; |
317 _supply[t] = -flow_value; |
317 _supply[t] = -flow_value; |
318 _valid_supply = true; |
318 _valid_supply = true; |
319 } |
319 } |
320 |
320 |
|
321 /// Destructor. |
|
322 ~CostScaling() { |
|
323 if (_local_flow) delete _flow; |
|
324 if (_local_potential) delete _potential; |
|
325 delete _res_graph; |
|
326 delete _red_cost; |
|
327 } |
|
328 |
|
329 /// \brief Sets the flow map. |
|
330 /// |
|
331 /// Sets the flow map. |
|
332 /// |
|
333 /// \return \c (*this) |
|
334 CostScaling& flowMap(FlowMap &map) { |
|
335 if (_local_flow) { |
|
336 delete _flow; |
|
337 _local_flow = false; |
|
338 } |
|
339 _flow = ↦ |
|
340 return *this; |
|
341 } |
|
342 |
|
343 /// \brief Sets the potential map. |
|
344 /// |
|
345 /// Sets the potential map. |
|
346 /// |
|
347 /// \return \c (*this) |
|
348 CostScaling& potentialMap(PotentialMap &map) { |
|
349 if (_local_potential) { |
|
350 delete _potential; |
|
351 _local_potential = false; |
|
352 } |
|
353 _potential = ↦ |
|
354 return *this; |
|
355 } |
|
356 |
|
357 /// \name Execution control |
|
358 /// The only way to execute the algorithm is to call the run() |
|
359 /// function. |
|
360 |
|
361 /// @{ |
|
362 |
321 /// \brief Runs the algorithm. |
363 /// \brief Runs the algorithm. |
322 /// |
364 /// |
323 /// Runs the algorithm. |
365 /// Runs the algorithm. |
324 /// |
366 /// |
325 /// \return \c true if a feasible flow can be found. |
367 /// \return \c true if a feasible flow can be found. |
326 bool run() { |
368 bool run() { |
327 init() && start(); |
369 return init() && start(); |
328 } |
370 } |
|
371 |
|
372 /// @} |
|
373 |
|
374 /// \name Query Functions |
|
375 /// The result of the algorithm can be obtained using these |
|
376 /// functions. |
|
377 /// \n run() must be called before using them. |
|
378 |
|
379 /// @{ |
329 |
380 |
330 /// \brief Returns a const reference to the edge map storing the |
381 /// \brief Returns a const reference to the edge map storing the |
331 /// found flow. |
382 /// found flow. |
332 /// |
383 /// |
333 /// Returns a const reference to the edge map storing the found flow. |
384 /// Returns a const reference to the edge map storing the found flow. |
334 /// |
385 /// |
335 /// \pre \ref run() must be called before using this function. |
386 /// \pre \ref run() must be called before using this function. |
336 const FlowMap& flowMap() const { |
387 const FlowMap& flowMap() const { |
337 return _flow; |
388 return *_flow; |
338 } |
389 } |
339 |
390 |
340 /// \brief Returns a const reference to the node map storing the |
391 /// \brief Returns a const reference to the node map storing the |
341 /// found potentials (the dual solution). |
392 /// found potentials (the dual solution). |
342 /// |
393 /// |
343 /// Returns a const reference to the node map storing the found |
394 /// Returns a const reference to the node map storing the found |
344 /// potentials (the dual solution). |
395 /// potentials (the dual solution). |
345 /// |
396 /// |
346 /// \pre \ref run() must be called before using this function. |
397 /// \pre \ref run() must be called before using this function. |
347 const PotentialMap& potentialMap() const { |
398 const PotentialMap& potentialMap() const { |
348 return _potential; |
399 return *_potential; |
|
400 } |
|
401 |
|
402 /// \brief Returns the flow on the edge. |
|
403 /// |
|
404 /// Returns the flow on the edge. |
|
405 /// |
|
406 /// \pre \ref run() must be called before using this function. |
|
407 Capacity flow(const Edge& edge) const { |
|
408 return (*_flow)[edge]; |
|
409 } |
|
410 |
|
411 /// \brief Returns the potential of the node. |
|
412 /// |
|
413 /// Returns the potential of the node. |
|
414 /// |
|
415 /// \pre \ref run() must be called before using this function. |
|
416 Cost potential(const Node& node) const { |
|
417 return (*_potential)[node]; |
349 } |
418 } |
350 |
419 |
351 /// \brief Returns the total cost of the found flow. |
420 /// \brief Returns the total cost of the found flow. |
352 /// |
421 /// |
353 /// Returns the total cost of the found flow. The complexity of the |
422 /// Returns the total cost of the found flow. The complexity of the |
355 /// |
424 /// |
356 /// \pre \ref run() must be called before using this function. |
425 /// \pre \ref run() must be called before using this function. |
357 Cost totalCost() const { |
426 Cost totalCost() const { |
358 Cost c = 0; |
427 Cost c = 0; |
359 for (EdgeIt e(_graph); e != INVALID; ++e) |
428 for (EdgeIt e(_graph); e != INVALID; ++e) |
360 c += _flow[e] * _orig_cost[e]; |
429 c += (*_flow)[e] * _orig_cost[e]; |
361 return c; |
430 return c; |
362 } |
431 } |
|
432 |
|
433 /// @} |
363 |
434 |
364 private: |
435 private: |
365 |
436 |
366 /// Initializes the algorithm. |
437 /// Initializes the algorithm. |
367 bool init() { |
438 bool init() { |
368 if (!_valid_supply) return false; |
439 if (!_valid_supply) return false; |
|
440 |
|
441 // Initializing flow and potential maps |
|
442 if (!_flow) { |
|
443 _flow = new FlowMap(_graph); |
|
444 _local_flow = true; |
|
445 } |
|
446 if (!_potential) { |
|
447 _potential = new PotentialMap(_graph); |
|
448 _local_potential = true; |
|
449 } |
|
450 |
|
451 _red_cost = new ReducedCostMap(_graph, _cost, *_potential); |
|
452 _res_graph = new ResGraph(_graph, _capacity, *_flow); |
369 |
453 |
370 // Initializing the scaled cost map and the epsilon parameter |
454 // Initializing the scaled cost map and the epsilon parameter |
371 Cost max_cost = 0; |
455 Cost max_cost = 0; |
372 int node_num = countNodes(_graph); |
456 int node_num = countNodes(_graph); |
373 for (EdgeIt e(_graph); e != INVALID; ++e) { |
457 for (EdgeIt e(_graph); e != INVALID; ++e) { |
377 _epsilon = max_cost * node_num; |
461 _epsilon = max_cost * node_num; |
378 |
462 |
379 // Finding a feasible flow using Circulation |
463 // Finding a feasible flow using Circulation |
380 Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap, |
464 Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap, |
381 SupplyMap > |
465 SupplyMap > |
382 circulation( _graph, constMap<Edge>((Capacity)0), _capacity, |
466 circulation( _graph, constMap<Edge>(Capacity(0)), _capacity, |
383 _supply ); |
467 _supply ); |
384 return circulation.flowMap(_flow).run(); |
468 return circulation.flowMap(*_flow).run(); |
385 } |
469 } |
386 |
470 |
387 |
471 |
388 /// Executes the algorithm. |
472 /// Executes the algorithm. |
389 bool start() { |
473 bool start() { |
395 1 : _epsilon / ALPHA ) |
479 1 : _epsilon / ALPHA ) |
396 { |
480 { |
397 // Performing price refinement heuristic using Bellman-Ford |
481 // Performing price refinement heuristic using Bellman-Ford |
398 // algorithm |
482 // algorithm |
399 if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) { |
483 if (_epsilon <= BF_HEURISTIC_EPSILON_BOUND) { |
400 typedef ShiftMap<ResidualCostMap> ShiftCostMap; |
484 typedef ShiftMap< ResidualCostMap<LargeCostMap> > ShiftCostMap; |
401 ShiftCostMap shift_cost(_res_cost, _epsilon); |
485 ShiftCostMap shift_cost(_res_cost, _epsilon); |
402 BellmanFord<ResGraph, ShiftCostMap> bf(_res_graph, shift_cost); |
486 BellmanFord<ResGraph, ShiftCostMap> bf(*_res_graph, shift_cost); |
403 bf.init(0); |
487 bf.init(0); |
404 bool done = false; |
488 bool done = false; |
405 int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num)); |
489 int K = int(BF_HEURISTIC_BOUND_FACTOR * sqrt(node_num)); |
406 for (int i = 0; i < K && !done; ++i) |
490 for (int i = 0; i < K && !done; ++i) |
407 done = bf.processNextWeakRound(); |
491 done = bf.processNextWeakRound(); |
408 if (done) { |
492 if (done) { |
409 for (NodeIt n(_graph); n != INVALID; ++n) |
493 for (NodeIt n(_graph); n != INVALID; ++n) |
410 _potential[n] = bf.dist(n); |
494 (*_potential)[n] = bf.dist(n); |
411 continue; |
495 continue; |
412 } |
496 } |
413 } |
497 } |
414 |
498 |
415 // Saturating edges not satisfying the optimality condition |
499 // Saturating edges not satisfying the optimality condition |
416 Capacity delta; |
500 Capacity delta; |
417 for (EdgeIt e(_graph); e != INVALID; ++e) { |
501 for (EdgeIt e(_graph); e != INVALID; ++e) { |
418 if (_capacity[e] - _flow[e] > 0 && _red_cost[e] < 0) { |
502 if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) { |
419 delta = _capacity[e] - _flow[e]; |
503 delta = _capacity[e] - (*_flow)[e]; |
420 _excess[_graph.source(e)] -= delta; |
504 _excess[_graph.source(e)] -= delta; |
421 _excess[_graph.target(e)] += delta; |
505 _excess[_graph.target(e)] += delta; |
422 _flow[e] = _capacity[e]; |
506 (*_flow)[e] = _capacity[e]; |
423 } |
507 } |
424 if (_flow[e] > 0 && -_red_cost[e] < 0) { |
508 if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) { |
425 _excess[_graph.target(e)] -= _flow[e]; |
509 _excess[_graph.target(e)] -= (*_flow)[e]; |
426 _excess[_graph.source(e)] += _flow[e]; |
510 _excess[_graph.source(e)] += (*_flow)[e]; |
427 _flow[e] = 0; |
511 (*_flow)[e] = 0; |
428 } |
512 } |
429 } |
513 } |
430 |
514 |
431 // Finding active nodes (i.e. nodes with positive excess) |
515 // Finding active nodes (i.e. nodes with positive excess) |
432 for (NodeIt n(_graph); n != INVALID; ++n) |
516 for (NodeIt n(_graph); n != INVALID; ++n) |
438 bool relabel_enabled = true; |
522 bool relabel_enabled = true; |
439 |
523 |
440 // Performing push operations if there are admissible edges |
524 // Performing push operations if there are admissible edges |
441 if (_excess[n] > 0) { |
525 if (_excess[n] > 0) { |
442 for (OutEdgeIt e(_graph, n); e != INVALID; ++e) { |
526 for (OutEdgeIt e(_graph, n); e != INVALID; ++e) { |
443 if (_capacity[e] - _flow[e] > 0 && _red_cost[e] < 0) { |
527 if (_capacity[e] - (*_flow)[e] > 0 && (*_red_cost)[e] < 0) { |
444 delta = _capacity[e] - _flow[e] <= _excess[n] ? |
528 delta = _capacity[e] - (*_flow)[e] <= _excess[n] ? |
445 _capacity[e] - _flow[e] : _excess[n]; |
529 _capacity[e] - (*_flow)[e] : _excess[n]; |
446 t = _graph.target(e); |
530 t = _graph.target(e); |
447 |
531 |
448 // Push-look-ahead heuristic |
532 // Push-look-ahead heuristic |
449 Capacity ahead = -_excess[t]; |
533 Capacity ahead = -_excess[t]; |
450 for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) { |
534 for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) { |
451 if (_capacity[oe] - _flow[oe] > 0 && _red_cost[oe] < 0) |
535 if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0) |
452 ahead += _capacity[oe] - _flow[oe]; |
536 ahead += _capacity[oe] - (*_flow)[oe]; |
453 } |
537 } |
454 for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) { |
538 for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) { |
455 if (_flow[ie] > 0 && -_red_cost[ie] < 0) |
539 if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0) |
456 ahead += _flow[ie]; |
540 ahead += (*_flow)[ie]; |
457 } |
541 } |
458 if (ahead < 0) ahead = 0; |
542 if (ahead < 0) ahead = 0; |
459 |
543 |
460 // Pushing flow along the edge |
544 // Pushing flow along the edge |
461 if (ahead < delta) { |
545 if (ahead < delta) { |
462 _flow[e] += ahead; |
546 (*_flow)[e] += ahead; |
463 _excess[n] -= ahead; |
547 _excess[n] -= ahead; |
464 _excess[t] += ahead; |
548 _excess[t] += ahead; |
465 active_nodes.push_front(t); |
549 active_nodes.push_front(t); |
466 hyper[t] = true; |
550 hyper[t] = true; |
467 relabel_enabled = false; |
551 relabel_enabled = false; |
468 break; |
552 break; |
469 } else { |
553 } else { |
470 _flow[e] += delta; |
554 (*_flow)[e] += delta; |
471 _excess[n] -= delta; |
555 _excess[n] -= delta; |
472 _excess[t] += delta; |
556 _excess[t] += delta; |
473 if (_excess[t] > 0 && _excess[t] <= delta) |
557 if (_excess[t] > 0 && _excess[t] <= delta) |
474 active_nodes.push_back(t); |
558 active_nodes.push_back(t); |
475 } |
559 } |
479 } |
563 } |
480 } |
564 } |
481 |
565 |
482 if (_excess[n] > 0) { |
566 if (_excess[n] > 0) { |
483 for (InEdgeIt e(_graph, n); e != INVALID; ++e) { |
567 for (InEdgeIt e(_graph, n); e != INVALID; ++e) { |
484 if (_flow[e] > 0 && -_red_cost[e] < 0) { |
568 if ((*_flow)[e] > 0 && -(*_red_cost)[e] < 0) { |
485 delta = _flow[e] <= _excess[n] ? _flow[e] : _excess[n]; |
569 delta = (*_flow)[e] <= _excess[n] ? (*_flow)[e] : _excess[n]; |
486 t = _graph.source(e); |
570 t = _graph.source(e); |
487 |
571 |
488 // Push-look-ahead heuristic |
572 // Push-look-ahead heuristic |
489 Capacity ahead = -_excess[t]; |
573 Capacity ahead = -_excess[t]; |
490 for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) { |
574 for (OutEdgeIt oe(_graph, t); oe != INVALID; ++oe) { |
491 if (_capacity[oe] - _flow[oe] > 0 && _red_cost[oe] < 0) |
575 if (_capacity[oe] - (*_flow)[oe] > 0 && (*_red_cost)[oe] < 0) |
492 ahead += _capacity[oe] - _flow[oe]; |
576 ahead += _capacity[oe] - (*_flow)[oe]; |
493 } |
577 } |
494 for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) { |
578 for (InEdgeIt ie(_graph, t); ie != INVALID; ++ie) { |
495 if (_flow[ie] > 0 && -_red_cost[ie] < 0) |
579 if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < 0) |
496 ahead += _flow[ie]; |
580 ahead += (*_flow)[ie]; |
497 } |
581 } |
498 if (ahead < 0) ahead = 0; |
582 if (ahead < 0) ahead = 0; |
499 |
583 |
500 // Pushing flow along the edge |
584 // Pushing flow along the edge |
501 if (ahead < delta) { |
585 if (ahead < delta) { |
502 _flow[e] -= ahead; |
586 (*_flow)[e] -= ahead; |
503 _excess[n] -= ahead; |
587 _excess[n] -= ahead; |
504 _excess[t] += ahead; |
588 _excess[t] += ahead; |
505 active_nodes.push_front(t); |
589 active_nodes.push_front(t); |
506 hyper[t] = true; |
590 hyper[t] = true; |
507 relabel_enabled = false; |
591 relabel_enabled = false; |
508 break; |
592 break; |
509 } else { |
593 } else { |
510 _flow[e] -= delta; |
594 (*_flow)[e] -= delta; |
511 _excess[n] -= delta; |
595 _excess[n] -= delta; |
512 _excess[t] += delta; |
596 _excess[t] += delta; |
513 if (_excess[t] > 0 && _excess[t] <= delta) |
597 if (_excess[t] > 0 && _excess[t] <= delta) |
514 active_nodes.push_back(t); |
598 active_nodes.push_back(t); |
515 } |
599 } |
521 |
605 |
522 if (relabel_enabled && (_excess[n] > 0 || hyper[n])) { |
606 if (relabel_enabled && (_excess[n] > 0 || hyper[n])) { |
523 // Performing relabel operation if the node is still active |
607 // Performing relabel operation if the node is still active |
524 LCost min_red_cost = std::numeric_limits<LCost>::max(); |
608 LCost min_red_cost = std::numeric_limits<LCost>::max(); |
525 for (OutEdgeIt oe(_graph, n); oe != INVALID; ++oe) { |
609 for (OutEdgeIt oe(_graph, n); oe != INVALID; ++oe) { |
526 if ( _capacity[oe] - _flow[oe] > 0 && |
610 if ( _capacity[oe] - (*_flow)[oe] > 0 && |
527 _red_cost[oe] < min_red_cost ) |
611 (*_red_cost)[oe] < min_red_cost ) |
528 min_red_cost = _red_cost[oe]; |
612 min_red_cost = (*_red_cost)[oe]; |
529 } |
613 } |
530 for (InEdgeIt ie(_graph, n); ie != INVALID; ++ie) { |
614 for (InEdgeIt ie(_graph, n); ie != INVALID; ++ie) { |
531 if (_flow[ie] > 0 && -_red_cost[ie] < min_red_cost) |
615 if ((*_flow)[ie] > 0 && -(*_red_cost)[ie] < min_red_cost) |
532 min_red_cost = -_red_cost[ie]; |
616 min_red_cost = -(*_red_cost)[ie]; |
533 } |
617 } |
534 _potential[n] -= min_red_cost + _epsilon; |
618 (*_potential)[n] -= min_red_cost + _epsilon; |
535 hyper[n] = false; |
619 hyper[n] = false; |
536 } |
620 } |
537 |
621 |
538 // Removing active nodes with non-positive excess |
622 // Removing active nodes with non-positive excess |
539 while ( active_nodes.size() > 0 && |
623 while ( active_nodes.size() > 0 && |