gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Remane GomoryHuTree to GomoryHu (#66)
1 2 1
default
4 files changed with 22 insertions and 22 deletions:
↑ Collapse diff ↑
Show white space 384 line context
1 1
EXTRA_DIST += \
2 2
	lemon/lemon.pc.in \
3 3
	lemon/CMakeLists.txt
4 4

	
5 5
pkgconfig_DATA += lemon/lemon.pc
6 6

	
7 7
lib_LTLIBRARIES += lemon/libemon.la
8 8

	
9 9
lemon_libemon_la_SOURCES = \
10 10
	lemon/arg_parser.cc \
11 11
	lemon/base.cc \
12 12
	lemon/color.cc \
13 13
	lemon/lp_base.cc \
14 14
	lemon/lp_skeleton.cc \
15 15
        lemon/random.cc \
16 16
	lemon/bits/windows.cc
17 17

	
18 18

	
19 19
lemon_libemon_la_CXXFLAGS = \
20 20
	$(GLPK_CFLAGS) \
21 21
	$(CPLEX_CFLAGS) \
22 22
	$(SOPLEX_CXXFLAGS) \
23 23
	$(CLP_CXXFLAGS)
24 24

	
25 25
lemon_libemon_la_LDFLAGS = \
26 26
	$(GLPK_LIBS) \
27 27
	$(CPLEX_LIBS) \
28 28
	$(SOPLEX_LIBS) \
29 29
	$(CLP_LIBS)
30 30

	
31 31
if HAVE_GLPK
32 32
lemon_libemon_la_SOURCES += lemon/glpk.cc
33 33
endif
34 34

	
35 35
if HAVE_CPLEX
36 36
lemon_libemon_la_SOURCES += lemon/cplex.cc
37 37
endif
38 38

	
39 39
if HAVE_SOPLEX
40 40
lemon_libemon_la_SOURCES += lemon/soplex.cc
41 41
endif
42 42

	
43 43
if HAVE_CLP
44 44
lemon_libemon_la_SOURCES += lemon/clp.cc
45 45
endif
46 46

	
47 47
lemon_HEADERS += \
48 48
	lemon/adaptors.h \
49 49
	lemon/arg_parser.h \
50 50
	lemon/assert.h \
51 51
	lemon/bfs.h \
52 52
	lemon/bin_heap.h \
53 53
	lemon/circulation.h \
54 54
	lemon/clp.h \
55 55
	lemon/color.h \
56 56
	lemon/concept_check.h \
57 57
	lemon/connectivity.h \
58 58
	lemon/counter.h \
59 59
	lemon/core.h \
60 60
	lemon/cplex.h \
61 61
	lemon/dfs.h \
62 62
	lemon/dijkstra.h \
63 63
	lemon/dim2.h \
64 64
	lemon/dimacs.h \
65 65
	lemon/edge_set.h \
66 66
	lemon/elevator.h \
67 67
	lemon/error.h \
68 68
	lemon/euler.h \
69 69
	lemon/full_graph.h \
70 70
	lemon/glpk.h \
71
	lemon/gomory_hu_tree.h \
71
	lemon/gomory_hu.h \
72 72
	lemon/graph_to_eps.h \
73 73
	lemon/grid_graph.h \
74 74
	lemon/hypercube_graph.h \
75 75
	lemon/kruskal.h \
76 76
	lemon/hao_orlin.h \
77 77
	lemon/lgf_reader.h \
78 78
	lemon/lgf_writer.h \
79 79
	lemon/list_graph.h \
80 80
	lemon/lp.h \
81 81
	lemon/lp_base.h \
82 82
	lemon/lp_skeleton.h \
83 83
	lemon/list_graph.h \
84 84
	lemon/maps.h \
85 85
	lemon/math.h \
86 86
	lemon/max_matching.h \
87 87
	lemon/min_cost_arborescence.h \
88 88
	lemon/nauty_reader.h \
89 89
	lemon/path.h \
90 90
	lemon/preflow.h \
91 91
	lemon/radix_sort.h \
92 92
	lemon/random.h \
93 93
	lemon/smart_graph.h \
94 94
	lemon/soplex.h \
95 95
	lemon/suurballe.h \
96 96
	lemon/time_measure.h \
97 97
	lemon/tolerance.h \
98 98
	lemon/unionfind.h \
99 99
	lemon/bits/windows.h
100 100

	
101 101
bits_HEADERS += \
102 102
	lemon/bits/alteration_notifier.h \
103 103
	lemon/bits/array_map.h \
104 104
	lemon/bits/base_extender.h \
105 105
	lemon/bits/bezier.h \
106 106
	lemon/bits/default_map.h \
107 107
	lemon/bits/edge_set_extender.h \
108 108
	lemon/bits/enable_if.h \
109 109
	lemon/bits/graph_adaptor_extender.h \
110 110
	lemon/bits/graph_extender.h \
111 111
	lemon/bits/map_extender.h \
112 112
	lemon/bits/path_dump.h \
113 113
	lemon/bits/solver_bits.h \
114 114
	lemon/bits/traits.h \
115 115
	lemon/bits/variant.h \
116 116
	lemon/bits/vector_map.h
117 117

	
118 118
concept_HEADERS += \
119 119
	lemon/concepts/digraph.h \
120 120
	lemon/concepts/graph.h \
121 121
	lemon/concepts/graph_components.h \
122 122
	lemon/concepts/heap.h \
123 123
	lemon/concepts/maps.h \
124 124
	lemon/concepts/path.h
Show white space 384 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_GOMORY_HU_TREE_H
20 20
#define LEMON_GOMORY_HU_TREE_H
21 21

	
22 22
#include <limits>
23 23

	
24 24
#include <lemon/core.h>
25 25
#include <lemon/preflow.h>
26 26
#include <lemon/concept_check.h>
27 27
#include <lemon/concepts/maps.h>
28 28

	
29 29
/// \ingroup min_cut
30 30
/// \file 
31 31
/// \brief Gomory-Hu cut tree in graphs.
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  /// \ingroup min_cut
36 36
  ///
37 37
  /// \brief Gomory-Hu cut tree algorithm
38 38
  ///
39 39
  /// The Gomory-Hu tree is a tree on the node set of the graph, but it
40 40
  /// may contain edges which are not in the original digraph. It has the
41 41
  /// property that the minimum capacity edge of the path between two nodes 
42 42
  /// in this tree has the same weight as the minimum cut in the digraph
43 43
  /// between these nodes. Moreover the components obtained by removing
44 44
  /// this edge from the tree determine the corresponding minimum cut.
45 45
  ///
46 46
  /// Therefore once this tree is computed, the minimum cut between any pair
47 47
  /// of nodes can easily be obtained.
48 48
  /// 
49 49
  /// The algorithm calculates \e n-1 distinct minimum cuts (currently with
50 50
  /// the \ref Preflow algorithm), therefore the algorithm has
51 51
  /// \f$(O(n^3\sqrt{e})\f$ overall time complexity. It calculates a
52 52
  /// rooted Gomory-Hu tree, its structure and the weights can be obtained
53 53
  /// by \c predNode(), \c predValue() and \c rootDist().
54 54
  /// 
55 55
  /// The members \c minCutMap() and \c minCutValue() calculate
56 56
  /// the minimum cut and the minimum cut value between any two node
57 57
  /// in the digraph. You can also list (iterate on) the nodes and the
58 58
  /// edges of the cuts using MinCutNodeIt and MinCutEdgeIt.
59 59
  ///
60 60
  /// \tparam GR The undirected graph data structure the algorithm will run on
61 61
  /// \tparam CAP type of the EdgeMap describing the Edge capacities.
62 62
  /// it is typename GR::template EdgeMap<int> by default.
63 63
  template <typename GR,
64 64
	    typename CAP = typename GR::template EdgeMap<int>
65 65
            >
66
  class GomoryHuTree {
66
  class GomoryHu {
67 67
  public:
68 68

	
69 69
    /// The graph type
70 70
    typedef GR Graph;
71 71
    /// The type if the edge capacity map
72 72
    typedef CAP Capacity;
73 73
    /// The value type of capacities
74 74
    typedef typename Capacity::Value Value;
75 75
    
76 76
  private:
77 77

	
78 78
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
79 79

	
80 80
    const Graph& _graph;
81 81
    const Capacity& _capacity;
82 82

	
83 83
    Node _root;
84 84
    typename Graph::template NodeMap<Node>* _pred;
85 85
    typename Graph::template NodeMap<Value>* _weight;
86 86
    typename Graph::template NodeMap<int>* _order;
87 87

	
88 88
    void createStructures() {
89 89
      if (!_pred) {
90 90
	_pred = new typename Graph::template NodeMap<Node>(_graph);
91 91
      }
92 92
      if (!_weight) {
93 93
	_weight = new typename Graph::template NodeMap<Value>(_graph);
94 94
      }
95 95
      if (!_order) {
96 96
	_order = new typename Graph::template NodeMap<int>(_graph);
97 97
      }
98 98
    }
99 99

	
100 100
    void destroyStructures() {
101 101
      if (_pred) {
102 102
	delete _pred;
103 103
      }
104 104
      if (_weight) {
105 105
	delete _weight;
106 106
      }
107 107
      if (_order) {
108 108
	delete _order;
109 109
      }
110 110
    }
111 111
  
112 112
  public:
113 113

	
114 114
    /// \brief Constructor
115 115
    ///
116 116
    /// Constructor
117 117
    /// \param graph The graph the algorithm will run on.
118 118
    /// \param capacity The capacity map.
119
    GomoryHuTree(const Graph& graph, const Capacity& capacity) 
119
    GomoryHu(const Graph& graph, const Capacity& capacity) 
120 120
      : _graph(graph), _capacity(capacity),
121 121
	_pred(0), _weight(0), _order(0) 
122 122
    {
123 123
      checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
124 124
    }
125 125

	
126 126

	
127 127
    /// \brief Destructor
128 128
    ///
129 129
    /// Destructor
130
    ~GomoryHuTree() {
130
    ~GomoryHu() {
131 131
      destroyStructures();
132 132
    }
133 133

	
134 134
    // \brief Initialize the internal data structures.
135 135
    //
136 136
    // This function initializes the internal data structures.
137 137
    //
138 138
    void init() {
139 139
      createStructures();
140 140

	
141 141
      _root = NodeIt(_graph);
142 142
      for (NodeIt n(_graph); n != INVALID; ++n) {
143 143
	_pred->set(n, _root);
144 144
	_order->set(n, -1);
145 145
      }
146 146
      _pred->set(_root, INVALID);
147 147
      _weight->set(_root, std::numeric_limits<Value>::max()); 
148 148
    }
149 149

	
150 150

	
151 151
    // \brief Start the algorithm
152 152
    //
153 153
    // This function starts the algorithm.
154 154
    //
155 155
    // \pre \ref init() must be called before using this function.
156 156
    //
157 157
    void start() {
158 158
      Preflow<Graph, Capacity> fa(_graph, _capacity, _root, INVALID);
159 159

	
160 160
      for (NodeIt n(_graph); n != INVALID; ++n) {
161 161
	if (n == _root) continue;
162 162

	
163 163
	Node pn = (*_pred)[n];
164 164
	fa.source(n);
165 165
	fa.target(pn);
166 166

	
167 167
	fa.runMinCut();
168 168

	
169 169
	_weight->set(n, fa.flowValue());
170 170

	
171 171
	for (NodeIt nn(_graph); nn != INVALID; ++nn) {
172 172
	  if (nn != n && fa.minCut(nn) && (*_pred)[nn] == pn) {
173 173
	    _pred->set(nn, n);
174 174
	  }
175 175
	}
176 176
	if ((*_pred)[pn] != INVALID && fa.minCut((*_pred)[pn])) {
177 177
	  _pred->set(n, (*_pred)[pn]);
178 178
	  _pred->set(pn, n);
179 179
	  _weight->set(n, (*_weight)[pn]);
180 180
	  _weight->set(pn, fa.flowValue());	
181 181
	}
182 182
      }
183 183

	
184 184
      _order->set(_root, 0);
185 185
      int index = 1;
186 186

	
187 187
      for (NodeIt n(_graph); n != INVALID; ++n) {
188 188
	std::vector<Node> st;
189 189
	Node nn = n;
190 190
	while ((*_order)[nn] == -1) {
191 191
	  st.push_back(nn);
192 192
	  nn = (*_pred)[nn];
193 193
	}
194 194
	while (!st.empty()) {
195 195
	  _order->set(st.back(), index++);
196 196
	  st.pop_back();
197 197
	}
198 198
      }
199 199
    }
200 200

	
201 201
    ///\name Execution Control
202 202
 
203 203
    ///@{
204 204

	
205 205
    /// \brief Run the Gomory-Hu algorithm.
206 206
    ///
207 207
    /// This function runs the Gomory-Hu algorithm.
208 208
    void run() {
209 209
      init();
210 210
      start();
211 211
    }
212 212
    
213 213
    /// @}
214 214

	
215 215
    ///\name Query Functions
216 216
    ///The results of the algorithm can be obtained using these
217 217
    ///functions.\n
218 218
    ///The \ref run() "run()" should be called before using them.\n
219 219
    ///See also MinCutNodeIt and MinCutEdgeIt
220 220

	
221 221
    ///@{
222 222

	
223 223
    /// \brief Return the predecessor node in the Gomory-Hu tree.
224 224
    ///
225 225
    /// This function returns the predecessor node in the Gomory-Hu tree.
226 226
    /// If the node is
227 227
    /// the root of the Gomory-Hu tree, then it returns \c INVALID.
228 228
    Node predNode(const Node& node) {
229 229
      return (*_pred)[node];
230 230
    }
231 231

	
232 232
    /// \brief Return the distance from the root node in the Gomory-Hu tree.
233 233
    ///
234 234
    /// This function returns the distance of \c node from the root node
235 235
    /// in the Gomory-Hu tree.
236 236
    int rootDist(const Node& node) {
237 237
      return (*_order)[node];
238 238
    }
239 239

	
240 240
    /// \brief Return the weight of the predecessor edge in the
241 241
    /// Gomory-Hu tree.
242 242
    ///
243 243
    /// This function returns the weight of the predecessor edge in the
244 244
    /// Gomory-Hu tree.  If the node is the root, the result is undefined.
245 245
    Value predValue(const Node& node) {
246 246
      return (*_weight)[node];
247 247
    }
248 248

	
249 249
    /// \brief Return the minimum cut value between two nodes
250 250
    ///
251 251
    /// This function returns the minimum cut value between two nodes. The
252 252
    /// algorithm finds the nearest common ancestor in the Gomory-Hu
253 253
    /// tree and calculates the minimum weight arc on the paths to
254 254
    /// the ancestor.
255 255
    Value minCutValue(const Node& s, const Node& t) const {
256 256
      Node sn = s, tn = t;
257 257
      Value value = std::numeric_limits<Value>::max();
258 258
      
259 259
      while (sn != tn) {
260 260
	if ((*_order)[sn] < (*_order)[tn]) {
261 261
	  if ((*_weight)[tn] <= value) value = (*_weight)[tn];
262 262
	  tn = (*_pred)[tn];
263 263
	} else {
264 264
	  if ((*_weight)[sn] <= value) value = (*_weight)[sn];
265 265
	  sn = (*_pred)[sn];
266 266
	}
267 267
      }
268 268
      return value;
269 269
    }
270 270

	
271 271
    /// \brief Return the minimum cut between two nodes
272 272
    ///
273 273
    /// This function returns the minimum cut between the nodes \c s and \c t
274 274
    /// the \r cutMap parameter by setting the nodes in the component of
275 275
    /// \c \s to true and the other nodes to false.
276 276
    ///
277 277
    /// The \c cutMap should be \ref concepts::ReadWriteMap
278 278
    /// "ReadWriteMap".
279 279
    ///
280 280
    /// For higher level interfaces, see MinCutNodeIt and MinCutEdgeIt
281 281
    template <typename CutMap>
282 282
    Value minCutMap(const Node& s, ///< Base node
283 283
                    const Node& t,
284 284
                    ///< The node you want to separate from Node s.
285 285
                    CutMap& cutMap
286 286
                    ///< The cut will be return in this map.
287 287
                    /// It must be a \c bool \ref concepts::ReadWriteMap
288 288
                    /// "ReadWriteMap" on the graph nodes.
289 289
                    ) const {
290 290
      Node sn = s, tn = t;
291 291
      bool s_root=false;
292 292
      Node rn = INVALID;
293 293
      Value value = std::numeric_limits<Value>::max();
294 294
      
295 295
      while (sn != tn) {
296 296
	if ((*_order)[sn] < (*_order)[tn]) {
297 297
	  if ((*_weight)[tn] <= value) {
298 298
	    rn = tn;
299 299
            s_root = false;
300 300
	    value = (*_weight)[tn];
301 301
	  }
302 302
	  tn = (*_pred)[tn];
303 303
	} else {
304 304
	  if ((*_weight)[sn] <= value) {
305 305
	    rn = sn;
306 306
            s_root = true;
307 307
	    value = (*_weight)[sn];
308 308
	  }
309 309
	  sn = (*_pred)[sn];
310 310
	}
311 311
      }
312 312

	
313 313
      typename Graph::template NodeMap<bool> reached(_graph, false);
314 314
      reached.set(_root, true);
315 315
      cutMap.set(_root, !s_root);
316 316
      reached.set(rn, true);
317 317
      cutMap.set(rn, s_root);
318 318

	
319 319
      std::vector<Node> st;
320 320
      for (NodeIt n(_graph); n != INVALID; ++n) {
321 321
	st.clear();
322 322
        Node nn = n;
323 323
	while (!reached[nn]) {
324 324
	  st.push_back(nn);
325 325
	  nn = (*_pred)[nn];
326 326
	}
327 327
	while (!st.empty()) {
328 328
	  cutMap.set(st.back(), cutMap[nn]);
329 329
	  st.pop_back();
330 330
	}
331 331
      }
332 332
      
333 333
      return value;
334 334
    }
335 335

	
336 336
    ///@}
337 337

	
338 338
    friend class MinCutNodeIt;
339 339

	
340 340
    /// Iterate on the nodes of a minimum cut
341 341
    
342 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.
343
    /// GomoryHu. Before using it, you must allocate a GomoryHu class,
344
    /// and call its \ref GomoryHu::run() "run()" method.
345 345
    ///
346 346
    /// This example counts the nodes in the minimum cut separating \c s from
347 347
    /// \c t.
348 348
    /// \code
349
    /// GomoruHuTree<Graph> gom(g, capacities);
349
    /// GomoruHu<Graph> gom(g, capacities);
350 350
    /// gom.run();
351 351
    /// int sum=0;
352
    /// for(GomoruHuTree<Graph>::MinCutNodeIt n(gom,s,t);n!=INVALID;++n) ++sum;
352
    /// for(GomoruHu<Graph>::MinCutNodeIt n(gom,s,t);n!=INVALID;++n) ++sum;
353 353
    /// \endcode
354 354
    class MinCutNodeIt
355 355
    {
356 356
      bool _side;
357 357
      typename Graph::NodeIt _node_it;
358 358
      typename Graph::template NodeMap<bool> _cut;
359 359
    public:
360 360
      /// Constructor
361 361

	
362 362
      /// Constructor
363 363
      ///
364
      MinCutNodeIt(GomoryHuTree const &gomory,
365
                   ///< The GomoryHuTree class. You must call its
364
      MinCutNodeIt(GomoryHu const &gomory,
365
                   ///< The GomoryHu class. You must call its
366 366
                   ///  run() method
367 367
                   ///  before initializing this iterator
368 368
                   const Node& s, ///< Base node
369 369
                   const Node& t,
370 370
                   ///< The node you want to separate from Node s.
371 371
                   bool side=true
372 372
                   ///< If it is \c true (default) then the iterator lists
373 373
                   ///  the nodes of the component containing \c s,
374 374
                   ///  otherwise it lists the other component.
375 375
                   /// \note As the minimum cut is not always unique,
376 376
                   /// \code
377 377
                   /// MinCutNodeIt(gomory, s, t, true);
378 378
                   /// \endcode
379 379
                   /// and
380 380
                   /// \code
381 381
                   /// MinCutNodeIt(gomory, t, s, false);
382 382
                   /// \endcode
383 383
                   /// does not necessarily give the same set of nodes.
384 384
                   /// However it is ensured that
385 385
                   /// \code
386 386
                   /// MinCutNodeIt(gomory, s, t, true);
387 387
                   /// \endcode
388 388
                   /// and
389 389
                   /// \code
390 390
                   /// MinCutNodeIt(gomory, s, t, false);
391 391
                   /// \endcode
392 392
                   /// together list each node exactly once.
393 393
                   )
394 394
        : _side(side), _cut(gomory._graph)
395 395
      {
396 396
        gomory.minCutMap(s,t,_cut);
397 397
        for(_node_it=typename Graph::NodeIt(gomory._graph);
398 398
            _node_it!=INVALID && _cut[_node_it]!=_side;
399 399
            ++_node_it) {}
400 400
      }
401 401
      /// Conversion to Node
402 402

	
403 403
      /// Conversion to Node
404 404
      ///
405 405
      operator typename Graph::Node() const
406 406
      {
407 407
        return _node_it;
408 408
      }
409 409
      bool operator==(Invalid) { return _node_it==INVALID; }
410 410
      bool operator!=(Invalid) { return _node_it!=INVALID; }
411 411
      /// Next node
412 412

	
413 413
      /// Next node
414 414
      ///
415 415
      MinCutNodeIt &operator++()
416 416
      {
417 417
        for(++_node_it;_node_it!=INVALID&&_cut[_node_it]!=_side;++_node_it) {}
418 418
        return *this;
419 419
      }
420 420
      /// Postfix incrementation
421 421

	
422 422
      /// Postfix incrementation
423 423
      ///
424 424
      /// \warning This incrementation
425 425
      /// returns a \c Node, not a \ref MinCutNodeIt, as one may
426 426
      /// expect.
427 427
      typename Graph::Node operator++(int)
428 428
      {
429 429
        typename Graph::Node n=*this;
430 430
        ++(*this);
431 431
        return n;
432 432
      }
433 433
    };
434 434
    
435 435
    friend class MinCutEdgeIt;
436 436
    
437 437
    /// Iterate on the edges of a minimum cut
438 438
    
439 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.
440
    /// GomoryHu. Before using it, you must allocate a GomoryHu class,
441
    /// and call its \ref GomoryHu::run() "run()" method.
442 442
    ///
443 443
    /// This example computes the value of the minimum cut separating \c s from
444 444
    /// \c t.
445 445
    /// \code
446
    /// GomoruHuTree<Graph> gom(g, capacities);
446
    /// GomoruHu<Graph> gom(g, capacities);
447 447
    /// gom.run();
448 448
    /// int value=0;
449
    /// for(GomoruHuTree<Graph>::MinCutEdgeIt e(gom,s,t);e!=INVALID;++e)
449
    /// for(GomoruHu<Graph>::MinCutEdgeIt e(gom,s,t);e!=INVALID;++e)
450 450
    ///   value+=capacities[e];
451 451
    /// \endcode
452 452
    /// the result will be the same as it is returned by
453
    /// \ref GomoryHuTree::minCostValue() "gom.minCostValue(s,t)"
453
    /// \ref GomoryHu::minCostValue() "gom.minCostValue(s,t)"
454 454
    class MinCutEdgeIt
455 455
    {
456 456
      bool _side;
457 457
      const Graph &_graph;
458 458
      typename Graph::NodeIt _node_it;
459 459
      typename Graph::OutArcIt _arc_it;
460 460
      typename Graph::template NodeMap<bool> _cut;
461 461
      void step()
462 462
      {
463 463
        ++_arc_it;
464 464
        while(_node_it!=INVALID && _arc_it==INVALID)
465 465
          {
466 466
            for(++_node_it;_node_it!=INVALID&&!_cut[_node_it];++_node_it) {}
467 467
            if(_node_it!=INVALID)
468 468
              _arc_it=typename Graph::OutArcIt(_graph,_node_it);
469 469
          }
470 470
      }
471 471
      
472 472
    public:
473
      MinCutEdgeIt(GomoryHuTree const &gomory,
474
                   ///< The GomoryHuTree class. You must call its
473
      MinCutEdgeIt(GomoryHu const &gomory,
474
                   ///< The GomoryHu class. You must call its
475 475
                   ///  run() method
476 476
                   ///  before initializing this iterator
477 477
                   const Node& s,  ///< Base node
478 478
                   const Node& t,
479 479
                   ///< The node you want to separate from Node s.
480 480
                   bool side=true
481 481
                   ///< If it is \c true (default) then the listed arcs
482 482
                   ///  will be oriented from the
483 483
                   ///  the nodes of the component containing \c s,
484 484
                   ///  otherwise they will be oriented in the opposite
485 485
                   ///  direction.
486 486
                   )
487 487
        : _graph(gomory._graph), _cut(_graph)
488 488
      {
489 489
        gomory.minCutMap(s,t,_cut);
490 490
        if(!side)
491 491
          for(typename Graph::NodeIt n(_graph);n!=INVALID;++n)
492 492
            _cut[n]=!_cut[n];
493 493

	
494 494
        for(_node_it=typename Graph::NodeIt(_graph);
495 495
            _node_it!=INVALID && !_cut[_node_it];
496 496
            ++_node_it) {}
497 497
        _arc_it = _node_it!=INVALID ?
498 498
          typename Graph::OutArcIt(_graph,_node_it) : INVALID;
499 499
        while(_node_it!=INVALID && _arc_it == INVALID)
500 500
          {
501 501
            for(++_node_it; _node_it!=INVALID&&!_cut[_node_it]; ++_node_it) {}
502 502
            if(_node_it!=INVALID)
503 503
              _arc_it= typename Graph::OutArcIt(_graph,_node_it);
504 504
          }
505 505
        while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
506 506
      }
507 507
      /// Conversion to Arc
508 508

	
509 509
      /// Conversion to Arc
510 510
      ///
511 511
      operator typename Graph::Arc() const
512 512
      {
513 513
        return _arc_it;
514 514
      }
515 515
      /// Conversion to Edge
516 516

	
517 517
      /// Conversion to Edge
518 518
      ///
519 519
      operator typename Graph::Edge() const
520 520
      {
521 521
        return _arc_it;
522 522
      }
523 523
      bool operator==(Invalid) { return _node_it==INVALID; }
524 524
      bool operator!=(Invalid) { return _node_it!=INVALID; }
525 525
      /// Next edge
526 526

	
527 527
      /// Next edge
528 528
      ///
529 529
      MinCutEdgeIt &operator++()
530 530
      {
531 531
        step();
532 532
        while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
533 533
        return *this;
534 534
      }
535 535
      /// Postfix incrementation
536 536
      
537 537
      /// Postfix incrementation
538 538
      ///
539 539
      /// \warning This incrementation
540 540
      /// returns a \c Arc, not a \ref MinCutEdgeIt, as one may
541 541
      /// expect.
542 542
      typename Graph::Arc operator++(int)
543 543
      {
544 544
        typename Graph::Arc e=*this;
545 545
        ++(*this);
546 546
        return e;
547 547
      }
548 548
    };
549 549

	
550 550
  };
551 551

	
552 552
}
553 553

	
554 554
#endif
Show white space 384 line context
1 1
#include <iostream>
2 2

	
3 3
#include "test_tools.h"
4 4
#include <lemon/smart_graph.h>
5 5
#include <lemon/lgf_reader.h>
6
#include <lemon/gomory_hu_tree.h>
6
#include <lemon/gomory_hu.h>
7 7
#include <cstdlib>
8 8

	
9 9
using namespace std;
10 10
using namespace lemon;
11 11

	
12 12
typedef SmartGraph Graph;
13 13

	
14 14
char test_lgf[] =
15 15
  "@nodes\n"
16 16
  "label\n"
17 17
  "0\n"
18 18
  "1\n"
19 19
  "2\n"
20 20
  "3\n"
21 21
  "4\n"
22 22
  "@arcs\n"
23 23
  "     label capacity\n"
24 24
  "0 1  0     1\n"
25 25
  "1 2  1     1\n"
26 26
  "2 3  2     1\n"
27 27
  "0 3  4     5\n"
28 28
  "0 3  5     10\n"
29 29
  "0 3  6     7\n"
30 30
  "4 2  7     1\n"
31 31
  "@attributes\n"
32 32
  "source 0\n"
33 33
  "target 3\n";
34 34
  
35 35
GRAPH_TYPEDEFS(Graph);
36 36
typedef Graph::EdgeMap<int> IntEdgeMap;
37 37
typedef Graph::NodeMap<bool> BoolNodeMap;
38 38

	
39 39
int cutValue(const Graph& graph, const BoolNodeMap& cut,
40 40
	     const IntEdgeMap& capacity) {
41 41

	
42 42
  int sum = 0;
43 43
  for (EdgeIt e(graph); e != INVALID; ++e) {
44 44
    Node s = graph.u(e);
45 45
    Node t = graph.v(e);
46 46

	
47 47
    if (cut[s] != cut[t]) {
48 48
      sum += capacity[e];
49 49
    }
50 50
  }
51 51
  return sum;
52 52
}
53 53

	
54 54

	
55 55
int main() {
56 56
  Graph graph;
57 57
  IntEdgeMap capacity(graph);
58 58

	
59 59
  std::istringstream input(test_lgf);
60 60
  GraphReader<Graph>(graph, input).
61 61
    edgeMap("capacity", capacity).run();
62 62

	
63
  GomoryHuTree<Graph> ght(graph, capacity);
63
  GomoryHu<Graph> ght(graph, capacity);
64 64
  ght.init();
65 65
  ght.run();
66 66

	
67 67
  for (NodeIt u(graph); u != INVALID; ++u) {
68 68
    for (NodeIt v(graph); v != u; ++v) {
69 69
      Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
70 70
      pf.runMinCut();
71 71
      BoolNodeMap cm(graph);
72 72
      ght.minCutMap(u, v, cm);
73 73
      check(pf.flowValue() == ght.minCutValue(u, v), "Wrong cut 1");
74 74
      check(cm[u] != cm[v], "Wrong cut 3");
75 75
      check(pf.flowValue() == cutValue(graph, cm, capacity), "Wrong cut 2");
76 76

	
77 77
      int sum=0;
78
      for(GomoryHuTree<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
78
      for(GomoryHu<Graph>::MinCutEdgeIt a(ght, u, v);a!=INVALID;++a)
79 79
        sum+=capacity[a]; 
80 80
      check(sum == ght.minCutValue(u, v), "Problem with MinCutEdgeIt");
81 81

	
82 82
      sum=0;
83
      for(GomoryHuTree<Graph>::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n)
83
      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,true);n!=INVALID;++n)
84 84
        sum++;
85
      for(GomoryHuTree<Graph>::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n)
85
      for(GomoryHu<Graph>::MinCutNodeIt n(ght, u, v,false);n!=INVALID;++n)
86 86
        sum++;
87 87
      check(sum == countNodes(graph), "Problem with MinCutNodeIt");
88 88
      
89 89
    }
90 90
  }
91 91
  
92 92
  return 0;
93 93
}
0 comments (0 inline)