3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_GOMORY_HU_TREE_H
20 #define LEMON_GOMORY_HU_TREE_H
24 #include <lemon/core.h>
25 #include <lemon/preflow.h>
26 #include <lemon/concept_check.h>
27 #include <lemon/concepts/maps.h>
31 /// \brief Gomory-Hu cut tree in graphs.
37 /// \brief Gomory-Hu cut tree algorithm
39 /// The Gomory-Hu tree is a tree on the node set of the graph, but it
40 /// may contain edges which are not in the original digraph. It has the
41 /// property that the minimum capacity edge of the path between two nodes
42 /// in this tree has the same weight as the minimum cut in the digraph
43 /// between these nodes. Moreover the components obtained by removing
44 /// this edge from the tree determine the corresponding minimum cut.
46 /// Therefore once this tree is computed, the minimum cut between any pair
47 /// of nodes can easily be obtained.
49 /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
50 /// the \ref Preflow algorithm), therefore the algorithm has
51 /// \f$(O(n^3\sqrt{e})\f$ overall time complexity. It calculates a
52 /// rooted Gomory-Hu tree, its structure and the weights can be obtained
53 /// by \c predNode(), \c predValue() and \c rootDist().
55 /// The members \c minCutMap() and \c minCutValue() calculate
56 /// the minimum cut and the minimum cut value between any two node
57 /// in the digraph. You can also list (iterate on) the nodes and the
58 /// edges of the cuts using MinCutNodeIt and MinCutEdgeIt.
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>
71 /// The type if the edge capacity map
73 /// The value type of capacities
74 typedef typename Capacity::Value Value;
78 TEMPLATE_GRAPH_TYPEDEFS(Graph);
81 const Capacity& _capacity;
84 typename Graph::template NodeMap<Node>* _pred;
85 typename Graph::template NodeMap<Value>* _weight;
86 typename Graph::template NodeMap<int>* _order;
88 void createStructures() {
90 _pred = new typename Graph::template NodeMap<Node>(_graph);
93 _weight = new typename Graph::template NodeMap<Value>(_graph);
96 _order = new typename Graph::template NodeMap<int>(_graph);
100 void destroyStructures() {
114 /// \brief Constructor
117 /// \param graph The graph the algorithm will run on.
118 /// \param capacity The capacity map.
119 GomoryHuTree(const Graph& graph, const Capacity& capacity)
120 : _graph(graph), _capacity(capacity),
121 _pred(0), _weight(0), _order(0)
123 checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
127 /// \brief Destructor
134 // \brief Initialize the internal data structures.
136 // This function initializes the internal data structures.
141 _root = NodeIt(_graph);
142 for (NodeIt n(_graph); n != INVALID; ++n) {
143 _pred->set(n, _root);
146 _pred->set(_root, INVALID);
147 _weight->set(_root, std::numeric_limits<Value>::max());
151 // \brief Start the algorithm
153 // This function starts the algorithm.
155 // \pre \ref init() must be called before using this function.
158 Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
160 for (NodeIt n(_graph); n != INVALID; ++n) {
161 if (n == _root) continue;
163 Node pn = (*_pred)[n];
169 _weight->set(n, fa.flowValue());
171 for (NodeIt nn(_graph); nn != INVALID; ++nn) {
172 if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
176 if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
177 _pred->set(n, (*_pred)[pn]);
179 _weight->set(n, (*_weight)[pn]);
180 _weight->set(pn, fa.flowValue());
184 _order->set(_root, 0);
187 for (NodeIt n(_graph); n != INVALID; ++n) {
188 std::vector<Node> st;
190 while ((*_order)[nn] == -1) {
194 while (!st.empty()) {
195 _order->set(st.back(), index++);
201 ///\name Execution Control
205 /// \brief Run the Gomory-Hu algorithm.
207 /// This function runs the Gomory-Hu algorithm.
215 ///\name Query Functions
216 ///The results of the algorithm can be obtained using these
218 ///The \ref run() "run()" should be called before using them.\n
219 ///See also MinCutNodeIt and MinCutEdgeIt
223 /// \brief Return the predecessor node in the Gomory-Hu tree.
225 /// This function returns the predecessor node in the Gomory-Hu tree.
227 /// the root of the Gomory-Hu tree, then it returns \c INVALID.
228 Node predNode(const Node& node) {
229 return (*_pred)[node];
232 /// \brief Return the distance from the root node in the Gomory-Hu tree.
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];
240 /// \brief Return the weight of the predecessor edge in the
243 /// This function returns the weight of the predecessor edge in the
244 /// Gomory-Hu tree. If the node is the root, the result is undefined.
245 Value predValue(const Node& node) {
246 return (*_weight)[node];
249 /// \brief Return the minimum cut value between two nodes
251 /// This function returns the minimum cut value between two nodes. The
252 /// algorithm finds the nearest common ancestor in the Gomory-Hu
253 /// tree and calculates the minimum weight arc on the paths to
255 Value minCutValue(const Node& s, const Node& t) const {
257 Value value = std::numeric_limits<Value>::max();
260 if ((*_order)[sn] < (*_order)[tn]) {
261 if ((*_weight)[tn] <= value) value = (*_weight)[tn];
264 if ((*_weight)[sn] <= value) value = (*_weight)[sn];
271 /// \brief Return the minimum cut between two nodes
273 /// This function returns the minimum cut between the nodes \c s and \c t
274 /// the \r cutMap parameter by setting the nodes in the component of
275 /// \c \s to true and the other nodes to false.
277 /// The \c cutMap should be \ref concepts::ReadWriteMap
280 /// For higher level interfaces, see MinCutNodeIt and MinCutEdgeIt
281 template <typename CutMap>
282 Value minCutMap(const Node& s, ///< Base node
284 ///< The node you want to separate from Node s.
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.
293 Value value = std::numeric_limits<Value>::max();
296 if ((*_order)[sn] < (*_order)[tn]) {
297 if ((*_weight)[tn] <= value) {
300 value = (*_weight)[tn];
304 if ((*_weight)[sn] <= value) {
307 value = (*_weight)[sn];
313 typename Graph::template NodeMap<bool> reached(_graph, false);
314 reached.set(_root, true);
315 cutMap.set(_root, !s_root);
316 reached.set(rn, true);
317 cutMap.set(rn, s_root);
319 std::vector<Node> st;
320 for (NodeIt n(_graph); n != INVALID; ++n) {
323 while (!reached[nn]) {
327 while (!st.empty()) {
328 cutMap.set(st.back(), cutMap[nn]);
338 friend class MinCutNodeIt;
340 /// Iterate on the nodes of a minimum cut
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.
346 /// This example counts the nodes in the minimum cut separating \c s from
349 /// GomoruHuTree<Graph> gom(g, capacities);
352 /// for(GomoruHuTree<Graph>::MinCutNodeIt n(gom,s,t);n!=INVALID;++n) ++sum;
357 typename Graph::NodeIt _node_it;
358 typename Graph::template NodeMap<bool> _cut;
364 MinCutNodeIt(GomoryHuTree const &gomory,
365 ///< The GomoryHuTree class. You must call its
367 /// before initializing this iterator
368 const Node& s, ///< Base node
370 ///< The node you want to separate from Node s.
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,
377 /// MinCutNodeIt(gomory, s, t, true);
381 /// MinCutNodeIt(gomory, t, s, false);
383 /// does not necessarily give the same set of nodes.
384 /// However it is ensured that
386 /// MinCutNodeIt(gomory, s, t, true);
390 /// MinCutNodeIt(gomory, s, t, false);
392 /// together list each node exactly once.
394 : _side(side), _cut(gomory._graph)
396 gomory.minCutMap(s,t,_cut);
397 for(_node_it=typename Graph::NodeIt(gomory._graph);
398 _node_it!=INVALID && _cut[_node_it]!=_side;
401 /// Conversion to Node
403 /// Conversion to Node
405 operator typename Graph::Node() const
409 bool operator==(Invalid) { return _node_it==INVALID; }
410 bool operator!=(Invalid) { return _node_it!=INVALID; }
415 MinCutNodeIt &operator++()
417 for(++_node_it;_node_it!=INVALID&&_cut[_node_it]!=_side;++_node_it) {}
420 /// Postfix incrementation
422 /// Postfix incrementation
424 /// \warning This incrementation
425 /// returns a \c Node, not a \ref MinCutNodeIt, as one may
427 typename Graph::Node operator++(int)
429 typename Graph::Node n=*this;
435 friend class MinCutEdgeIt;
437 /// Iterate on the edges of a minimum cut
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.
443 /// This example computes the value of the minimum cut separating \c s from
446 /// GomoruHuTree<Graph> gom(g, capacities);
449 /// for(GomoruHuTree<Graph>::MinCutEdgeIt e(gom,s,t);e!=INVALID;++e)
450 /// value+=capacities[e];
452 /// the result will be the same as it is returned by
453 /// \ref GomoryHuTree::minCostValue() "gom.minCostValue(s,t)"
458 typename Graph::NodeIt _node_it;
459 typename Graph::OutArcIt _arc_it;
460 typename Graph::template NodeMap<bool> _cut;
464 while(_node_it!=INVALID && _arc_it==INVALID)
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);
473 MinCutEdgeIt(GomoryHuTree const &gomory,
474 ///< The GomoryHuTree class. You must call its
476 /// before initializing this iterator
477 const Node& s, ///< Base node
479 ///< The node you want to separate from Node s.
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
487 : _graph(gomory._graph), _cut(_graph)
489 gomory.minCutMap(s,t,_cut);
491 for(typename Graph::NodeIt n(_graph);n!=INVALID;++n)
494 for(_node_it=typename Graph::NodeIt(_graph);
495 _node_it!=INVALID && !_cut[_node_it];
497 _arc_it = _node_it!=INVALID ?
498 typename Graph::OutArcIt(_graph,_node_it) : INVALID;
499 while(_node_it!=INVALID && _arc_it == INVALID)
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);
505 while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
507 /// Conversion to Arc
509 /// Conversion to Arc
511 operator typename Graph::Arc() const
515 /// Conversion to Edge
517 /// Conversion to Edge
519 operator typename Graph::Edge() const
523 bool operator==(Invalid) { return _node_it==INVALID; }
524 bool operator!=(Invalid) { return _node_it!=INVALID; }
529 MinCutEdgeIt &operator++()
532 while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
535 /// Postfix incrementation
537 /// Postfix incrementation
539 /// \warning This incrementation
540 /// returns a \c Arc, not a \ref MinCutEdgeIt, as one may
542 typename Graph::Arc operator++(int)
544 typename Graph::Arc e=*this;