1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/lemon/hao_orlin.h Tue Dec 02 11:01:48 2008 +0000
1.3 @@ -0,0 +1,966 @@
1.4 +/* -*- mode: C++; indent-tabs-mode: nil; -*-
1.5 + *
1.6 + * This file is a part of LEMON, a generic C++ optimization library.
1.7 + *
1.8 + * Copyright (C) 2003-2008
1.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
1.11 + *
1.12 + * Permission to use, modify and distribute this software is granted
1.13 + * provided that this copyright notice appears in all copies. For
1.14 + * precise terms see the accompanying LICENSE file.
1.15 + *
1.16 + * This software is provided "AS IS" with no warranty of any kind,
1.17 + * express or implied, and with no claim as to its suitability for any
1.18 + * purpose.
1.19 + *
1.20 + */
1.21 +
1.22 +#ifndef LEMON_HAO_ORLIN_H
1.23 +#define LEMON_HAO_ORLIN_H
1.24 +
1.25 +#include <vector>
1.26 +#include <list>
1.27 +#include <limits>
1.28 +
1.29 +#include <lemon/maps.h>
1.30 +#include <lemon/core.h>
1.31 +#include <lemon/tolerance.h>
1.32 +
1.33 +/// \file
1.34 +/// \ingroup min_cut
1.35 +/// \brief Implementation of the Hao-Orlin algorithm.
1.36 +///
1.37 +/// Implementation of the Hao-Orlin algorithm class for testing network
1.38 +/// reliability.
1.39 +
1.40 +namespace lemon {
1.41 +
1.42 + /// \ingroup min_cut
1.43 + ///
1.44 + /// \brief %Hao-Orlin algorithm to find a minimum cut in directed graphs.
1.45 + ///
1.46 + /// Hao-Orlin calculates a minimum cut in a directed graph
1.47 + /// \f$D=(V,A)\f$. It takes a fixed node \f$ source \in V \f$ and
1.48 + /// consists of two phases: in the first phase it determines a
1.49 + /// minimum cut with \f$ source \f$ on the source-side (i.e. a set
1.50 + /// \f$ X\subsetneq V \f$ with \f$ source \in X \f$ and minimal
1.51 + /// out-degree) and in the second phase it determines a minimum cut
1.52 + /// with \f$ source \f$ on the sink-side (i.e. a set
1.53 + /// \f$ X\subsetneq V \f$ with \f$ source \notin X \f$ and minimal
1.54 + /// out-degree). Obviously, the smaller of these two cuts will be a
1.55 + /// minimum cut of \f$ D \f$. The algorithm is a modified
1.56 + /// push-relabel preflow algorithm and our implementation calculates
1.57 + /// the minimum cut in \f$ O(n^2\sqrt{m}) \f$ time (we use the
1.58 + /// highest-label rule), or in \f$O(nm)\f$ for unit capacities. The
1.59 + /// purpose of such algorithm is testing network reliability. For an
1.60 + /// undirected graph you can run just the first phase of the
1.61 + /// algorithm or you can use the algorithm of Nagamochi and Ibaraki
1.62 + /// which solves the undirected problem in
1.63 + /// \f$ O(nm + n^2 \log(n)) \f$ time: it is implemented in the
1.64 + /// NagamochiIbaraki algorithm class.
1.65 + ///
1.66 + /// \param _Digraph is the graph type of the algorithm.
1.67 + /// \param _CapacityMap is an edge map of capacities which should
1.68 + /// be any numreric type. The default type is _Digraph::ArcMap<int>.
1.69 + /// \param _Tolerance is the handler of the inexact computation. The
1.70 + /// default type for this is Tolerance<CapacityMap::Value>.
1.71 +#ifdef DOXYGEN
1.72 + template <typename _Digraph, typename _CapacityMap, typename _Tolerance>
1.73 +#else
1.74 + template <typename _Digraph,
1.75 + typename _CapacityMap = typename _Digraph::template ArcMap<int>,
1.76 + typename _Tolerance = Tolerance<typename _CapacityMap::Value> >
1.77 +#endif
1.78 + class HaoOrlin {
1.79 + private:
1.80 +
1.81 + typedef _Digraph Digraph;
1.82 + typedef _CapacityMap CapacityMap;
1.83 + typedef _Tolerance Tolerance;
1.84 +
1.85 + typedef typename CapacityMap::Value Value;
1.86 +
1.87 + TEMPLATE_GRAPH_TYPEDEFS(Digraph);
1.88 +
1.89 + const Digraph& _graph;
1.90 + const CapacityMap* _capacity;
1.91 +
1.92 + typedef typename Digraph::template ArcMap<Value> FlowMap;
1.93 + FlowMap* _flow;
1.94 +
1.95 + Node _source;
1.96 +
1.97 + int _node_num;
1.98 +
1.99 + // Bucketing structure
1.100 + std::vector<Node> _first, _last;
1.101 + typename Digraph::template NodeMap<Node>* _next;
1.102 + typename Digraph::template NodeMap<Node>* _prev;
1.103 + typename Digraph::template NodeMap<bool>* _active;
1.104 + typename Digraph::template NodeMap<int>* _bucket;
1.105 +
1.106 + std::vector<bool> _dormant;
1.107 +
1.108 + std::list<std::list<int> > _sets;
1.109 + std::list<int>::iterator _highest;
1.110 +
1.111 + typedef typename Digraph::template NodeMap<Value> ExcessMap;
1.112 + ExcessMap* _excess;
1.113 +
1.114 + typedef typename Digraph::template NodeMap<bool> SourceSetMap;
1.115 + SourceSetMap* _source_set;
1.116 +
1.117 + Value _min_cut;
1.118 +
1.119 + typedef typename Digraph::template NodeMap<bool> MinCutMap;
1.120 + MinCutMap* _min_cut_map;
1.121 +
1.122 + Tolerance _tolerance;
1.123 +
1.124 + public:
1.125 +
1.126 + /// \brief Constructor
1.127 + ///
1.128 + /// Constructor of the algorithm class.
1.129 + HaoOrlin(const Digraph& graph, const CapacityMap& capacity,
1.130 + const Tolerance& tolerance = Tolerance()) :
1.131 + _graph(graph), _capacity(&capacity), _flow(0), _source(),
1.132 + _node_num(), _first(), _last(), _next(0), _prev(0),
1.133 + _active(0), _bucket(0), _dormant(), _sets(), _highest(),
1.134 + _excess(0), _source_set(0), _min_cut(), _min_cut_map(0),
1.135 + _tolerance(tolerance) {}
1.136 +
1.137 + ~HaoOrlin() {
1.138 + if (_min_cut_map) {
1.139 + delete _min_cut_map;
1.140 + }
1.141 + if (_source_set) {
1.142 + delete _source_set;
1.143 + }
1.144 + if (_excess) {
1.145 + delete _excess;
1.146 + }
1.147 + if (_next) {
1.148 + delete _next;
1.149 + }
1.150 + if (_prev) {
1.151 + delete _prev;
1.152 + }
1.153 + if (_active) {
1.154 + delete _active;
1.155 + }
1.156 + if (_bucket) {
1.157 + delete _bucket;
1.158 + }
1.159 + if (_flow) {
1.160 + delete _flow;
1.161 + }
1.162 + }
1.163 +
1.164 + private:
1.165 +
1.166 + void activate(const Node& i) {
1.167 + _active->set(i, true);
1.168 +
1.169 + int bucket = (*_bucket)[i];
1.170 +
1.171 + if ((*_prev)[i] == INVALID || (*_active)[(*_prev)[i]]) return;
1.172 + //unlace
1.173 + _next->set((*_prev)[i], (*_next)[i]);
1.174 + if ((*_next)[i] != INVALID) {
1.175 + _prev->set((*_next)[i], (*_prev)[i]);
1.176 + } else {
1.177 + _last[bucket] = (*_prev)[i];
1.178 + }
1.179 + //lace
1.180 + _next->set(i, _first[bucket]);
1.181 + _prev->set(_first[bucket], i);
1.182 + _prev->set(i, INVALID);
1.183 + _first[bucket] = i;
1.184 + }
1.185 +
1.186 + void deactivate(const Node& i) {
1.187 + _active->set(i, false);
1.188 + int bucket = (*_bucket)[i];
1.189 +
1.190 + if ((*_next)[i] == INVALID || !(*_active)[(*_next)[i]]) return;
1.191 +
1.192 + //unlace
1.193 + _prev->set((*_next)[i], (*_prev)[i]);
1.194 + if ((*_prev)[i] != INVALID) {
1.195 + _next->set((*_prev)[i], (*_next)[i]);
1.196 + } else {
1.197 + _first[bucket] = (*_next)[i];
1.198 + }
1.199 + //lace
1.200 + _prev->set(i, _last[bucket]);
1.201 + _next->set(_last[bucket], i);
1.202 + _next->set(i, INVALID);
1.203 + _last[bucket] = i;
1.204 + }
1.205 +
1.206 + void addItem(const Node& i, int bucket) {
1.207 + (*_bucket)[i] = bucket;
1.208 + if (_last[bucket] != INVALID) {
1.209 + _prev->set(i, _last[bucket]);
1.210 + _next->set(_last[bucket], i);
1.211 + _next->set(i, INVALID);
1.212 + _last[bucket] = i;
1.213 + } else {
1.214 + _prev->set(i, INVALID);
1.215 + _first[bucket] = i;
1.216 + _next->set(i, INVALID);
1.217 + _last[bucket] = i;
1.218 + }
1.219 + }
1.220 +
1.221 + void findMinCutOut() {
1.222 +
1.223 + for (NodeIt n(_graph); n != INVALID; ++n) {
1.224 + _excess->set(n, 0);
1.225 + }
1.226 +
1.227 + for (ArcIt a(_graph); a != INVALID; ++a) {
1.228 + _flow->set(a, 0);
1.229 + }
1.230 +
1.231 + int bucket_num = 0;
1.232 + std::vector<Node> queue(_node_num);
1.233 + int qfirst = 0, qlast = 0, qsep = 0;
1.234 +
1.235 + {
1.236 + typename Digraph::template NodeMap<bool> reached(_graph, false);
1.237 +
1.238 + reached.set(_source, true);
1.239 + bool first_set = true;
1.240 +
1.241 + for (NodeIt t(_graph); t != INVALID; ++t) {
1.242 + if (reached[t]) continue;
1.243 + _sets.push_front(std::list<int>());
1.244 +
1.245 + queue[qlast++] = t;
1.246 + reached.set(t, true);
1.247 +
1.248 + while (qfirst != qlast) {
1.249 + if (qsep == qfirst) {
1.250 + ++bucket_num;
1.251 + _sets.front().push_front(bucket_num);
1.252 + _dormant[bucket_num] = !first_set;
1.253 + _first[bucket_num] = _last[bucket_num] = INVALID;
1.254 + qsep = qlast;
1.255 + }
1.256 +
1.257 + Node n = queue[qfirst++];
1.258 + addItem(n, bucket_num);
1.259 +
1.260 + for (InArcIt a(_graph, n); a != INVALID; ++a) {
1.261 + Node u = _graph.source(a);
1.262 + if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
1.263 + reached.set(u, true);
1.264 + queue[qlast++] = u;
1.265 + }
1.266 + }
1.267 + }
1.268 + first_set = false;
1.269 + }
1.270 +
1.271 + ++bucket_num;
1.272 + _bucket->set(_source, 0);
1.273 + _dormant[0] = true;
1.274 + }
1.275 + _source_set->set(_source, true);
1.276 +
1.277 + Node target = _last[_sets.back().back()];
1.278 + {
1.279 + for (OutArcIt a(_graph, _source); a != INVALID; ++a) {
1.280 + if (_tolerance.positive((*_capacity)[a])) {
1.281 + Node u = _graph.target(a);
1.282 + _flow->set(a, (*_capacity)[a]);
1.283 + _excess->set(u, (*_excess)[u] + (*_capacity)[a]);
1.284 + if (!(*_active)[u] && u != _source) {
1.285 + activate(u);
1.286 + }
1.287 + }
1.288 + }
1.289 +
1.290 + if ((*_active)[target]) {
1.291 + deactivate(target);
1.292 + }
1.293 +
1.294 + _highest = _sets.back().begin();
1.295 + while (_highest != _sets.back().end() &&
1.296 + !(*_active)[_first[*_highest]]) {
1.297 + ++_highest;
1.298 + }
1.299 + }
1.300 +
1.301 + while (true) {
1.302 + while (_highest != _sets.back().end()) {
1.303 + Node n = _first[*_highest];
1.304 + Value excess = (*_excess)[n];
1.305 + int next_bucket = _node_num;
1.306 +
1.307 + int under_bucket;
1.308 + if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
1.309 + under_bucket = -1;
1.310 + } else {
1.311 + under_bucket = *(++std::list<int>::iterator(_highest));
1.312 + }
1.313 +
1.314 + for (OutArcIt a(_graph, n); a != INVALID; ++a) {
1.315 + Node v = _graph.target(a);
1.316 + if (_dormant[(*_bucket)[v]]) continue;
1.317 + Value rem = (*_capacity)[a] - (*_flow)[a];
1.318 + if (!_tolerance.positive(rem)) continue;
1.319 + if ((*_bucket)[v] == under_bucket) {
1.320 + if (!(*_active)[v] && v != target) {
1.321 + activate(v);
1.322 + }
1.323 + if (!_tolerance.less(rem, excess)) {
1.324 + _flow->set(a, (*_flow)[a] + excess);
1.325 + _excess->set(v, (*_excess)[v] + excess);
1.326 + excess = 0;
1.327 + goto no_more_push;
1.328 + } else {
1.329 + excess -= rem;
1.330 + _excess->set(v, (*_excess)[v] + rem);
1.331 + _flow->set(a, (*_capacity)[a]);
1.332 + }
1.333 + } else if (next_bucket > (*_bucket)[v]) {
1.334 + next_bucket = (*_bucket)[v];
1.335 + }
1.336 + }
1.337 +
1.338 + for (InArcIt a(_graph, n); a != INVALID; ++a) {
1.339 + Node v = _graph.source(a);
1.340 + if (_dormant[(*_bucket)[v]]) continue;
1.341 + Value rem = (*_flow)[a];
1.342 + if (!_tolerance.positive(rem)) continue;
1.343 + if ((*_bucket)[v] == under_bucket) {
1.344 + if (!(*_active)[v] && v != target) {
1.345 + activate(v);
1.346 + }
1.347 + if (!_tolerance.less(rem, excess)) {
1.348 + _flow->set(a, (*_flow)[a] - excess);
1.349 + _excess->set(v, (*_excess)[v] + excess);
1.350 + excess = 0;
1.351 + goto no_more_push;
1.352 + } else {
1.353 + excess -= rem;
1.354 + _excess->set(v, (*_excess)[v] + rem);
1.355 + _flow->set(a, 0);
1.356 + }
1.357 + } else if (next_bucket > (*_bucket)[v]) {
1.358 + next_bucket = (*_bucket)[v];
1.359 + }
1.360 + }
1.361 +
1.362 + no_more_push:
1.363 +
1.364 + _excess->set(n, excess);
1.365 +
1.366 + if (excess != 0) {
1.367 + if ((*_next)[n] == INVALID) {
1.368 + typename std::list<std::list<int> >::iterator new_set =
1.369 + _sets.insert(--_sets.end(), std::list<int>());
1.370 + new_set->splice(new_set->end(), _sets.back(),
1.371 + _sets.back().begin(), ++_highest);
1.372 + for (std::list<int>::iterator it = new_set->begin();
1.373 + it != new_set->end(); ++it) {
1.374 + _dormant[*it] = true;
1.375 + }
1.376 + while (_highest != _sets.back().end() &&
1.377 + !(*_active)[_first[*_highest]]) {
1.378 + ++_highest;
1.379 + }
1.380 + } else if (next_bucket == _node_num) {
1.381 + _first[(*_bucket)[n]] = (*_next)[n];
1.382 + _prev->set((*_next)[n], INVALID);
1.383 +
1.384 + std::list<std::list<int> >::iterator new_set =
1.385 + _sets.insert(--_sets.end(), std::list<int>());
1.386 +
1.387 + new_set->push_front(bucket_num);
1.388 + _bucket->set(n, bucket_num);
1.389 + _first[bucket_num] = _last[bucket_num] = n;
1.390 + _next->set(n, INVALID);
1.391 + _prev->set(n, INVALID);
1.392 + _dormant[bucket_num] = true;
1.393 + ++bucket_num;
1.394 +
1.395 + while (_highest != _sets.back().end() &&
1.396 + !(*_active)[_first[*_highest]]) {
1.397 + ++_highest;
1.398 + }
1.399 + } else {
1.400 + _first[*_highest] = (*_next)[n];
1.401 + _prev->set((*_next)[n], INVALID);
1.402 +
1.403 + while (next_bucket != *_highest) {
1.404 + --_highest;
1.405 + }
1.406 +
1.407 + if (_highest == _sets.back().begin()) {
1.408 + _sets.back().push_front(bucket_num);
1.409 + _dormant[bucket_num] = false;
1.410 + _first[bucket_num] = _last[bucket_num] = INVALID;
1.411 + ++bucket_num;
1.412 + }
1.413 + --_highest;
1.414 +
1.415 + _bucket->set(n, *_highest);
1.416 + _next->set(n, _first[*_highest]);
1.417 + if (_first[*_highest] != INVALID) {
1.418 + _prev->set(_first[*_highest], n);
1.419 + } else {
1.420 + _last[*_highest] = n;
1.421 + }
1.422 + _first[*_highest] = n;
1.423 + }
1.424 + } else {
1.425 +
1.426 + deactivate(n);
1.427 + if (!(*_active)[_first[*_highest]]) {
1.428 + ++_highest;
1.429 + if (_highest != _sets.back().end() &&
1.430 + !(*_active)[_first[*_highest]]) {
1.431 + _highest = _sets.back().end();
1.432 + }
1.433 + }
1.434 + }
1.435 + }
1.436 +
1.437 + if ((*_excess)[target] < _min_cut) {
1.438 + _min_cut = (*_excess)[target];
1.439 + for (NodeIt i(_graph); i != INVALID; ++i) {
1.440 + _min_cut_map->set(i, true);
1.441 + }
1.442 + for (std::list<int>::iterator it = _sets.back().begin();
1.443 + it != _sets.back().end(); ++it) {
1.444 + Node n = _first[*it];
1.445 + while (n != INVALID) {
1.446 + _min_cut_map->set(n, false);
1.447 + n = (*_next)[n];
1.448 + }
1.449 + }
1.450 + }
1.451 +
1.452 + {
1.453 + Node new_target;
1.454 + if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
1.455 + if ((*_next)[target] == INVALID) {
1.456 + _last[(*_bucket)[target]] = (*_prev)[target];
1.457 + new_target = (*_prev)[target];
1.458 + } else {
1.459 + _prev->set((*_next)[target], (*_prev)[target]);
1.460 + new_target = (*_next)[target];
1.461 + }
1.462 + if ((*_prev)[target] == INVALID) {
1.463 + _first[(*_bucket)[target]] = (*_next)[target];
1.464 + } else {
1.465 + _next->set((*_prev)[target], (*_next)[target]);
1.466 + }
1.467 + } else {
1.468 + _sets.back().pop_back();
1.469 + if (_sets.back().empty()) {
1.470 + _sets.pop_back();
1.471 + if (_sets.empty())
1.472 + break;
1.473 + for (std::list<int>::iterator it = _sets.back().begin();
1.474 + it != _sets.back().end(); ++it) {
1.475 + _dormant[*it] = false;
1.476 + }
1.477 + }
1.478 + new_target = _last[_sets.back().back()];
1.479 + }
1.480 +
1.481 + _bucket->set(target, 0);
1.482 +
1.483 + _source_set->set(target, true);
1.484 + for (OutArcIt a(_graph, target); a != INVALID; ++a) {
1.485 + Value rem = (*_capacity)[a] - (*_flow)[a];
1.486 + if (!_tolerance.positive(rem)) continue;
1.487 + Node v = _graph.target(a);
1.488 + if (!(*_active)[v] && !(*_source_set)[v]) {
1.489 + activate(v);
1.490 + }
1.491 + _excess->set(v, (*_excess)[v] + rem);
1.492 + _flow->set(a, (*_capacity)[a]);
1.493 + }
1.494 +
1.495 + for (InArcIt a(_graph, target); a != INVALID; ++a) {
1.496 + Value rem = (*_flow)[a];
1.497 + if (!_tolerance.positive(rem)) continue;
1.498 + Node v = _graph.source(a);
1.499 + if (!(*_active)[v] && !(*_source_set)[v]) {
1.500 + activate(v);
1.501 + }
1.502 + _excess->set(v, (*_excess)[v] + rem);
1.503 + _flow->set(a, 0);
1.504 + }
1.505 +
1.506 + target = new_target;
1.507 + if ((*_active)[target]) {
1.508 + deactivate(target);
1.509 + }
1.510 +
1.511 + _highest = _sets.back().begin();
1.512 + while (_highest != _sets.back().end() &&
1.513 + !(*_active)[_first[*_highest]]) {
1.514 + ++_highest;
1.515 + }
1.516 + }
1.517 + }
1.518 + }
1.519 +
1.520 + void findMinCutIn() {
1.521 +
1.522 + for (NodeIt n(_graph); n != INVALID; ++n) {
1.523 + _excess->set(n, 0);
1.524 + }
1.525 +
1.526 + for (ArcIt a(_graph); a != INVALID; ++a) {
1.527 + _flow->set(a, 0);
1.528 + }
1.529 +
1.530 + int bucket_num = 0;
1.531 + std::vector<Node> queue(_node_num);
1.532 + int qfirst = 0, qlast = 0, qsep = 0;
1.533 +
1.534 + {
1.535 + typename Digraph::template NodeMap<bool> reached(_graph, false);
1.536 +
1.537 + reached.set(_source, true);
1.538 +
1.539 + bool first_set = true;
1.540 +
1.541 + for (NodeIt t(_graph); t != INVALID; ++t) {
1.542 + if (reached[t]) continue;
1.543 + _sets.push_front(std::list<int>());
1.544 +
1.545 + queue[qlast++] = t;
1.546 + reached.set(t, true);
1.547 +
1.548 + while (qfirst != qlast) {
1.549 + if (qsep == qfirst) {
1.550 + ++bucket_num;
1.551 + _sets.front().push_front(bucket_num);
1.552 + _dormant[bucket_num] = !first_set;
1.553 + _first[bucket_num] = _last[bucket_num] = INVALID;
1.554 + qsep = qlast;
1.555 + }
1.556 +
1.557 + Node n = queue[qfirst++];
1.558 + addItem(n, bucket_num);
1.559 +
1.560 + for (OutArcIt a(_graph, n); a != INVALID; ++a) {
1.561 + Node u = _graph.target(a);
1.562 + if (!reached[u] && _tolerance.positive((*_capacity)[a])) {
1.563 + reached.set(u, true);
1.564 + queue[qlast++] = u;
1.565 + }
1.566 + }
1.567 + }
1.568 + first_set = false;
1.569 + }
1.570 +
1.571 + ++bucket_num;
1.572 + _bucket->set(_source, 0);
1.573 + _dormant[0] = true;
1.574 + }
1.575 + _source_set->set(_source, true);
1.576 +
1.577 + Node target = _last[_sets.back().back()];
1.578 + {
1.579 + for (InArcIt a(_graph, _source); a != INVALID; ++a) {
1.580 + if (_tolerance.positive((*_capacity)[a])) {
1.581 + Node u = _graph.source(a);
1.582 + _flow->set(a, (*_capacity)[a]);
1.583 + _excess->set(u, (*_excess)[u] + (*_capacity)[a]);
1.584 + if (!(*_active)[u] && u != _source) {
1.585 + activate(u);
1.586 + }
1.587 + }
1.588 + }
1.589 + if ((*_active)[target]) {
1.590 + deactivate(target);
1.591 + }
1.592 +
1.593 + _highest = _sets.back().begin();
1.594 + while (_highest != _sets.back().end() &&
1.595 + !(*_active)[_first[*_highest]]) {
1.596 + ++_highest;
1.597 + }
1.598 + }
1.599 +
1.600 +
1.601 + while (true) {
1.602 + while (_highest != _sets.back().end()) {
1.603 + Node n = _first[*_highest];
1.604 + Value excess = (*_excess)[n];
1.605 + int next_bucket = _node_num;
1.606 +
1.607 + int under_bucket;
1.608 + if (++std::list<int>::iterator(_highest) == _sets.back().end()) {
1.609 + under_bucket = -1;
1.610 + } else {
1.611 + under_bucket = *(++std::list<int>::iterator(_highest));
1.612 + }
1.613 +
1.614 + for (InArcIt a(_graph, n); a != INVALID; ++a) {
1.615 + Node v = _graph.source(a);
1.616 + if (_dormant[(*_bucket)[v]]) continue;
1.617 + Value rem = (*_capacity)[a] - (*_flow)[a];
1.618 + if (!_tolerance.positive(rem)) continue;
1.619 + if ((*_bucket)[v] == under_bucket) {
1.620 + if (!(*_active)[v] && v != target) {
1.621 + activate(v);
1.622 + }
1.623 + if (!_tolerance.less(rem, excess)) {
1.624 + _flow->set(a, (*_flow)[a] + excess);
1.625 + _excess->set(v, (*_excess)[v] + excess);
1.626 + excess = 0;
1.627 + goto no_more_push;
1.628 + } else {
1.629 + excess -= rem;
1.630 + _excess->set(v, (*_excess)[v] + rem);
1.631 + _flow->set(a, (*_capacity)[a]);
1.632 + }
1.633 + } else if (next_bucket > (*_bucket)[v]) {
1.634 + next_bucket = (*_bucket)[v];
1.635 + }
1.636 + }
1.637 +
1.638 + for (OutArcIt a(_graph, n); a != INVALID; ++a) {
1.639 + Node v = _graph.target(a);
1.640 + if (_dormant[(*_bucket)[v]]) continue;
1.641 + Value rem = (*_flow)[a];
1.642 + if (!_tolerance.positive(rem)) continue;
1.643 + if ((*_bucket)[v] == under_bucket) {
1.644 + if (!(*_active)[v] && v != target) {
1.645 + activate(v);
1.646 + }
1.647 + if (!_tolerance.less(rem, excess)) {
1.648 + _flow->set(a, (*_flow)[a] - excess);
1.649 + _excess->set(v, (*_excess)[v] + excess);
1.650 + excess = 0;
1.651 + goto no_more_push;
1.652 + } else {
1.653 + excess -= rem;
1.654 + _excess->set(v, (*_excess)[v] + rem);
1.655 + _flow->set(a, 0);
1.656 + }
1.657 + } else if (next_bucket > (*_bucket)[v]) {
1.658 + next_bucket = (*_bucket)[v];
1.659 + }
1.660 + }
1.661 +
1.662 + no_more_push:
1.663 +
1.664 + _excess->set(n, excess);
1.665 +
1.666 + if (excess != 0) {
1.667 + if ((*_next)[n] == INVALID) {
1.668 + typename std::list<std::list<int> >::iterator new_set =
1.669 + _sets.insert(--_sets.end(), std::list<int>());
1.670 + new_set->splice(new_set->end(), _sets.back(),
1.671 + _sets.back().begin(), ++_highest);
1.672 + for (std::list<int>::iterator it = new_set->begin();
1.673 + it != new_set->end(); ++it) {
1.674 + _dormant[*it] = true;
1.675 + }
1.676 + while (_highest != _sets.back().end() &&
1.677 + !(*_active)[_first[*_highest]]) {
1.678 + ++_highest;
1.679 + }
1.680 + } else if (next_bucket == _node_num) {
1.681 + _first[(*_bucket)[n]] = (*_next)[n];
1.682 + _prev->set((*_next)[n], INVALID);
1.683 +
1.684 + std::list<std::list<int> >::iterator new_set =
1.685 + _sets.insert(--_sets.end(), std::list<int>());
1.686 +
1.687 + new_set->push_front(bucket_num);
1.688 + _bucket->set(n, bucket_num);
1.689 + _first[bucket_num] = _last[bucket_num] = n;
1.690 + _next->set(n, INVALID);
1.691 + _prev->set(n, INVALID);
1.692 + _dormant[bucket_num] = true;
1.693 + ++bucket_num;
1.694 +
1.695 + while (_highest != _sets.back().end() &&
1.696 + !(*_active)[_first[*_highest]]) {
1.697 + ++_highest;
1.698 + }
1.699 + } else {
1.700 + _first[*_highest] = (*_next)[n];
1.701 + _prev->set((*_next)[n], INVALID);
1.702 +
1.703 + while (next_bucket != *_highest) {
1.704 + --_highest;
1.705 + }
1.706 + if (_highest == _sets.back().begin()) {
1.707 + _sets.back().push_front(bucket_num);
1.708 + _dormant[bucket_num] = false;
1.709 + _first[bucket_num] = _last[bucket_num] = INVALID;
1.710 + ++bucket_num;
1.711 + }
1.712 + --_highest;
1.713 +
1.714 + _bucket->set(n, *_highest);
1.715 + _next->set(n, _first[*_highest]);
1.716 + if (_first[*_highest] != INVALID) {
1.717 + _prev->set(_first[*_highest], n);
1.718 + } else {
1.719 + _last[*_highest] = n;
1.720 + }
1.721 + _first[*_highest] = n;
1.722 + }
1.723 + } else {
1.724 +
1.725 + deactivate(n);
1.726 + if (!(*_active)[_first[*_highest]]) {
1.727 + ++_highest;
1.728 + if (_highest != _sets.back().end() &&
1.729 + !(*_active)[_first[*_highest]]) {
1.730 + _highest = _sets.back().end();
1.731 + }
1.732 + }
1.733 + }
1.734 + }
1.735 +
1.736 + if ((*_excess)[target] < _min_cut) {
1.737 + _min_cut = (*_excess)[target];
1.738 + for (NodeIt i(_graph); i != INVALID; ++i) {
1.739 + _min_cut_map->set(i, false);
1.740 + }
1.741 + for (std::list<int>::iterator it = _sets.back().begin();
1.742 + it != _sets.back().end(); ++it) {
1.743 + Node n = _first[*it];
1.744 + while (n != INVALID) {
1.745 + _min_cut_map->set(n, true);
1.746 + n = (*_next)[n];
1.747 + }
1.748 + }
1.749 + }
1.750 +
1.751 + {
1.752 + Node new_target;
1.753 + if ((*_prev)[target] != INVALID || (*_next)[target] != INVALID) {
1.754 + if ((*_next)[target] == INVALID) {
1.755 + _last[(*_bucket)[target]] = (*_prev)[target];
1.756 + new_target = (*_prev)[target];
1.757 + } else {
1.758 + _prev->set((*_next)[target], (*_prev)[target]);
1.759 + new_target = (*_next)[target];
1.760 + }
1.761 + if ((*_prev)[target] == INVALID) {
1.762 + _first[(*_bucket)[target]] = (*_next)[target];
1.763 + } else {
1.764 + _next->set((*_prev)[target], (*_next)[target]);
1.765 + }
1.766 + } else {
1.767 + _sets.back().pop_back();
1.768 + if (_sets.back().empty()) {
1.769 + _sets.pop_back();
1.770 + if (_sets.empty())
1.771 + break;
1.772 + for (std::list<int>::iterator it = _sets.back().begin();
1.773 + it != _sets.back().end(); ++it) {
1.774 + _dormant[*it] = false;
1.775 + }
1.776 + }
1.777 + new_target = _last[_sets.back().back()];
1.778 + }
1.779 +
1.780 + _bucket->set(target, 0);
1.781 +
1.782 + _source_set->set(target, true);
1.783 + for (InArcIt a(_graph, target); a != INVALID; ++a) {
1.784 + Value rem = (*_capacity)[a] - (*_flow)[a];
1.785 + if (!_tolerance.positive(rem)) continue;
1.786 + Node v = _graph.source(a);
1.787 + if (!(*_active)[v] && !(*_source_set)[v]) {
1.788 + activate(v);
1.789 + }
1.790 + _excess->set(v, (*_excess)[v] + rem);
1.791 + _flow->set(a, (*_capacity)[a]);
1.792 + }
1.793 +
1.794 + for (OutArcIt a(_graph, target); a != INVALID; ++a) {
1.795 + Value rem = (*_flow)[a];
1.796 + if (!_tolerance.positive(rem)) continue;
1.797 + Node v = _graph.target(a);
1.798 + if (!(*_active)[v] && !(*_source_set)[v]) {
1.799 + activate(v);
1.800 + }
1.801 + _excess->set(v, (*_excess)[v] + rem);
1.802 + _flow->set(a, 0);
1.803 + }
1.804 +
1.805 + target = new_target;
1.806 + if ((*_active)[target]) {
1.807 + deactivate(target);
1.808 + }
1.809 +
1.810 + _highest = _sets.back().begin();
1.811 + while (_highest != _sets.back().end() &&
1.812 + !(*_active)[_first[*_highest]]) {
1.813 + ++_highest;
1.814 + }
1.815 + }
1.816 + }
1.817 + }
1.818 +
1.819 + public:
1.820 +
1.821 + /// \name Execution control
1.822 + /// The simplest way to execute the algorithm is to use
1.823 + /// one of the member functions called \c run(...).
1.824 + /// \n
1.825 + /// If you need more control on the execution,
1.826 + /// first you must call \ref init(), then the \ref calculateIn() or
1.827 + /// \ref calculateOut() functions.
1.828 +
1.829 + /// @{
1.830 +
1.831 + /// \brief Initializes the internal data structures.
1.832 + ///
1.833 + /// Initializes the internal data structures. It creates
1.834 + /// the maps, residual graph adaptors and some bucket structures
1.835 + /// for the algorithm.
1.836 + void init() {
1.837 + init(NodeIt(_graph));
1.838 + }
1.839 +
1.840 + /// \brief Initializes the internal data structures.
1.841 + ///
1.842 + /// Initializes the internal data structures. It creates
1.843 + /// the maps, residual graph adaptor and some bucket structures
1.844 + /// for the algorithm. Node \c source is used as the push-relabel
1.845 + /// algorithm's source.
1.846 + void init(const Node& source) {
1.847 + _source = source;
1.848 +
1.849 + _node_num = countNodes(_graph);
1.850 +
1.851 + _first.resize(_node_num);
1.852 + _last.resize(_node_num);
1.853 +
1.854 + _dormant.resize(_node_num);
1.855 +
1.856 + if (!_flow) {
1.857 + _flow = new FlowMap(_graph);
1.858 + }
1.859 + if (!_next) {
1.860 + _next = new typename Digraph::template NodeMap<Node>(_graph);
1.861 + }
1.862 + if (!_prev) {
1.863 + _prev = new typename Digraph::template NodeMap<Node>(_graph);
1.864 + }
1.865 + if (!_active) {
1.866 + _active = new typename Digraph::template NodeMap<bool>(_graph);
1.867 + }
1.868 + if (!_bucket) {
1.869 + _bucket = new typename Digraph::template NodeMap<int>(_graph);
1.870 + }
1.871 + if (!_excess) {
1.872 + _excess = new ExcessMap(_graph);
1.873 + }
1.874 + if (!_source_set) {
1.875 + _source_set = new SourceSetMap(_graph);
1.876 + }
1.877 + if (!_min_cut_map) {
1.878 + _min_cut_map = new MinCutMap(_graph);
1.879 + }
1.880 +
1.881 + _min_cut = std::numeric_limits<Value>::max();
1.882 + }
1.883 +
1.884 +
1.885 + /// \brief Calculates a minimum cut with \f$ source \f$ on the
1.886 + /// source-side.
1.887 + ///
1.888 + /// Calculates a minimum cut with \f$ source \f$ on the
1.889 + /// source-side (i.e. a set \f$ X\subsetneq V \f$ with
1.890 + /// \f$ source \in X \f$ and minimal out-degree).
1.891 + void calculateOut() {
1.892 + findMinCutOut();
1.893 + }
1.894 +
1.895 + /// \brief Calculates a minimum cut with \f$ source \f$ on the
1.896 + /// target-side.
1.897 + ///
1.898 + /// Calculates a minimum cut with \f$ source \f$ on the
1.899 + /// target-side (i.e. a set \f$ X\subsetneq V \f$ with
1.900 + /// \f$ source \in X \f$ and minimal out-degree).
1.901 + void calculateIn() {
1.902 + findMinCutIn();
1.903 + }
1.904 +
1.905 +
1.906 + /// \brief Runs the algorithm.
1.907 + ///
1.908 + /// Runs the algorithm. It finds nodes \c source and \c target
1.909 + /// arbitrarily and then calls \ref init(), \ref calculateOut()
1.910 + /// and \ref calculateIn().
1.911 + void run() {
1.912 + init();
1.913 + calculateOut();
1.914 + calculateIn();
1.915 + }
1.916 +
1.917 + /// \brief Runs the algorithm.
1.918 + ///
1.919 + /// Runs the algorithm. It uses the given \c source node, finds a
1.920 + /// proper \c target and then calls the \ref init(), \ref
1.921 + /// calculateOut() and \ref calculateIn().
1.922 + void run(const Node& s) {
1.923 + init(s);
1.924 + calculateOut();
1.925 + calculateIn();
1.926 + }
1.927 +
1.928 + /// @}
1.929 +
1.930 + /// \name Query Functions
1.931 + /// The result of the %HaoOrlin algorithm
1.932 + /// can be obtained using these functions.
1.933 + /// \n
1.934 + /// Before using these functions, either \ref run(), \ref
1.935 + /// calculateOut() or \ref calculateIn() must be called.
1.936 +
1.937 + /// @{
1.938 +
1.939 + /// \brief Returns the value of the minimum value cut.
1.940 + ///
1.941 + /// Returns the value of the minimum value cut.
1.942 + Value minCutValue() const {
1.943 + return _min_cut;
1.944 + }
1.945 +
1.946 +
1.947 + /// \brief Returns a minimum cut.
1.948 + ///
1.949 + /// Sets \c nodeMap to the characteristic vector of a minimum
1.950 + /// value cut: it will give a nonempty set \f$ X\subsetneq V \f$
1.951 + /// with minimal out-degree (i.e. \c nodeMap will be true exactly
1.952 + /// for the nodes of \f$ X \f$). \pre nodeMap should be a
1.953 + /// bool-valued node-map.
1.954 + template <typename NodeMap>
1.955 + Value minCutMap(NodeMap& nodeMap) const {
1.956 + for (NodeIt it(_graph); it != INVALID; ++it) {
1.957 + nodeMap.set(it, (*_min_cut_map)[it]);
1.958 + }
1.959 + return _min_cut;
1.960 + }
1.961 +
1.962 + /// @}
1.963 +
1.964 + }; //class HaoOrlin
1.965 +
1.966 +
1.967 +} //namespace lemon
1.968 +
1.969 +#endif //LEMON_HAO_ORLIN_H