lemon/hao_orlin.h
author athos
Mon, 02 Oct 2006 11:18:30 +0000
changeset 2226 0411ac8a2d87
parent 2211 c790d04e192a
child 2228 f71b0f9a7c3a
permissions -rw-r--r--
MIP interface tested (and corrected) for cplex 9.0
deba@2211
     1
/* -*- C++ -*-
deba@2211
     2
 *
deba@2225
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2225
     4
 *
deba@2225
     5
 * Copyright (C) 2003-2006
deba@2225
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2211
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2211
     8
 *
deba@2211
     9
 * Permission to use, modify and distribute this software is granted
deba@2211
    10
 * provided that this copyright notice appears in all copies. For
deba@2211
    11
 * precise terms see the accompanying LICENSE file.
deba@2211
    12
 *
deba@2211
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2211
    14
 * express or implied, and with no claim as to its suitability for any
deba@2211
    15
 * purpose.
deba@2211
    16
 *
deba@2211
    17
 */
deba@2211
    18
deba@2211
    19
#ifndef LEMON_HAO_ORLIN_H
deba@2211
    20
#define LEMON_HAO_ORLIN_H
deba@2211
    21
deba@2211
    22
#include <vector>
deba@2211
    23
#include <queue>
deba@2211
    24
#include <limits>
deba@2211
    25
deba@2211
    26
#include <lemon/maps.h>
deba@2211
    27
#include <lemon/graph_utils.h>
deba@2211
    28
#include <lemon/graph_adaptor.h>
deba@2211
    29
#include <lemon/iterable_maps.h>
deba@2211
    30
 
deba@2211
    31
deba@2211
    32
/// \file
deba@2211
    33
/// \ingroup flowalgs
deba@2225
    34
/// \brief Implementation of the Hao-Orlin algorithm.
deba@2225
    35
///
deba@2225
    36
/// Implementation of the HaoOrlin algorithms class for testing network 
deba@2211
    37
/// reliability.
deba@2211
    38
deba@2211
    39
