50 /// \tparam SupplyMap The type of the supply map. |
50 /// \tparam SupplyMap The type of the supply map. |
51 /// |
51 /// |
52 /// \warning |
52 /// \warning |
53 /// - Edge capacities and costs should be \e non-negative \e integers. |
53 /// - Edge capacities and costs should be \e non-negative \e integers. |
54 /// - Supply values should be \e signed \e integers. |
54 /// - Supply values should be \e signed \e integers. |
55 /// - \c LowerMap::Value must be convertible to \c CapacityMap::Value. |
55 /// - The value types of the maps should be convertible to each other. |
56 /// - \c CapacityMap::Value and \c SupplyMap::Value must be |
56 /// - \c CostMap::Value must be signed type. |
57 /// convertible to each other. |
|
58 /// - All value types must be convertible to \c CostMap::Value, which |
|
59 /// must be signed type. |
|
60 /// |
57 /// |
61 /// \note By default the \ref BellmanFord "Bellman-Ford" algorithm is |
58 /// \note By default the \ref BellmanFord "Bellman-Ford" algorithm is |
62 /// used for negative cycle detection with limited iteration number. |
59 /// used for negative cycle detection with limited iteration number. |
63 /// However \ref CycleCanceling also provides the "Minimum Mean |
60 /// However \ref CycleCanceling also provides the "Minimum Mean |
64 /// Cycle-Canceling" algorithm, which is \e strongly \e polynomial, |
61 /// Cycle-Canceling" algorithm, which is \e strongly \e polynomial, |
141 // The modified supply map |
140 // The modified supply map |
142 SupplyNodeMap _supply; |
141 SupplyNodeMap _supply; |
143 bool _valid_supply; |
142 bool _valid_supply; |
144 |
143 |
145 // Edge map of the current flow |
144 // Edge map of the current flow |
146 FlowMap _flow; |
145 FlowMap *_flow; |
|
146 bool _local_flow; |
|
147 // Node map of the current potentials |
|
148 PotentialMap *_potential; |
|
149 bool _local_potential; |
147 |
150 |
148 // The residual graph |
151 // The residual graph |
149 ResGraph _res_graph; |
152 ResGraph *_res_graph; |
150 // The residual cost map |
153 // The residual cost map |
151 ResidualCostMap _res_cost; |
154 ResidualCostMap _res_cost; |
152 |
155 |
153 public: |
156 public: |
154 |
157 |
155 /// \brief General constructor of the class (with lower bounds). |
158 /// \brief General constructor (with lower bounds). |
156 /// |
159 /// |
157 /// General constructor of the class (with lower bounds). |
160 /// General constructor (with lower bounds). |
158 /// |
161 /// |
159 /// \param graph The directed graph the algorithm runs on. |
162 /// \param graph The directed graph the algorithm runs on. |
160 /// \param lower The lower bounds of the edges. |
163 /// \param lower The lower bounds of the edges. |
161 /// \param capacity The capacities (upper bounds) of the edges. |
164 /// \param capacity The capacities (upper bounds) of the edges. |
162 /// \param cost The cost (length) values of the edges. |
165 /// \param cost The cost (length) values of the edges. |
165 const LowerMap &lower, |
168 const LowerMap &lower, |
166 const CapacityMap &capacity, |
169 const CapacityMap &capacity, |
167 const CostMap &cost, |
170 const CostMap &cost, |
168 const SupplyMap &supply ) : |
171 const SupplyMap &supply ) : |
169 _graph(graph), _lower(&lower), _capacity(graph), _cost(cost), |
172 _graph(graph), _lower(&lower), _capacity(graph), _cost(cost), |
170 _supply(graph), _flow(graph, 0), |
173 _supply(graph), _flow(0), _local_flow(false), |
171 _res_graph(graph, _capacity, _flow), _res_cost(_cost) |
174 _potential(0), _local_potential(false), _res_cost(_cost) |
172 { |
175 { |
173 // Removing non-zero lower bounds |
176 // Removing non-zero lower bounds |
174 _capacity = subMap(capacity, lower); |
177 _capacity = subMap(capacity, lower); |
175 Supply sum = 0; |
178 Supply sum = 0; |
176 for (NodeIt n(_graph); n != INVALID; ++n) { |
179 for (NodeIt n(_graph); n != INVALID; ++n) { |
182 sum += (_supply[n] = s); |
185 sum += (_supply[n] = s); |
183 } |
186 } |
184 _valid_supply = sum == 0; |
187 _valid_supply = sum == 0; |
185 } |
188 } |
186 |
189 |
187 /// \brief General constructor of the class (without lower bounds). |
190 /// \brief General constructor (without lower bounds). |
188 /// |
191 /// |
189 /// General constructor of the class (without lower bounds). |
192 /// General constructor (without lower bounds). |
190 /// |
193 /// |
191 /// \param graph The directed graph the algorithm runs on. |
194 /// \param graph The directed graph the algorithm runs on. |
192 /// \param capacity The capacities (upper bounds) of the edges. |
195 /// \param capacity The capacities (upper bounds) of the edges. |
193 /// \param cost The cost (length) values of the edges. |
196 /// \param cost The cost (length) values of the edges. |
194 /// \param supply The supply values of the nodes (signed). |
197 /// \param supply The supply values of the nodes (signed). |
195 CycleCanceling( const Graph &graph, |
198 CycleCanceling( const Graph &graph, |
196 const CapacityMap &capacity, |
199 const CapacityMap &capacity, |
197 const CostMap &cost, |
200 const CostMap &cost, |
198 const SupplyMap &supply ) : |
201 const SupplyMap &supply ) : |
199 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost), |
202 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost), |
200 _supply(supply), _flow(graph, 0), |
203 _supply(supply), _flow(0), _local_flow(false), |
201 _res_graph(graph, _capacity, _flow), _res_cost(_cost) |
204 _potential(0), _local_potential(false), _res_cost(_cost) |
202 { |
205 { |
203 // Checking the sum of supply values |
206 // Checking the sum of supply values |
204 Supply sum = 0; |
207 Supply sum = 0; |
205 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n]; |
208 for (NodeIt n(_graph); n != INVALID; ++n) sum += _supply[n]; |
206 _valid_supply = sum == 0; |
209 _valid_supply = sum == 0; |
207 } |
210 } |
208 |
211 |
209 /// \brief Simple constructor of the class (with lower bounds). |
212 /// \brief Simple constructor (with lower bounds). |
210 /// |
213 /// |
211 /// Simple constructor of the class (with lower bounds). |
214 /// Simple constructor (with lower bounds). |
212 /// |
215 /// |
213 /// \param graph The directed graph the algorithm runs on. |
216 /// \param graph The directed graph the algorithm runs on. |
214 /// \param lower The lower bounds of the edges. |
217 /// \param lower The lower bounds of the edges. |
215 /// \param capacity The capacities (upper bounds) of the edges. |
218 /// \param capacity The capacities (upper bounds) of the edges. |
216 /// \param cost The cost (length) values of the edges. |
219 /// \param cost The cost (length) values of the edges. |
223 const CapacityMap &capacity, |
226 const CapacityMap &capacity, |
224 const CostMap &cost, |
227 const CostMap &cost, |
225 Node s, Node t, |
228 Node s, Node t, |
226 Supply flow_value ) : |
229 Supply flow_value ) : |
227 _graph(graph), _lower(&lower), _capacity(graph), _cost(cost), |
230 _graph(graph), _lower(&lower), _capacity(graph), _cost(cost), |
228 _supply(graph), _flow(graph, 0), |
231 _supply(graph), _flow(0), _local_flow(false), |
229 _res_graph(graph, _capacity, _flow), _res_cost(_cost) |
232 _potential(0), _local_potential(false), _res_cost(_cost) |
230 { |
233 { |
231 // Removing non-zero lower bounds |
234 // Removing non-zero lower bounds |
232 _capacity = subMap(capacity, lower); |
235 _capacity = subMap(capacity, lower); |
233 for (NodeIt n(_graph); n != INVALID; ++n) { |
236 for (NodeIt n(_graph); n != INVALID; ++n) { |
234 Supply sum = 0; |
237 Supply sum = 0; |
241 _supply[n] = sum; |
244 _supply[n] = sum; |
242 } |
245 } |
243 _valid_supply = true; |
246 _valid_supply = true; |
244 } |
247 } |
245 |
248 |
246 /// \brief Simple constructor of the class (without lower bounds). |
249 /// \brief Simple constructor (without lower bounds). |
247 /// |
250 /// |
248 /// Simple constructor of the class (without lower bounds). |
251 /// Simple constructor (without lower bounds). |
249 /// |
252 /// |
250 /// \param graph The directed graph the algorithm runs on. |
253 /// \param graph The directed graph the algorithm runs on. |
251 /// \param capacity The capacities (upper bounds) of the edges. |
254 /// \param capacity The capacities (upper bounds) of the edges. |
252 /// \param cost The cost (length) values of the edges. |
255 /// \param cost The cost (length) values of the edges. |
253 /// \param s The source node. |
256 /// \param s The source node. |
258 const CapacityMap &capacity, |
261 const CapacityMap &capacity, |
259 const CostMap &cost, |
262 const CostMap &cost, |
260 Node s, Node t, |
263 Node s, Node t, |
261 Supply flow_value ) : |
264 Supply flow_value ) : |
262 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost), |
265 _graph(graph), _lower(NULL), _capacity(capacity), _cost(cost), |
263 _supply(graph, 0), _flow(graph, 0), |
266 _supply(graph, 0), _flow(0), _local_flow(false), |
264 _res_graph(graph, _capacity, _flow), _res_cost(_cost) |
267 _potential(0), _local_potential(false), _res_cost(_cost) |
265 { |
268 { |
266 _supply[s] = flow_value; |
269 _supply[s] = flow_value; |
267 _supply[t] = -flow_value; |
270 _supply[t] = -flow_value; |
268 _valid_supply = true; |
271 _valid_supply = true; |
269 } |
272 } |
270 |
273 |
|
274 /// Destructor. |
|
275 ~CycleCanceling() { |
|
276 if (_local_flow) delete _flow; |
|
277 if (_local_potential) delete _potential; |
|
278 delete _res_graph; |
|
279 } |
|
280 |
|
281 /// \brief Sets the flow map. |
|
282 /// |
|
283 /// Sets the flow map. |
|
284 /// |
|
285 /// \return \c (*this) |
|
286 CycleCanceling& flowMap(FlowMap &map) { |
|
287 if (_local_flow) { |
|
288 delete _flow; |
|
289 _local_flow = false; |
|
290 } |
|
291 _flow = ↦ |
|
292 return *this; |
|
293 } |
|
294 |
|
295 /// \brief Sets the potential map. |
|
296 /// |
|
297 /// Sets the potential map. |
|
298 /// |
|
299 /// \return \c (*this) |
|
300 CycleCanceling& potentialMap(PotentialMap &map) { |
|
301 if (_local_potential) { |
|
302 delete _potential; |
|
303 _local_potential = false; |
|
304 } |
|
305 _potential = ↦ |
|
306 return *this; |
|
307 } |
|
308 |
|
309 /// \name Execution control |
|
310 /// The only way to execute the algorithm is to call the run() |
|
311 /// function. |
|
312 |
|
313 /// @{ |
|
314 |
271 /// \brief Runs the algorithm. |
315 /// \brief Runs the algorithm. |
272 /// |
316 /// |
273 /// Runs the algorithm. |
317 /// Runs the algorithm. |
274 /// |
318 /// |
275 /// \param min_mean_cc Set this parameter to \c true to run the |
319 /// \param min_mean_cc Set this parameter to \c true to run the |
279 /// \return \c true if a feasible flow can be found. |
323 /// \return \c true if a feasible flow can be found. |
280 bool run(bool min_mean_cc = false) { |
324 bool run(bool min_mean_cc = false) { |
281 return init() && start(min_mean_cc); |
325 return init() && start(min_mean_cc); |
282 } |
326 } |
283 |
327 |
|
328 /// @} |
|
329 |
|
330 /// \name Query Functions |
|
331 /// The result of the algorithm can be obtained using these |
|
332 /// functions. |
|
333 /// \n run() must be called before using them. |
|
334 |
|
335 /// @{ |
|
336 |
284 /// \brief Returns a const reference to the edge map storing the |
337 /// \brief Returns a const reference to the edge map storing the |
285 /// found flow. |
338 /// found flow. |
286 /// |
339 /// |
287 /// Returns a const reference to the edge map storing the found flow. |
340 /// Returns a const reference to the edge map storing the found flow. |
288 /// |
341 /// |
289 /// \pre \ref run() must be called before using this function. |
342 /// \pre \ref run() must be called before using this function. |
290 const FlowMap& flowMap() const { |
343 const FlowMap& flowMap() const { |
291 return _flow; |
344 return *_flow; |
|
345 } |
|
346 |
|
347 /// \brief Returns a const reference to the node map storing the |
|
348 /// found potentials (the dual solution). |
|
349 /// |
|
350 /// Returns a const reference to the node map storing the found |
|
351 /// potentials (the dual solution). |
|
352 /// |
|
353 /// \pre \ref run() must be called before using this function. |
|
354 const PotentialMap& potentialMap() const { |
|
355 return *_potential; |
|
356 } |
|
357 |
|
358 /// \brief Returns the flow on the edge. |
|
359 /// |
|
360 /// Returns the flow on the edge. |
|
361 /// |
|
362 /// \pre \ref run() must be called before using this function. |
|
363 Capacity flow(const Edge& edge) const { |
|
364 return (*_flow)[edge]; |
|
365 } |
|
366 |
|
367 /// \brief Returns the potential of the node. |
|
368 /// |
|
369 /// Returns the potential of the node. |
|
370 /// |
|
371 /// \pre \ref run() must be called before using this function. |
|
372 Cost potential(const Node& node) const { |
|
373 return (*_potential)[node]; |
292 } |
374 } |
293 |
375 |
294 /// \brief Returns the total cost of the found flow. |
376 /// \brief Returns the total cost of the found flow. |
295 /// |
377 /// |
296 /// Returns the total cost of the found flow. The complexity of the |
378 /// Returns the total cost of the found flow. The complexity of the |
298 /// |
380 /// |
299 /// \pre \ref run() must be called before using this function. |
381 /// \pre \ref run() must be called before using this function. |
300 Cost totalCost() const { |
382 Cost totalCost() const { |
301 Cost c = 0; |
383 Cost c = 0; |
302 for (EdgeIt e(_graph); e != INVALID; ++e) |
384 for (EdgeIt e(_graph); e != INVALID; ++e) |
303 c += _flow[e] * _cost[e]; |
385 c += (*_flow)[e] * _cost[e]; |
304 return c; |
386 return c; |
305 } |
387 } |
|
388 |
|
389 /// @} |
306 |
390 |
307 private: |
391 private: |
308 |
392 |
309 /// Initializes the algorithm. |
393 /// Initializes the algorithm. |
310 bool init() { |
394 bool init() { |
311 if (!_valid_supply) return false; |
395 if (!_valid_supply) return false; |
312 |
396 |
|
397 // Initializing flow and potential maps |
|
398 if (!_flow) { |
|
399 _flow = new FlowMap(_graph); |
|
400 _local_flow = true; |
|
401 } |
|
402 if (!_potential) { |
|
403 _potential = new PotentialMap(_graph); |
|
404 _local_potential = true; |
|
405 } |
|
406 |
|
407 _res_graph = new ResGraph(_graph, _capacity, *_flow); |
|
408 |
313 // Finding a feasible flow using Circulation |
409 // Finding a feasible flow using Circulation |
314 Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap, |
410 Circulation< Graph, ConstMap<Edge, Capacity>, CapacityEdgeMap, |
315 SupplyMap > |
411 SupplyMap > |
316 circulation( _graph, constMap<Edge>((Capacity)0), _capacity, |
412 circulation( _graph, constMap<Edge>(Capacity(0)), _capacity, |
317 _supply ); |
413 _supply ); |
318 return circulation.flowMap(_flow).run(); |
414 return circulation.flowMap(*_flow).run(); |
319 } |
415 } |
320 |
416 |
321 bool start(bool min_mean_cc) { |
417 bool start(bool min_mean_cc) { |
322 if (min_mean_cc) |
418 if (min_mean_cc) |
323 return startMinMean(); |
419 startMinMean(); |
324 else |
420 else |
325 return start(); |
421 start(); |
|
422 |
|
423 // Handling non-zero lower bounds |
|
424 if (_lower) { |
|
425 for (EdgeIt e(_graph); e != INVALID; ++e) |
|
426 (*_flow)[e] += (*_lower)[e]; |
|
427 } |
|
428 return true; |
326 } |
429 } |
327 |
430 |
328 /// \brief Executes the algorithm using \ref BellmanFord. |
431 /// \brief Executes the algorithm using \ref BellmanFord. |
329 /// |
432 /// |
330 /// Executes the algorithm using the \ref BellmanFord |
433 /// Executes the algorithm using the \ref BellmanFord |
331 /// "Bellman-Ford" algorithm for negative cycle detection with |
434 /// "Bellman-Ford" algorithm for negative cycle detection with |
332 /// successively larger limit for the number of iterations. |
435 /// successively larger limit for the number of iterations. |
333 bool start() { |
436 void start() { |
334 typename BellmanFord<ResGraph, ResidualCostMap>::PredMap pred(_res_graph); |
437 typename BellmanFord<ResGraph, ResidualCostMap>::PredMap pred(*_res_graph); |
335 typename ResGraph::template NodeMap<int> visited(_res_graph); |
438 typename ResGraph::template NodeMap<int> visited(*_res_graph); |
336 std::vector<ResEdge> cycle; |
439 std::vector<ResEdge> cycle; |
337 int node_num = countNodes(_graph); |
440 int node_num = countNodes(_graph); |
338 |
441 |
339 int length_bound = BF_FIRST_LIMIT; |
442 int length_bound = BF_FIRST_LIMIT; |
340 bool optimal = false; |
443 bool optimal = false; |
341 while (!optimal) { |
444 while (!optimal) { |
342 BellmanFord<ResGraph, ResidualCostMap> bf(_res_graph, _res_cost); |
445 BellmanFord<ResGraph, ResidualCostMap> bf(*_res_graph, _res_cost); |
343 bf.predMap(pred); |
446 bf.predMap(pred); |
344 bf.init(0); |
447 bf.init(0); |
345 int iter_num = 0; |
448 int iter_num = 0; |
346 bool cycle_found = false; |
449 bool cycle_found = false; |
347 while (!cycle_found) { |
450 while (!cycle_found) { |
354 real_iter_num = i; |
457 real_iter_num = i; |
355 break; |
458 break; |
356 } |
459 } |
357 } |
460 } |
358 if (real_iter_num < curr_iter_num) { |
461 if (real_iter_num < curr_iter_num) { |
|
462 // Optimal flow is found |
359 optimal = true; |
463 optimal = true; |
|
464 // Setting node potentials |
|
465 for (NodeIt n(_graph); n != INVALID; ++n) |
|
466 (*_potential)[n] = bf.dist(n); |
360 break; |
467 break; |
361 } else { |
468 } else { |
362 // Searching for node disjoint negative cycles |
469 // Searching for node disjoint negative cycles |
363 for (ResNodeIt n(_res_graph); n != INVALID; ++n) |
470 for (ResNodeIt n(*_res_graph); n != INVALID; ++n) |
364 visited[n] = 0; |
471 visited[n] = 0; |
365 int id = 0; |
472 int id = 0; |
366 for (ResNodeIt n(_res_graph); n != INVALID; ++n) { |
473 for (ResNodeIt n(*_res_graph); n != INVALID; ++n) { |
367 if (visited[n] > 0) continue; |
474 if (visited[n] > 0) continue; |
368 visited[n] = ++id; |
475 visited[n] = ++id; |
369 ResNode u = pred[n] == INVALID ? |
476 ResNode u = pred[n] == INVALID ? |
370 INVALID : _res_graph.source(pred[n]); |
477 INVALID : _res_graph->source(pred[n]); |
371 while (u != INVALID && visited[u] == 0) { |
478 while (u != INVALID && visited[u] == 0) { |
372 visited[u] = id; |
479 visited[u] = id; |
373 u = pred[u] == INVALID ? |
480 u = pred[u] == INVALID ? |
374 INVALID : _res_graph.source(pred[u]); |
481 INVALID : _res_graph->source(pred[u]); |
375 } |
482 } |
376 if (u != INVALID && visited[u] == id) { |
483 if (u != INVALID && visited[u] == id) { |
377 // Finding the negative cycle |
484 // Finding the negative cycle |
378 cycle_found = true; |
485 cycle_found = true; |
379 cycle.clear(); |
486 cycle.clear(); |
380 ResEdge e = pred[u]; |
487 ResEdge e = pred[u]; |
381 cycle.push_back(e); |
488 cycle.push_back(e); |
382 Capacity d = _res_graph.rescap(e); |
489 Capacity d = _res_graph->rescap(e); |
383 while (_res_graph.source(e) != u) { |
490 while (_res_graph->source(e) != u) { |
384 cycle.push_back(e = pred[_res_graph.source(e)]); |
491 cycle.push_back(e = pred[_res_graph->source(e)]); |
385 if (_res_graph.rescap(e) < d) |
492 if (_res_graph->rescap(e) < d) |
386 d = _res_graph.rescap(e); |
493 d = _res_graph->rescap(e); |
387 } |
494 } |
388 |
495 |
389 // Augmenting along the cycle |
496 // Augmenting along the cycle |
390 for (int i = 0; i < int(cycle.size()); ++i) |
497 for (int i = 0; i < int(cycle.size()); ++i) |
391 _res_graph.augment(cycle[i], d); |
498 _res_graph->augment(cycle[i], d); |
392 } |
499 } |
393 } |
500 } |
394 } |
501 } |
395 |
502 |
396 if (!cycle_found) |
503 if (!cycle_found) |
397 length_bound = int(length_bound * BF_ALPHA); |
504 length_bound = int(length_bound * BF_ALPHA); |
398 } |
505 } |
399 } |
506 } |
400 |
|
401 // Handling non-zero lower bounds |
|
402 if (_lower) { |
|
403 for (EdgeIt e(_graph); e != INVALID; ++e) |
|
404 _flow[e] += (*_lower)[e]; |
|
405 } |
|
406 return true; |
|
407 } |
507 } |
408 |
508 |
409 /// \brief Executes the algorithm using \ref MinMeanCycle. |
509 /// \brief Executes the algorithm using \ref MinMeanCycle. |
410 /// |
510 /// |
411 /// Executes the algorithm using \ref MinMeanCycle for negative |
511 /// Executes the algorithm using \ref MinMeanCycle for negative |
412 /// cycle detection. |
512 /// cycle detection. |
413 bool startMinMean() { |
513 void startMinMean() { |
414 typedef Path<ResGraph> ResPath; |
514 typedef Path<ResGraph> ResPath; |
415 MinMeanCycle<ResGraph, ResidualCostMap> mmc(_res_graph, _res_cost); |
515 MinMeanCycle<ResGraph, ResidualCostMap> mmc(*_res_graph, _res_cost); |
416 ResPath cycle; |
516 ResPath cycle; |
417 |
517 |
418 mmc.cyclePath(cycle).init(); |
518 mmc.cyclePath(cycle).init(); |
419 if (mmc.findMinMean()) { |
519 if (mmc.findMinMean()) { |
420 while (mmc.cycleLength() < 0) { |
520 while (mmc.cycleLength() < 0) { |
423 |
523 |
424 // Finding the largest flow amount that can be augmented |
524 // Finding the largest flow amount that can be augmented |
425 // along the cycle |
525 // along the cycle |
426 Capacity delta = 0; |
526 Capacity delta = 0; |
427 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) { |
527 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) { |
428 if (delta == 0 || _res_graph.rescap(e) < delta) |
528 if (delta == 0 || _res_graph->rescap(e) < delta) |
429 delta = _res_graph.rescap(e); |
529 delta = _res_graph->rescap(e); |
430 } |
530 } |
431 |
531 |
432 // Augmenting along the cycle |
532 // Augmenting along the cycle |
433 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) |
533 for (typename ResPath::EdgeIt e(cycle); e != INVALID; ++e) |
434 _res_graph.augment(e, delta); |
534 _res_graph->augment(e, delta); |
435 |
535 |
436 // Finding the minimum cycle mean for the modified residual |
536 // Finding the minimum cycle mean for the modified residual |
437 // graph |
537 // graph |
438 mmc.reset(); |
538 mmc.reset(); |
439 if (!mmc.findMinMean()) break; |
539 if (!mmc.findMinMean()) break; |
440 } |
540 } |
441 } |
541 } |
442 |
542 |
443 // Handling non-zero lower bounds |
543 // Computing node potentials |
444 if (_lower) { |
544 BellmanFord<ResGraph, ResidualCostMap> bf(*_res_graph, _res_cost); |
445 for (EdgeIt e(_graph); e != INVALID; ++e) |
545 bf.init(0); bf.start(); |
446 _flow[e] += (*_lower)[e]; |
546 for (NodeIt n(_graph); n != INVALID; ++n) |
447 } |
547 (*_potential)[n] = bf.dist(n); |
448 return true; |
|
449 } |
548 } |
450 |
549 |
451 }; //class CycleCanceling |
550 }; //class CycleCanceling |
452 |
551 |
453 ///@} |
552 ///@} |