lemon/gomory_hu_tree.h
author ladanyi
Wed, 02 Jul 2008 12:37:47 +0000
changeset 2615 2bf1f6e3d5ae
parent 2528 e6bc5c0032e9
permissions -rw-r--r--
Fix bug caused by m4 consuming pairs of square brackets (#108).
deba@2528
     1
/* -*- C++ -*-
deba@2528
     2
 *
deba@2528
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2528
     4
 *
alpar@2553
     5
 * Copyright (C) 2003-2008
deba@2528
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2528
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2528
     8
 *
deba@2528
     9
 * Permission to use, modify and distribute this software is granted
deba@2528
    10
 * provided that this copyright notice appears in all copies. For
deba@2528
    11
 * precise terms see the accompanying LICENSE file.
deba@2528
    12
 *
deba@2528
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2528
    14
 * express or implied, and with no claim as to its suitability for any
deba@2528
    15
 * purpose.
deba@2528
    16
 *
deba@2528
    17
 */
deba@2528
    18
deba@2528
    19
#ifndef LEMON_GOMORY_HU_TREE_H
deba@2528
    20
#define LEMON_GOMORY_HU_TREE_H
deba@2528
    21
deba@2528
    22
#include <lemon/preflow.h>
deba@2528
    23
#include <lemon/concept_check.h>
deba@2528
    24
#include <lemon/concepts/maps.h>
deba@2528
    25
deba@2528
    26
/// \ingroup min_cut
deba@2528
    27
/// \file 
deba@2528
    28
/// \brief Gomory-Hu cut tree in undirected graphs.
deba@2528
    29
deba@2528
    30
namespace lemon {
deba@2528
    31
deba@2528
    32
  /// \ingroup min_cut
deba@2528
    33
  ///
deba@2528
    34
  /// \brief Gomory-Hu cut tree algorithm
deba@2528
    35
  ///
deba@2528
    36
  /// The Gomory-Hu tree is a tree on the nodeset of the graph, but it
deba@2528
    37
  /// may contain edges which are not in the original graph. It helps
deba@2528
    38
  /// to calculate the minimum cut between all pairs of nodes, because
deba@2528
    39
  /// the minimum capacity edge on the tree path between two nodes has
deba@2528
    40
  /// the same weight as the minimum cut in the graph between these
deba@2528
    41
  /// nodes. Moreover this edge separates the nodes to two parts which
deba@2528
    42
  /// determine this minimum cut.
deba@2528
    43
  /// 
deba@2528
    44
  /// The algorithm calculates \e n-1 distinict minimum cuts with
deba@2528
    45
  /// preflow algorithm, therefore the algorithm has
deba@2528
    46
  /// \f$(O(n^3\sqrt{e})\f$ overall time complexity. It calculates a
deba@2528
    47
  /// rooted Gomory-Hu tree, the structure of the tree and the weights
deba@2528
    48
  /// can be obtained with \c predNode() and \c predValue()
deba@2528
    49
  /// functions. The \c minCutValue() and \c minCutMap() calculates
deba@2528
    50
  /// the minimum cut and the minimum cut value between any two node
deba@2528
    51
  /// in the graph.
deba@2528
    52
  template <typename _UGraph, 
deba@2528
    53
	    typename _Capacity = typename _UGraph::template UEdgeMap<int> >
deba@2528
    54
  class GomoryHuTree {
deba@2528
    55
  public:
deba@2528
    56
deba@2528
    57
    /// The undirected graph type
deba@2528
    58
    typedef _UGraph UGraph;
deba@2528
    59
    /// The capacity on undirected edges
deba@2528
    60
    typedef _Capacity Capacity;
deba@2528
    61
    /// The value type of capacities
deba@2528
    62
    typedef typename Capacity::Value Value;
deba@2528
    63
    
deba@2528
    64
  private:
deba@2528
    65
deba@2528
    66
    UGRAPH_TYPEDEFS(typename UGraph);
deba@2528
    67
deba@2528
    68
    const UGraph& _ugraph;
deba@2528
    69
    const Capacity& _capacity;
deba@2528
    70
deba@2528
    71
    Node _root;
deba@2528
    72
    typename UGraph::template NodeMap<Node>* _pred;
deba@2528
    73
    typename UGraph::template NodeMap<Value>* _weight;
deba@2528
    74
    typename UGraph::template NodeMap<int>* _order;
deba@2528
    75
deba@2528
    76
    void createStructures() {
deba@2528
    77
      if (!_pred) {
deba@2528
    78
	_pred = new typename UGraph::template NodeMap<Node>(_ugraph);
deba@2528
    79
      }
deba@2528
    80
      if (!_weight) {
deba@2528
    81
	_weight = new typename UGraph::template NodeMap<Value>(_ugraph);
deba@2528
    82
      }
deba@2528
    83
      if (!_order) {
deba@2528
    84
	_order = new typename UGraph::template NodeMap<int>(_ugraph);
deba@2528
    85
      }
deba@2528
    86
    }
deba@2528
    87
deba@2528
    88
    void destroyStructures() {
deba@2528
    89
      if (_pred) {
deba@2528
    90
	delete _pred;
deba@2528
    91
      }
deba@2528
    92
      if (_weight) {
deba@2528
    93
	delete _weight;
deba@2528
    94
      }
deba@2528
    95
      if (_order) {
deba@2528
    96
	delete _order;
deba@2528
    97
      }
deba@2528
    98
    }
deba@2528
    99
  
deba@2528
   100
  public:
deba@2528
   101
deba@2528
   102
    /// \brief Constructor
deba@2528
   103
    ///
deba@2528
   104
    /// Constructor
deba@2528
   105
    /// \param ugraph The undirected graph type.
deba@2528
   106
    /// \param capacity The capacity map.
deba@2528
   107
    GomoryHuTree(const UGraph& ugraph, const Capacity& capacity) 
deba@2528
   108
      : _ugraph(ugraph), _capacity(capacity),
deba@2528
   109
	_pred(0), _weight(0), _order(0) 
deba@2528
   110
    {
deba@2528
   111
      checkConcept<concepts::ReadMap<UEdge, Value>, Capacity>();
deba@2528
   112
    }
deba@2528
   113
deba@2528
   114
deba@2528
   115
    /// \brief Destructor
deba@2528
   116
    ///
deba@2528
   117
    /// Destructor
deba@2528
   118
    ~GomoryHuTree() {
deba@2528
   119
      destroyStructures();
deba@2528
   120
    }
deba@2528
   121
deba@2528
   122
    /// \brief Initializes the internal data structures.
deba@2528
   123
    ///
deba@2528
   124
    /// Initializes the internal data structures.
deba@2528
   125
    ///
deba@2528
   126
    void init() {
deba@2528
   127
      createStructures();
deba@2528
   128
deba@2528
   129
      _root = NodeIt(_ugraph);
deba@2528
   130
      for (NodeIt n(_ugraph); n != INVALID; ++n) {
deba@2528
   131
	_pred->set(n, _root);
deba@2528
   132
	_order->set(n, -1);
deba@2528
   133
      }
deba@2528
   134
      _pred->set(_root, INVALID);
deba@2528
   135
      _weight->set(_root, std::numeric_limits<Value>::max()); 
deba@2528
   136
    }
deba@2528
   137
deba@2528
   138
deba@2528
   139
    /// \brief Starts the algorithm
deba@2528
   140
    ///
deba@2528
   141
    /// Starts the algorithm.
deba@2528
   142
    void start() {
deba@2528
   143
      Preflow<UGraph, Capacity> fa(_ugraph, _capacity, _root, INVALID);
deba@2528
   144
deba@2528
   145
      for (NodeIt n(_ugraph); n != INVALID; ++n) {
deba@2528
   146
	if (n == _root) continue;
deba@2528
   147
deba@2528
   148
	Node pn = (*_pred)[n];
deba@2528
   149
	fa.source(n);
deba@2528
   150
	fa.target(pn);
deba@2528
   151
deba@2528
   152
	fa.runMinCut();
deba@2528
   153
deba@2528
   154
	_weight->set(n, fa.flowValue());
deba@2528
   155
deba@2528
   156
	for (NodeIt nn(_ugraph); nn != INVALID; ++nn) {
deba@2528
   157
	  if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
deba@2528
   158
	    _pred->set(nn, n);
deba@2528
   159
	  }
deba@2528
   160
	}
deba@2528
   161
	if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
deba@2528
   162
	  _pred->set(n, (*_pred)[pn]);
deba@2528
   163
	  _pred->set(pn, n);
deba@2528
   164
	  _weight->set(n, (*_weight)[pn]);
deba@2528
   165
	  _weight->set(pn, fa.flowValue());	
deba@2528
   166
	}
deba@2528
   167
      }
deba@2528
   168
deba@2528
   169
      _order->set(_root, 0);
deba@2528
   170
      int index = 1;
deba@2528
   171
deba@2528
   172
      for (NodeIt n(_ugraph); n != INVALID; ++n) {
deba@2528
   173
	std::vector<Node> st;
deba@2528
   174
	Node nn = n;
deba@2528
   175
	while ((*_order)[nn] == -1) {
deba@2528
   176
	  st.push_back(nn);
deba@2528
   177
	  nn = (*_pred)[nn];
deba@2528
   178
	}
deba@2528
   179
	while (!st.empty()) {
deba@2528
   180
	  _order->set(st.back(), index++);
deba@2528
   181
	  st.pop_back();
deba@2528
   182
	}
deba@2528
   183
      }
deba@2528
   184
    }
deba@2528
   185
deba@2528
   186
    /// \brief Runs the Gomory-Hu algorithm.  
deba@2528
   187
    ///
deba@2528
   188
    /// Runs the Gomory-Hu algorithm.
deba@2528
   189
    /// \note gh.run() is just a shortcut of the following code.
deba@2528
   190
    /// \code
deba@2528
   191
    ///   ght.init();
deba@2528
   192
    ///   ght.start();
deba@2528
   193
    /// \endcode
deba@2528
   194
    void run() {
deba@2528
   195
      init();
deba@2528
   196
      start();
deba@2528
   197
    }
deba@2528
   198
deba@2528
   199
    /// \brief Returns the predecessor node in the Gomory-Hu tree.
deba@2528
   200
    ///
deba@2528
   201
    /// Returns the predecessor node in the Gomory-Hu tree. If the node is
deba@2528
   202
    /// the root of the Gomory-Hu tree, then it returns \c INVALID.
deba@2528
   203
    Node predNode(const Node& node) {
deba@2528
   204
      return (*_pred)[node];
deba@2528
   205
    }
deba@2528
   206
deba@2528
   207
    /// \brief Returns the weight of the predecessor edge in the
deba@2528
   208
    /// Gomory-Hu tree.
deba@2528
   209
    ///
deba@2528
   210
    /// Returns the weight of the predecessor edge in the Gomory-Hu
deba@2528
   211
    /// tree.  If the node is the root of the Gomory-Hu tree, the
deba@2528
   212
    /// result is undefined.
deba@2528
   213
    Value predValue(const Node& node) {
deba@2528
   214
      return (*_weight)[node];
deba@2528
   215
    }
deba@2528
   216
deba@2528
   217
    /// \brief Returns the minimum cut value between two nodes
deba@2528
   218
    ///
deba@2528
   219
    /// Returns the minimum cut value between two nodes. The
deba@2528
   220
    /// algorithm finds the nearest common ancestor in the Gomory-Hu
deba@2528
   221
    /// tree and calculates the minimum weight edge on the paths to
deba@2528
   222
    /// the ancestor.
deba@2528
   223
    Value minCutValue(const Node& s, const Node& t) const {
deba@2528
   224
      Node sn = s, tn = t;
deba@2528
   225
      Value value = std::numeric_limits<Value>::max();
deba@2528
   226
      
deba@2528
   227
      while (sn != tn) {
deba@2528
   228
	if ((*_order)[sn] < (*_order)[tn]) {
deba@2528
   229
	  if ((*_weight)[tn] < value) value = (*_weight)[tn];
deba@2528
   230
	  tn = (*_pred)[tn];
deba@2528
   231
	} else {
deba@2528
   232
	  if ((*_weight)[sn] < value) value = (*_weight)[sn];
deba@2528
   233
	  sn = (*_pred)[sn];
deba@2528
   234
	}
deba@2528
   235
      }
deba@2528
   236
      return value;
deba@2528
   237
    }
deba@2528
   238
deba@2528
   239
    /// \brief Returns the minimum cut between two nodes
deba@2528
   240
    ///
deba@2528
   241
    /// Returns the minimum cut value between two nodes. The
deba@2528
   242
    /// algorithm finds the nearest common ancestor in the Gomory-Hu
deba@2528
   243
    /// tree and calculates the minimum weight edge on the paths to
deba@2528
   244
    /// the ancestor. Then it sets all nodes to the cut determined by
deba@2528
   245
    /// this edge. The \c cutMap should be \ref concepts::ReadWriteMap
deba@2528
   246
    /// "ReadWriteMap".
deba@2528
   247
    template <typename CutMap>
deba@2528
   248
    Value minCutMap(const Node& s, const Node& t, CutMap& cutMap) const {
deba@2528
   249
      Node sn = s, tn = t;
deba@2528
   250
deba@2528
   251
      Node rn = INVALID;
deba@2528
   252
      Value value = std::numeric_limits<Value>::max();
deba@2528
   253
      
deba@2528
   254
      while (sn != tn) {
deba@2528
   255
	if ((*_order)[sn] < (*_order)[tn]) {
deba@2528
   256
	  if ((*_weight)[tn] < value) {
deba@2528
   257
	    rn = tn;
deba@2528
   258
	    value = (*_weight)[tn];
deba@2528
   259
	  }
deba@2528
   260
	  tn = (*_pred)[tn];
deba@2528
   261
	} else {
deba@2528
   262
	  if ((*_weight)[sn] < value) {
deba@2528
   263
	    rn = sn;
deba@2528
   264
	    value = (*_weight)[sn];
deba@2528
   265
	  }
deba@2528
   266
	  sn = (*_pred)[sn];
deba@2528
   267
	}
deba@2528
   268
      }
deba@2528
   269
deba@2528
   270
      typename UGraph::template NodeMap<bool> reached(_ugraph, false);
deba@2528
   271
      reached.set(_root, true);
deba@2528
   272
      cutMap.set(_root, false);
deba@2528
   273
      reached.set(rn, true);
deba@2528
   274
      cutMap.set(rn, true);
deba@2528
   275
deba@2528
   276
      for (NodeIt n(_ugraph); n != INVALID; ++n) {
deba@2528
   277
	std::vector<Node> st;
deba@2528
   278
	Node nn = n;
deba@2528
   279
	while (!reached[nn]) {
deba@2528
   280
	  st.push_back(nn);
deba@2528
   281
	  nn = (*_pred)[nn];
deba@2528
   282
	}
deba@2528
   283
	while (!st.empty()) {
deba@2528
   284
	  cutMap.set(st.back(), cutMap[nn]);
deba@2528
   285
	  st.pop_back();
deba@2528
   286
	}
deba@2528
   287
      }
deba@2528
   288
      
deba@2528
   289
      return value;
deba@2528
   290
    }
deba@2528
   291
deba@2528
   292
  };
deba@2528
   293
deba@2528
   294
}
deba@2528
   295
deba@2528
   296
#endif