namespace lemon {
deba@2211
    40
deba@2225
    41
  /// \ingroup flowalgs
deba@2225
    42
  ///
deba@2225
    43
  /// \brief %Hao-Orlin algorithm for calculate minimum cut in directed graphs.
deba@2211
    44
  ///
deba@2211
    45
  /// Hao-Orlin calculates the minimum cut in directed graphs. It
deba@2225
    46
  /// separates the nodes of the graph into two disjoint sets, 
deba@2225
    47
  /// \f$ V_{out} \f$ and \f$ V_{in} \f$. This separation is the minimum
deba@2225
    48
  /// cut if the summary of the edge capacities which source is in
deba@2225
    49
  /// \f$ V_{out} \f$ and the target is in \f$ V_{in} \f$ is the
deba@2225
    50
  /// minimum.  The algorithm is a modified push-relabel preflow
deba@2225
    51
  /// algorithm and it calculates the minimum cut in \f$ O(n^3) \f$
deba@2225
    52
  /// time. The purpose of such algorithm is testing network
deba@2225
    53
  /// reliability. For sparse undirected graph you can use the
deba@2225
    54
  /// algorithm of Nagamochi and Ibaraki which solves the undirected
deba@2225
    55
  /// problem in \f$ O(ne + n^2 \log(n)) \f$ time and it is implemented in the
deba@2225
    56
  /// MinCut algorithm class.
deba@2225
    57
  ///
deba@2225
    58
  /// \param _Graph is the graph type of the algorithm.
deba@2225
    59
  /// \param _CapacityMap is an edge map of capacities which should
deba@2225
    60
  /// be any numreric type. The default type is _Graph::EdgeMap<int>.
deba@2225
    61
  /// \param _Tolerance is the handler of the inexact computation. The
deba@2225
    62
  /// default type for it is Tolerance<typename CapacityMap::Value>.
deba@2211
    63
  ///
deba@2211
    64
  /// \author Attila Bernath and Balazs Dezso
deba@2225
    65
#ifdef DOXYGEN
deba@2225
    66
  template <typename _Graph, typename _CapacityMap, typename _Tolerance>
deba@2225
    67
#else
deba@2211
    68
  template <typename _Graph,
deba@2211
    69
	    typename _CapacityMap = typename _Graph::template EdgeMap<int>,
deba@2211
    70
            typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
deba@2225
    71
#endif
deba@2211
    72
  class HaoOrlin {
deba@2211
    73
  protected:
deba@2211
    74
deba@2211
    75
    typedef _Graph Graph;
deba@2211
    76
    typedef _CapacityMap CapacityMap;
deba@2211
    77
    typedef _Tolerance Tolerance;
deba@2211
    78
deba@2211
    79
    typedef typename CapacityMap::Value Value;
deba@2211
    80
deba@2211
    81
    
deba@2211
    82
    typedef typename Graph::Node Node;
deba@2211
    83
    typedef typename Graph::NodeIt NodeIt;
deba@2211
    84
    typedef typename Graph::EdgeIt EdgeIt;
deba@2211
    85
    typedef typename Graph::OutEdgeIt OutEdgeIt;
deba@2211
    86
    typedef typename Graph::InEdgeIt InEdgeIt;
deba@2211
    87
deba@2211
    88
    const Graph* _graph;
deba@2225
    89
deba@2211
    90
    const CapacityMap* _capacity;
deba@2211
    91
deba@2211
    92
    typedef typename Graph::template EdgeMap<Value> FlowMap;
deba@2211
    93
deba@2211
    94
    FlowMap* _preflow;
deba@2211
    95
deba@2211
    96
    Node _source, _target;
deba@2211
    97
    int _node_num;
deba@2211
    98
deba@2211
    99
    typedef ResGraphAdaptor<const Graph, Value, CapacityMap, 
deba@2225
   100
                            FlowMap, Tolerance> OutResGraph;
deba@2225
   101
    typedef typename OutResGraph::Edge OutResEdge;
deba@2225
   102
    
deba@2225
   103
    OutResGraph* _out_res_graph;
deba@2211
   104
deba@2225
   105
    typedef typename Graph::template NodeMap<OutResEdge> OutCurrentEdgeMap;
deba@2225
   106
    OutCurrentEdgeMap* _out_current_edge;  
deba@2211
   107
deba@2225
   108
    typedef RevGraphAdaptor<const Graph> RevGraph;
deba@2225
   109
    RevGraph* _rev_graph;
deba@2225
   110
deba@2225
   111
    typedef ResGraphAdaptor<const RevGraph, Value, CapacityMap, 
deba@2225
   112
                            FlowMap, Tolerance> InResGraph;
deba@2225
   113
    typedef typename InResGraph::Edge InResEdge;
deba@2225
   114
    
deba@2225
   115
    InResGraph* _in_res_graph;
deba@2225
   116
deba@2225
   117
    typedef typename Graph::template NodeMap<InResEdge> InCurrentEdgeMap;
deba@2225
   118
    InCurrentEdgeMap* _in_current_edge;  
deba@2211
   119
deba@2211
   120
deba@2211
   121
    typedef IterableBoolMap<Graph, Node> WakeMap;
deba@2211
   122
    WakeMap* _wake;
deba@2211
   123
deba@2211
   124
    typedef typename Graph::template NodeMap<int> DistMap;
deba@2211
   125
    DistMap* _dist;  
deba@2211
   126
    
deba@2211
   127
    typedef typename Graph::template NodeMap<Value> ExcessMap;
deba@2211
   128
    ExcessMap* _excess;
deba@2211
   129
deba@2211
   130
    typedef typename Graph::template NodeMap<bool> SourceSetMap;
deba@2211
   131
    SourceSetMap* _source_set;
deba@2211
   132
deba@2211
   133
    std::vector<int> _level_size;
deba@2211
   134
deba@2211
   135
    int _highest_active;
deba@2211
   136
    std::vector<std::list<Node> > _active_nodes;
deba@2211
   137
deba@2211
   138
    int _dormant_max;
deba@2211
   139
    std::vector<std::list<Node> > _dormant;
deba@2211
   140
deba@2211
   141
deba@2211
   142
    Value _min_cut;
deba@2211
   143
deba@2211
   144
    typedef typename Graph::template NodeMap<bool> MinCutMap;
deba@2211
   145
    MinCutMap* _min_cut_map;
deba@2211
   146
deba@2211
   147
    Tolerance _tolerance;
deba@2211
   148
deba@2211
   149
  public: 
deba@2211
   150
deba@2225
   151
    /// \brief Constructor
deba@2225
   152
    ///
deba@2225
   153
    /// Constructor of the algorithm class. 
deba@2211
   154
    HaoOrlin(const Graph& graph, const CapacityMap& capacity, 
deba@2211
   155
             const Tolerance& tolerance = Tolerance()) :
deba@2211
   156
      _graph(&graph), _capacity(&capacity), 
deba@2225
   157
      _preflow(0), _source(), _target(), 
deba@2225
   158
      _out_res_graph(0), _out_current_edge(0),
deba@2225
   159
      _rev_graph(0), _in_res_graph(0), _in_current_edge(0),
deba@2211
   160
      _wake(0),_dist(0), _excess(0), _source_set(0), 
deba@2211
   161
      _highest_active(), _active_nodes(), _dormant_max(), _dormant(), 
deba@2211
   162
      _min_cut(), _min_cut_map(0), _tolerance(tolerance) {}
deba@2211
   163
deba@2211
   164
    ~HaoOrlin() {
deba@2211
   165
      if (_min_cut_map) {
deba@2211
   166
        delete _min_cut_map;
deba@2211
   167
      } 
deba@2225
   168
      if (_in_current_edge) {
deba@2225
   169
        delete _in_current_edge;
deba@2225
   170
      }
deba@2225
   171
      if (_in_res_graph) {
deba@2225
   172
        delete _in_res_graph;
deba@2225
   173
      }
deba@2225
   174
      if (_rev_graph) {
deba@2225
   175
        delete _rev_graph;
deba@2225
   176
      }
deba@2225
   177
      if (_out_current_edge) {
deba@2225
   178
        delete _out_current_edge;
deba@2225
   179
      }
deba@2225
   180
      if (_out_res_graph) {
deba@2225
   181
        delete _out_res_graph;
deba@2211
   182
      }
deba@2211
   183
      if (_source_set) {
deba@2211
   184
        delete _source_set;
deba@2211
   185
      }
deba@2211
   186
      if (_excess) {
deba@2211
   187
        delete _excess;
deba@2211
   188
      }
deba@2211
   189
      if (_dist) {
deba@2211
   190
        delete _dist;
deba@2211
   191
      }
deba@2211
   192
      if (_wake) {
deba@2211
   193
        delete _wake;
deba@2211
   194
      }
deba@2211
   195
      if (_preflow) {
deba@2211
   196
        delete _preflow;
deba@2211
   197
      }
deba@2211
   198
    }
deba@2211
   199
    
deba@2211
   200
  private:
deba@2211
   201
    
deba@2225
   202
    template <typename ResGraph, typename EdgeMap>
deba@2225
   203
    void findMinCut(const Node& target, bool out, 
deba@2225
   204
                    ResGraph& res_graph, EdgeMap& current_edge) {
deba@2225
   205
      typedef typename ResGraph::Edge ResEdge;
deba@2225
   206
      typedef typename ResGraph::OutEdgeIt ResOutEdgeIt;
deba@2225
   207
deba@2225
   208
      for (typename Graph::EdgeIt it(*_graph); it != INVALID; ++it) {
deba@2225
   209
        (*_preflow)[it] = 0;      
deba@2225
   210
      }
deba@2225
   211
      for (NodeIt it(*_graph); it != INVALID; ++it) {
deba@2225
   212
        (*_wake)[it] = true;
deba@2225
   213
        (*_dist)[it] = 1;
deba@2225
   214
        (*_excess)[it] = 0;
deba@2225
   215
        (*_source_set)[it] = false;
deba@2225
   216
deba@2225
   217
        res_graph.firstOut(current_edge[it], it);
deba@2225
   218
      }
deba@2225
   219
deba@2225
   220
      _target = target;
deba@2225
   221
      (*_dist)[target] = 0;
deba@2225
   222
deba@2225
   223
      for (ResOutEdgeIt it(res_graph, _source); it != INVALID; ++it) {
deba@2225
   224
        Value delta = res_graph.rescap(it);
deba@2225
   225
        if (!_tolerance.positive(delta)) continue;
deba@2225
   226
        
deba@2225
   227
        (*_excess)[res_graph.source(it)] -= delta;
deba@2225
   228
        res_graph.augment(it, delta);
deba@2225
   229
        Node a = res_graph.target(it);
deba@2225
   230
        if (!_tolerance.positive((*_excess)[a]) && 
deba@2225
   231
            (*_wake)[a] && a != _target) {
deba@2225
   232
          _active_nodes[(*_dist)[a]].push_front(a);
deba@2225
   233
          if (_highest_active < (*_dist)[a]) {
deba@2225
   234
            _highest_active = (*_dist)[a];
deba@2225
   235
          }
deba@2225
   236
        }
deba@2225
   237
        (*_excess)[a] += delta;
deba@2225
   238
      }
deba@2225
   239
deba@2225
   240
      _dormant[0].push_front(_source);
deba@2225
   241
      (*_source_set)[_source] = true;
deba@2225
   242
      _dormant_max = 0;
deba@2225
   243
      (*_wake)[_source] = false;
deba@2225
   244
deba@2225
   245
      _level_size[0] = 1;
deba@2225
   246
      _level_size[1] = _node_num - 1;
deba@2225
   247
deba@2225
   248
      do {
deba@2225
   249
	Node n;
deba@2225
   250
	while ((n = findActiveNode()) != INVALID) {
deba@2225
   251
	  ResEdge e;
deba@2225
   252
	  while (_tolerance.positive((*_excess)[n]) && 
deba@2225
   253
                 (e = findAdmissibleEdge(n, res_graph, current_edge)) 
deba@2225
   254
                 != INVALID){
deba@2225
   255
	    Value delta;
deba@2225
   256
	    if ((*_excess)[n] < res_graph.rescap(e)) {
deba@2225
   257
	      delta = (*_excess)[n];
deba@2225
   258
	    } else {
deba@2225
   259
	      delta = res_graph.rescap(e);
deba@2225
   260
	      res_graph.nextOut(current_edge[n]);
deba@2225
   261
	    }
deba@2225
   262
            if (!_tolerance.positive(delta)) continue;
deba@2225
   263
	    res_graph.augment(e, delta);
deba@2225
   264
	    (*_excess)[res_graph.source(e)] -= delta;
deba@2225
   265
	    Node a = res_graph.target(e);
deba@2225
   266
	    if (!_tolerance.positive((*_excess)[a]) && a != _target) {
deba@2225
   267
	      _active_nodes[(*_dist)[a]].push_front(a);
deba@2225
   268
	    }
deba@2225
   269
	    (*_excess)[a] += delta;
deba@2225
   270
	  }
deba@2225
   271
	  if (_tolerance.positive((*_excess)[n])) {
deba@2225
   272
	    relabel(n, res_graph, current_edge);
deba@2225
   273
          }
deba@2225
   274
	}
deba@2225
   275
deba@2225
   276
	Value current_value = cutValue(out);
deba@2225
   277
 	if (_min_cut > current_value){
deba@2225
   278
          if (out) {
deba@2225
   279
            for (NodeIt it(*_graph); it != INVALID; ++it) {
deba@2225
   280
              _min_cut_map->set(it, !(*_wake)[it]);
deba@2225
   281
            } 
deba@2225
   282
          } else {
deba@2225
   283
            for (NodeIt it(*_graph); it != INVALID; ++it) {
deba@2225
   284
              _min_cut_map->set(it, (*_wake)[it]);
deba@2225
   285
            } 
deba@2225
   286
          }
deba@2225
   287
deba@2225
   288
	  _min_cut = current_value;
deba@2225
   289
 	}
deba@2225
   290
deba@2225
   291
      } while (selectNewSink(res_graph));
deba@2225
   292
    }
deba@2225
   293
deba@2225
   294
    template <typename ResGraph, typename EdgeMap>
deba@2225
   295
    void relabel(const Node& n, ResGraph& res_graph, EdgeMap& current_edge) {
deba@2225
   296
      typedef typename ResGraph::OutEdgeIt ResOutEdgeIt;
deba@2225
   297
deba@2225
   298
      int k = (*_dist)[n];
deba@2211
   299
      if (_level_size[k] == 1) {
deba@2211
   300
	++_dormant_max;
deba@2211
   301
	for (NodeIt it(*_graph); it != INVALID; ++it) {
deba@2211
   302
	  if ((*_wake)[it] && (*_dist)[it] >= k) {
deba@2211
   303
	    (*_wake)[it] = false;
deba@2211
   304
	    _dormant[_dormant_max].push_front(it);
deba@2211
   305
	    --_level_size[(*_dist)[it]];
deba@2211
   306
	  }
deba@2211
   307
	}
deba@2211
   308
	--_highest_active;
deba@2225
   309
      } else {	
deba@2225
   310
        int new_dist = _node_num;
deba@2225
   311
        for (ResOutEdgeIt e(res_graph, n); e != INVALID; ++e) {
deba@2225
   312
          Node t = res_graph.target(e);
deba@2225
   313
          if ((*_wake)[t] && new_dist > (*_dist)[t]) {
deba@2225
   314
            new_dist = (*_dist)[t];
deba@2225
   315
          }
deba@2225
   316
        }
deba@2225
   317
        if (new_dist == _node_num) {
deba@2211
   318
	  ++_dormant_max;
deba@2225
   319
	  (*_wake)[n] = false;
deba@2225
   320
	  _dormant[_dormant_max].push_front(n);
deba@2225
   321
	  --_level_size[(*_dist)[n]];
deba@2225
   322
	} else {	    
deba@2225
   323
	  --_level_size[(*_dist)[n]];
deba@2225
   324
	  (*_dist)[n] = new_dist + 1;
deba@2225
   325
	  _highest_active = (*_dist)[n];
deba@2225
   326
	  _active_nodes[_highest_active].push_front(n);
deba@2225
   327
	  ++_level_size[(*_dist)[n]];
deba@2225
   328
	  res_graph.firstOut(current_edge[n], n);
deba@2211
   329
	}
deba@2211
   330
      }
deba@2211
   331
    }
deba@2211
   332
deba@2225
   333
    template <typename ResGraph>
deba@2225
   334
    bool selectNewSink(ResGraph& res_graph) {
deba@2225
   335
      typedef typename ResGraph::OutEdgeIt ResOutEdgeIt;
deba@2225
   336
deba@2211
   337
      Node old_target = _target;
deba@2211
   338
      (*_wake)[_target] = false;
deba@2211
   339
      --_level_size[(*_dist)[_target]];
deba@2211
   340
      _dormant[0].push_front(_target);
deba@2211
   341
      (*_source_set)[_target] = true;
deba@2211
   342
      if ((int)_dormant[0].size() == _node_num){
deba@2211
   343
        _dormant[0].clear();
deba@2211
   344
	return false;
deba@2211
   345
      }
deba@2211
   346
deba@2211
   347
      bool wake_was_empty = false;
deba@2211
   348
deba@2211
   349
      if(_wake->trueNum() == 0) {
deba@2211
   350
	while (!_dormant[_dormant_max].empty()){
deba@2211
   351
	  (*_wake)[_dormant[_dormant_max].front()] = true;
deba@2211
   352
	  ++_level_size[(*_dist)[_dormant[_dormant_max].front()]];
deba@2211
   353
	  _dormant[_dormant_max].pop_front();
deba@2211
   354
	}
deba@2211
   355
	--_dormant_max;
deba@2211
   356
	wake_was_empty = true;
deba@2211
   357
      }
deba@2211
   358
deba@2211
   359
      int min_dist = std::numeric_limits<int>::max();
deba@2211
   360
      for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
deba@2211
   361
	if (min_dist > (*_dist)[it]){
deba@2211
   362
	  _target = it;
deba@2211
   363
	  min_dist = (*_dist)[it];
deba@2211
   364
	}
deba@2211
   365
      }
deba@2211
   366
deba@2211
   367
      if (wake_was_empty){
deba@2211
   368
	for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
deba@2211
   369
          if (_tolerance.positive((*_excess)[it])) {
deba@2211
   370
	    if ((*_wake)[it] && it != _target) {
deba@2211
   371
	      _active_nodes[(*_dist)[it]].push_front(it);
deba@2211
   372
            }
deba@2211
   373
	    if (_highest_active < (*_dist)[it]) {
deba@2211
   374
	      _highest_active = (*_dist)[it];		    
deba@2211
   375
            }
deba@2211
   376
	  }
deba@2211
   377
	}
deba@2211
   378
      }
deba@2211
   379
deba@2225
   380
      for (ResOutEdgeIt e(res_graph, old_target); e!=INVALID; ++e){
deba@2225
   381
	if (!(*_source_set)[res_graph.target(e)]) {
deba@2225
   382
          Value delta = res_graph.rescap(e);
deba@2225
   383
          if (!_tolerance.positive(delta)) continue;
deba@2225
   384
          res_graph.augment(e, delta);
deba@2225
   385
          (*_excess)[res_graph.source(e)] -= delta;
deba@2225
   386
          Node a = res_graph.target(e);
deba@2225
   387
          if (!_tolerance.positive((*_excess)[a]) && 
deba@2225
   388
              (*_wake)[a] && a != _target) {
deba@2225
   389
            _active_nodes[(*_dist)[a]].push_front(a);
deba@2225
   390
            if (_highest_active < (*_dist)[a]) {
deba@2225
   391
              _highest_active = (*_dist)[a];
deba@2225
   392
            }
deba@2225
   393
          }
deba@2225
   394
          (*_excess)[a] += delta;
deba@2211
   395
	}
deba@2211
   396
      }
deba@2211
   397
      
deba@2211
   398
      return true;
deba@2211
   399
    }
