gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Doc improvements in GomoryHu (#66) And make init() and start() private + bug fix in the test file.
0 2 0
default
2 files changed with 59 insertions and 63 deletions:
↑ Collapse diff ↑
Ignore white space 12 line context
... ...
@@ -33,16 +33,16 @@
33 33
namespace lemon {
34 34

	
35 35
  /// \ingroup min_cut
36 36
  ///
37 37
  /// \brief Gomory-Hu cut tree algorithm
38 38
  ///
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
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 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
42
  /// in this tree has the same weight as the minimum cut in the graph
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
  /// 
... ...
@@ -50,28 +50,32 @@
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
  /// 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.
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.
59 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.
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.
63
#ifdef DOXYGEN
63 64
  template <typename GR,
64
	    typename CAP = typename GR::template EdgeMap<int>
65
            >
65
	    typename CAP>
66
#else
67
  template <typename GR,
68
	    typename CAP = typename GR::template EdgeMap<int> >
69
#endif
66 70
  class GomoryHu {
67 71
  public:
68 72

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

	
... ...
@@ -111,14 +115,14 @@
111 115
  
112 116
  public:
113 117

	
114 118
    /// \brief Constructor
115 119
    ///
116 120
    /// Constructor
117
    /// \param graph The graph the algorithm will run on.
118
    /// \param capacity The capacity map.
121
    /// \param graph The undirected graph the algorithm runs on.
122
    /// \param capacity The edge capacity map.
119 123
    GomoryHu(const Graph& graph, const Capacity& capacity) 
120 124
      : _graph(graph), _capacity(capacity),
121 125
	_pred(0), _weight(0), _order(0) 
122 126
    {
123 127
      checkConcept<concepts::ReadMap<Edge, Value>, Capacity>();
124 128
    }
... ...
@@ -128,16 +132,15 @@
128 132
    ///
129 133
    /// Destructor
130 134
    ~GomoryHu() {
131 135
      destroyStructures();
132 136
    }
133 137

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

	
141 144
      _root = NodeIt(_graph);
142 145
      for (NodeIt n(_graph); n != INVALID; ++n) {
143 146
	_pred->set(n, _root);
... ...
@@ -145,18 +148,13 @@
145 148
      }
146 149
      _pred->set(_root, INVALID);
147 150
      _weight->set(_root, std::numeric_limits<Value>::max()); 
148 151
    }
149 152

	
150 153

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

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

	
... ...
@@ -195,12 +193,14 @@
195 193
	  _order->set(st.back(), index++);
196 194
	  st.pop_back();
197 195
	}
198 196
      }
199 197
    }
200 198

	
199
  public:
200

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

	
205 205
    /// \brief Run the Gomory-Hu algorithm.
206 206
    ///
... ...
@@ -212,14 +212,14 @@
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
    ///The \ref run() "run()" should be called before using them.\n
219
    ///See also MinCutNodeIt and MinCutEdgeIt
218
    ///\ref run() "run()" should be called before using them.\n
219
    ///See also \ref MinCutNodeIt and \ref 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.
... ...
@@ -247,13 +247,13 @@
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
    /// tree and calculates the minimum weight arc on the paths to
253
    /// tree and calculates the minimum weight edge 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) {
... ...
@@ -268,27 +268,25 @@
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
    /// the \r cutMap parameter by setting the nodes in the component of
275
    /// \c \s to true and the other nodes to false.
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.
276 276
    ///
277
    /// The \c cutMap should be \ref concepts::ReadWriteMap
278
    /// "ReadWriteMap".
279
    ///
280
    /// For higher level interfaces, see MinCutNodeIt and MinCutEdgeIt
277
    /// For higher level interfaces, see MinCutNodeIt and MinCutEdgeIt.
281 278
    template <typename CutMap>
