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 a given graph, but it
40 /// may contain edges which are not in the original graph. 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 graph
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 nodes
57 /// in the graph. You can also list (iterate on) the nodes and the
58 /// edges of the cuts using \c MinCutNodeIt and \c MinCutEdgeIt.
60 /// \tparam GR The type of the undirected graph the algorithm runs on.
61 /// \tparam CAP The type of the edge map describing the edge capacities.
62 /// It is \ref concepts::Graph::EdgeMap "GR::EdgeMap<int>" by default.
64 template <typename GR,
67 template <typename GR,
68 typename CAP = typename GR::template EdgeMap<int> >
75 /// The type of the edge capacity map
77 /// The value type of capacities
78 typedef typename Capacity::Value Value;
82 TEMPLATE_GRAPH_TYPEDEFS(Graph);
85 const Capacity& _capacity;
88 typename Graph::template NodeMap<Node>* _pred;
89 typename Graph::template NodeMap<Value>* _weight;
90 typename Graph::template NodeMap<int>* _order;
92 void createStructures() {
94 _pred = new typename Graph::template NodeMap<Node>(_graph);
97 _weight = new typename Graph::template NodeMap<Value>(_graph);
100 _order = new typename Graph::template NodeMap<int>(_graph);
104 void destroyStructures() {
118 /// \brief Constructor
121 /// \param graph The undirected graph the algorithm runs on.
122 /// \param capacity The edge capacity map.
123 GomoryHu(const Graph& graph, const Capacity& capacity)
124 : _graph(graph), _capacity(capacity),
125 _pred(0), _weight(0), _order(0)
127 checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
131 /// \brief Destructor
140 // Initialize the internal data structures
144 _root = NodeIt(_graph);
145 for (NodeIt n(_graph); n != INVALID; ++n) {
149 (*_pred)[_root] = INVALID;
150 (*_weight)[_root] = std::numeric_limits<Value>::max();
154 // Start the algorithm
156 Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
158 for (NodeIt n(_graph); n != INVALID; ++n) {
159 if (n == _root) continue;
161 Node pn = (*_pred)[n];
167 (*_weight)[n] = fa.flowValue();
169 for (NodeIt nn(_graph); nn != INVALID; ++nn) {
170 if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
174 if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
175 (*_pred)[n] = (*_pred)[pn];
177 (*_weight)[n] = (*_weight)[pn];
178 (*_weight)[pn] = fa.flowValue();
182 (*_order)[_root] = 0;
185 for (NodeIt n(_graph); n != INVALID; ++n) {
186 std::vector<Node> st;
188 while ((*_order)[nn] == -1) {
192 while (!st.empty()) {
193 (*_order)[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 ///\ref run() "run()" should be called before using them.\n
219 ///See also \ref MinCutNodeIt and \ref 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 edge 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 /// in the \c cutMap parameter by setting the nodes in the component of
275 /// \c s to \c true and the other nodes to \c false.
277 /// For higher level interfaces, see MinCutNodeIt and MinCutEdgeIt.
278 template <typename CutMap>
279 Value minCutMap(const Node& s, ///< The base node.
281 ///< The node you want to separate from node \c s.
283 ///< The cut will be returned in this map.
284 /// It must be a \c bool (or convertible)
285 /// \ref concepts::ReadWriteMap "ReadWriteMap"
286 /// on the graph nodes.
291 Value value = std::numeric_limits<Value>::max();
294 if ((*_order)[sn] < (*_order)[tn]) {
295 if ((*_weight)[tn] <= value) {
298 value = (*_weight)[tn];
302 if ((*_weight)[sn] <= value) {
305 value = (*_weight)[sn];
311 typename Graph::template NodeMap<bool> reached(_graph, false);
312 reached[_root] = true;
313 cutMap.set(_root, !s_root);
315 cutMap.set(rn, s_root);
317 std::vector<Node> st;
318 for (NodeIt n(_graph); n != INVALID; ++n) {
321 while (!reached[nn]) {
325 while (!st.empty()) {
326 cutMap.set(st.back(), cutMap[nn]);
336 friend class MinCutNodeIt;
338 /// Iterate on the nodes of a minimum cut
340 /// This iterator class lists the nodes of a minimum cut found by
341 /// GomoryHu. Before using it, you must allocate a GomoryHu class,
342 /// and call its \ref GomoryHu::run() "run()" method.
344 /// This example counts the nodes in the minimum cut separating \c s from
347 /// GomoruHu<Graph> gom(g, capacities);
350 /// for(GomoruHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
355 typename Graph::NodeIt _node_it;
356 typename Graph::template NodeMap<bool> _cut;
362 MinCutNodeIt(GomoryHu const &gomory,
363 ///< The GomoryHu class. You must call its
365 /// before initializing this iterator.
366 const Node& s, ///< The base node.
368 ///< The node you want to separate from node \c s.
370 ///< If it is \c true (default) then the iterator lists
371 /// the nodes of the component containing \c s,
372 /// otherwise it lists the other component.
373 /// \note As the minimum cut is not always unique,
375 /// MinCutNodeIt(gomory, s, t, true);
379 /// MinCutNodeIt(gomory, t, s, false);
381 /// does not necessarily give the same set of nodes.
382 /// However it is ensured that
384 /// MinCutNodeIt(gomory, s, t, true);
388 /// MinCutNodeIt(gomory, s, t, false);
390 /// together list each node exactly once.
392 : _side(side), _cut(gomory._graph)
394 gomory.minCutMap(s,t,_cut);
395 for(_node_it=typename Graph::NodeIt(gomory._graph);
396 _node_it!=INVALID && _cut[_node_it]!=_side;
399 /// Conversion to \c Node
401 /// Conversion to \c Node.
403 operator typename Graph::Node() const
407 bool operator==(Invalid) { return _node_it==INVALID; }
408 bool operator!=(Invalid) { return _node_it!=INVALID; }
413 MinCutNodeIt &operator++()
415 for(++_node_it;_node_it!=INVALID&&_cut[_node_it]!=_side;++_node_it) {}
418 /// Postfix incrementation
420 /// Postfix incrementation.
422 /// \warning This incrementation
423 /// returns a \c Node, not a \c MinCutNodeIt, as one may
425 typename Graph::Node operator++(int)
427 typename Graph::Node n=*this;
433 friend class MinCutEdgeIt;
435 /// Iterate on the edges of a minimum cut
437 /// This iterator class lists the edges of a minimum cut found by
438 /// GomoryHu. Before using it, you must allocate a GomoryHu class,
439 /// and call its \ref GomoryHu::run() "run()" method.
441 /// This example computes the value of the minimum cut separating \c s from
444 /// GomoruHu<Graph> gom(g, capacities);
447 /// for(GomoruHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
448 /// value+=capacities[e];
450 /// the result will be the same as it is returned by
451 /// \ref GomoryHu::minCutValue() "gom.minCutValue(s,t)"
456 typename Graph::NodeIt _node_it;
457 typename Graph::OutArcIt _arc_it;
458 typename Graph::template NodeMap<bool> _cut;
462 while(_node_it!=INVALID && _arc_it==INVALID)
464 for(++_node_it;_node_it!=INVALID&&!_cut[_node_it];++_node_it) {}
465 if(_node_it!=INVALID)
466 _arc_it=typename Graph::OutArcIt(_graph,_node_it);
471 MinCutEdgeIt(GomoryHu const &gomory,
472 ///< The GomoryHu class. You must call its
474 /// before initializing this iterator.
475 const Node& s, ///< The base node.
477 ///< The node you want to separate from node \c s.
479 ///< If it is \c true (default) then the listed arcs
480 /// will be oriented from the
481 /// the nodes of the component containing \c s,
482 /// otherwise they will be oriented in the opposite
485 : _graph(gomory._graph), _cut(_graph)
487 gomory.minCutMap(s,t,_cut);
489 for(typename Graph::NodeIt n(_graph);n!=INVALID;++n)
492 for(_node_it=typename Graph::NodeIt(_graph);
493 _node_it!=INVALID && !_cut[_node_it];
495 _arc_it = _node_it!=INVALID ?
496 typename Graph::OutArcIt(_graph,_node_it) : INVALID;
497 while(_node_it!=INVALID && _arc_it == INVALID)
499 for(++_node_it; _node_it!=INVALID&&!_cut[_node_it]; ++_node_it) {}
500 if(_node_it!=INVALID)
501 _arc_it= typename Graph::OutArcIt(_graph,_node_it);
503 while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
505 /// Conversion to \c Arc
507 /// Conversion to \c Arc.
509 operator typename Graph::Arc() const
513 /// Conversion to \c Edge
515 /// Conversion to \c Edge.
517 operator typename Graph::Edge() const
521 bool operator==(Invalid) { return _node_it==INVALID; }
522 bool operator!=(Invalid) { return _node_it!=INVALID; }
527 MinCutEdgeIt &operator++()
530 while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
533 /// Postfix incrementation
535 /// Postfix incrementation.
537 /// \warning This incrementation
538 /// returns an \c Arc, not a \c MinCutEdgeIt, as one may expect.
539 typename Graph::Arc operator++(int)
541 typename Graph::Arc e=*this;