deba@2211
   400
    
deba@2211
   401
    Node findActiveNode() {
deba@2211
   402
      while (_highest_active > 0 && _active_nodes[_highest_active].empty()){ 
deba@2211
   403
	--_highest_active;
deba@2211
   404
      }
deba@2211
   405
      if( _highest_active > 0) {
deba@2211
   406
       	Node n = _active_nodes[_highest_active].front();
deba@2211
   407
	_active_nodes[_highest_active].pop_front();
deba@2211
   408
	return n;
deba@2211
   409
      } else {
deba@2211
   410
	return INVALID;
deba@2211
   411
      }
deba@2211
   412
    }
deba@2211
   413
deba@2225
   414
    template <typename ResGraph, typename EdgeMap>
deba@2225
   415
    typename ResGraph::Edge findAdmissibleEdge(const Node& n, 
deba@2225
   416
                                               ResGraph& res_graph, 
deba@2225
   417
                                               EdgeMap& current_edge) {
deba@2225
   418
      typedef typename ResGraph::Edge ResEdge;
deba@2225
   419
      ResEdge e = current_edge[n];
deba@2211
   420
      while (e != INVALID && 
deba@2225
   421
             ((*_dist)[n] <= (*_dist)[res_graph.target(e)] || 
deba@2225
   422
              !(*_wake)[res_graph.target(e)])) {
deba@2225
   423
	res_graph.nextOut(e);
deba@2211
   424
      }
deba@2211
   425
      if (e != INVALID) {
deba@2225
   426
	current_edge[n] = e;	
deba@2211
   427
	return e;
deba@2211
   428
      } else {
deba@2211
   429
	return INVALID;
deba@2211
   430
      }
deba@2211
   431
    }
