1.1 --- a/src/lemon/preflow.h Sat May 21 21:04:57 2005 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,868 +0,0 @@
1.4 -/* -*- C++ -*-
1.5 - * src/lemon/preflow.h - Part of LEMON, a generic C++ optimization library
1.6 - *
1.7 - * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.8 - * (Egervary Research Group on Combinatorial Optimization, EGRES).
1.9 - *
1.10 - * Permission to use, modify and distribute this software is granted
1.11 - * provided that this copyright notice appears in all copies. For
1.12 - * precise terms see the accompanying LICENSE file.
1.13 - *
1.14 - * This software is provided "AS IS" with no warranty of any kind,
1.15 - * express or implied, and with no claim as to its suitability for any
1.16 - * purpose.
1.17 - *
1.18 - */
1.19 -
1.20 -#ifndef LEMON_PREFLOW_H
1.21 -#define LEMON_PREFLOW_H
1.22 -
1.23 -#include <vector>
1.24 -#include <queue>
1.25 -
1.26 -#include <lemon/invalid.h>
1.27 -#include <lemon/maps.h>
1.28 -#include <lemon/graph_utils.h>
1.29 -
1.30 -/// \file
1.31 -/// \ingroup flowalgs
1.32 -/// Implementation of the preflow algorithm.
1.33 -
1.34 -namespace lemon {
1.35 -
1.36 - /// \addtogroup flowalgs
1.37 - /// @{
1.38 -
1.39 - ///%Preflow algorithms class.
1.40 -
1.41 - ///This class provides an implementation of the \e preflow \e
1.42 - ///algorithm producing a flow of maximum value in a directed
1.43 - ///graph. The preflow algorithms are the fastest known max flow algorithms
1.44 - ///up to now. The \e source node, the \e target node, the \e
1.45 - ///capacity of the edges and the \e starting \e flow value of the
1.46 - ///edges should be passed to the algorithm through the
1.47 - ///constructor. It is possible to change these quantities using the
1.48 - ///functions \ref source, \ref target, \ref capacityMap and \ref
1.49 - ///flowMap.
1.50 - ///
1.51 - ///After running \ref lemon::Preflow::phase1() "phase1()"
1.52 - ///or \ref lemon::Preflow::run() "run()", the maximal flow
1.53 - ///value can be obtained by calling \ref flowValue(). The minimum
1.54 - ///value cut can be written into a <tt>bool</tt> node map by
1.55 - ///calling \ref minCut(). (\ref minMinCut() and \ref maxMinCut() writes
1.56 - ///the inclusionwise minimum and maximum of the minimum value cuts,
1.57 - ///resp.)
1.58 - ///
1.59 - ///\param Graph The directed graph type the algorithm runs on.
1.60 - ///\param Num The number type of the capacities and the flow values.
1.61 - ///\param CapacityMap The capacity map type.
1.62 - ///\param FlowMap The flow map type.
1.63 - ///
1.64 - ///\author Jacint Szabo
1.65 - ///\todo Second template parameter is superfluous
1.66 - template <typename Graph, typename Num,
1.67 - typename CapacityMap=typename Graph::template EdgeMap<Num>,
1.68 - typename FlowMap=typename Graph::template EdgeMap<Num> >
1.69 - class Preflow {
1.70 - protected:
1.71 - typedef typename Graph::Node Node;
1.72 - typedef typename Graph::NodeIt NodeIt;
1.73 - typedef typename Graph::EdgeIt EdgeIt;
1.74 - typedef typename Graph::OutEdgeIt OutEdgeIt;
1.75 - typedef typename Graph::InEdgeIt InEdgeIt;
1.76 -
1.77 - typedef typename Graph::template NodeMap<Node> NNMap;
1.78 - typedef typename std::vector<Node> VecNode;
1.79 -
1.80 - const Graph* _g;
1.81 - Node _source;
1.82 - Node _target;
1.83 - const CapacityMap* _capacity;
1.84 - FlowMap* _flow;
1.85 - int _node_num; //the number of nodes of G
1.86 -
1.87 - typename Graph::template NodeMap<int> level;
1.88 - typename Graph::template NodeMap<Num> excess;
1.89 -
1.90 - // constants used for heuristics
1.91 - static const int H0=20;
1.92 - static const int H1=1;
1.93 -
1.94 - public:
1.95 -
1.96 - ///Indicates the property of the starting flow map.
1.97 -
1.98 - ///Indicates the property of the starting flow map.
1.99 - ///The meanings are as follows:
1.100 - ///- \c ZERO_FLOW: constant zero flow
1.101 - ///- \c GEN_FLOW: any flow, i.e. the sum of the in-flows equals to
1.102 - ///the sum of the out-flows in every node except the \e source and
1.103 - ///the \e target.
1.104 - ///- \c PRE_FLOW: any preflow, i.e. the sum of the in-flows is at
1.105 - ///least the sum of the out-flows in every node except the \e source.
1.106 - ///- \c NO_FLOW: indicates an unspecified edge map. \c flow will be
1.107 - ///set to the constant zero flow in the beginning of
1.108 - ///the algorithm in this case.
1.109 - ///
1.110 - enum FlowEnum{
1.111 - NO_FLOW,
1.112 - ZERO_FLOW,
1.113 - GEN_FLOW,
1.114 - PRE_FLOW
1.115 - };
1.116 -
1.117 - ///Indicates the state of the preflow algorithm.
1.118 -
1.119 - ///Indicates the state of the preflow algorithm.
1.120 - ///The meanings are as follows:
1.121 - ///- \c AFTER_NOTHING: before running the algorithm or
1.122 - /// at an unspecified state.
1.123 - ///- \c AFTER_PREFLOW_PHASE_1: right after running \c phase1
1.124 - ///- \c AFTER_PREFLOW_PHASE_2: after running \ref phase2()
1.125 - ///
1.126 - enum StatusEnum {
1.127 - AFTER_NOTHING,
1.128 - AFTER_PREFLOW_PHASE_1,
1.129 - AFTER_PREFLOW_PHASE_2
1.130 - };
1.131 -
1.132 - protected:
1.133 - FlowEnum flow_prop;
1.134 - StatusEnum status; // Do not needle this flag only if necessary.
1.135 -
1.136 - public:
1.137 - ///The constructor of the class.
1.138 -
1.139 - ///The constructor of the class.
1.140 - ///\param _gr The directed graph the algorithm runs on.
1.141 - ///\param _s The source node.
1.142 - ///\param _t The target node.
1.143 - ///\param _cap The capacity of the edges.
1.144 - ///\param _f The flow of the edges.
1.145 - ///Except the graph, all of these parameters can be reset by
1.146 - ///calling \ref source, \ref target, \ref capacityMap and \ref
1.147 - ///flowMap, resp.
1.148 - Preflow(const Graph& _gr, Node _s, Node _t,
1.149 - const CapacityMap& _cap, FlowMap& _f) :
1.150 - _g(&_gr), _source(_s), _target(_t), _capacity(&_cap),
1.151 - _flow(&_f), _node_num(countNodes(_gr)), level(_gr), excess(_gr,0),
1.152 - flow_prop(NO_FLOW), status(AFTER_NOTHING) { }
1.153 -
1.154 -
1.155 -
1.156 - ///Runs the preflow algorithm.
1.157 -
1.158 - ///Runs the preflow algorithm.
1.159 - ///
1.160 - void run() {
1.161 - phase1(flow_prop);
1.162 - phase2();
1.163 - }
1.164 -
1.165 - ///Runs the preflow algorithm.
1.166 -
1.167 - ///Runs the preflow algorithm.
1.168 - ///\pre The starting flow map must be
1.169 - /// - a constant zero flow if \c fp is \c ZERO_FLOW,
1.170 - /// - an arbitrary flow if \c fp is \c GEN_FLOW,
1.171 - /// - an arbitrary preflow if \c fp is \c PRE_FLOW,
1.172 - /// - any map if \c fp is NO_FLOW.
1.173 - ///If the starting flow map is a flow or a preflow then
1.174 - ///the algorithm terminates faster.
1.175 - void run(FlowEnum fp) {
1.176 - flow_prop=fp;
1.177 - run();
1.178 - }
1.179 -
1.180 - ///Runs the first phase of the preflow algorithm.
1.181 -
1.182 - ///The preflow algorithm consists of two phases, this method runs
1.183 - ///the first phase. After the first phase the maximum flow value
1.184 - ///and a minimum value cut can already be computed, although a
1.185 - ///maximum flow is not yet obtained. So after calling this method
1.186 - ///\ref flowValue returns the value of a maximum flow and \ref
1.187 - ///minCut returns a minimum cut.
1.188 - ///\warning \ref minMinCut and \ref maxMinCut do not give minimum
1.189 - ///value cuts unless calling \ref phase2.
1.190 - ///\pre The starting flow must be
1.191 - ///- a constant zero flow if \c fp is \c ZERO_FLOW,
1.192 - ///- an arbitary flow if \c fp is \c GEN_FLOW,
1.193 - ///- an arbitary preflow if \c fp is \c PRE_FLOW,
1.194 - ///- any map if \c fp is NO_FLOW.
1.195 - void phase1(FlowEnum fp)
1.196 - {
1.197 - flow_prop=fp;
1.198 - phase1();
1.199 - }
1.200 -
1.201 -
1.202 - ///Runs the first phase of the preflow algorithm.
1.203 -
1.204 - ///The preflow algorithm consists of two phases, this method runs
1.205 - ///the first phase. After the first phase the maximum flow value
1.206 - ///and a minimum value cut can already be computed, although a
1.207 - ///maximum flow is not yet obtained. So after calling this method
1.208 - ///\ref flowValue returns the value of a maximum flow and \ref
1.209 - ///minCut returns a minimum cut.
1.210 - ///\warning \ref minCut(), \ref minMinCut() and \ref maxMinCut() do not
1.211 - ///give minimum value cuts unless calling \ref phase2().
1.212 - void phase1()
1.213 - {
1.214 - int heur0=(int)(H0*_node_num); //time while running 'bound decrease'
1.215 - int heur1=(int)(H1*_node_num); //time while running 'highest label'
1.216 - int heur=heur1; //starting time interval (#of relabels)
1.217 - int numrelabel=0;
1.218 -
1.219 - bool what_heur=1;
1.220 - //It is 0 in case 'bound decrease' and 1 in case 'highest label'
1.221 -
1.222 - bool end=false;
1.223 - //Needed for 'bound decrease', true means no active
1.224 - //nodes are above bound b.
1.225 -
1.226 - int k=_node_num-2; //bound on the highest level under n containing a node
1.227 - int b=k; //bound on the highest level under n of an active node
1.228 -
1.229 - VecNode first(_node_num, INVALID);
1.230 - NNMap next(*_g, INVALID);
1.231 -
1.232 - NNMap left(*_g, INVALID);
1.233 - NNMap right(*_g, INVALID);
1.234 - VecNode level_list(_node_num,INVALID);
1.235 - //List of the nodes in level i<n, set to n.
1.236 -
1.237 - preflowPreproc(first, next, level_list, left, right);
1.238 -
1.239 - //Push/relabel on the highest level active nodes.
1.240 - while ( true ) {
1.241 - if ( b == 0 ) {
1.242 - if ( !what_heur && !end && k > 0 ) {
1.243 - b=k;
1.244 - end=true;
1.245 - } else break;
1.246 - }
1.247 -
1.248 - if ( first[b]==INVALID ) --b;
1.249 - else {
1.250 - end=false;
1.251 - Node w=first[b];
1.252 - first[b]=next[w];
1.253 - int newlevel=push(w, next, first);
1.254 - if ( excess[w] > 0 ) relabel(w, newlevel, first, next, level_list,
1.255 - left, right, b, k, what_heur);
1.256 -
1.257 - ++numrelabel;
1.258 - if ( numrelabel >= heur ) {
1.259 - numrelabel=0;
1.260 - if ( what_heur ) {
1.261 - what_heur=0;
1.262 - heur=heur0;
1.263 - end=false;
1.264 - } else {
1.265 - what_heur=1;
1.266 - heur=heur1;
1.267 - b=k;
1.268 - }
1.269 - }
1.270 - }
1.271 - }
1.272 - flow_prop=PRE_FLOW;
1.273 - status=AFTER_PREFLOW_PHASE_1;
1.274 - }
1.275 - // Heuristics:
1.276 - // 2 phase
1.277 - // gap
1.278 - // list 'level_list' on the nodes on level i implemented by hand
1.279 - // stack 'active' on the active nodes on level i
1.280 - // runs heuristic 'highest label' for H1*n relabels
1.281 - // runs heuristic 'bound decrease' for H0*n relabels,
1.282 - // starts with 'highest label'
1.283 - // Parameters H0 and H1 are initialized to 20 and 1.
1.284 -
1.285 -
1.286 - ///Runs the second phase of the preflow algorithm.
1.287 -
1.288 - ///The preflow algorithm consists of two phases, this method runs
1.289 - ///the second phase. After calling \ref phase1 and then \ref
1.290 - ///phase2, \ref flow contains a maximum flow, \ref flowValue
1.291 - ///returns the value of a maximum flow, \ref minCut returns a
1.292 - ///minimum cut, while the methods \ref minMinCut and \ref
1.293 - ///maxMinCut return the inclusionwise minimum and maximum cuts of
1.294 - ///minimum value, resp. \pre \ref phase1 must be called before.
1.295 - void phase2()
1.296 - {
1.297 -
1.298 - int k=_node_num-2; //bound on the highest level under n containing a node
1.299 - int b=k; //bound on the highest level under n of an active node
1.300 -
1.301 -
1.302 - VecNode first(_node_num, INVALID);
1.303 - NNMap next(*_g, INVALID);
1.304 - level.set(_source,0);
1.305 - std::queue<Node> bfs_queue;
1.306 - bfs_queue.push(_source);
1.307 -
1.308 - while ( !bfs_queue.empty() ) {
1.309 -
1.310 - Node v=bfs_queue.front();
1.311 - bfs_queue.pop();
1.312 - int l=level[v]+1;
1.313 -
1.314 - for(InEdgeIt e(*_g,v); e!=INVALID; ++e) {
1.315 - if ( (*_capacity)[e] <= (*_flow)[e] ) continue;
1.316 - Node u=_g->source(e);
1.317 - if ( level[u] >= _node_num ) {
1.318 - bfs_queue.push(u);
1.319 - level.set(u, l);
1.320 - if ( excess[u] > 0 ) {
1.321 - next.set(u,first[l]);
1.322 - first[l]=u;
1.323 - }
1.324 - }
1.325 - }
1.326 -
1.327 - for(OutEdgeIt e(*_g,v); e!=INVALID; ++e) {
1.328 - if ( 0 >= (*_flow)[e] ) continue;
1.329 - Node u=_g->target(e);
1.330 - if ( level[u] >= _node_num ) {
1.331 - bfs_queue.push(u);
1.332 - level.set(u, l);
1.333 - if ( excess[u] > 0 ) {
1.334 - next.set(u,first[l]);
1.335 - first[l]=u;
1.336 - }
1.337 - }
1.338 - }
1.339 - }
1.340 - b=_node_num-2;
1.341 -
1.342 - while ( true ) {
1.343 -
1.344 - if ( b == 0 ) break;
1.345 - if ( first[b]==INVALID ) --b;
1.346 - else {
1.347 - Node w=first[b];
1.348 - first[b]=next[w];
1.349 - int newlevel=push(w,next, first);
1.350 -
1.351 - //relabel
1.352 - if ( excess[w] > 0 ) {
1.353 - level.set(w,++newlevel);
1.354 - next.set(w,first[newlevel]);
1.355 - first[newlevel]=w;
1.356 - b=newlevel;
1.357 - }
1.358 - }
1.359 - } // while(true)
1.360 - flow_prop=GEN_FLOW;
1.361 - status=AFTER_PREFLOW_PHASE_2;
1.362 - }
1.363 -
1.364 - /// Returns the value of the maximum flow.
1.365 -
1.366 - /// Returns the value of the maximum flow by returning the excess
1.367 - /// of the target node \c t. This value equals to the value of
1.368 - /// the maximum flow already after running \ref phase1.
1.369 - Num flowValue() const {
1.370 - return excess[_target];
1.371 - }
1.372 -
1.373 -
1.374 - ///Returns a minimum value cut.
1.375 -
1.376 - ///Sets \c M to the characteristic vector of a minimum value
1.377 - ///cut. This method can be called both after running \ref
1.378 - ///phase1 and \ref phase2. It is much faster after
1.379 - ///\ref phase1. \pre M should be a bool-valued node-map. \pre
1.380 - ///If \ref minCut() is called after \ref phase2() then M should
1.381 - ///be initialized to false.
1.382 - template<typename _CutMap>
1.383 - void minCut(_CutMap& M) const {
1.384 - switch ( status ) {
1.385 - case AFTER_PREFLOW_PHASE_1:
1.386 - for(NodeIt v(*_g); v!=INVALID; ++v) {
1.387 - if (level[v] < _node_num) {
1.388 - M.set(v, false);
1.389 - } else {
1.390 - M.set(v, true);
1.391 - }
1.392 - }
1.393 - break;
1.394 - case AFTER_PREFLOW_PHASE_2:
1.395 - minMinCut(M);
1.396 - break;
1.397 - case AFTER_NOTHING:
1.398 - break;
1.399 - }
1.400 - }
1.401 -
1.402 - ///Returns the inclusionwise minimum of the minimum value cuts.
1.403 -
1.404 - ///Sets \c M to the characteristic vector of the minimum value cut
1.405 - ///which is inclusionwise minimum. It is computed by processing a
1.406 - ///bfs from the source node \c s in the residual graph. \pre M
1.407 - ///should be a node map of bools initialized to false. \pre \ref
1.408 - ///phase2 should already be run.
1.409 - template<typename _CutMap>
1.410 - void minMinCut(_CutMap& M) const {
1.411 -
1.412 - std::queue<Node> queue;
1.413 - M.set(_source,true);
1.414 - queue.push(_source);
1.415 -
1.416 - while (!queue.empty()) {
1.417 - Node w=queue.front();
1.418 - queue.pop();
1.419 -
1.420 - for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
1.421 - Node v=_g->target(e);
1.422 - if (!M[v] && (*_flow)[e] < (*_capacity)[e] ) {
1.423 - queue.push(v);
1.424 - M.set(v, true);
1.425 - }
1.426 - }
1.427 -
1.428 - for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
1.429 - Node v=_g->source(e);
1.430 - if (!M[v] && (*_flow)[e] > 0 ) {
1.431 - queue.push(v);
1.432 - M.set(v, true);
1.433 - }
1.434 - }
1.435 - }
1.436 - }
1.437 -
1.438 - ///Returns the inclusionwise maximum of the minimum value cuts.
1.439 -
1.440 - ///Sets \c M to the characteristic vector of the minimum value cut
1.441 - ///which is inclusionwise maximum. It is computed by processing a
1.442 - ///backward bfs from the target node \c t in the residual graph.
1.443 - ///\pre \ref phase2() or run() should already be run.
1.444 - template<typename _CutMap>
1.445 - void maxMinCut(_CutMap& M) const {
1.446 -
1.447 - for(NodeIt v(*_g) ; v!=INVALID; ++v) M.set(v, true);
1.448 -
1.449 - std::queue<Node> queue;
1.450 -
1.451 - M.set(_target,false);
1.452 - queue.push(_target);
1.453 -
1.454 - while (!queue.empty()) {
1.455 - Node w=queue.front();
1.456 - queue.pop();
1.457 -
1.458 - for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
1.459 - Node v=_g->source(e);
1.460 - if (M[v] && (*_flow)[e] < (*_capacity)[e] ) {
1.461 - queue.push(v);
1.462 - M.set(v, false);
1.463 - }
1.464 - }
1.465 -
1.466 - for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
1.467 - Node v=_g->target(e);
1.468 - if (M[v] && (*_flow)[e] > 0 ) {
1.469 - queue.push(v);
1.470 - M.set(v, false);
1.471 - }
1.472 - }
1.473 - }
1.474 - }
1.475 -
1.476 - ///Sets the source node to \c _s.
1.477 -
1.478 - ///Sets the source node to \c _s.
1.479 - ///
1.480 - void source(Node _s) {
1.481 - _source=_s;
1.482 - if ( flow_prop != ZERO_FLOW ) flow_prop=NO_FLOW;
1.483 - status=AFTER_NOTHING;
1.484 - }
1.485 -
1.486 - ///Returns the source node.
1.487 -
1.488 - ///Returns the source node.
1.489 - ///
1.490 - Node source() const {
1.491 - return _source;
1.492 - }
1.493 -
1.494 - ///Sets the target node to \c _t.
1.495 -
1.496 - ///Sets the target node to \c _t.
1.497 - ///
1.498 - void target(Node _t) {
1.499 - _target=_t;
1.500 - if ( flow_prop == GEN_FLOW ) flow_prop=PRE_FLOW;
1.501 - status=AFTER_NOTHING;
1.502 - }
1.503 -
1.504 - ///Returns the target node.
1.505 -
1.506 - ///Returns the target node.
1.507 - ///
1.508 - Node target() const {
1.509 - return _target;
1.510 - }
1.511 -
1.512 - /// Sets the edge map of the capacities to _cap.
1.513 -
1.514 - /// Sets the edge map of the capacities to _cap.
1.515 - ///
1.516 - void capacityMap(const CapacityMap& _cap) {
1.517 - _capacity=&_cap;
1.518 - status=AFTER_NOTHING;
1.519 - }
1.520 - /// Returns a reference to capacity map.
1.521 -
1.522 - /// Returns a reference to capacity map.
1.523 - ///
1.524 - const CapacityMap &capacityMap() const {
1.525 - return *_capacity;
1.526 - }
1.527 -
1.528 - /// Sets the edge map of the flows to _flow.
1.529 -
1.530 - /// Sets the edge map of the flows to _flow.
1.531 - ///
1.532 - void flowMap(FlowMap& _f) {
1.533 - _flow=&_f;
1.534 - flow_prop=NO_FLOW;
1.535 - status=AFTER_NOTHING;
1.536 - }
1.537 -
1.538 - /// Returns a reference to flow map.
1.539 -
1.540 - /// Returns a reference to flow map.
1.541 - ///
1.542 - const FlowMap &flowMap() const {
1.543 - return *_flow;
1.544 - }
1.545 -
1.546 - private:
1.547 -
1.548 - int push(Node w, NNMap& next, VecNode& first) {
1.549 -
1.550 - int lev=level[w];
1.551 - Num exc=excess[w];
1.552 - int newlevel=_node_num; //bound on the next level of w
1.553 -
1.554 - for(OutEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
1.555 - if ( (*_flow)[e] >= (*_capacity)[e] ) continue;
1.556 - Node v=_g->target(e);
1.557 -
1.558 - if( lev > level[v] ) { //Push is allowed now
1.559 -
1.560 - if ( excess[v]<=0 && v!=_target && v!=_source ) {
1.561 - next.set(v,first[level[v]]);
1.562 - first[level[v]]=v;
1.563 - }
1.564 -
1.565 - Num cap=(*_capacity)[e];
1.566 - Num flo=(*_flow)[e];
1.567 - Num remcap=cap-flo;
1.568 -
1.569 - if ( remcap >= exc ) { //A nonsaturating push.
1.570 -
1.571 - _flow->set(e, flo+exc);
1.572 - excess.set(v, excess[v]+exc);
1.573 - exc=0;
1.574 - break;
1.575 -
1.576 - } else { //A saturating push.
1.577 - _flow->set(e, cap);
1.578 - excess.set(v, excess[v]+remcap);
1.579 - exc-=remcap;
1.580 - }
1.581 - } else if ( newlevel > level[v] ) newlevel = level[v];
1.582 - } //for out edges wv
1.583 -
1.584 - if ( exc > 0 ) {
1.585 - for(InEdgeIt e(*_g,w) ; e!=INVALID; ++e) {
1.586 -
1.587 - if( (*_flow)[e] <= 0 ) continue;
1.588 - Node v=_g->source(e);
1.589 -
1.590 - if( lev > level[v] ) { //Push is allowed now
1.591 -
1.592 - if ( excess[v]<=0 && v!=_target && v!=_source ) {
1.593 - next.set(v,first[level[v]]);
1.594 - first[level[v]]=v;
1.595 - }
1.596 -
1.597 - Num flo=(*_flow)[e];
1.598 -
1.599 - if ( flo >= exc ) { //A nonsaturating push.
1.600 -
1.601 - _flow->set(e, flo-exc);
1.602 - excess.set(v, excess[v]+exc);
1.603 - exc=0;
1.604 - break;
1.605 - } else { //A saturating push.
1.606 -
1.607 - excess.set(v, excess[v]+flo);
1.608 - exc-=flo;
1.609 - _flow->set(e,0);
1.610 - }
1.611 - } else if ( newlevel > level[v] ) newlevel = level[v];
1.612 - } //for in edges vw
1.613 -
1.614 - } // if w still has excess after the out edge for cycle
1.615 -
1.616 - excess.set(w, exc);
1.617 -
1.618 - return newlevel;
1.619 - }
1.620 -
1.621 -
1.622 -
1.623 - void preflowPreproc(VecNode& first, NNMap& next,
1.624 - VecNode& level_list, NNMap& left, NNMap& right)
1.625 - {
1.626 - for(NodeIt v(*_g); v!=INVALID; ++v) level.set(v,_node_num);
1.627 - std::queue<Node> bfs_queue;
1.628 -
1.629 - if ( flow_prop == GEN_FLOW || flow_prop == PRE_FLOW ) {
1.630 - //Reverse_bfs from t in the residual graph,
1.631 - //to find the starting level.
1.632 - level.set(_target,0);
1.633 - bfs_queue.push(_target);
1.634 -
1.635 - while ( !bfs_queue.empty() ) {
1.636 -
1.637 - Node v=bfs_queue.front();
1.638 - bfs_queue.pop();
1.639 - int l=level[v]+1;
1.640 -
1.641 - for(InEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
1.642 - if ( (*_capacity)[e] <= (*_flow)[e] ) continue;
1.643 - Node w=_g->source(e);
1.644 - if ( level[w] == _node_num && w != _source ) {
1.645 - bfs_queue.push(w);
1.646 - Node z=level_list[l];
1.647 - if ( z!=INVALID ) left.set(z,w);
1.648 - right.set(w,z);
1.649 - level_list[l]=w;
1.650 - level.set(w, l);
1.651 - }
1.652 - }
1.653 -
1.654 - for(OutEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
1.655 - if ( 0 >= (*_flow)[e] ) continue;
1.656 - Node w=_g->target(e);
1.657 - if ( level[w] == _node_num && w != _source ) {
1.658 - bfs_queue.push(w);
1.659 - Node z=level_list[l];
1.660 - if ( z!=INVALID ) left.set(z,w);
1.661 - right.set(w,z);
1.662 - level_list[l]=w;
1.663 - level.set(w, l);
1.664 - }
1.665 - }
1.666 - } //while
1.667 - } //if
1.668 -
1.669 -
1.670 - switch (flow_prop) {
1.671 - case NO_FLOW:
1.672 - for(EdgeIt e(*_g); e!=INVALID; ++e) _flow->set(e,0);
1.673 - case ZERO_FLOW:
1.674 - for(NodeIt v(*_g); v!=INVALID; ++v) excess.set(v,0);
1.675 -
1.676 - //Reverse_bfs from t, to find the starting level.
1.677 - level.set(_target,0);
1.678 - bfs_queue.push(_target);
1.679 -
1.680 - while ( !bfs_queue.empty() ) {
1.681 -
1.682 - Node v=bfs_queue.front();
1.683 - bfs_queue.pop();
1.684 - int l=level[v]+1;
1.685 -
1.686 - for(InEdgeIt e(*_g,v) ; e!=INVALID; ++e) {
1.687 - Node w=_g->source(e);
1.688 - if ( level[w] == _node_num && w != _source ) {
1.689 - bfs_queue.push(w);
1.690 - Node z=level_list[l];
1.691 - if ( z!=INVALID ) left.set(z,w);
1.692 - right.set(w,z);
1.693 - level_list[l]=w;
1.694 - level.set(w, l);
1.695 - }
1.696 - }
1.697 - }
1.698 -
1.699 - //the starting flow
1.700 - for(OutEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
1.701 - Num c=(*_capacity)[e];
1.702 - if ( c <= 0 ) continue;
1.703 - Node w=_g->target(e);
1.704 - if ( level[w] < _node_num ) {
1.705 - if ( excess[w] <= 0 && w!=_target ) { //putting into the stack
1.706 - next.set(w,first[level[w]]);
1.707 - first[level[w]]=w;
1.708 - }
1.709 - _flow->set(e, c);
1.710 - excess.set(w, excess[w]+c);
1.711 - }
1.712 - }
1.713 - break;
1.714 -
1.715 - case GEN_FLOW:
1.716 - for(NodeIt v(*_g); v!=INVALID; ++v) excess.set(v,0);
1.717 - {
1.718 - Num exc=0;
1.719 - for(InEdgeIt e(*_g,_target) ; e!=INVALID; ++e) exc+=(*_flow)[e];
1.720 - for(OutEdgeIt e(*_g,_target) ; e!=INVALID; ++e) exc-=(*_flow)[e];
1.721 - excess.set(_target,exc);
1.722 - }
1.723 -
1.724 - //the starting flow
1.725 - for(OutEdgeIt e(*_g,_source); e!=INVALID; ++e) {
1.726 - Num rem=(*_capacity)[e]-(*_flow)[e];
1.727 - if ( rem <= 0 ) continue;
1.728 - Node w=_g->target(e);
1.729 - if ( level[w] < _node_num ) {
1.730 - if ( excess[w] <= 0 && w!=_target ) { //putting into the stack
1.731 - next.set(w,first[level[w]]);
1.732 - first[level[w]]=w;
1.733 - }
1.734 - _flow->set(e, (*_capacity)[e]);
1.735 - excess.set(w, excess[w]+rem);
1.736 - }
1.737 - }
1.738 -
1.739 - for(InEdgeIt e(*_g,_source); e!=INVALID; ++e) {
1.740 - if ( (*_flow)[e] <= 0 ) continue;
1.741 - Node w=_g->source(e);
1.742 - if ( level[w] < _node_num ) {
1.743 - if ( excess[w] <= 0 && w!=_target ) {
1.744 - next.set(w,first[level[w]]);
1.745 - first[level[w]]=w;
1.746 - }
1.747 - excess.set(w, excess[w]+(*_flow)[e]);
1.748 - _flow->set(e, 0);
1.749 - }
1.750 - }
1.751 - break;
1.752 -
1.753 - case PRE_FLOW:
1.754 - //the starting flow
1.755 - for(OutEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
1.756 - Num rem=(*_capacity)[e]-(*_flow)[e];
1.757 - if ( rem <= 0 ) continue;
1.758 - Node w=_g->target(e);
1.759 - if ( level[w] < _node_num ) _flow->set(e, (*_capacity)[e]);
1.760 - }
1.761 -
1.762 - for(InEdgeIt e(*_g,_source) ; e!=INVALID; ++e) {
1.763 - if ( (*_flow)[e] <= 0 ) continue;
1.764 - Node w=_g->source(e);
1.765 - if ( level[w] < _node_num ) _flow->set(e, 0);
1.766 - }
1.767 -
1.768 - //computing the excess
1.769 - for(NodeIt w(*_g); w!=INVALID; ++w) {
1.770 - Num exc=0;
1.771 - for(InEdgeIt e(*_g,w); e!=INVALID; ++e) exc+=(*_flow)[e];
1.772 - for(OutEdgeIt e(*_g,w); e!=INVALID; ++e) exc-=(*_flow)[e];
1.773 - excess.set(w,exc);
1.774 -
1.775 - //putting the active nodes into the stack
1.776 - int lev=level[w];
1.777 - if ( exc > 0 && lev < _node_num && Node(w) != _target ) {
1.778 - next.set(w,first[lev]);
1.779 - first[lev]=w;
1.780 - }
1.781 - }
1.782 - break;
1.783 - } //switch
1.784 - } //preflowPreproc
1.785 -
1.786 -
1.787 - void relabel(Node w, int newlevel, VecNode& first, NNMap& next,
1.788 - VecNode& level_list, NNMap& left,
1.789 - NNMap& right, int& b, int& k, bool what_heur )
1.790 - {
1.791 -
1.792 - int lev=level[w];
1.793 -
1.794 - Node right_n=right[w];
1.795 - Node left_n=left[w];
1.796 -
1.797 - //unlacing starts
1.798 - if ( right_n!=INVALID ) {
1.799 - if ( left_n!=INVALID ) {
1.800 - right.set(left_n, right_n);
1.801 - left.set(right_n, left_n);
1.802 - } else {
1.803 - level_list[lev]=right_n;
1.804 - left.set(right_n, INVALID);
1.805 - }
1.806 - } else {
1.807 - if ( left_n!=INVALID ) {
1.808 - right.set(left_n, INVALID);
1.809 - } else {
1.810 - level_list[lev]=INVALID;
1.811 - }
1.812 - }
1.813 - //unlacing ends
1.814 -
1.815 - if ( level_list[lev]==INVALID ) {
1.816 -
1.817 - //gapping starts
1.818 - for (int i=lev; i!=k ; ) {
1.819 - Node v=level_list[++i];
1.820 - while ( v!=INVALID ) {
1.821 - level.set(v,_node_num);
1.822 - v=right[v];
1.823 - }
1.824 - level_list[i]=INVALID;
1.825 - if ( !what_heur ) first[i]=INVALID;
1.826 - }
1.827 -
1.828 - level.set(w,_node_num);
1.829 - b=lev-1;
1.830 - k=b;
1.831 - //gapping ends
1.832 -
1.833 - } else {
1.834 -
1.835 - if ( newlevel == _node_num ) level.set(w,_node_num);
1.836 - else {
1.837 - level.set(w,++newlevel);
1.838 - next.set(w,first[newlevel]);
1.839 - first[newlevel]=w;
1.840 - if ( what_heur ) b=newlevel;
1.841 - if ( k < newlevel ) ++k; //now k=newlevel
1.842 - Node z=level_list[newlevel];
1.843 - if ( z!=INVALID ) left.set(z,w);
1.844 - right.set(w,z);
1.845 - left.set(w,INVALID);
1.846 - level_list[newlevel]=w;
1.847 - }
1.848 - }
1.849 - } //relabel
1.850 -
1.851 - };
1.852 -
1.853 - ///Function type interface for Preflow algorithm.
1.854 -
1.855 - /// \ingroup flowalgs
1.856 - ///Function type interface for Preflow algorithm.
1.857 - ///\sa Preflow
1.858 - template<class GR, class CM, class FM>
1.859 - Preflow<GR,typename CM::Value,CM,FM> preflow(const GR &g,
1.860 - typename GR::Node source,
1.861 - typename GR::Node target,
1.862 - const CM &cap,
1.863 - FM &flow
1.864 - )
1.865 - {
1.866 - return Preflow<GR,typename CM::Value,CM,FM>(g,source,target,cap,flow);
1.867 - }
1.868 -
1.869 -} //namespace lemon
1.870 -
1.871 -#endif //LEMON_PREFLOW_H