1.1 --- a/doc/groups.dox Fri Nov 30 09:22:38 2007 +0000
1.2 +++ b/doc/groups.dox Tue Dec 04 10:55:27 2007 +0000
1.3 @@ -258,13 +258,34 @@
1.4 */
1.5
1.6 /**
1.7 -@defgroup min_cut Minimum Cut algorithms
1.8 -@ingroup algs
1.9 -\brief This group describes the algorithms
1.10 -for finding minimum cut in graphs.
1.11 +@defgroup min_cut Minimum Cut algorithms
1.12 +@ingroup algs
1.13
1.14 -This group describes the algorithms
1.15 -for finding minimum cut in graphs.
1.16 +\brief This group describes the algorithms for finding minimum cut in
1.17 +graphs.
1.18 +
1.19 +This group describes the algorithms for finding minimum cut in graphs.
1.20 +
1.21 +The minimum cut problem is to find a non-empty and non-complete
1.22 +\f$X\f$ subset of the vertices with minimum overall capacity on
1.23 +outgoing arcs. Formally, there is \f$G=(V,A)\f$ directed graph, an
1.24 +\f$c_a:A\rightarrow\mathbf{R}^+_0\f$ capacity function. The minimum
1.25 +cut is the solution of the next optimization problem:
1.26 +
1.27 +\f[ \min_{X \subset V, X\not\in \{\emptyset, V\}}\sum_{uv\in A, u\in X, v\not\in X}c_{uv}\f]
1.28 +
1.29 +The lemon contains several algorithms related to minimum cut problems:
1.30 +
1.31 +- \ref lemon::HaoOrlin "Hao-Orlin algorithm" for calculate minimum cut
1.32 + in directed graphs
1.33 +- \ref lemon::NagamochiIbaraki "Nagamochi-Ibaraki algorithm" for
1.34 + calculate minimum cut in undirected graphs
1.35 +- \ref lemon::GomoryHuTree "Gomory-Hu tree computation" for calculate all
1.36 + pairs minimum cut in undirected graphs
1.37 +
1.38 +If you want to find minimum cut just between two distinict nodes,
1.39 +please see the \ref max_flow "Maximum Flow page".
1.40 +
1.41 */
1.42
1.43 /**
2.1 --- a/lemon/hao_orlin.h Fri Nov 30 09:22:38 2007 +0000
2.2 +++ b/lemon/hao_orlin.h Tue Dec 04 10:55:27 2007 +0000
2.3 @@ -19,13 +19,9 @@
2.4 #ifndef LEMON_HAO_ORLIN_H
2.5 #define LEMON_HAO_ORLIN_H
2.6
2.7 -#include <cassert>
2.8 -
2.9 -
2.10 -
2.11 #include <vector>
2.12 -#include <queue>
2.13 #include <list>
2.14 +#include <ext/hash_set>
2.15 #include <limits>
2.16
2.17 #include <lemon/maps.h>
2.18 @@ -37,7 +33,7 @@
2.19 /// \ingroup min_cut
2.20 /// \brief Implementation of the Hao-Orlin algorithm.
2.21 ///
2.22 -/// Implementation of the HaoOrlin algorithms class for testing network
2.23 +/// Implementation of the Hao-Orlin algorithm class for testing network
2.24 /// reliability.
2.25
2.26 namespace lemon {
2.27 @@ -46,24 +42,25 @@
2.28 ///
2.29 /// \brief %Hao-Orlin algorithm to find a minimum cut in directed graphs.
2.30 ///
2.31 - /// Hao-Orlin calculates a minimum cut in a directed graph
2.32 - /// \f$ D=(V,A) \f$. It takes a fixed node \f$ source \in V \f$ and consists
2.33 - /// of two phases: in the first phase it determines a minimum cut
2.34 - /// with \f$ source \f$ on the source-side (i.e. a set \f$ X\subsetneq V \f$
2.35 - /// with \f$ source \in X \f$ and minimal out-degree) and in the
2.36 - /// second phase it determines a minimum cut with \f$ source \f$ on the
2.37 - /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with \f$ source \notin X \f$
2.38 - /// and minimal out-degree). Obviously, the smaller of these two
2.39 - /// cuts will be a minimum cut of \f$ D \f$. The algorithm is a
2.40 - /// modified push-relabel preflow algorithm and our implementation
2.41 - /// calculates the minimum cut in \f$ O(n^3) \f$ time (we use the
2.42 - /// highest-label rule). The purpose of such an algorithm is testing
2.43 - /// network reliability. For an undirected graph with \f$ n \f$
2.44 - /// nodes and \f$ e \f$ edges you can use the algorithm of Nagamochi
2.45 - /// and Ibaraki which solves the undirected problem in
2.46 - /// \f$ O(ne + n^2 \log(n)) \f$ time: it is implemented in the MinCut
2.47 - /// algorithm
2.48 - /// class.
2.49 + /// Hao-Orlin calculates a minimum cut in a directed graph
2.50 + /// \f$D=(V,A)\f$. It takes a fixed node \f$ source \in V \f$ and
2.51 + /// consists of two phases: in the first phase it determines a
2.52 + /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
2.53 + /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal
2.54 + /// out-degree) and in the second phase it determines a minimum cut
2.55 + /// with \f$ source \f$ on the sink-side (i.e. a set
2.56 + /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal
2.57 + /// out-degree). Obviously, the smaller of these two cuts will be a
2.58 + /// minimum cut of \f$ D \f$. The algorithm is a modified
2.59 + /// push-relabel preflow algorithm and our implementation calculates
2.60 + /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
2.61 + /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The
2.62 + /// purpose of such algorithm is testing network reliability. For an
2.63 + /// undirected graph you can run just the first phase of the
2.64 + /// algorithm or you can use the algorithm of Nagamochi and Ibaraki
2.65 + /// which solves the undirected problem in
2.66 + /// \f$ O(nm + n^2 \log(n)) \f$ time: it is implemented in the
2.67 + /// NagamochiIbaraki algorithm class.
2.68 ///
2.69 /// \param _Graph is the graph type of the algorithm.
2.70 /// \param _CapacityMap is an edge map of capacities which should
2.71 @@ -80,7 +77,7 @@
2.72 typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
2.73 #endif
2.74 class HaoOrlin {
2.75 - protected:
2.76 + private:
2.77
2.78 typedef _Graph Graph;
2.79 typedef _CapacityMap CapacityMap;
2.80 @@ -88,44 +85,29 @@
2.81
2.82 typedef typename CapacityMap::Value Value;
2.83
2.84 + GRAPH_TYPEDEFS(typename Graph);
2.85
2.86 - typedef typename Graph::Node Node;
2.87 - typedef typename Graph::NodeIt NodeIt;
2.88 - typedef typename Graph::EdgeIt EdgeIt;
2.89 - typedef typename Graph::OutEdgeIt OutEdgeIt;
2.90 - typedef typename Graph::InEdgeIt InEdgeIt;
2.91 -
2.92 - const Graph* _graph;
2.93 -
2.94 + const Graph& _graph;
2.95 const CapacityMap* _capacity;
2.96
2.97 typedef typename Graph::template EdgeMap<Value> FlowMap;
2.98 + FlowMap* _flow;
2.99
2.100 - FlowMap* _preflow;
2.101 + Node _source;
2.102
2.103 - Node _source, _target;
2.104 int _node_num;
2.105
2.106 - typedef ResGraphAdaptor<const Graph, Value, CapacityMap,
2.107 - FlowMap, Tolerance> OutResGraph;
2.108 - typedef typename OutResGraph::Edge OutResEdge;
2.109 + // Bucketing structure
2.110 + std::vector<Node> _first, _last;
2.111 + typename Graph::template NodeMap<Node>* _next;
2.112 + typename Graph::template NodeMap<Node>* _prev;
2.113 + typename Graph::template NodeMap<bool>* _active;
2.114 + typename Graph::template NodeMap<int>* _bucket;
2.115
2.116 - OutResGraph* _out_res_graph;
2.117 + std::vector<bool> _dormant;
2.118
2.119 - typedef RevGraphAdaptor<const Graph> RevGraph;
2.120 - RevGraph* _rev_graph;
2.121 -
2.122 - typedef ResGraphAdaptor<const RevGraph, Value, CapacityMap,
2.123 - FlowMap, Tolerance> InResGraph;
2.124 - typedef typename InResGraph::Edge InResEdge;
2.125 -
2.126 - InResGraph* _in_res_graph;
2.127 -
2.128 - typedef IterableBoolMap<Graph, Node> WakeMap;
2.129 - WakeMap* _wake;
2.130 -
2.131 - typedef typename Graph::template NodeMap<int> DistMap;
2.132 - DistMap* _dist;
2.133 + std::list<std::list<int> > _sets;
2.134 + std::list<int>::iterator _highest;
2.135
2.136 typedef typename Graph::template NodeMap<Value> ExcessMap;
2.137 ExcessMap* _excess;
2.138 @@ -133,15 +115,6 @@
2.139 typedef typename Graph::template NodeMap<bool> SourceSetMap;
2.140 SourceSetMap* _source_set;
2.141
2.142 - std::vector<int> _level_size;
2.143 -
2.144 - int _highest_active;
2.145 - std::vector<std::list<Node> > _active_nodes;
2.146 -
2.147 - int _dormant_max;
2.148 - std::vector<std::list<Node> > _dormant;
2.149 -
2.150 -
2.151 Value _min_cut;
2.152
2.153 typedef typename Graph::template NodeMap<bool> MinCutMap;
2.154 @@ -156,267 +129,695 @@
2.155 /// Constructor of the algorithm class.
2.156 HaoOrlin(const Graph& graph, const CapacityMap& capacity,
2.157 const Tolerance& tolerance = Tolerance()) :
2.158 - _graph(&graph), _capacity(&capacity),
2.159 - _preflow(0), _source(), _target(),
2.160 - _out_res_graph(0), _rev_graph(0), _in_res_graph(0),
2.161 - _wake(0),_dist(0), _excess(0), _source_set(0),
2.162 - _highest_active(), _active_nodes(), _dormant_max(), _dormant(),
2.163 - _min_cut(), _min_cut_map(0), _tolerance(tolerance) {}
2.164 + _graph(graph), _capacity(&capacity), _flow(0), _source(),
2.165 + _node_num(), _first(), _last(), _next(0), _prev(0),
2.166 + _active(0), _bucket(0), _dormant(), _sets(), _highest(),
2.167 + _excess(0), _source_set(0), _min_cut(), _min_cut_map(0),
2.168 + _tolerance(tolerance) {}
2.169
2.170 ~HaoOrlin() {
2.171 if (_min_cut_map) {
2.172 delete _min_cut_map;
2.173 }
2.174 - if (_in_res_graph) {
2.175 - delete _in_res_graph;
2.176 - }
2.177 - if (_rev_graph) {
2.178 - delete _rev_graph;
2.179 - }
2.180 - if (_out_res_graph) {
2.181 - delete _out_res_graph;
2.182 - }
2.183 if (_source_set) {
2.184 delete _source_set;
2.185 }
2.186 if (_excess) {
2.187 delete _excess;
2.188 }
2.189 - if (_dist) {
2.190 - delete _dist;
2.191 + if (_next) {
2.192 + delete _next;
2.193 }
2.194 - if (_wake) {
2.195 - delete _wake;
2.196 + if (_prev) {
2.197 + delete _prev;
2.198 }
2.199 - if (_preflow) {
2.200 - delete _preflow;
2.201 + if (_active) {
2.202 + delete _active;
2.203 + }
2.204 + if (_bucket) {
2.205 + delete _bucket;
2.206 + }
2.207 + if (_flow) {
2.208 + delete _flow;
2.209 }
2.210 }
2.211
2.212 private:
2.213 +
2.214 + void activate(const Node& i) {
2.215 + _active->set(i, true);
2.216 +
2.217 + int bucket = (*_bucket)[i];
2.218 +
2.219 + if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return;
2.220 + //unlace
2.221 + _next->set((*_prev)[i], (*_next)[i]);
2.222 + if ((*_next)[i] != INVALID) {
2.223 + _prev->set((*_next)[i], (*_prev)[i]);
2.224 + } else {
2.225 + _last[bucket] = (*_prev)[i];
2.226 + }
2.227 + //lace
2.228 + _next->set(i, _first[bucket]);
2.229 + _prev->set(_first[bucket], i);
2.230 + _prev->set(i, INVALID);
2.231 + _first[bucket] = i;
2.232 + }
2.233 +
2.234 + void deactivate(const Node& i) {
2.235 + _active->set(i, false);
2.236 + int bucket = (*_bucket)[i];
2.237 +
2.238 + if ((*_next)[i] == INVALID || !(*_active)[(*_next)[i]]) return;
2.239 +
2.240 + //unlace
2.241 + _prev->set((*_next)[i], (*_prev)[i]);
2.242 + if ((*_prev)[i] != INVALID) {
2.243 + _next->set((*_prev)[i], (*_next)[i]);
2.244 + } else {
2.245 + _first[bucket] = (*_next)[i];
2.246 + }
2.247 + //lace
2.248 + _prev->set(i, _last[bucket]);
2.249 + _next->set(_last[bucket], i);
2.250 + _next->set(i, INVALID);
2.251 + _last[bucket] = i;
2.252 + }
2.253 +
2.254 + void addItem(const Node& i, int bucket) {
2.255 + (*_bucket)[i] = bucket;
2.256 + if (_last[bucket] != INVALID) {
2.257 + _prev->set(i, _last[bucket]);
2.258 + _next->set(_last[bucket], i);
2.259 + _next->set(i, INVALID);
2.260 + _last[bucket] = i;
2.261 + } else {
2.262 + _prev->set(i, INVALID);
2.263 + _first[bucket] = i;
2.264 + _next->set(i, INVALID);
2.265 + _last[bucket] = i;
2.266 + }
2.267 + }
2.268
2.269 - template <typename ResGraph>
2.270 - void findMinCut(const Node& target, bool out, ResGraph& res_graph) {
2.271 - typedef typename ResGraph::Edge ResEdge;
2.272 - typedef typename ResGraph::OutEdgeIt ResOutEdgeIt;
2.273 + void findMinCutOut() {
2.274
2.275 - for (typename Graph::EdgeIt it(*_graph); it != INVALID; ++it) {
2.276 - (*_preflow)[it] = 0;
2.277 - }
2.278 - for (NodeIt it(*_graph); it != INVALID; ++it) {
2.279 - (*_wake)[it] = true;
2.280 - (*_dist)[it] = 1;
2.281 - (*_excess)[it] = 0;
2.282 - (*_source_set)[it] = false;
2.283 + for (NodeIt n(_graph); n != INVALID; ++n) {
2.284 + _excess->set(n, 0);
2.285 }
2.286
2.287 - _dormant[0].push_front(_source);
2.288 - (*_source_set)[_source] = true;
2.289 - _dormant_max = 0;
2.290 - (*_wake)[_source] = false;
2.291 -
2.292 - _level_size[0] = 1;
2.293 - _level_size[1] = _node_num - 1;
2.294 -
2.295 - _target = target;
2.296 - (*_dist)[target] = 0;
2.297 -
2.298 - for (ResOutEdgeIt it(res_graph, _source); it != INVALID; ++it) {
2.299 - Value delta = res_graph.rescap(it);
2.300 - (*_excess)[_source] -= delta;
2.301 - res_graph.augment(it, delta);
2.302 - Node a = res_graph.target(it);
2.303 - if ((*_excess)[a] == 0 && (*_wake)[a] && a != _target) {
2.304 - _active_nodes[(*_dist)[a]].push_front(a);
2.305 - if (_highest_active < (*_dist)[a]) {
2.306 - _highest_active = (*_dist)[a];
2.307 - }
2.308 - }
2.309 - (*_excess)[a] += delta;
2.310 + for (EdgeIt e(_graph); e != INVALID; ++e) {
2.311 + _flow->set(e, 0);
2.312 }
2.313
2.314 + int bucket_num = 1;
2.315 +
2.316 + {
2.317 + typename Graph::template NodeMap<bool> reached(_graph, false);
2.318 +
2.319 + reached.set(_source, true);
2.320
2.321 - do {
2.322 - Node n;
2.323 - while ((n = findActiveNode()) != INVALID) {
2.324 - for (ResOutEdgeIt e(res_graph, n); e != INVALID; ++e) {
2.325 - Node a = res_graph.target(e);
2.326 - if ((*_dist)[a] >= (*_dist)[n] || !(*_wake)[a]) continue;
2.327 - Value delta = res_graph.rescap(e);
2.328 - if (_tolerance.positive((*_excess)[n] - delta)) {
2.329 - (*_excess)[n] -= delta;
2.330 - } else {
2.331 - delta = (*_excess)[n];
2.332 - (*_excess)[n] = 0;
2.333 + bool first_set = true;
2.334 +
2.335 + for (NodeIt t(_graph); t != INVALID; ++t) {
2.336 + if (reached[t]) continue;
2.337 + _sets.push_front(std::list<int>());
2.338 + _sets.front().push_front(bucket_num);
2.339 + _dormant[bucket_num] = !first_set;
2.340 +
2.341 + _bucket->set(t, bucket_num);
2.342 + _first[bucket_num] = _last[bucket_num] = t;
2.343 + _next->set(t, INVALID);
2.344 + _prev->set(t, INVALID);
2.345 +
2.346 + ++bucket_num;
2.347 +
2.348 + std::vector<Node> queue;
2.349 + queue.push_back(t);
2.350 + reached.set(t, true);
2.351 +
2.352 + while (!queue.empty()) {
2.353 + _sets.front().push_front(bucket_num);
2.354 + _dormant[bucket_num] = !first_set;
2.355 + _first[bucket_num] = _last[bucket_num] = INVALID;
2.356 +
2.357 + std::vector<Node> nqueue;
2.358 + for (int i = 0; i < int(queue.size()); ++i) {
2.359 + Node n = queue[i];
2.360 + for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
2.361 + Node u = _graph.source(e);
2.362 + if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
2.363 + reached.set(u, true);
2.364 + addItem(u, bucket_num);
2.365 + nqueue.push_back(u);
2.366 + }
2.367 + }
2.368 }
2.369 - res_graph.augment(e, delta);
2.370 - if ((*_excess)[a] == 0 && a != _target) {
2.371 - _active_nodes[(*_dist)[a]].push_front(a);
2.372 - }
2.373 - (*_excess)[a] += delta;
2.374 - if ((*_excess)[n] == 0) break;
2.375 + queue.swap(nqueue);
2.376 + ++bucket_num;
2.377 }
2.378 - if ((*_excess)[n] != 0) {
2.379 - relabel(n, res_graph);
2.380 - }
2.381 + _sets.front().pop_front();
2.382 + --bucket_num;
2.383 + first_set = false;
2.384 }
2.385
2.386 - Value current_value = cutValue(out);
2.387 - if (_min_cut > current_value){
2.388 - if (out) {
2.389 - for (NodeIt it(*_graph); it != INVALID; ++it) {
2.390 - _min_cut_map->set(it, !(*_wake)[it]);
2.391 - }
2.392 - } else {
2.393 - for (NodeIt it(*_graph); it != INVALID; ++it) {
2.394 - _min_cut_map->set(it, (*_wake)[it]);
2.395 - }
2.396 - }
2.397 -
2.398 - _min_cut = current_value;
2.399 - }
2.400 -
2.401 - } while (selectNewSink(res_graph));
2.402 - }
2.403 -
2.404 - template <typename ResGraph>
2.405 - void relabel(const Node& n, ResGraph& res_graph) {
2.406 - typedef typename ResGraph::OutEdgeIt ResOutEdgeIt;
2.407 -
2.408 - int k = (*_dist)[n];
2.409 - if (_level_size[k] == 1) {
2.410 - ++_dormant_max;
2.411 - for (NodeIt it(*_graph); it != INVALID; ++it) {
2.412 - if ((*_wake)[it] && (*_dist)[it] >= k) {
2.413 - (*_wake)[it] = false;
2.414 - _dormant[_dormant_max].push_front(it);
2.415 - --_level_size[(*_dist)[it]];
2.416 + _bucket->set(_source, 0);
2.417 + _dormant[0] = true;
2.418 + }
2.419 + _source_set->set(_source, true);
2.420 +
2.421 + Node target = _last[_sets.back().back()];
2.422 + {
2.423 + for (OutEdgeIt e(_graph, _source); e != INVALID; ++e) {
2.424 + if (_tolerance.positive((*_capacity)[e])) {
2.425 + Node u = _graph.target(e);
2.426 + _flow->set(e, (*_capacity)[e]);
2.427 + _excess->set(u, (*_excess)[u] + (*_capacity)[e]);
2.428 + if (!(*_active)[u] && u != _source) {
2.429 + activate(u);
2.430 + }
2.431 }
2.432 }
2.433 - --_highest_active;
2.434 - } else {
2.435 - int new_dist = _node_num;
2.436 - for (ResOutEdgeIt e(res_graph, n); e != INVALID; ++e) {
2.437 - Node t = res_graph.target(e);
2.438 - if ((*_wake)[t] && new_dist > (*_dist)[t]) {
2.439 - new_dist = (*_dist)[t];
2.440 - }
2.441 - }
2.442 - if (new_dist == _node_num) {
2.443 - ++_dormant_max;
2.444 - (*_wake)[n] = false;
2.445 - _dormant[_dormant_max].push_front(n);
2.446 - --_level_size[(*_dist)[n]];
2.447 - } else {
2.448 - --_level_size[(*_dist)[n]];
2.449 - (*_dist)[n] = new_dist + 1;
2.450 - _highest_active = (*_dist)[n];
2.451 - _active_nodes[_highest_active].push_front(n);
2.452 - ++_level_size[(*_dist)[n]];
2.453 + if ((*_active)[target]) {
2.454 + deactivate(target);
2.455 + }
2.456 +
2.457 + _highest = _sets.back().begin();
2.458 + while (_highest != _sets.back().end() &&
2.459 + !(*_active)[_first[*_highest]]) {
2.460 + ++_highest;
2.461 + }
2.462 + }
2.463 +
2.464 +
2.465 + while (true) {
2.466 + while (_highest != _sets.back().end()) {
2.467 + Node n = _first[*_highest];
2.468 + Value excess = (*_excess)[n];
2.469 + int next_bucket = _node_num;
2.470 +
2.471 + int under_bucket;
2.472 + if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
2.473 + under_bucket = -1;
2.474 + } else {
2.475 + under_bucket = *(++std::list<int>::iterator(_highest));
2.476 + }
2.477 +
2.478 + for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
2.479 + Node v = _graph.target(e);
2.480 + if (_dormant[(*_bucket)[v]]) continue;
2.481 + Value rem = (*_capacity)[e] - (*_flow)[e];
2.482 + if (!_tolerance.positive(rem)) continue;
2.483 + if ((*_bucket)[v] == under_bucket) {
2.484 + if (!(*_active)[v] && v != target) {
2.485 + activate(v);
2.486 + }
2.487 + if (!_tolerance.less(rem, excess)) {
2.488 + _flow->set(e, (*_flow)[e] + excess);
2.489 + _excess->set(v, (*_excess)[v] + excess);
2.490 + excess = 0;
2.491 + goto no_more_push;
2.492 + } else {
2.493 + excess -= rem;
2.494 + _excess->set(v, (*_excess)[v] + rem);
2.495 + _flow->set(e, (*_capacity)[e]);
2.496 + }
2.497 + } else if (next_bucket > (*_bucket)[v]) {
2.498 + next_bucket = (*_bucket)[v];
2.499 + }
2.500 + }
2.501 +
2.502 + for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
2.503 + Node v = _graph.source(e);
2.504 + if (_dormant[(*_bucket)[v]]) continue;
2.505 + Value rem = (*_flow)[e];
2.506 + if (!_tolerance.positive(rem)) continue;
2.507 + if ((*_bucket)[v] == under_bucket) {
2.508 + if (!(*_active)[v] && v != target) {
2.509 + activate(v);
2.510 + }
2.511 + if (!_tolerance.less(rem, excess)) {
2.512 + _flow->set(e, (*_flow)[e] - excess);
2.513 + _excess->set(v, (*_excess)[v] + excess);
2.514 + excess = 0;
2.515 + goto no_more_push;
2.516 + } else {
2.517 + excess -= rem;
2.518 + _excess->set(v, (*_excess)[v] + rem);
2.519 + _flow->set(e, 0);
2.520 + }
2.521 + } else if (next_bucket > (*_bucket)[v]) {
2.522 + next_bucket = (*_bucket)[v];
2.523 + }
2.524 + }
2.525 +
2.526 + no_more_push:
2.527 +
2.528 + _excess->set(n, excess);
2.529 +
2.530 + if (excess != 0) {
2.531 + if ((*_next)[n] == INVALID) {
2.532 + typename std::list<std::list<int> >::iterator new_set =
2.533 + _sets.insert(--_sets.end(), std::list<int>());
2.534 + new_set->splice(new_set->end(), _sets.back(),
2.535 + _sets.back().begin(), ++_highest);
2.536 + for (std::list<int>::iterator it = new_set->begin();
2.537 + it != new_set->end(); ++it) {
2.538 + _dormant[*it] = true;
2.539 + }
2.540 + while (_highest != _sets.back().end() &&
2.541 + !(*_active)[_first[*_highest]]) {
2.542 + ++_highest;
2.543 + }
2.544 + } else if (next_bucket == _node_num) {
2.545 + _first[(*_bucket)[n]] = (*_next)[n];
2.546 + _prev->set((*_next)[n], INVALID);
2.547 +
2.548 + std::list<std::list<int> >::iterator new_set =
2.549 + _sets.insert(--_sets.end(), std::list<int>());
2.550 +
2.551 + new_set->push_front(bucket_num);
2.552 + _bucket->set(n, bucket_num);
2.553 + _first[bucket_num] = _last[bucket_num] = n;
2.554 + _next->set(n, INVALID);
2.555 + _prev->set(n, INVALID);
2.556 + _dormant[bucket_num] = true;
2.557 + ++bucket_num;
2.558 +
2.559 + while (_highest != _sets.back().end() &&
2.560 + !(*_active)[_first[*_highest]]) {
2.561 + ++_highest;
2.562 + }
2.563 + } else {
2.564 + _first[*_highest] = (*_next)[n];
2.565 + _prev->set((*_next)[n], INVALID);
2.566 +
2.567 + while (next_bucket != *_highest) {
2.568 + --_highest;
2.569 + }
2.570 +
2.571 + if (_highest == _sets.back().begin()) {
2.572 + _sets.back().push_front(bucket_num);
2.573 + _dormant[bucket_num] = false;
2.574 + _first[bucket_num] = _last[bucket_num] = INVALID;
2.575 + ++bucket_num;
2.576 + }
2.577 + --_highest;
2.578 +
2.579 + _bucket->set(n, *_highest);
2.580 + _next->set(n, _first[*_highest]);
2.581 + if (_first[*_highest] != INVALID) {
2.582 + _prev->set(_first[*_highest], n);
2.583 + } else {
2.584 + _last[*_highest] = n;
2.585 + }
2.586 + _first[*_highest] = n;
2.587 + }
2.588 + } else {
2.589 +
2.590 + deactivate(n);
2.591 + if (!(*_active)[_first[*_highest]]) {
2.592 + ++_highest;
2.593 + if (_highest != _sets.back().end() &&
2.594 + !(*_active)[_first[*_highest]]) {
2.595 + _highest = _sets.back().end();
2.596 + }
2.597 + }
2.598 + }
2.599 + }
2.600 +
2.601 + if ((*_excess)[target] < _min_cut) {
2.602 + _min_cut = (*_excess)[target];
2.603 + for (NodeIt i(_graph); i != INVALID; ++i) {
2.604 + _min_cut_map->set(i, true);
2.605 + }
2.606 + for (std::list<int>::iterator it = _sets.back().begin();
2.607 + it != _sets.back().end(); ++it) {
2.608 + Node n = _first[*it];
2.609 + while (n != INVALID) {
2.610 + _min_cut_map->set(n, false);
2.611 + n = (*_next)[n];
2.612 + }
2.613 + }
2.614 + }
2.615 +
2.616 + {
2.617 + Node new_target;
2.618 + if ((*_prev)[target] != INVALID) {
2.619 + _last[(*_bucket)[target]] = (*_prev)[target];
2.620 + _next->set((*_prev)[target], INVALID);
2.621 + new_target = (*_prev)[target];
2.622 + } else {
2.623 + _sets.back().pop_back();
2.624 + if (_sets.back().empty()) {
2.625 + _sets.pop_back();
2.626 + if (_sets.empty())
2.627 + break;
2.628 + for (std::list<int>::iterator it = _sets.back().begin();
2.629 + it != _sets.back().end(); ++it) {
2.630 + _dormant[*it] = false;
2.631 + }
2.632 + }
2.633 + new_target = _last[_sets.back().back()];
2.634 + }
2.635 +
2.636 + _bucket->set(target, 0);
2.637 +
2.638 + _source_set->set(target, true);
2.639 + for (OutEdgeIt e(_graph, target); e != INVALID; ++e) {
2.640 + Value rem = (*_capacity)[e] - (*_flow)[e];
2.641 + if (!_tolerance.positive(rem)) continue;
2.642 + Node v = _graph.target(e);
2.643 + if (!(*_active)[v] && !(*_source_set)[v]) {
2.644 + activate(v);
2.645 + }
2.646 + _excess->set(v, (*_excess)[v] + rem);
2.647 + _flow->set(e, (*_capacity)[e]);
2.648 + }
2.649 +
2.650 + for (InEdgeIt e(_graph, target); e != INVALID; ++e) {
2.651 + Value rem = (*_flow)[e];
2.652 + if (!_tolerance.positive(rem)) continue;
2.653 + Node v = _graph.source(e);
2.654 + if (!(*_active)[v] && !(*_source_set)[v]) {
2.655 + activate(v);
2.656 + }
2.657 + _excess->set(v, (*_excess)[v] + rem);
2.658 + _flow->set(e, 0);
2.659 + }
2.660 +
2.661 + target = new_target;
2.662 + if ((*_active)[target]) {
2.663 + deactivate(target);
2.664 + }
2.665 +
2.666 + _highest = _sets.back().begin();
2.667 + while (_highest != _sets.back().end() &&
2.668 + !(*_active)[_first[*_highest]]) {
2.669 + ++_highest;
2.670 + }
2.671 + }
2.672 + }
2.673 + }
2.674 +
2.675 + void findMinCutIn() {
2.676 +
2.677 + for (NodeIt n(_graph); n != INVALID; ++n) {
2.678 + _excess->set(n, 0);
2.679 + }
2.680 +
2.681 + for (EdgeIt e(_graph); e != INVALID; ++e) {
2.682 + _flow->set(e, 0);
2.683 + }
2.684 +
2.685 + int bucket_num = 1;
2.686 +
2.687 + {
2.688 + typename Graph::template NodeMap<bool> reached(_graph, false);
2.689 +
2.690 + reached.set(_source, true);
2.691 +
2.692 + bool first_set = true;
2.693 +
2.694 + for (NodeIt t(_graph); t != INVALID; ++t) {
2.695 + if (reached[t]) continue;
2.696 + _sets.push_front(std::list<int>());
2.697 + _sets.front().push_front(bucket_num);
2.698 + _dormant[bucket_num] = !first_set;
2.699 +
2.700 + _bucket->set(t, bucket_num);
2.701 + _first[bucket_num] = _last[bucket_num] = t;
2.702 + _next->set(t, INVALID);
2.703 + _prev->set(t, INVALID);
2.704 +
2.705 + ++bucket_num;
2.706 +
2.707 + std::vector<Node> queue;
2.708 + queue.push_back(t);
2.709 + reached.set(t, true);
2.710 +
2.711 + while (!queue.empty()) {
2.712 + _sets.front().push_front(bucket_num);
2.713 + _dormant[bucket_num] = !first_set;
2.714 + _first[bucket_num] = _last[bucket_num] = INVALID;
2.715 +
2.716 + std::vector<Node> nqueue;
2.717 + for (int i = 0; i < int(queue.size()); ++i) {
2.718 + Node n = queue[i];
2.719 + for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
2.720 + Node u = _graph.target(e);
2.721 + if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
2.722 + reached.set(u, true);
2.723 + addItem(u, bucket_num);
2.724 + nqueue.push_back(u);
2.725 + }
2.726 + }
2.727 + }
2.728 + queue.swap(nqueue);
2.729 + ++bucket_num;
2.730 + }
2.731 + _sets.front().pop_front();
2.732 + --bucket_num;
2.733 + first_set = false;
2.734 + }
2.735 +
2.736 + _bucket->set(_source, 0);
2.737 + _dormant[0] = true;
2.738 + }
2.739 + _source_set->set(_source, true);
2.740 +
2.741 + Node target = _last[_sets.back().back()];
2.742 + {
2.743 + for (InEdgeIt e(_graph, _source); e != INVALID; ++e) {
2.744 + if (_tolerance.positive((*_capacity)[e])) {
2.745 + Node u = _graph.source(e);
2.746 + _flow->set(e, (*_capacity)[e]);
2.747 + _excess->set(u, (*_excess)[u] + (*_capacity)[e]);
2.748 + if (!(*_active)[u] && u != _source) {
2.749 + activate(u);
2.750 + }
2.751 + }
2.752 + }
2.753 + if ((*_active)[target]) {
2.754 + deactivate(target);
2.755 + }
2.756 +
2.757 + _highest = _sets.back().begin();
2.758 + while (_highest != _sets.back().end() &&
2.759 + !(*_active)[_first[*_highest]]) {
2.760 + ++_highest;
2.761 + }
2.762 + }
2.763 +
2.764 +
2.765 + while (true) {
2.766 + while (_highest != _sets.back().end()) {
2.767 + Node n = _first[*_highest];
2.768 + Value excess = (*_excess)[n];
2.769 + int next_bucket = _node_num;
2.770 +
2.771 + int under_bucket;
2.772 + if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
2.773 + under_bucket = -1;
2.774 + } else {
2.775 + under_bucket = *(++std::list<int>::iterator(_highest));
2.776 + }
2.777 +
2.778 + for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
2.779 + Node v = _graph.source(e);
2.780 + if (_dormant[(*_bucket)[v]]) continue;
2.781 + Value rem = (*_capacity)[e] - (*_flow)[e];
2.782 + if (!_tolerance.positive(rem)) continue;
2.783 + if ((*_bucket)[v] == under_bucket) {
2.784 + if (!(*_active)[v] && v != target) {
2.785 + activate(v);
2.786 + }
2.787 + if (!_tolerance.less(rem, excess)) {
2.788 + _flow->set(e, (*_flow)[e] + excess);
2.789 + _excess->set(v, (*_excess)[v] + excess);
2.790 + excess = 0;
2.791 + goto no_more_push;
2.792 + } else {
2.793 + excess -= rem;
2.794 + _excess->set(v, (*_excess)[v] + rem);
2.795 + _flow->set(e, (*_capacity)[e]);
2.796 + }
2.797 + } else if (next_bucket > (*_bucket)[v]) {
2.798 + next_bucket = (*_bucket)[v];
2.799 + }
2.800 + }
2.801 +
2.802 + for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
2.803 + Node v = _graph.target(e);
2.804 + if (_dormant[(*_bucket)[v]]) continue;
2.805 + Value rem = (*_flow)[e];
2.806 + if (!_tolerance.positive(rem)) continue;
2.807 + if ((*_bucket)[v] == under_bucket) {
2.808 + if (!(*_active)[v] && v != target) {
2.809 + activate(v);
2.810 + }
2.811 + if (!_tolerance.less(rem, excess)) {
2.812 + _flow->set(e, (*_flow)[e] - excess);
2.813 + _excess->set(v, (*_excess)[v] + excess);
2.814 + excess = 0;
2.815 + goto no_more_push;
2.816 + } else {
2.817 + excess -= rem;
2.818 + _excess->set(v, (*_excess)[v] + rem);
2.819 + _flow->set(e, 0);
2.820 + }
2.821 + } else if (next_bucket > (*_bucket)[v]) {
2.822 + next_bucket = (*_bucket)[v];
2.823 + }
2.824 + }
2.825 +
2.826 + no_more_push:
2.827 +
2.828 + _excess->set(n, excess);
2.829 +
2.830 + if (excess != 0) {
2.831 + if ((*_next)[n] == INVALID) {
2.832 + typename std::list<std::list<int> >::iterator new_set =
2.833 + _sets.insert(--_sets.end(), std::list<int>());
2.834 + new_set->splice(new_set->end(), _sets.back(),
2.835 + _sets.back().begin(), ++_highest);
2.836 + for (std::list<int>::iterator it = new_set->begin();
2.837 + it != new_set->end(); ++it) {
2.838 + _dormant[*it] = true;
2.839 + }
2.840 + while (_highest != _sets.back().end() &&
2.841 + !(*_active)[_first[*_highest]]) {
2.842 + ++_highest;
2.843 + }
2.844 + } else if (next_bucket == _node_num) {
2.845 + _first[(*_bucket)[n]] = (*_next)[n];
2.846 + _prev->set((*_next)[n], INVALID);
2.847 +
2.848 + std::list<std::list<int> >::iterator new_set =
2.849 + _sets.insert(--_sets.end(), std::list<int>());
2.850 +
2.851 + new_set->push_front(bucket_num);
2.852 + _bucket->set(n, bucket_num);
2.853 + _first[bucket_num] = _last[bucket_num] = n;
2.854 + _next->set(n, INVALID);
2.855 + _prev->set(n, INVALID);
2.856 + _dormant[bucket_num] = true;
2.857 + ++bucket_num;
2.858 +
2.859 + while (_highest != _sets.back().end() &&
2.860 + !(*_active)[_first[*_highest]]) {
2.861 + ++_highest;
2.862 + }
2.863 + } else {
2.864 + _first[*_highest] = (*_next)[n];
2.865 + _prev->set((*_next)[n], INVALID);
2.866 +
2.867 + while (next_bucket != *_highest) {
2.868 + --_highest;
2.869 + }
2.870 + if (_highest == _sets.back().begin()) {
2.871 + _sets.back().push_front(bucket_num);
2.872 + _dormant[bucket_num] = false;
2.873 + _first[bucket_num] = _last[bucket_num] = INVALID;
2.874 + ++bucket_num;
2.875 + }
2.876 + --_highest;
2.877 +
2.878 + _bucket->set(n, *_highest);
2.879 + _next->set(n, _first[*_highest]);
2.880 + if (_first[*_highest] != INVALID) {
2.881 + _prev->set(_first[*_highest], n);
2.882 + } else {
2.883 + _last[*_highest] = n;
2.884 + }
2.885 + _first[*_highest] = n;
2.886 + }
2.887 + } else {
2.888 +
2.889 + deactivate(n);
2.890 + if (!(*_active)[_first[*_highest]]) {
2.891 + ++_highest;
2.892 + if (_highest != _sets.back().end() &&
2.893 + !(*_active)[_first[*_highest]]) {
2.894 + _highest = _sets.back().end();
2.895 + }
2.896 + }
2.897 + }
2.898 + }
2.899 +
2.900 + if ((*_excess)[target] < _min_cut) {
2.901 + _min_cut = (*_excess)[target];
2.902 + for (NodeIt i(_graph); i != INVALID; ++i) {
2.903 + _min_cut_map->set(i, false);
2.904 + }
2.905 + for (std::list<int>::iterator it = _sets.back().begin();
2.906 + it != _sets.back().end(); ++it) {
2.907 + Node n = _first[*it];
2.908 + while (n != INVALID) {
2.909 + _min_cut_map->set(n, true);
2.910 + n = (*_next)[n];
2.911 + }
2.912 + }
2.913 + }
2.914 +
2.915 + {
2.916 + Node new_target;
2.917 + if ((*_prev)[target] != INVALID) {
2.918 + _last[(*_bucket)[target]] = (*_prev)[target];
2.919 + _next->set((*_prev)[target], INVALID);
2.920 + new_target = (*_prev)[target];
2.921 + } else {
2.922 + _sets.back().pop_back();
2.923 + if (_sets.back().empty()) {
2.924 + _sets.pop_back();
2.925 + if (_sets.empty())
2.926 + break;
2.927 + for (std::list<int>::iterator it = _sets.back().begin();
2.928 + it != _sets.back().end(); ++it) {
2.929 + _dormant[*it] = false;
2.930 + }
2.931 + }
2.932 + new_target = _last[_sets.back().back()];
2.933 + }
2.934 +
2.935 + _bucket->set(target, 0);
2.936 +
2.937 + _source_set->set(target, true);
2.938 + for (InEdgeIt e(_graph, target); e != INVALID; ++e) {
2.939 + Value rem = (*_capacity)[e] - (*_flow)[e];
2.940 + if (!_tolerance.positive(rem)) continue;
2.941 + Node v = _graph.source(e);
2.942 + if (!(*_active)[v] && !(*_source_set)[v]) {
2.943 + activate(v);
2.944 + }
2.945 + _excess->set(v, (*_excess)[v] + rem);
2.946 + _flow->set(e, (*_capacity)[e]);
2.947 + }
2.948 +
2.949 + for (OutEdgeIt e(_graph, target); e != INVALID; ++e) {
2.950 + Value rem = (*_flow)[e];
2.951 + if (!_tolerance.positive(rem)) continue;
2.952 + Node v = _graph.target(e);
2.953 + if (!(*_active)[v] && !(*_source_set)[v]) {
2.954 + activate(v);
2.955 + }
2.956 + _excess->set(v, (*_excess)[v] + rem);
2.957 + _flow->set(e, 0);
2.958 + }
2.959 +
2.960 + target = new_target;
2.961 + if ((*_active)[target]) {
2.962 + deactivate(target);
2.963 + }
2.964 +
2.965 + _highest = _sets.back().begin();
2.966 + while (_highest != _sets.back().end() &&
2.967 + !(*_active)[_first[*_highest]]) {
2.968 + ++_highest;
2.969 + }
2.970 }
2.971 }
2.972 }
2.973
2.974 - template <typename ResGraph>
2.975 - bool selectNewSink(ResGraph& res_graph) {
2.976 - typedef typename ResGraph::OutEdgeIt ResOutEdgeIt;
2.977 -
2.978 - Node old_target = _target;
2.979 - (*_wake)[_target] = false;
2.980 - --_level_size[(*_dist)[_target]];
2.981 - _dormant[0].push_front(_target);
2.982 - (*_source_set)[_target] = true;
2.983 - if (int(_dormant[0].size()) == _node_num){
2.984 - _dormant[0].clear();
2.985 - return false;
2.986 - }
2.987 -
2.988 - bool wake_was_empty = false;
2.989 -
2.990 - if(_wake->trueNum() == 0) {
2.991 - while (!_dormant[_dormant_max].empty()){
2.992 - (*_wake)[_dormant[_dormant_max].front()] = true;
2.993 - ++_level_size[(*_dist)[_dormant[_dormant_max].front()]];
2.994 - _dormant[_dormant_max].pop_front();
2.995 - }
2.996 - --_dormant_max;
2.997 - wake_was_empty = true;
2.998 - }
2.999 -
2.1000 - int min_dist = std::numeric_limits<int>::max();
2.1001 - for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
2.1002 - if (min_dist > (*_dist)[it]){
2.1003 - _target = it;
2.1004 - min_dist = (*_dist)[it];
2.1005 - }
2.1006 - }
2.1007 -
2.1008 - if (wake_was_empty){
2.1009 - for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
2.1010 - if ((*_excess)[it] != 0 && it != _target) {
2.1011 - _active_nodes[(*_dist)[it]].push_front(it);
2.1012 - if (_highest_active < (*_dist)[it]) {
2.1013 - _highest_active = (*_dist)[it];
2.1014 - }
2.1015 - }
2.1016 - }
2.1017 - }
2.1018 -
2.1019 - Node n = old_target;
2.1020 - for (ResOutEdgeIt e(res_graph, n); e != INVALID; ++e){
2.1021 - Node a = res_graph.target(e);
2.1022 - if (!(*_wake)[a]) continue;
2.1023 - Value delta = res_graph.rescap(e);
2.1024 - res_graph.augment(e, delta);
2.1025 - (*_excess)[n] -= delta;
2.1026 - if ((*_excess)[a] == 0 && (*_wake)[a] && a != _target) {
2.1027 - _active_nodes[(*_dist)[a]].push_front(a);
2.1028 - if (_highest_active < (*_dist)[a]) {
2.1029 - _highest_active = (*_dist)[a];
2.1030 - }
2.1031 - }
2.1032 - (*_excess)[a] += delta;
2.1033 - }
2.1034 -
2.1035 - return true;
2.1036 - }
2.1037 -
2.1038 - Node findActiveNode() {
2.1039 - while (_highest_active > 0 && _active_nodes[_highest_active].empty()){
2.1040 - --_highest_active;
2.1041 - }
2.1042 - if( _highest_active > 0) {
2.1043 - Node n = _active_nodes[_highest_active].front();
2.1044 - _active_nodes[_highest_active].pop_front();
2.1045 - return n;
2.1046 - } else {
2.1047 - return INVALID;
2.1048 - }
2.1049 - }
2.1050 -
2.1051 - Value cutValue(bool out) {
2.1052 - Value value = 0;
2.1053 - if (out) {
2.1054 - for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
2.1055 - for (InEdgeIt e(*_graph, it); e != INVALID; ++e) {
2.1056 - if (!(*_wake)[_graph->source(e)]){
2.1057 - value += (*_capacity)[e];
2.1058 - }
2.1059 - }
2.1060 - }
2.1061 - } else {
2.1062 - for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
2.1063 - for (OutEdgeIt e(*_graph, it); e != INVALID; ++e) {
2.1064 - if (!(*_wake)[_graph->target(e)]){
2.1065 - value += (*_capacity)[e];
2.1066 - }
2.1067 - }
2.1068 - }
2.1069 - }
2.1070 - return value;
2.1071 - }
2.1072 -
2.1073 -
2.1074 public:
2.1075
2.1076 /// \name Execution control
2.1077 @@ -435,7 +836,7 @@
2.1078 /// the maps, residual graph adaptors and some bucket structures
2.1079 /// for the algorithm.
2.1080 void init() {
2.1081 - init(NodeIt(*_graph));
2.1082 + init(NodeIt(_graph));
2.1083 }
2.1084
2.1085 /// \brief Initializes the internal data structures.
2.1086 @@ -446,38 +847,37 @@
2.1087 /// algorithm's source.
2.1088 void init(const Node& source) {
2.1089 _source = source;
2.1090 - _node_num = countNodes(*_graph);
2.1091 +
2.1092 + _node_num = countNodes(_graph);
2.1093 +
2.1094 + _first.resize(_node_num);
2.1095 + _last.resize(_node_num);
2.1096
2.1097 _dormant.resize(_node_num);
2.1098 - _level_size.resize(_node_num, 0);
2.1099 - _active_nodes.resize(_node_num);
2.1100
2.1101 - if (!_preflow) {
2.1102 - _preflow = new FlowMap(*_graph);
2.1103 + if (!_flow) {
2.1104 + _flow = new FlowMap(_graph);
2.1105 }
2.1106 - if (!_wake) {
2.1107 - _wake = new WakeMap(*_graph);
2.1108 + if (!_next) {
2.1109 + _next = new typename Graph::template NodeMap<Node>(_graph);
2.1110 }
2.1111 - if (!_dist) {
2.1112 - _dist = new DistMap(*_graph);
2.1113 + if (!_prev) {
2.1114 + _prev = new typename Graph::template NodeMap<Node>(_graph);
2.1115 + }
2.1116 + if (!_active) {
2.1117 + _active = new typename Graph::template NodeMap<bool>(_graph);
2.1118 + }
2.1119 + if (!_bucket) {
2.1120 + _bucket = new typename Graph::template NodeMap<int>(_graph);
2.1121 }
2.1122 if (!_excess) {
2.1123 - _excess = new ExcessMap(*_graph);
2.1124 + _excess = new ExcessMap(_graph);
2.1125 }
2.1126 if (!_source_set) {
2.1127 - _source_set = new SourceSetMap(*_graph);
2.1128 - }
2.1129 - if (!_out_res_graph) {
2.1130 - _out_res_graph = new OutResGraph(*_graph, *_capacity, *_preflow);
2.1131 - }
2.1132 - if (!_rev_graph) {
2.1133 - _rev_graph = new RevGraph(*_graph);
2.1134 - }
2.1135 - if (!_in_res_graph) {
2.1136 - _in_res_graph = new InResGraph(*_rev_graph, *_capacity, *_preflow);
2.1137 + _source_set = new SourceSetMap(_graph);
2.1138 }
2.1139 if (!_min_cut_map) {
2.1140 - _min_cut_map = new MinCutMap(*_graph);
2.1141 + _min_cut_map = new MinCutMap(_graph);
2.1142 }
2.1143
2.1144 _min_cut = std::numeric_limits<Value>::max();
2.1145 @@ -487,56 +887,23 @@
2.1146 /// \brief Calculates a minimum cut with \f$ source \f$ on the
2.1147 /// source-side.
2.1148 ///
2.1149 - /// \brief Calculates a minimum cut with \f$ source \f$ on the
2.1150 - /// source-side (i.e. a set \f$ X\subsetneq V \f$ with \f$ source \in X \f$
2.1151 - /// and minimal out-degree).
2.1152 + /// Calculates a minimum cut with \f$ source \f$ on the
2.1153 + /// source-side (i.e. a set \f$ X\subsetneq V \f$ with \f$ source
2.1154 + /// \in X \f$ and minimal out-degree).
2.1155 void calculateOut() {
2.1156 - for (NodeIt it(*_graph); it != INVALID; ++it) {
2.1157 - if (it != _source) {
2.1158 - calculateOut(it);
2.1159 - return;
2.1160 - }
2.1161 - }
2.1162 + findMinCutOut();
2.1163 }
2.1164
2.1165 /// \brief Calculates a minimum cut with \f$ source \f$ on the
2.1166 - /// source-side.
2.1167 + /// target-side.
2.1168 ///
2.1169 - /// \brief Calculates a minimum cut with \f$ source \f$ on the
2.1170 - /// source-side (i.e. a set \f$ X\subsetneq V \f$ with \f$ source \in X \f$
2.1171 - /// and minimal out-degree). The \c target is the initial target
2.1172 - /// for the push-relabel algorithm.
2.1173 - void calculateOut(const Node& target) {
2.1174 - findMinCut(target, true, *_out_res_graph);
2.1175 + /// Calculates a minimum cut with \f$ source \f$ on the
2.1176 + /// target-side (i.e. a set \f$ X\subsetneq V \f$ with \f$ source
2.1177 + /// \in X \f$ and minimal out-degree).
2.1178 + void calculateIn() {
2.1179 + findMinCutIn();
2.1180 }
2.1181
2.1182 - /// \brief Calculates a minimum cut with \f$ source \f$ on the
2.1183 - /// sink-side.
2.1184 - ///
2.1185 - /// \brief Calculates a minimum cut with \f$ source \f$ on the
2.1186 - /// sink-side (i.e. a set \f$ X\subsetneq V \f$ with
2.1187 - /// \f$ source \notin X \f$
2.1188 - /// and minimal out-degree).
2.1189 - void calculateIn() {
2.1190 - for (NodeIt it(*_graph); it != INVALID; ++it) {
2.1191 - if (it != _source) {
2.1192 - calculateIn(it);
2.1193 - return;
2.1194 - }
2.1195 - }
2.1196 - }
2.1197 -
2.1198 - /// \brief Calculates a minimum cut with \f$ source \f$ on the
2.1199 - /// sink-side.
2.1200 - ///
2.1201 - /// \brief Calculates a minimum cut with \f$ source \f$ on the
2.1202 - /// sink-side (i.e. a set \f$ X\subsetneq V
2.1203 - /// \f$ with \f$ source \notin X \f$ and minimal out-degree).
2.1204 - /// The \c target is the initial
2.1205 - /// target for the push-relabel algorithm.
2.1206 - void calculateIn(const Node& target) {
2.1207 - findMinCut(target, false, *_in_res_graph);
2.1208 - }
2.1209
2.1210 /// \brief Runs the algorithm.
2.1211 ///
2.1212 @@ -545,13 +912,8 @@
2.1213 /// and \ref calculateIn().
2.1214 void run() {
2.1215 init();
2.1216 - for (NodeIt it(*_graph); it != INVALID; ++it) {
2.1217 - if (it != _source) {
2.1218 - calculateOut(it);
2.1219 - calculateIn(it);
2.1220 - return;
2.1221 - }
2.1222 - }
2.1223 + calculateOut();
2.1224 + calculateIn();
2.1225 }
2.1226
2.1227 /// \brief Runs the algorithm.
2.1228 @@ -561,23 +923,8 @@
2.1229 /// calculateOut() and \ref calculateIn().
2.1230 void run(const Node& s) {
2.1231 init(s);
2.1232 - for (NodeIt it(*_graph); it != INVALID; ++it) {
2.1233 - if (it != _source) {
2.1234 - calculateOut(it);
2.1235 - calculateIn(it);
2.1236 - return;
2.1237 - }
2.1238 - }
2.1239 - }
2.1240 -
2.1241 - /// \brief Runs the algorithm.
2.1242 - ///
2.1243 - /// Runs the algorithm. It just calls the \ref init() and then
2.1244 - /// \ref calculateOut() and \ref calculateIn().
2.1245 - void run(const Node& s, const Node& t) {
2.1246 - init(s);
2.1247 - calculateOut(t);
2.1248 - calculateIn(t);
2.1249 + calculateOut();
2.1250 + calculateIn();
2.1251 }
2.1252
2.1253 /// @}
2.1254 @@ -608,7 +955,7 @@
2.1255 /// bool-valued node-map.
2.1256 template <typename NodeMap>
2.1257 Value minCut(NodeMap& nodeMap) const {
2.1258 - for (NodeIt it(*_graph); it != INVALID; ++it) {
2.1259 + for (NodeIt it(_graph); it != INVALID; ++it) {
2.1260 nodeMap.set(it, (*_min_cut_map)[it]);
2.1261 }
2.1262 return minCut();
3.1 --- a/lemon/nagamochi_ibaraki.h Fri Nov 30 09:22:38 2007 +0000
3.2 +++ b/lemon/nagamochi_ibaraki.h Tue Dec 04 10:55:27 2007 +0000
3.3 @@ -847,9 +847,9 @@
3.4 /// distinict subnetwork.
3.5 ///
3.6 /// The complexity of the algorithm is \f$ O(ne\log(n)) \f$ but with
3.7 - /// Fibonacci heap it can be decreased to \f$ O(ne+n^2\log(n)) \f$.
3.8 - /// When capacity map is neutral then it uses BucketHeap which
3.9 - /// results \f$ O(ne) \f$ time complexity.
3.10 + /// Fibonacci heap it can be decreased to \f$ O(ne+n^2\log(n)) \f$.
3.11 + /// When unit capacity minimum cut is computed then it uses
3.12 + /// BucketHeap which results \f$ O(ne) \f$ time complexity.
3.13 ///
3.14 /// \warning The value type of the capacity map should be able to hold
3.15 /// any cut value of the graph, otherwise the result can overflow.
3.16 @@ -906,7 +906,7 @@
3.17
3.18 ///@{
3.19
3.20 - struct DefNeutralCapacityTraits : public Traits {
3.21 + struct DefUnitCapacityTraits : public Traits {
3.22 typedef ConstMap<typename Graph::UEdge, Const<int, 1> > CapacityMap;
3.23 static CapacityMap *createCapacityMap(const Graph&) {
3.24 return new CapacityMap();
3.25 @@ -917,11 +917,11 @@
3.26 ///
3.27 /// \ref named-templ-param "Named parameter" for setting
3.28 /// the capacity type to constMap<UEdge, int, 1>()
3.29 - struct DefNeutralCapacity
3.30 + struct DefUnitCapacity
3.31 : public NagamochiIbaraki<Graph, CapacityMap,
3.32 - DefNeutralCapacityTraits> {
3.33 + DefUnitCapacityTraits> {
3.34 typedef NagamochiIbaraki<Graph, CapacityMap,
3.35 - DefNeutralCapacityTraits> Create;
3.36 + DefUnitCapacityTraits> Create;
3.37 };
3.38
3.39
3.40 @@ -1134,7 +1134,7 @@
3.41 ///
3.42 /// This constructor can be used only when the Traits class
3.43 /// defines how can we instantiate a local capacity map.
3.44 - /// If the DefNeutralCapacity used the algorithm automatically
3.45 + /// If the DefUnitCapacity used the algorithm automatically
3.46 /// construct the capacity map.
3.47 ///
3.48 ///\param graph the graph the algorithm will run on.