deba@2211
   432
deba@2225
   433
    Value cutValue(bool out) {
deba@2225
   434
      Value value = 0;
deba@2225
   435
      if (out) {
deba@2225
   436
        for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
deba@2225
   437
          for (InEdgeIt e(*_graph, it); e != INVALID; ++e) {
deba@2225
   438
            if (!(*_wake)[_graph->source(e)]){
deba@2225
   439
              value += (*_capacity)[e];
deba@2225
   440
            }	
deba@2225
   441
          }
deba@2225
   442
        }
deba@2225
   443
      } else {
deba@2225
   444
        for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
deba@2225
   445
          for (OutEdgeIt e(*_graph, it); e != INVALID; ++e) {
deba@2225
   446
            if (!(*_wake)[_graph->target(e)]){
deba@2225
   447
              value += (*_capacity)[e];
deba@2225
   448
            }	
deba@2225
   449
          }
deba@2211
   450
        }
deba@2211
   451
      }
deba@2225
   452
      return value;
deba@2211
   453
    }
deba@2225
   454
deba@2211
   455
deba@2211
   456
  public:
deba@2211
   457
deba@2225
   458
    /// \name Execution control
deba@2225
   459
    /// The simplest way to execute the algorithm is to use
deba@2225
   460
    /// one of the member functions called \c run(...).
