33 |
34 |
34 /// \ingroup min_cut |
35 /// \ingroup min_cut |
35 /// |
36 /// |
36 /// \brief Gomory-Hu cut tree algorithm |
37 /// \brief Gomory-Hu cut tree algorithm |
37 /// |
38 /// |
38 /// The Gomory-Hu tree is a tree on the nodeset of the digraph, but it |
39 /// The Gomory-Hu tree is a tree on the node set of the graph, but it |
39 /// may contain arcs which are not in the original digraph. It helps |
40 /// may contain edges which are not in the original digraph. It has the |
40 /// to calculate the minimum cut between all pairs of nodes, because |
41 /// property that the minimum capacity edge of the path between two nodes |
41 /// the minimum capacity arc on the tree path between two nodes has |
42 /// in this tree has the same weight as the minimum cut in the digraph |
42 /// the same weight as the minimum cut in the digraph between these |
43 /// between these nodes. Moreover the components obtained by removing |
43 /// nodes. Moreover this arc separates the nodes to two parts which |
44 /// this edge from the tree determine the corresponding minimum cut. |
44 /// determine this minimum cut. |
45 /// |
|
46 /// Therefore once this tree is computed, the minimum cut between any pair |
|
47 /// of nodes can easily be obtained. |
45 /// |
48 /// |
46 /// The algorithm calculates \e n-1 distinict minimum cuts with |
49 /// The algorithm calculates \e n-1 distinct minimum cuts (currently with |
47 /// preflow algorithm, therefore the algorithm has |
50 /// the \ref Preflow algorithm), therefore the algorithm has |
48 /// \f$(O(n^3\sqrt{e})\f$ overall time complexity. It calculates a |
51 /// \f$(O(n^3\sqrt{e})\f$ overall time complexity. It calculates a |
49 /// rooted Gomory-Hu tree, the structure of the tree and the weights |
52 /// rooted Gomory-Hu tree, its structure and the weights can be obtained |
50 /// can be obtained with \c predNode() and \c predValue() |
53 /// by \c predNode(), \c predValue() and \c rootDist(). |
51 /// functions. The \c minCutValue() and \c minCutMap() calculates |
54 /// |
|
55 /// The members \c minCutMap() and \c minCutValue() calculate |
52 /// the minimum cut and the minimum cut value between any two node |
56 /// the minimum cut and the minimum cut value between any two node |
53 /// in the digraph. |
57 /// in the digraph. You can also list (iterate on) the nodes and the |
54 template <typename _Graph, |
58 /// edges of the cuts using MinCutNodeIt and MinCutEdgeIt. |
55 typename _Capacity = typename _Graph::template EdgeMap<int> > |
59 /// |
|
60 /// \tparam GR The undirected graph data structure the algorithm will run on |
|
61 /// \tparam CAP type of the EdgeMap describing the Edge capacities. |
|
62 /// it is typename GR::template EdgeMap<int> by default. |
|
63 template <typename GR, |
|
64 typename CAP = typename GR::template EdgeMap<int> |
|
65 > |
56 class GomoryHuTree { |
66 class GomoryHuTree { |
57 public: |
67 public: |
58 |
68 |
59 /// The graph type |
69 /// The graph type |
60 typedef _Graph Graph; |
70 typedef GR Graph; |
61 /// The capacity on edges |
71 /// The type if the edge capacity map |
62 typedef _Capacity Capacity; |
72 typedef CAP Capacity; |
63 /// The value type of capacities |
73 /// The value type of capacities |
64 typedef typename Capacity::Value Value; |
74 typedef typename Capacity::Value Value; |
65 |
75 |
66 private: |
76 private: |
67 |
77 |
183 st.pop_back(); |
196 st.pop_back(); |
184 } |
197 } |
185 } |
198 } |
186 } |
199 } |
187 |
200 |
188 /// \brief Runs the Gomory-Hu algorithm. |
201 ///\name Execution Control |
189 /// |
202 |
190 /// Runs the Gomory-Hu algorithm. |
203 ///@{ |
191 /// \note gh.run() is just a shortcut of the following code. |
204 |
192 /// \code |
205 /// \brief Run the Gomory-Hu algorithm. |
193 /// ght.init(); |
206 /// |
194 /// ght.start(); |
207 /// This function runs the Gomory-Hu algorithm. |
195 /// \endcode |
|
196 void run() { |
208 void run() { |
197 init(); |
209 init(); |
198 start(); |
210 start(); |
199 } |
211 } |
200 |
212 |
201 /// \brief Returns the predecessor node in the Gomory-Hu tree. |
213 /// @} |
202 /// |
214 |
203 /// Returns the predecessor node in the Gomory-Hu tree. If the node is |
215 ///\name Query Functions |
|
216 ///The results of the algorithm can be obtained using these |
|
217 ///functions.\n |
|
218 ///The \ref run() "run()" should be called before using them.\n |
|
219 ///See also MinCutNodeIt and MinCutEdgeIt |
|
220 |
|
221 ///@{ |
|
222 |
|
223 /// \brief Return the predecessor node in the Gomory-Hu tree. |
|
224 /// |
|
225 /// This function returns the predecessor node in the Gomory-Hu tree. |
|
226 /// If the node is |
204 /// the root of the Gomory-Hu tree, then it returns \c INVALID. |
227 /// the root of the Gomory-Hu tree, then it returns \c INVALID. |
205 Node predNode(const Node& node) { |
228 Node predNode(const Node& node) { |
206 return (*_pred)[node]; |
229 return (*_pred)[node]; |
207 } |
230 } |
208 |
231 |
209 /// \brief Returns the weight of the predecessor arc in the |
232 /// \brief Return the distance from the root node in the Gomory-Hu tree. |
|
233 /// |
|
234 /// This function returns the distance of \c node from the root node |
|
235 /// in the Gomory-Hu tree. |
|
236 int rootDist(const Node& node) { |
|
237 return (*_order)[node]; |
|
238 } |
|
239 |
|
240 /// \brief Return the weight of the predecessor edge in the |
210 /// Gomory-Hu tree. |
241 /// Gomory-Hu tree. |
211 /// |
242 /// |
212 /// Returns the weight of the predecessor arc in the Gomory-Hu |
243 /// This function returns the weight of the predecessor edge in the |
213 /// tree. If the node is the root of the Gomory-Hu tree, the |
244 /// Gomory-Hu tree. If the node is the root, the result is undefined. |
214 /// result is undefined. |
|
215 Value predValue(const Node& node) { |
245 Value predValue(const Node& node) { |
216 return (*_weight)[node]; |
246 return (*_weight)[node]; |
217 } |
247 } |
218 |
248 |
219 /// \brief Returns the minimum cut value between two nodes |
249 /// \brief Return the minimum cut value between two nodes |
220 /// |
250 /// |
221 /// Returns the minimum cut value between two nodes. The |
251 /// This function returns the minimum cut value between two nodes. The |
222 /// algorithm finds the nearest common ancestor in the Gomory-Hu |
252 /// algorithm finds the nearest common ancestor in the Gomory-Hu |
223 /// tree and calculates the minimum weight arc on the paths to |
253 /// tree and calculates the minimum weight arc on the paths to |
224 /// the ancestor. |
254 /// the ancestor. |
225 Value minCutValue(const Node& s, const Node& t) const { |
255 Value minCutValue(const Node& s, const Node& t) const { |
226 Node sn = s, tn = t; |
256 Node sn = s, tn = t; |
227 Value value = std::numeric_limits<Value>::max(); |
257 Value value = std::numeric_limits<Value>::max(); |
228 |
258 |
229 while (sn != tn) { |
259 while (sn != tn) { |
230 if ((*_order)[sn] < (*_order)[tn]) { |
260 if ((*_order)[sn] < (*_order)[tn]) { |
231 if ((*_weight)[tn] < value) value = (*_weight)[tn]; |
261 if ((*_weight)[tn] <= value) value = (*_weight)[tn]; |
232 tn = (*_pred)[tn]; |
262 tn = (*_pred)[tn]; |
233 } else { |
263 } else { |
234 if ((*_weight)[sn] < value) value = (*_weight)[sn]; |
264 if ((*_weight)[sn] <= value) value = (*_weight)[sn]; |
235 sn = (*_pred)[sn]; |
265 sn = (*_pred)[sn]; |
236 } |
266 } |
237 } |
267 } |
238 return value; |
268 return value; |
239 } |
269 } |
240 |
270 |
241 /// \brief Returns the minimum cut between two nodes |
271 /// \brief Return the minimum cut between two nodes |
242 /// |
272 /// |
243 /// Returns the minimum cut value between two nodes. The |
273 /// This function returns the minimum cut between the nodes \c s and \c t |
244 /// algorithm finds the nearest common ancestor in the Gomory-Hu |
274 /// the \r cutMap parameter by setting the nodes in the component of |
245 /// tree and calculates the minimum weight arc on the paths to |
275 /// \c \s to true and the other nodes to false. |
246 /// the ancestor. Then it sets all nodes to the cut determined by |
276 /// |
247 /// this arc. The \c cutMap should be \ref concepts::ReadWriteMap |
277 /// The \c cutMap should be \ref concepts::ReadWriteMap |
248 /// "ReadWriteMap". |
278 /// "ReadWriteMap". |
|
279 /// |
|
280 /// For higher level interfaces, see MinCutNodeIt and MinCutEdgeIt |
249 template <typename CutMap> |
281 template <typename CutMap> |
250 Value minCutMap(const Node& s, const Node& t, CutMap& cutMap) const { |
282 Value minCutMap(const Node& s, ///< Base node |
|
283 const Node& t, |
|
284 ///< The node you want to separate from Node s. |
|
285 CutMap& cutMap |
|
286 ///< The cut will be return in this map. |
|
287 /// It must be a \c bool \ref concepts::ReadWriteMap |
|
288 /// "ReadWriteMap" on the graph nodes. |
|
289 ) const { |
251 Node sn = s, tn = t; |
290 Node sn = s, tn = t; |
252 |
291 bool s_root=false; |
253 Node rn = INVALID; |
292 Node rn = INVALID; |
254 Value value = std::numeric_limits<Value>::max(); |
293 Value value = std::numeric_limits<Value>::max(); |
255 |
294 |
256 while (sn != tn) { |
295 while (sn != tn) { |
257 if ((*_order)[sn] < (*_order)[tn]) { |
296 if ((*_order)[sn] < (*_order)[tn]) { |
258 if ((*_weight)[tn] < value) { |
297 if ((*_weight)[tn] <= value) { |
259 rn = tn; |
298 rn = tn; |
|
299 s_root = false; |
260 value = (*_weight)[tn]; |
300 value = (*_weight)[tn]; |
261 } |
301 } |
262 tn = (*_pred)[tn]; |
302 tn = (*_pred)[tn]; |
263 } else { |
303 } else { |
264 if ((*_weight)[sn] < value) { |
304 if ((*_weight)[sn] <= value) { |
265 rn = sn; |
305 rn = sn; |
|
306 s_root = true; |
266 value = (*_weight)[sn]; |
307 value = (*_weight)[sn]; |
267 } |
308 } |
268 sn = (*_pred)[sn]; |
309 sn = (*_pred)[sn]; |
269 } |
310 } |
270 } |
311 } |
271 |
312 |
272 typename Graph::template NodeMap<bool> reached(_graph, false); |
313 typename Graph::template NodeMap<bool> reached(_graph, false); |
273 reached.set(_root, true); |
314 reached.set(_root, true); |
274 cutMap.set(_root, false); |
315 cutMap.set(_root, !s_root); |
275 reached.set(rn, true); |
316 reached.set(rn, true); |
276 cutMap.set(rn, true); |
317 cutMap.set(rn, s_root); |
277 |
318 |
|
319 std::vector<Node> st; |
278 for (NodeIt n(_graph); n != INVALID; ++n) { |
320 for (NodeIt n(_graph); n != INVALID; ++n) { |
279 std::vector<Node> st; |
321 st.clear(); |
280 Node nn = n; |
322 Node nn = n; |
281 while (!reached[nn]) { |
323 while (!reached[nn]) { |
282 st.push_back(nn); |
324 st.push_back(nn); |
283 nn = (*_pred)[nn]; |
325 nn = (*_pred)[nn]; |
284 } |
326 } |
285 while (!st.empty()) { |
327 while (!st.empty()) { |
289 } |
331 } |
290 |
332 |
291 return value; |
333 return value; |
292 } |
334 } |
293 |
335 |
|
336 ///@} |
|
337 |
|
338 friend class MinCutNodeIt; |
|
339 |
|
340 /// Iterate on the nodes of a minimum cut |
|
341 |
|
342 /// This iterator class lists the nodes of a minimum cut found by |
|
343 /// GomoryHuTree. Before using it, you must allocate a GomoryHuTree class, |
|
344 /// and call its \ref GomoryHuTree::run() "run()" method. |
|
345 /// |
|
346 /// This example counts the nodes in the minimum cut separating \c s from |
|
347 /// \c t. |
|
348 /// \code |
|
349 /// GomoruHuTree<Graph> gom(g, capacities); |
|
350 /// gom.run(); |
|
351 /// int sum=0; |
|
352 /// for(GomoruHuTree<Graph>::MinCutNodeIt n(gom,s,t);n!=INVALID;++n) ++sum; |
|
353 /// \endcode |
|
354 class MinCutNodeIt |
|
355 { |
|
356 bool _side; |
|
357 typename Graph::NodeIt _node_it; |
|
358 typename Graph::template NodeMap<bool> _cut; |
|
359 public: |
|
360 /// Constructor |
|
361 |
|
362 /// Constructor |
|
363 /// |
|
364 MinCutNodeIt(GomoryHuTree const &gomory, |
|
365 ///< The GomoryHuTree class. You must call its |
|
366 /// run() method |
|
367 /// before initializing this iterator |
|
368 const Node& s, ///< Base node |
|
369 const Node& t, |
|
370 ///< The node you want to separate from Node s. |
|
371 bool side=true |
|
372 ///< If it is \c true (default) then the iterator lists |
|
373 /// the nodes of the component containing \c s, |
|
374 /// otherwise it lists the other component. |
|
375 /// \note As the minimum cut is not always unique, |
|
376 /// \code |
|
377 /// MinCutNodeIt(gomory, s, t, true); |
|
378 /// \endcode |
|
379 /// and |
|
380 /// \code |
|
381 /// MinCutNodeIt(gomory, t, s, false); |
|
382 /// \endcode |
|
383 /// does not necessarily give the same set of nodes. |
|
384 /// However it is ensured that |
|
385 /// \code |
|
386 /// MinCutNodeIt(gomory, s, t, true); |
|
387 /// \endcode |
|
388 /// and |
|
389 /// \code |
|
390 /// MinCutNodeIt(gomory, s, t, false); |
|
391 /// \endcode |
|
392 /// together list each node exactly once. |
|
393 ) |
|
394 : _side(side), _cut(gomory._graph) |
|
395 { |
|
396 gomory.minCutMap(s,t,_cut); |
|
397 for(_node_it=typename Graph::NodeIt(gomory._graph); |
|
398 _node_it!=INVALID && _cut[_node_it]!=_side; |
|
399 ++_node_it) {} |
|
400 } |
|
401 /// Conversion to Node |
|
402 |
|
403 /// Conversion to Node |
|
404 /// |
|
405 operator typename Graph::Node() const |
|
406 { |
|
407 return _node_it; |
|
408 } |
|
409 bool operator==(Invalid) { return _node_it==INVALID; } |
|
410 bool operator!=(Invalid) { return _node_it!=INVALID; } |
|
411 /// Next node |
|
412 |
|
413 /// Next node |
|
414 /// |
|
415 MinCutNodeIt &operator++() |
|
416 { |
|
417 for(++_node_it;_node_it!=INVALID&&_cut[_node_it]!=_side;++_node_it) {} |
|
418 return *this; |
|
419 } |
|
420 /// Postfix incrementation |
|
421 |
|
422 /// Postfix incrementation |
|
423 /// |
|
424 /// \warning This incrementation |
|
425 /// returns a \c Node, not a \ref MinCutNodeIt, as one may |
|
426 /// expect. |
|
427 typename Graph::Node operator++(int) |
|
428 { |
|
429 typename Graph::Node n=*this; |
|
430 ++(*this); |
|
431 return n; |
|
432 } |
|
433 }; |
|
434 |
|
435 friend class MinCutEdgeIt; |
|
436 |
|
437 /// Iterate on the edges of a minimum cut |
|
438 |
|
439 /// This iterator class lists the edges of a minimum cut found by |
|
440 /// GomoryHuTree. Before using it, you must allocate a GomoryHuTree class, |
|
441 /// and call its \ref GomoryHuTree::run() "run()" method. |
|
442 /// |
|
443 /// This example computes the value of the minimum cut separating \c s from |
|
444 /// \c t. |
|
445 /// \code |
|
446 /// GomoruHuTree<Graph> gom(g, capacities); |
|
447 /// gom.run(); |
|
448 /// int value=0; |
|
449 /// for(GomoruHuTree<Graph>::MinCutEdgeIt e(gom,s,t);e!=INVALID;++e) |
|
450 /// value+=capacities[e]; |
|
451 /// \endcode |
|
452 /// the result will be the same as it is returned by |
|
453 /// \ref GomoryHuTree::minCostValue() "gom.minCostValue(s,t)" |
|
454 class MinCutEdgeIt |
|
455 { |
|
456 bool _side; |
|
457 const Graph &_graph; |
|
458 typename Graph::NodeIt _node_it; |
|
459 typename Graph::OutArcIt _arc_it; |
|
460 typename Graph::template NodeMap<bool> _cut; |
|
461 void step() |
|
462 { |
|
463 ++_arc_it; |
|
464 while(_node_it!=INVALID && _arc_it==INVALID) |
|
465 { |
|
466 for(++_node_it;_node_it!=INVALID&&!_cut[_node_it];++_node_it) {} |
|
467 if(_node_it!=INVALID) |
|
468 _arc_it=typename Graph::OutArcIt(_graph,_node_it); |
|
469 } |
|
470 } |
|
471 |
|
472 public: |
|
473 MinCutEdgeIt(GomoryHuTree const &gomory, |
|
474 ///< The GomoryHuTree class. You must call its |
|
475 /// run() method |
|
476 /// before initializing this iterator |
|
477 const Node& s, ///< Base node |
|
478 const Node& t, |
|
479 ///< The node you want to separate from Node s. |
|
480 bool side=true |
|
481 ///< If it is \c true (default) then the listed arcs |
|
482 /// will be oriented from the |
|
483 /// the nodes of the component containing \c s, |
|
484 /// otherwise they will be oriented in the opposite |
|
485 /// direction. |
|
486 ) |
|
487 : _graph(gomory._graph), _cut(_graph) |
|
488 { |
|
489 gomory.minCutMap(s,t,_cut); |
|
490 if(!side) |
|
491 for(typename Graph::NodeIt n(_graph);n!=INVALID;++n) |
|
492 _cut[n]=!_cut[n]; |
|
493 |
|
494 for(_node_it=typename Graph::NodeIt(_graph); |
|
495 _node_it!=INVALID && !_cut[_node_it]; |
|
496 ++_node_it) {} |
|
497 _arc_it = _node_it!=INVALID ? |
|
498 typename Graph::OutArcIt(_graph,_node_it) : INVALID; |
|
499 while(_node_it!=INVALID && _arc_it == INVALID) |
|
500 { |
|
501 for(++_node_it; _node_it!=INVALID&&!_cut[_node_it]; ++_node_it) {} |
|
502 if(_node_it!=INVALID) |
|
503 _arc_it= typename Graph::OutArcIt(_graph,_node_it); |
|
504 } |
|
505 while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step(); |
|
506 } |
|
507 /// Conversion to Arc |
|
508 |
|
509 /// Conversion to Arc |
|
510 /// |
|
511 operator typename Graph::Arc() const |
|
512 { |
|
513 return _arc_it; |
|
514 } |
|
515 /// Conversion to Edge |
|
516 |
|
517 /// Conversion to Edge |
|
518 /// |
|
519 operator typename Graph::Edge() const |
|
520 { |
|
521 return _arc_it; |
|
522 } |
|
523 bool operator==(Invalid) { return _node_it==INVALID; } |
|
524 bool operator!=(Invalid) { return _node_it!=INVALID; } |
|
525 /// Next edge |
|
526 |
|
527 /// Next edge |
|
528 /// |
|
529 MinCutEdgeIt &operator++() |
|
530 { |
|
531 step(); |
|
532 while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step(); |
|
533 return *this; |
|
534 } |
|
535 /// Postfix incrementation |
|
536 |
|
537 /// Postfix incrementation |
|
538 /// |
|
539 /// \warning This incrementation |
|
540 /// returns a \c Arc, not a \ref MinCutEdgeIt, as one may |
|
541 /// expect. |
|
542 typename Graph::Arc operator++(int) |
|
543 { |
|
544 typename Graph::Arc e=*this; |
|
545 ++(*this); |
|
546 return e; |
|
547 } |
|
548 }; |
|
549 |
294 }; |
550 }; |
295 |
551 |
296 } |
552 } |
297 |
553 |
298 #endif |
554 #endif |