282
    Value minCutMap(const Node& s, ///< Base node
279
    Value minCutMap(const Node& s, ///< The base node.
283 280
                    const Node& t,
284
                    ///< The node you want to separate from Node s.
281
                    ///< The node you want to separate from node \c s.
285 282
                    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.
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.
289 287
                    ) const {
290 288
      Node sn = s, tn = t;
291 289
      bool s_root=false;
292 290
      Node rn = INVALID;
293 291
      Value value = std::numeric_limits<Value>::max();
294 292
      
... ...
@@ -345,32 +343,32 @@
345 343
    ///
346 344
    /// This example counts the nodes in the minimum cut separating \c s from
347 345
    /// \c t.
348 346
    /// \code
349 347
    /// GomoruHu<Graph> gom(g, capacities);
350 348
    /// gom.run();
351
    /// int sum=0;
352
    /// for(GomoruHu<Graph>::MinCutNodeIt n(gom,s,t);n!=INVALID;++n) ++sum;
349
    /// int cnt=0;
350
    /// for(GomoruHu<Graph>::MinCutNodeIt n(gom,s,t); n!=INVALID; ++n) ++cnt;
353 351
    /// \endcode
354 352
    class MinCutNodeIt
355 353
    {
356 354
      bool _side;
357 355
      typename Graph::NodeIt _node_it;
358 356
      typename Graph::template NodeMap<bool> _cut;
359 357
    public:
360 358
      /// Constructor
361 359

	
362
      /// Constructor
360
      /// Constructor.
363 361
      ///
364 362
      MinCutNodeIt(GomoryHu const &gomory,
365 363
                   ///< The GomoryHu class. You must call its
366 364
                   ///  run() method
367
                   ///  before initializing this iterator
368
                   const Node& s, ///< Base node
365
                   ///  before initializing this iterator.
366
                   const Node& s, ///< The base node.
369 367
                   const Node& t,
370
                   ///< The node you want to separate from Node s.
368
                   ///< The node you want to separate from node \c s.
371 369
                   bool side=true
372 370
                   ///< If it is \c true (default) then the iterator lists
373 371
                   ///  the nodes of the component containing \c s,
374 372
                   ///  otherwise it lists the other component.
375 373
                   /// \note As the minimum cut is not always unique,
376 374
                   /// \code
... ...
@@ -395,37 +393,37 @@
395 393
      {
396 394
        gomory.minCutMap(s,t,_cut);
397 395
        for(_node_it=typename Graph::NodeIt(gomory._graph);
398 396
            _node_it!=INVALID && _cut[_node_it]!=_side;
399 397
            ++_node_it) {}
400 398
      }
401
      /// Conversion to Node
399
      /// Conversion to \c Node
402 400

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

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

	
422
      /// Postfix incrementation
420
      /// Postfix incrementation.
423 421
      ///
424 422
      /// \warning This incrementation
425
      /// returns a \c Node, not a \ref MinCutNodeIt, as one may
423
      /// returns a \c Node, not a \c MinCutNodeIt, as one may
426 424
      /// expect.
427 425
      typename Graph::Node operator++(int)
428 426
      {
429 427
        typename Graph::Node n=*this;
430 428
        ++(*this);
431 429
        return n;
... ...
@@ -443,17 +441,17 @@
443 441
    /// This example computes the value of the minimum cut separating \c s from
444 442
    /// \c t.
445 443
    /// \code
446 444
    /// GomoruHu<Graph> gom(g, capacities);
447 445
    /// gom.run();
448 446
    /// int value=0;
449
    /// for(GomoruHu<Graph>::MinCutEdgeIt e(gom,s,t);e!=INVALID;++e)
447
    /// for(GomoruHu<Graph>::MinCutEdgeIt e(gom,s,t); e!=INVALID; ++e)
450 448
    ///   value+=capacities[e];
451 449
    /// \endcode
452 450
    /// the result will be the same as it is returned by
453
    /// \ref GomoryHu::minCostValue() "gom.minCostValue(s,t)"
451
    /// \ref GomoryHu::minCutValue() "gom.minCutValue(s,t)"
454 452
    class MinCutEdgeIt
455 453
    {
456 454
      bool _side;
457 455
      const Graph &_graph;
458 456
      typename Graph::NodeIt _node_it;
459 457
      typename Graph::OutArcIt _arc_it;
... ...
@@ -470,16 +468,16 @@
470 468
      }
471 469
      
472 470
    public:
473 471
      MinCutEdgeIt(GomoryHu const &gomory,
474 472
                   ///< The GomoryHu class. You must call its
475 473
                   ///  run() method
476
                   ///  before initializing this iterator
477
                   const Node& s,  ///< Base node
474
                   ///  before initializing this iterator.
475
                   const Node& s,  ///< The base node.
478 476
                   const Node& t,
479
                   ///< The node you want to separate from Node s.
477
                   ///< The node you want to separate from node \c s.
480 478
                   bool side=true
481 479
                   ///< If it is \c true (default) then the listed arcs
482 480
                   ///  will be oriented from the
483 481
                   ///  the nodes of the component containing \c s,
484 482
                   ///  otherwise they will be oriented in the opposite
485 483
                   ///  direction.
... ...
@@ -501,47 +499,46 @@
501 499
            for(++_node_it; _node_it!=INVALID&&!_cut[_node_it]; ++_node_it) {}
502 500
            if(_node_it!=INVALID)
503 501
              _arc_it= typename Graph::OutArcIt(_graph,_node_it);
504 502
          }
505 503
        while(_arc_it!=INVALID && _cut[_graph.target(_arc_it)]) step();
506 504
      }
507
      /// Conversion to Arc
505
      /// Conversion to \c Arc
508 506

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

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

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

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

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

	
67 66
  for (NodeIt u(graph); u != INVALID; ++u) {
68 67
    for (NodeIt v(graph); v != u; ++v) {
69 68
      Preflow<Graph, IntEdgeMap> pf(graph, capacity, u, v);
70 69
      pf.runMinCut();
0 comments (0 inline)