deba@2225
   461
    /// \n
deba@2225
   462
    /// If you need more control on the execution,
deba@2225
   463
    /// first you must call \ref init(), then the \ref calculateIn() or
deba@2225
   464
    /// \ref calculateIn() functions.
deba@2225
   465
deba@2225
   466
    /// @{
deba@2225
   467
deba@2211
   468
    /// \brief Initializes the internal data structures.
deba@2211
   469
    ///
deba@2211
   470
    /// Initializes the internal data structures. It creates
deba@2225
   471
    /// the maps, residual graph adaptors and some bucket structures
deba@2211
   472
    /// for the algorithm. 
deba@2211
   473
    void init() {
deba@2211
   474
      init(NodeIt(*_graph));
deba@2211
   475
    }
deba@2211
   476
deba@2211
   477
    /// \brief Initializes the internal data structures.
deba@2211
   478
    ///
deba@2211
   479
    /// Initializes the internal data structures. It creates
deba@2211
   480
    /// the maps, residual graph adaptor and some bucket structures
deba@2211
   481
    /// for the algorithm. The \c source node is used as the push-relabel
deba@2211
   482
    /// algorithm's source.
deba@2211
   483
    void init(const Node& source) {
deba@2211
   484
      _source = source;
deba@2211
   485
      _node_num = countNodes(*_graph);
deba@2211
   486
deba@2211
   487
      _dormant.resize(_node_num);
deba@2211
   488
      _level_size.resize(_node_num, 0);
deba@2211
   489
      _active_nodes.resize(_node_num);
deba@2211
   490
deba@2211
   491
      if (!_preflow) {
deba@2211
   492
        _preflow = new FlowMap(*_graph);
deba@2211
   493
      }
deba@2211
   494
      if (!_wake) {
deba@2211
   495
        _wake = new WakeMap(*_graph);
deba@2211
   496
      }
deba@2211
   497
      if (!_dist) {
deba@2211
   498
        _dist = new DistMap(*_graph);
deba@2211
   499
      }
deba@2211
   500
      if (!_excess) {
deba@2211
   501
        _excess = new ExcessMap(*_graph);
deba@2211
   502
      }
deba@2211
   503
      if (!_source_set) {
deba@2211
   504
        _source_set = new SourceSetMap(*_graph);
deba@2211
   505
      }
deba@2225
   506
      if (!_out_res_graph) {
deba@2225
   507
        _out_res_graph = new OutResGraph(*_graph, *_capacity, *_preflow);
deba@2225
   508
      }
deba@2225
   509
      if (!_out_current_edge) {
deba@2225
   510
        _out_current_edge = new OutCurrentEdgeMap(*_graph);
deba@2225
   511
      }
deba@2225
   512
      if (!_rev_graph) {
deba@2225
   513
        _rev_graph = new RevGraph(*_graph);
deba@2225
   514
      }
deba@2225
   515
      if (!_in_res_graph) {
deba@2225
   516
        _in_res_graph = new InResGraph(*_rev_graph, *_capacity, *_preflow);
deba@2225
   517
      }
deba@2225
   518
      if (!_in_current_edge) {
deba@2225
   519
        _in_current_edge = new InCurrentEdgeMap(*_graph);
deba@2211
   520
      }
deba@2211
   521
      if (!_min_cut_map) {
deba@2211
   522
        _min_cut_map = new MinCutMap(*_graph);
deba@2211
   523
      }
deba@2211
   524
deba@2211
   525
      _min_cut = std::numeric_limits<Value>::max();
deba@2211
   526
    }
deba@2211
   527
deba@2211
   528
deba@2211
   529
    /// \brief Calculates the minimum cut with the \c source node
deba@2225
   530
    /// in the \f$ V_{out} \f$.
deba@2211
   531
    ///
deba@2211
   532
    /// Calculates the minimum cut with the \c source node
deba@2225
   533
    /// in the \f$ V_{out} \f$.
deba@2211
   534
    void calculateOut() {
deba@2211
   535
      for (NodeIt it(*_graph); it != INVALID; ++it) {
deba@2211
   536
        if (it != _source) {
deba@2211
   537
          calculateOut(it);
deba@2211
   538
          return;
deba@2211
   539
        }
deba@2211
   540
      }
deba@2211
   541
    }
deba@2211
   542
deba@2211
   543
    /// \brief Calculates the minimum cut with the \c source node
deba@2225
   544
    /// in the \f$ V_{out} \f$.
deba@2211
   545
    ///
deba@2211
   546
    /// Calculates the minimum cut with the \c source node
deba@2225
   547
    /// in the \f$ V_{out} \f$. The \c target is the initial target
deba@2211
   548
    /// for the push-relabel algorithm.
deba@2211
   549
    void calculateOut(const Node& target) {
deba@2225
   550
      findMinCut(target, true, *_out_res_graph, *_out_current_edge);
deba@2211
   551
    }
deba@2211
   552
deba@2225
   553
    /// \brief Calculates the minimum cut with the \c source node
deba@2225
   554
    /// in the \f$ V_{in} \f$.
deba@2225
   555
    ///
deba@2225
   556
    /// Calculates the minimum cut with the \c source node
deba@2225
   557
    /// in the \f$ V_{in} \f$.
deba@2211
   558
    void calculateIn() {
deba@2211
   559
      for (NodeIt it(*_graph); it != INVALID; ++it) {
deba@2211
   560
        if (it != _source) {
deba@2211
   561
          calculateIn(it);
deba@2211
   562
          return;
deba@2211
   563
        }
deba@2211
   564
      }
deba@2211
   565
    }
deba@2211
   566
deba@2225
   567
    /// \brief Calculates the minimum cut with the \c source node
deba@2225
   568
    /// in the \f$ V_{in} \f$.
deba@2225
   569
    ///
deba@2225
   570
    /// Calculates the minimum cut with the \c source node
deba@2225
   571
    /// in the \f$ V_{in} \f$. The \c target is the initial target
deba@2225
   572
    /// for the push-relabel algorithm.
deba@2225
   573
    void calculateIn(const Node& target) {
deba@2225
   574
      findMinCut(target, false, *_in_res_graph, *_in_current_edge);
deba@2225
   575
    }
deba@2225
   576
deba@2225
   577
    /// \brief Runs the algorithm.
deba@2225
   578
    ///
deba@2225
   579
    /// Runs the algorithm. It finds a proper \c source and \c target
deba@2225
   580
    /// and then calls the \ref init(), \ref calculateOut() and \ref
deba@2225
   581
    /// calculateIn().
deba@2211
   582
    void run() {
deba@2211
   583
      init();
deba@2211
   584
      for (NodeIt it(*_graph); it != INVALID; ++it) {
deba@2211
   585
        if (it != _source) {
deba@2225
   586
          calculateOut(it);
deba@2225
   587
          calculateIn(it);
deba@2211
   588
          return;
deba@2211
   589
        }
deba@2211
   590
      }
deba@2211
   591
    }
deba@2211
   592
deba@2225
   593
    /// \brief Runs the algorithm.
deba@2225
   594
    ///
deba@2225
   595
    /// Runs the algorithm. It finds a proper \c target and then calls
deba@2225
   596
    /// the \ref init(), \ref calculateOut() and \ref calculateIn().
deba@2211
   597
    void run(const Node& s) {
deba@2211
   598
      init(s);
deba@2211
   599
      for (NodeIt it(*_graph); it != INVALID; ++it) {
deba@2211
   600
        if (it != _source) {
deba@2225
   601
          calculateOut(it);
deba@2225
   602
          calculateIn(it);
deba@2211
   603
          return;
deba@2211
   604
        }
deba@2211
   605
      }
deba@2211
   606
    }
deba@2211
   607
deba@2225
   608
    /// \brief Runs the algorithm.
deba@2225
   609
    ///
deba@2225
   610
    /// Runs the algorithm. It just calls the \ref init() and then
deba@2225
   611
    /// \ref calculateOut() and \ref calculateIn().
deba@2211
   612
    void run(const Node& s, const Node& t) {
deba@2225
   613
      init(s); 
deba@2225
   614
      calculateOut(t);
deba@2225
   615
      calculateIn(t);
deba@2211
   616
    }
deba@2225
   617
deba@2225
   618
    /// @}
deba@2211
   619
    
deba@2225
   620
    /// \name Query Functions The result of the %HaoOrlin algorithm
deba@2225
   621
    /// can be obtained using these functions.
deba@2225
   622
    /// \n
deba@2225
   623
    /// Before the use of these functions, either \ref run(), \ref
deba@2225
   624
    /// calculateOut() or \ref calculateIn() must be called.
deba@2225
   625
    
deba@2225
   626
    /// @{
deba@2225
   627
deba@2225
   628
    /// \brief Returns the value of the minimum value cut.
deba@2211
   629
    /// 
deba@2225
   630
    /// Returns the value of the minimum value cut.
deba@2211
   631
    Value minCut() const {
deba@2211
   632
      return _min_cut;
deba@2211
   633
    }
deba@2211
   634
deba@2211
   635
deba@2211
   636
    /// \brief Returns a minimum value cut.
deba@2211
   637
    ///
deba@2211
   638
    /// Sets \c nodeMap to the characteristic vector of a minimum
deba@2225
   639
    /// value cut. The nodes in \f$ V_{out} \f$ will be set true and
deba@2225
   640
    /// the nodes in \f$ V_{in} \f$ will be set false. 
deba@2211
   641
    /// \pre nodeMap should be a bool-valued node-map.
deba@2211
   642
    template <typename NodeMap>
deba@2211
   643
    Value minCut(NodeMap& nodeMap) const {
deba@2211
   644
      for (NodeIt it(*_graph); it != INVALID; ++it) {
deba@2211
   645
	nodeMap.set(it, (*_min_cut_map)[it]);
deba@2211
   646
      }
deba@2211
   647
      return minCut();
deba@2211
   648
    }
deba@2225
   649
deba@2225
   650
    /// @}
deba@2211
   651
    
deba@2211
   652
  }; //class HaoOrlin 
deba@2211
   653
deba@2211
   654
deba@2211
   655
} //namespace lemon
deba@2211
   656
deba@2211
   657
#endif //LEMON_HAO_ORLIN_H