deba@2514: /* -*- C++ -*-
deba@2514:  *
deba@2514:  * This file is a part of LEMON, a generic C++ optimization library
deba@2514:  *
alpar@2553:  * Copyright (C) 2003-2008
deba@2514:  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2514:  * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2514:  *
deba@2514:  * Permission to use, modify and distribute this software is granted
deba@2514:  * provided that this copyright notice appears in all copies. For
deba@2514:  * precise terms see the accompanying LICENSE file.
deba@2514:  *
deba@2514:  * This software is provided "AS IS" with no warranty of any kind,
deba@2514:  * express or implied, and with no claim as to its suitability for any
deba@2514:  * purpose.
deba@2514:  *
deba@2514:  */
deba@2514: 
deba@2514: #ifndef LEMON_GOLDBERG_TARJAN_H
deba@2514: #define LEMON_GOLDBERG_TARJAN_H
deba@2514: 
deba@2514: #include <vector>
deba@2514: #include <queue>
deba@2514: 
deba@2514: #include <lemon/error.h>
deba@2514: #include <lemon/bits/invalid.h>
deba@2514: #include <lemon/tolerance.h>
deba@2514: #include <lemon/maps.h>
deba@2514: #include <lemon/graph_utils.h>
deba@2514: #include <lemon/dynamic_tree.h>
deba@2514: #include <limits>
deba@2514: 
deba@2514: /// \file
deba@2514: /// \ingroup max_flow
deba@2514: /// \brief Implementation of the preflow algorithm.
deba@2514: 
deba@2514: namespace lemon {
deba@2514: 
deba@2514:   /// \brief Default traits class of GoldbergTarjan class.
deba@2514:   ///
deba@2514:   /// Default traits class of GoldbergTarjan class.
deba@2514:   /// \param _Graph Graph type.
deba@2514:   /// \param _CapacityMap Type of capacity map.
deba@2514:   template <typename _Graph, typename _CapacityMap>
deba@2514:   struct GoldbergTarjanDefaultTraits {
deba@2514: 
deba@2514:     /// \brief The graph type the algorithm runs on. 
deba@2514:     typedef _Graph Graph;
deba@2514: 
deba@2514:     /// \brief The type of the map that stores the edge capacities.
deba@2514:     ///
deba@2514:     /// The type of the map that stores the edge capacities.
deba@2514:     /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
deba@2514:     typedef _CapacityMap CapacityMap;
deba@2514: 
deba@2514:     /// \brief The type of the length of the edges.
deba@2514:     typedef typename CapacityMap::Value Value;
deba@2514: 
deba@2514:     /// \brief The map type that stores the flow values.
deba@2514:     ///
deba@2514:     /// The map type that stores the flow values. 
deba@2514:     /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
deba@2514:     typedef typename Graph::template EdgeMap<Value> FlowMap;
deba@2514: 
deba@2514:     /// \brief Instantiates a FlowMap.
deba@2514:     ///
deba@2514:     /// This function instantiates a \ref FlowMap. 
deba@2514:     /// \param graph The graph, to which we would like to define the flow map.
deba@2514:     static FlowMap* createFlowMap(const Graph& graph) {
deba@2514:       return new FlowMap(graph);
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief The eleavator type used by GoldbergTarjan algorithm.
deba@2514:     /// 
deba@2514:     /// The elevator type used by GoldbergTarjan algorithm.
deba@2514:     ///
deba@2514:     /// \sa Elevator
deba@2514:     /// \sa LinkedElevator
deba@2514:     typedef LinkedElevator<Graph, typename Graph::Node> Elevator;
deba@2514:     
deba@2514:     /// \brief Instantiates an Elevator.
deba@2514:     ///
deba@2514:     /// This function instantiates a \ref Elevator. 
deba@2514:     /// \param graph The graph, to which we would like to define the elevator.
deba@2514:     /// \param max_level The maximum level of the elevator.
deba@2514:     static Elevator* createElevator(const Graph& graph, int max_level) {
deba@2514:       return new Elevator(graph, max_level);
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief The tolerance used by the algorithm
deba@2514:     ///
deba@2514:     /// The tolerance used by the algorithm to handle inexact computation.
deba@2514:     typedef Tolerance<Value> Tolerance;
deba@2514: 
deba@2514:   };
deba@2514: 
deba@2514:   /// \ingroup max_flow
deba@2514:   /// \brief Goldberg-Tarjan algorithms class.
deba@2514:   ///
deba@2514:   /// This class provides an implementation of the \e GoldbergTarjan
deba@2514:   /// \e algorithm producing a flow of maximum value in a directed
deba@2514:   /// graph. The GoldbergTarjan algorithm is a theoretical improvement
deba@2514:   /// of the Goldberg's \ref Preflow "preflow" algorithm by using the \ref
deba@2514:   /// DynamicTree "dynamic tree" data structure of Sleator and Tarjan.
deba@2514:   /// 
deba@2522:   /// The original preflow algorithm with \e highest \e label
deba@2522:   /// heuristic has \f$O(n^2\sqrt{e})\f$ or with \e FIFO heuristic has
deba@2522:   /// \f$O(n^3)\f$ time complexity. The current algorithm improved
deba@2522:   /// this complexity to \f$O(nm\log(\frac{n^2}{m}))\f$. The algorithm
deba@2522:   /// builds limited size dynamic trees on the residual graph, which
deba@2522:   /// can be used to make multilevel push operations and gives a
deba@2522:   /// better bound on the number of non-saturating pushes.
deba@2514:   ///
deba@2514:   /// \param Graph The directed graph type the algorithm runs on.
deba@2514:   /// \param CapacityMap The capacity map type.
deba@2514:   /// \param _Traits Traits class to set various data types used by
deba@2514:   /// the algorithm.  The default traits class is \ref
deba@2514:   /// GoldbergTarjanDefaultTraits.  See \ref
deba@2514:   /// GoldbergTarjanDefaultTraits for the documentation of a
deba@2514:   /// Goldberg-Tarjan traits class.
deba@2514:   ///
deba@2514:   /// \author Tamas Hamori and Balazs Dezso
deba@2514: #ifdef DOXYGEN
deba@2514:   template <typename _Graph, typename _CapacityMap, typename _Traits> 
deba@2514: #else
deba@2514:   template <typename _Graph,
deba@2514: 	    typename _CapacityMap = typename _Graph::template EdgeMap<int>,
deba@2514:             typename _Traits = 
deba@2514: 	    GoldbergTarjanDefaultTraits<_Graph, _CapacityMap> >
deba@2514: #endif
deba@2514:   class GoldbergTarjan {
deba@2514:   public:
deba@2514: 
deba@2514:     typedef _Traits Traits;
deba@2514:     typedef typename Traits::Graph Graph;
deba@2514:     typedef typename Traits::CapacityMap CapacityMap;
deba@2514:     typedef typename Traits::Value Value; 
deba@2514: 
deba@2514:     typedef typename Traits::FlowMap FlowMap;
deba@2514:     typedef typename Traits::Elevator Elevator;
deba@2514:     typedef typename Traits::Tolerance Tolerance;
deba@2514:     
deba@2514:   protected:
deba@2514: 
deba@2514:     GRAPH_TYPEDEFS(typename Graph);
deba@2514: 
deba@2514:     typedef typename Graph::template NodeMap<Node> NodeNodeMap;
deba@2514:     typedef typename Graph::template NodeMap<int> IntNodeMap;
deba@2514: 
deba@2514:     typedef typename Graph::template NodeMap<Edge> EdgeNodeMap;
deba@2514:     typedef typename Graph::template EdgeMap<Edge> EdgeEdgeMap;
deba@2514: 
deba@2514:     typedef typename std::vector<Node> VecNode;
deba@2514:  
deba@2514:     typedef DynamicTree<Value,IntNodeMap,Tolerance> DynTree;
deba@2514: 
deba@2514:     const Graph& _graph;
deba@2514:     const CapacityMap* _capacity;
deba@2514:     int _node_num; //the number of nodes of G
deba@2514: 
deba@2514:     Node _source;
deba@2514:     Node _target;
deba@2514: 
deba@2514:     FlowMap* _flow;
deba@2514:     bool _local_flow;
deba@2514: 
deba@2514:     Elevator* _level;
deba@2514:     bool _local_level;
deba@2514: 
deba@2514:     typedef typename Graph::template NodeMap<Value> ExcessMap;
deba@2514:     ExcessMap* _excess;
deba@2514:     
deba@2514:     Tolerance _tolerance;
deba@2514: 
deba@2514:     bool _phase;
deba@2514: 
deba@2514:     // constant for treesize
deba@2514:     static const double _tree_bound = 2;
deba@2514:     int _max_tree_size;
deba@2514:     
deba@2514:     //tags for the dynamic tree
deba@2514:     DynTree *_dt; 
deba@2514:     //datastructure of dyanamic tree
deba@2514:     IntNodeMap *_dt_index;
deba@2514:     //datastrucure for solution of the communication between the two class
deba@2514:     EdgeNodeMap *_dt_edges; 
deba@2514:     //nodeMap for storing the outgoing edge from the node in the tree  
deba@2514: 
deba@2514:     //max of the type Value
deba@2514:     const Value _max_value;
deba@2514:             
deba@2514:   public:
deba@2514: 
deba@2514:     typedef GoldbergTarjan Create;
deba@2514: 
deba@2514:     ///\name Named template parameters
deba@2514: 
deba@2514:     ///@{
deba@2514: 
deba@2514:     template <typename _FlowMap>
deba@2514:     struct DefFlowMapTraits : public Traits {
deba@2514:       typedef _FlowMap FlowMap;
deba@2514:       static FlowMap *createFlowMap(const Graph&) {
deba@2514: 	throw UninitializedParameter();
deba@2514:       }
deba@2514:     };
deba@2514: 
deba@2514:     /// \brief \ref named-templ-param "Named parameter" for setting
deba@2514:     /// FlowMap type
deba@2514:     ///
deba@2514:     /// \ref named-templ-param "Named parameter" for setting FlowMap
deba@2514:     /// type
deba@2514:     template <typename _FlowMap>
deba@2514:     struct DefFlowMap 
deba@2514:       : public GoldbergTarjan<Graph, CapacityMap, 
deba@2514: 			      DefFlowMapTraits<_FlowMap> > {
deba@2514:       typedef GoldbergTarjan<Graph, CapacityMap, 
deba@2514: 			     DefFlowMapTraits<_FlowMap> > Create;
deba@2514:     };
deba@2514: 
deba@2514:     template <typename _Elevator>
deba@2514:     struct DefElevatorTraits : public Traits {
deba@2514:       typedef _Elevator Elevator;
deba@2514:       static Elevator *createElevator(const Graph&, int) {
deba@2514: 	throw UninitializedParameter();
deba@2514:       }
deba@2514:     };
deba@2514: 
deba@2514:     /// \brief \ref named-templ-param "Named parameter" for setting
deba@2514:     /// Elevator type
deba@2514:     ///
deba@2514:     /// \ref named-templ-param "Named parameter" for setting Elevator
deba@2514:     /// type
deba@2514:     template <typename _Elevator>
deba@2514:     struct DefElevator 
deba@2514:       : public GoldbergTarjan<Graph, CapacityMap, 
deba@2514: 			      DefElevatorTraits<_Elevator> > {
deba@2514:       typedef GoldbergTarjan<Graph, CapacityMap, 
deba@2514: 			     DefElevatorTraits<_Elevator> > Create;
deba@2514:     };
deba@2514: 
deba@2514:     template <typename _Elevator>
deba@2514:     struct DefStandardElevatorTraits : public Traits {
deba@2514:       typedef _Elevator Elevator;
deba@2514:       static Elevator *createElevator(const Graph& graph, int max_level) {
deba@2514: 	return new Elevator(graph, max_level);
deba@2514:       }
deba@2514:     };
deba@2514: 
deba@2514:     /// \brief \ref named-templ-param "Named parameter" for setting
deba@2514:     /// Elevator type
deba@2514:     ///
deba@2514:     /// \ref named-templ-param "Named parameter" for setting Elevator
deba@2514:     /// type. The Elevator should be standard constructor interface, ie.
deba@2514:     /// the graph and the maximum level should be passed to it.
deba@2514:     template <typename _Elevator>
deba@2514:     struct DefStandardElevator 
deba@2514:       : public GoldbergTarjan<Graph, CapacityMap, 
deba@2514: 			      DefStandardElevatorTraits<_Elevator> > {
deba@2514:       typedef GoldbergTarjan<Graph, CapacityMap, 
deba@2514: 			     DefStandardElevatorTraits<_Elevator> > Create;
deba@2514:     };    
deba@2514: 
deba@2514: 
deba@2514:     ///\ref Exception for the case when s=t.
deba@2514: 
deba@2514:     ///\ref Exception for the case when the source equals the target.
deba@2514:     class InvalidArgument : public lemon::LogicError {
deba@2514:     public:
deba@2514:       virtual const char* what() const throw() {
deba@2514: 	return "lemon::GoldbergTarjan::InvalidArgument";
deba@2514:       }
deba@2514:     };
deba@2514: 
deba@2527:   protected:
deba@2527:     
deba@2527:     GoldbergTarjan() {}
deba@2527: 
deba@2527:   public:
deba@2514: 
deba@2514:     /// \brief The constructor of the class.
deba@2514:     ///
deba@2514:     /// The constructor of the class. 
deba@2514:     /// \param graph The directed graph the algorithm runs on. 
deba@2514:     /// \param capacity The capacity of the edges. 
deba@2514:     /// \param source The source node.
deba@2514:     /// \param target The target node.
deba@2514:     /// Except the graph, all of these parameters can be reset by
deba@2514:     /// calling \ref source, \ref target, \ref capacityMap and \ref
deba@2514:     /// flowMap, resp.
deba@2514:     GoldbergTarjan(const Graph& graph, const CapacityMap& capacity,
deba@2514: 		   Node source, Node target) 
deba@2514:       : _graph(graph), _capacity(&capacity), 
deba@2514: 	_node_num(), _source(source), _target(target),
deba@2514: 	_flow(0), _local_flow(false),
deba@2514: 	_level(0), _local_level(false),
deba@2514: 	_excess(0), _tolerance(), 
deba@2514: 	_phase(), _max_tree_size(),
deba@2514: 	_dt(0), _dt_index(0), _dt_edges(0), 
deba@2514: 	_max_value(std::numeric_limits<Value>::max()) { 
deba@2514:       if (_source == _target) throw InvalidArgument();
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Destrcutor.
deba@2514:     ///
deba@2514:     /// Destructor.
deba@2514:     ~GoldbergTarjan() {
deba@2514:       destroyStructures();
deba@2514:     }
deba@2514:     
deba@2514:     /// \brief Sets the capacity map.
deba@2514:     ///
deba@2514:     /// Sets the capacity map.
deba@2514:     /// \return \c (*this)
deba@2514:     GoldbergTarjan& capacityMap(const CapacityMap& map) {
deba@2514:       _capacity = &map;
deba@2514:       return *this;
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Sets the flow map.
deba@2514:     ///
deba@2514:     /// Sets the flow map.
deba@2514:     /// \return \c (*this)
deba@2514:     GoldbergTarjan& flowMap(FlowMap& map) {
deba@2514:       if (_local_flow) {
deba@2514: 	delete _flow;
deba@2514: 	_local_flow = false;
deba@2514:       }
deba@2514:       _flow = &map;
deba@2514:       return *this;
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Returns the flow map.
deba@2514:     ///
deba@2514:     /// \return The flow map.
deba@2514:     const FlowMap& flowMap() {
deba@2514:       return *_flow;
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Sets the elevator.
deba@2514:     ///
deba@2514:     /// Sets the elevator.
deba@2514:     /// \return \c (*this)
deba@2514:     GoldbergTarjan& elevator(Elevator& elevator) {
deba@2514:       if (_local_level) {
deba@2514: 	delete _level;
deba@2514: 	_local_level = false;
deba@2514:       }
deba@2514:       _level = &elevator;
deba@2514:       return *this;
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Returns the elevator.
deba@2514:     ///
deba@2514:     /// \return The elevator.
deba@2514:     const Elevator& elevator() {
deba@2514:       return *_level;
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Sets the source node.
deba@2514:     ///
deba@2514:     /// Sets the source node.
deba@2514:     /// \return \c (*this)
deba@2514:     GoldbergTarjan& source(const Node& node) {
deba@2514:       _source = node;
deba@2514:       return *this;
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Sets the target node.
deba@2514:     ///
deba@2514:     /// Sets the target node.
deba@2514:     /// \return \c (*this)
deba@2514:     GoldbergTarjan& target(const Node& node) {
deba@2514:       _target = node;
deba@2514:       return *this;
deba@2514:     }
deba@2514:  
deba@2514:     /// \brief Sets the tolerance used by algorithm.
deba@2514:     ///
deba@2514:     /// Sets the tolerance used by algorithm.
deba@2514:     GoldbergTarjan& tolerance(const Tolerance& tolerance) const {
deba@2514:       _tolerance = tolerance;
deba@2514:       if (_dt) {
deba@2514: 	_dt->tolerance(_tolerance);
deba@2514:       }
deba@2514:       return *this;
deba@2514:     } 
deba@2514: 
deba@2514:     /// \brief Returns the tolerance used by algorithm.
deba@2514:     ///
deba@2514:     /// Returns the tolerance used by algorithm.
deba@2514:     const Tolerance& tolerance() const {
deba@2514:       return tolerance;
deba@2514:     } 
deba@2514: 
deba@2514:          
deba@2514:   private:
deba@2514:     
deba@2514:     void createStructures() {
deba@2514:       _node_num = countNodes(_graph);
deba@2514: 
deba@2518:       _max_tree_size = int((double(_node_num) * double(_node_num)) / 
deba@2518: 			   double(countEdges(_graph)));
deba@2514: 
deba@2514:       if (!_flow) {
deba@2514: 	_flow = Traits::createFlowMap(_graph);
deba@2514: 	_local_flow = true;
deba@2514:       }
deba@2514:       if (!_level) {
deba@2514: 	_level = Traits::createElevator(_graph, _node_num);
deba@2514: 	_local_level = true;
deba@2514:       }
deba@2514:       if (!_excess) {
deba@2514: 	_excess = new ExcessMap(_graph);
deba@2514:       }
deba@2514:       if (!_dt_index && !_dt) {
deba@2514: 	_dt_index = new IntNodeMap(_graph);
deba@2514: 	_dt = new DynTree(*_dt_index, _tolerance);
deba@2514:       }
deba@2514:       if (!_dt_edges) {
deba@2514: 	_dt_edges = new EdgeNodeMap(_graph);
deba@2514:       }
deba@2514:     }
deba@2514: 
deba@2514:     void destroyStructures() {
deba@2514:       if (_local_flow) {
deba@2514: 	delete _flow;
deba@2514:       }
deba@2514:       if (_local_level) {
deba@2514: 	delete _level;
deba@2514:       }
deba@2514:       if (_excess) {
deba@2514: 	delete _excess;
deba@2514:       }
deba@2514:       if (_dt) {
deba@2514: 	delete _dt;
deba@2514:       }
deba@2514:       if (_dt_index) {
deba@2514: 	delete _dt_index;
deba@2514:       }
deba@2514:       if (_dt_edges) {
deba@2514: 	delete _dt_edges;
deba@2514:       }
deba@2514:     }
deba@2514: 
deba@2514:     bool sendOut(Node n, Value& excess) {
deba@2514: 
deba@2514:       Node w = _dt->findRoot(n);
deba@2514:       
deba@2514:       while (w != n) {
deba@2514:       
deba@2514: 	Value rem;      
deba@2514: 	Node u = _dt->findCost(n, rem);
deba@2514: 
deba@2514:         if (_tolerance.positive(rem) && !_level->active(w) && w != _target) {
deba@2514: 	  _level->activate(w);
deba@2514:         }
deba@2514: 
deba@2514:         if (!_tolerance.less(rem, excess)) {
deba@2514: 	  _dt->addCost(n, - excess);
deba@2514: 	  _excess->set(w, (*_excess)[w] + excess);
deba@2514: 	  excess = 0;
deba@2514: 	  return true;
deba@2514: 	}
deba@2514: 	
deba@2514: 	
deba@2514:         _dt->addCost(n, - rem);
deba@2514: 
deba@2514:         excess -= rem;
deba@2514:         _excess->set(w, (*_excess)[w] + rem);
deba@2514:         
deba@2514: 	_dt->cut(u);
deba@2514: 	_dt->addCost(u, _max_value);
deba@2514: 	  
deba@2514: 	Edge e = (*_dt_edges)[u];
deba@2514: 	_dt_edges->set(u, INVALID);
deba@2514:         
deba@2514: 	if (u == _graph.source(e)) {
deba@2514: 	  _flow->set(e, (*_capacity)[e]);
deba@2514: 	} else {
deba@2514: 	  _flow->set(e, 0);
deba@2514: 	}           
deba@2514: 
deba@2514:         w = _dt->findRoot(n);
deba@2514:       }      
deba@2514:       return false;
deba@2514:     }
deba@2514: 
deba@2514:     bool sendIn(Node n, Value& excess) {
deba@2514: 
deba@2514:       Node w = _dt->findRoot(n);
deba@2514:       
deba@2514:       while (w != n) {
deba@2514:       
deba@2514: 	Value rem;      
deba@2514: 	Node u = _dt->findCost(n, rem);
deba@2514: 
deba@2514:         if (_tolerance.positive(rem) && !_level->active(w) && w != _source) {
deba@2514: 	  _level->activate(w);
deba@2514:         }
deba@2514: 
deba@2514:         if (!_tolerance.less(rem, excess)) {
deba@2514: 	  _dt->addCost(n, - excess);
deba@2514: 	  _excess->set(w, (*_excess)[w] + excess);
deba@2514: 	  excess = 0;
deba@2514: 	  return true;
deba@2514: 	}
deba@2514: 	
deba@2514: 	
deba@2514:         _dt->addCost(n, - rem);
deba@2514: 
deba@2514:         excess -= rem;
deba@2514:         _excess->set(w, (*_excess)[w] + rem);
deba@2514:         
deba@2514: 	_dt->cut(u);
deba@2514: 	_dt->addCost(u, _max_value);
deba@2514: 	  
deba@2514: 	Edge e = (*_dt_edges)[u];
deba@2514: 	_dt_edges->set(u, INVALID);
deba@2514:         
deba@2514: 	if (u == _graph.source(e)) {
deba@2514: 	  _flow->set(e, (*_capacity)[e]);
deba@2514: 	} else {
deba@2514: 	  _flow->set(e, 0);
deba@2514: 	}           
deba@2514: 
deba@2514:         w = _dt->findRoot(n);
deba@2514:       }      
deba@2514:       return false;
deba@2514:     }
deba@2514: 
deba@2514:     void cutChildren(Node n) {
deba@2514:     
deba@2514:       for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
deba@2514:         
deba@2514:         Node v = _graph.target(e);
deba@2514:         
deba@2514:         if ((*_dt_edges)[v] != INVALID && (*_dt_edges)[v] == e) {
deba@2514:           _dt->cut(v);
deba@2514:           _dt_edges->set(v, INVALID);
deba@2514: 	  Value rem;
deba@2514:           _dt->findCost(v, rem);
deba@2514:           _dt->addCost(v, - rem);
deba@2514:           _dt->addCost(v, _max_value);
deba@2514:           _flow->set(e, rem);
deba@2514: 
deba@2514:         }      
deba@2514:       }
deba@2514: 
deba@2514:       for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
deba@2514:         
deba@2514:         Node v = _graph.source(e);
deba@2514:         
deba@2514:         if ((*_dt_edges)[v] != INVALID && (*_dt_edges)[v] == e) {
deba@2514:           _dt->cut(v);
deba@2514:           _dt_edges->set(v, INVALID);
deba@2514: 	  Value rem;
deba@2514:           _dt->findCost(v, rem);
deba@2514:           _dt->addCost(v, - rem);
deba@2514:           _dt->addCost(v, _max_value);
deba@2514:           _flow->set(e, (*_capacity)[e] - rem);
deba@2514: 
deba@2514:         }      
deba@2514:       }
deba@2514:     }
deba@2514: 
deba@2514:     void extractTrees() {
deba@2514:       for (NodeIt n(_graph); n != INVALID; ++n) {
deba@2514: 	
deba@2514: 	Node w = _dt->findRoot(n);
deba@2514:       
deba@2514: 	while (w != n) {
deba@2514:       
deba@2514: 	  Value rem;      
deba@2514: 	  Node u = _dt->findCost(n, rem);
deba@2514: 
deba@2514: 	  _dt->cut(u);
deba@2514: 	  _dt->addCost(u, - rem);
deba@2514: 	  _dt->addCost(u, _max_value);
deba@2514: 	  
deba@2514: 	  Edge e = (*_dt_edges)[u];
deba@2514: 	  _dt_edges->set(u, INVALID);
deba@2514: 	  
deba@2514: 	  if (u == _graph.source(e)) {
deba@2514: 	    _flow->set(e, (*_capacity)[e] - rem);
deba@2514: 	  } else {
deba@2514: 	    _flow->set(e, rem);
deba@2514: 	  }
deba@2514: 	  
deba@2514: 	  w = _dt->findRoot(n);
deba@2514: 	}      
deba@2514:       }
deba@2514:     }
deba@2514: 
deba@2514:   public:    
deba@2514: 
deba@2514:     /// \name Execution control The simplest way to execute the
deba@2514:     /// algorithm is to use one of the member functions called \c
deba@2514:     /// run().  
deba@2514:     /// \n
deba@2514:     /// If you need more control on initial solution or
deba@2514:     /// execution then you have to call one \ref init() function and then
deba@2514:     /// the startFirstPhase() and if you need the startSecondPhase().  
deba@2514:     
deba@2514:     ///@{
deba@2514: 
deba@2514:     /// \brief Initializes the internal data structures.
deba@2514:     ///
deba@2514:     /// Initializes the internal data structures.
deba@2514:     ///
deba@2514:     void init() {
deba@2514:       createStructures();
deba@2514: 
deba@2514:       for (NodeIt n(_graph); n != INVALID; ++n) {
deba@2514: 	_excess->set(n, 0);
deba@2514:       }
deba@2514: 
deba@2514:       for (EdgeIt e(_graph); e != INVALID; ++e) {
deba@2514: 	_flow->set(e, 0);
deba@2514:       }
deba@2514: 
deba@2514:       _dt->clear();
deba@2514:       for (NodeIt v(_graph); v != INVALID; ++v) {
deba@2514:         (*_dt_edges)[v] = INVALID;
deba@2514:         _dt->makeTree(v);
deba@2514:         _dt->addCost(v, _max_value);
deba@2514:       }
deba@2514: 
deba@2514:       typename Graph::template NodeMap<bool> reached(_graph, false);
deba@2514: 
deba@2514:       _level->initStart();
deba@2514:       _level->initAddItem(_target);
deba@2514: 
deba@2514:       std::vector<Node> queue;
deba@2514:       reached.set(_source, true);
deba@2514: 
deba@2514:       queue.push_back(_target);
deba@2514:       reached.set(_target, true);
deba@2514:       while (!queue.empty()) {
deba@2514: 	_level->initNewLevel();
deba@2514: 	std::vector<Node> nqueue;
deba@2514: 	for (int i = 0; i < int(queue.size()); ++i) {
deba@2514: 	  Node n = queue[i];
deba@2514: 	  for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
deba@2514: 	    Node u = _graph.source(e);
deba@2514: 	    if (!reached[u] && _tolerance.positive((*_capacity)[e])) {
deba@2514: 	      reached.set(u, true);
deba@2514: 	      _level->initAddItem(u);
deba@2514: 	      nqueue.push_back(u);
deba@2514: 	    }
deba@2514: 	  }
deba@2514: 	}
deba@2514: 	queue.swap(nqueue);
deba@2514:       }
deba@2514:       _level->initFinish();
deba@2514: 
deba@2514:       for (OutEdgeIt e(_graph, _source); e != INVALID; ++e) {
deba@2514: 	if (_tolerance.positive((*_capacity)[e])) {
deba@2514: 	  Node u = _graph.target(e);
deba@2514: 	  if ((*_level)[u] == _level->maxLevel()) continue;
deba@2514: 	  _flow->set(e, (*_capacity)[e]);
deba@2514: 	  _excess->set(u, (*_excess)[u] + (*_capacity)[e]);
deba@2514: 	  if (u != _target && !_level->active(u)) {
deba@2514: 	    _level->activate(u);
deba@2514: 	  }
deba@2514: 	}
deba@2514:       }
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Starts the first phase of the preflow algorithm.
deba@2514:     ///
deba@2514:     /// The preflow algorithm consists of two phases, this method runs
deba@2514:     /// the first phase. After the first phase the maximum flow value
deba@2514:     /// and a minimum value cut can already be computed, although a
deba@2514:     /// maximum flow is not yet obtained. So after calling this method
deba@2514:     /// \ref flowValue() returns the value of a maximum flow and \ref
deba@2514:     /// minCut() returns a minimum cut.     
deba@2514:     /// \pre One of the \ref init() functions should be called. 
deba@2514:     void startFirstPhase() {
deba@2514:       _phase = true;
deba@2514:       Node n;
deba@2514: 
deba@2514:       while ((n = _level->highestActive()) != INVALID) {
deba@2514: 	Value excess = (*_excess)[n];
deba@2514: 	int level = _level->highestActiveLevel();
deba@2514: 	int new_level = _level->maxLevel();
deba@2514: 
deba@2514: 	if (_dt->findRoot(n) != n) {
deba@2514: 	  if (sendOut(n, excess)) goto no_more_push;
deba@2514: 	}
deba@2514: 	
deba@2514: 	for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
deba@2514: 	  Value rem = (*_capacity)[e] - (*_flow)[e];
deba@2514: 	  Node v = _graph.target(e);
deba@2514: 	  
deba@2514: 	  if (!_tolerance.positive(rem) && (*_dt_edges)[v] != e) continue;
deba@2514: 
deba@2514: 	  if ((*_level)[v] < level) {
deba@2514: 	    
deba@2514: 	    if (_dt->findSize(n) + _dt->findSize(v) < 
deba@2514: 		_tree_bound * _max_tree_size) {
deba@2514: 	      _dt->addCost(n, -_max_value);
deba@2514: 	      _dt->addCost(n, rem);
deba@2514: 	      _dt->link(n, v);
deba@2514: 	      _dt_edges->set(n, e);
deba@2514: 	      if (sendOut(n, excess)) goto no_more_push;
deba@2514: 	    } else {
deba@2514: 	      if (!_level->active(v) && v != _target) {
deba@2514: 		_level->activate(v);
deba@2514: 	      }
deba@2514: 	      if (!_tolerance.less(rem, excess)) {
deba@2514: 		_flow->set(e, (*_flow)[e] + excess);
deba@2514: 		_excess->set(v, (*_excess)[v] + excess);
deba@2514: 		excess = 0;		  
deba@2514: 		goto no_more_push;
deba@2514: 	      } else {
deba@2514: 		excess -= rem;
deba@2514: 		_excess->set(v, (*_excess)[v] + rem);
deba@2514: 		_flow->set(e, (*_capacity)[e]);
deba@2514: 	      }		
deba@2514: 	    }
deba@2514: 	  } else if (new_level > (*_level)[v]) {
deba@2514: 	    new_level = (*_level)[v];
deba@2514: 	  }
deba@2514: 	}
deba@2514: 
deba@2514: 	for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
deba@2514: 	  Value rem = (*_flow)[e];
deba@2514: 	  Node v = _graph.source(e);
deba@2514: 	  if (!_tolerance.positive(rem) && (*_dt_edges)[v] != e) continue;
deba@2514: 
deba@2514: 	  if ((*_level)[v] < level) {
deba@2514: 	    
deba@2514: 	    if (_dt->findSize(n) + _dt->findSize(v) < 
deba@2514: 		_tree_bound * _max_tree_size) {
deba@2514: 	      _dt->addCost(n, - _max_value);
deba@2514: 	      _dt->addCost(n, rem);
deba@2514: 	      _dt->link(n, v);
deba@2514: 	      _dt_edges->set(n, e);
deba@2514: 	      if (sendOut(n, excess)) goto no_more_push;
deba@2514: 	    } else {
deba@2514: 	      if (!_level->active(v) && v != _target) {
deba@2514: 		_level->activate(v);
deba@2514: 	      }
deba@2514: 	      if (!_tolerance.less(rem, excess)) {
deba@2514: 		_flow->set(e, (*_flow)[e] - excess);
deba@2514: 		_excess->set(v, (*_excess)[v] + excess);
deba@2514: 		excess = 0;		  
deba@2514: 		goto no_more_push;
deba@2514: 	      } else {
deba@2514: 		excess -= rem;
deba@2514: 		_excess->set(v, (*_excess)[v] + rem);
deba@2514: 		_flow->set(e, 0);
deba@2514: 	      }		
deba@2514: 	    }
deba@2514: 	  } else if (new_level > (*_level)[v]) {
deba@2514: 	    new_level = (*_level)[v];
deba@2514: 	  }
deba@2514: 	}
deba@2514: 		
deba@2514:       no_more_push:
deba@2514: 
deba@2514: 	_excess->set(n, excess);
deba@2514: 	
deba@2514: 	if (excess != 0) {
deba@2514: 	  cutChildren(n);
deba@2514: 	  if (new_level + 1 < _level->maxLevel()) {
deba@2514: 	    _level->liftHighestActive(new_level + 1);
deba@2514: 	  } else {
deba@2514: 	    _level->liftHighestActiveToTop();
deba@2514: 	  }
deba@2514: 	  if (_level->emptyLevel(level)) {
deba@2514: 	    _level->liftToTop(level);
deba@2514: 	  }
deba@2514: 	} else {
deba@2514: 	  _level->deactivate(n);
deba@2514: 	}	
deba@2514:       }
deba@2514:       extractTrees();
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Starts the second phase of the preflow algorithm.
deba@2514:     ///
deba@2514:     /// The preflow algorithm consists of two phases, this method runs
deba@2514:     /// the second phase. After calling \ref init() and \ref
deba@2514:     /// startFirstPhase() and then \ref startSecondPhase(), \ref
deba@2514:     /// flowMap() return a maximum flow, \ref flowValue() returns the
deba@2514:     /// value of a maximum flow, \ref minCut() returns a minimum cut
deba@2514:     /// \pre The \ref init() and startFirstPhase() functions should be
deba@2514:     /// called before.
deba@2514:     void startSecondPhase() {
deba@2514:       _phase = false;
deba@2514:       
deba@2514:       typename Graph::template NodeMap<bool> reached(_graph, false);
deba@2514:       for (NodeIt n(_graph); n != INVALID; ++n) {
deba@2514: 	reached.set(n, (*_level)[n] < _level->maxLevel());
deba@2514:       }
deba@2514: 
deba@2514:       _level->initStart();
deba@2514:       _level->initAddItem(_source);
deba@2514:  
deba@2514:       std::vector<Node> queue;
deba@2514:       queue.push_back(_source);
deba@2514:       reached.set(_source, true);
deba@2514: 
deba@2514:       while (!queue.empty()) {
deba@2514: 	_level->initNewLevel();
deba@2514: 	std::vector<Node> nqueue;
deba@2514: 	for (int i = 0; i < int(queue.size()); ++i) {
deba@2514: 	  Node n = queue[i];
deba@2514: 	  for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
deba@2514: 	    Node v = _graph.target(e);
deba@2514: 	    if (!reached[v] && _tolerance.positive((*_flow)[e])) {
deba@2514: 	      reached.set(v, true);
deba@2514: 	      _level->initAddItem(v);
deba@2514: 	      nqueue.push_back(v);
deba@2514: 	    }
deba@2514: 	  }
deba@2514: 	  for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
deba@2514: 	    Node u = _graph.source(e);
deba@2514: 	    if (!reached[u] && 
deba@2514: 		_tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
deba@2514: 	      reached.set(u, true);
deba@2514: 	      _level->initAddItem(u);
deba@2514: 	      nqueue.push_back(u);
deba@2514: 	    }
deba@2514: 	  }
deba@2514: 	}
deba@2514: 	queue.swap(nqueue);
deba@2514:       }
deba@2514:       _level->initFinish();
deba@2514: 
deba@2514:       for (NodeIt n(_graph); n != INVALID; ++n) {
deba@2518: 	if (!reached[n]) {
deba@2518: 	  _level->markToBottom(n);
deba@2518: 	} else if ((*_excess)[n] > 0 && _target != n) {
deba@2514: 	  _level->activate(n);
deba@2514: 	}
deba@2514:       }
deba@2514: 
deba@2514:       Node n;
deba@2514: 
deba@2514:       while ((n = _level->highestActive()) != INVALID) {
deba@2514: 	Value excess = (*_excess)[n];
deba@2514: 	int level = _level->highestActiveLevel();
deba@2514: 	int new_level = _level->maxLevel();
deba@2514: 
deba@2514: 	if (_dt->findRoot(n) != n) {
deba@2514: 	  if (sendIn(n, excess)) goto no_more_push;
deba@2514: 	}
deba@2514: 	
deba@2514: 	for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
deba@2514: 	  Value rem = (*_capacity)[e] - (*_flow)[e];
deba@2514: 	  Node v = _graph.target(e);
deba@2514: 	  
deba@2514: 	  if (!_tolerance.positive(rem) && (*_dt_edges)[v] != e) continue;
deba@2514: 
deba@2514: 	  if ((*_level)[v] < level) {
deba@2514: 	    
deba@2514: 	    if (_dt->findSize(n) + _dt->findSize(v) < 
deba@2514: 		_tree_bound * _max_tree_size) {
deba@2514: 	      _dt->addCost(n, -_max_value);
deba@2514: 	      _dt->addCost(n, rem);
deba@2514: 	      _dt->link(n, v);
deba@2514: 	      _dt_edges->set(n, e);
deba@2514: 	      if (sendIn(n, excess)) goto no_more_push;
deba@2514: 	    } else {
deba@2514: 	      if (!_level->active(v) && v != _source) {
deba@2514: 		_level->activate(v);
deba@2514: 	      }
deba@2514: 	      if (!_tolerance.less(rem, excess)) {
deba@2514: 		_flow->set(e, (*_flow)[e] + excess);
deba@2514: 		_excess->set(v, (*_excess)[v] + excess);
deba@2514: 		excess = 0;		  
deba@2514: 		goto no_more_push;
deba@2514: 	      } else {
deba@2514: 		excess -= rem;
deba@2514: 		_excess->set(v, (*_excess)[v] + rem);
deba@2514: 		_flow->set(e, (*_capacity)[e]);
deba@2514: 	      }		
deba@2514: 	    }
deba@2514: 	  } else if (new_level > (*_level)[v]) {
deba@2514: 	    new_level = (*_level)[v];
deba@2514: 	  }
deba@2514: 	}
deba@2514: 
deba@2514: 	for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
deba@2514: 	  Value rem = (*_flow)[e];
deba@2514: 	  Node v = _graph.source(e);
deba@2514: 	  if (!_tolerance.positive(rem) && (*_dt_edges)[v] != e) continue;
deba@2514: 
deba@2514: 	  if ((*_level)[v] < level) {
deba@2514: 	    
deba@2514: 	    if (_dt->findSize(n) + _dt->findSize(v) < 
deba@2514: 		_tree_bound * _max_tree_size) {
deba@2514: 	      _dt->addCost(n, - _max_value);
deba@2514: 	      _dt->addCost(n, rem);
deba@2514: 	      _dt->link(n, v);
deba@2514: 	      _dt_edges->set(n, e);
deba@2514: 	      if (sendIn(n, excess)) goto no_more_push;
deba@2514: 	    } else {
deba@2514: 	      if (!_level->active(v) && v != _source) {
deba@2514: 		_level->activate(v);
deba@2514: 	      }
deba@2514: 	      if (!_tolerance.less(rem, excess)) {
deba@2514: 		_flow->set(e, (*_flow)[e] - excess);
deba@2514: 		_excess->set(v, (*_excess)[v] + excess);
deba@2514: 		excess = 0;		  
deba@2514: 		goto no_more_push;
deba@2514: 	      } else {
deba@2514: 		excess -= rem;
deba@2514: 		_excess->set(v, (*_excess)[v] + rem);
deba@2514: 		_flow->set(e, 0);
deba@2514: 	      }		
deba@2514: 	    }
deba@2514: 	  } else if (new_level > (*_level)[v]) {
deba@2514: 	    new_level = (*_level)[v];
deba@2514: 	  }
deba@2514: 	}
deba@2514: 		
deba@2514:       no_more_push:
deba@2514: 
deba@2514: 	_excess->set(n, excess);
deba@2514: 	
deba@2514: 	if (excess != 0) {
deba@2514: 	  cutChildren(n);
deba@2514: 	  if (new_level + 1 < _level->maxLevel()) {
deba@2514: 	    _level->liftHighestActive(new_level + 1);
deba@2514: 	  } else {
deba@2514: 	    _level->liftHighestActiveToTop();
deba@2514: 	  }
deba@2514: 	  if (_level->emptyLevel(level)) {
deba@2514: 	    _level->liftToTop(level);
deba@2514: 	  }
deba@2514: 	} else {
deba@2514: 	  _level->deactivate(n);
deba@2514: 	}	
deba@2514:       }
deba@2514:       extractTrees();
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Runs the Goldberg-Tarjan algorithm.  
deba@2514:     ///
deba@2514:     /// Runs the Goldberg-Tarjan algorithm.
deba@2514:     /// \note pf.run() is just a shortcut of the following code.
deba@2514:     /// \code
deba@2514:     ///   pf.init();
deba@2514:     ///   pf.startFirstPhase();
deba@2514:     ///   pf.startSecondPhase();
deba@2514:     /// \endcode
deba@2514:     void run() {
deba@2514:       init();
deba@2514:       startFirstPhase();
deba@2514:       startSecondPhase();
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Runs the Goldberg-Tarjan algorithm to compute the minimum cut.  
deba@2514:     ///
deba@2514:     /// Runs the Goldberg-Tarjan algorithm to compute the minimum cut.
deba@2514:     /// \note pf.runMinCut() is just a shortcut of the following code.
deba@2514:     /// \code
deba@2514:     ///   pf.init();
deba@2514:     ///   pf.startFirstPhase();
deba@2514:     /// \endcode
deba@2514:     void runMinCut() {
deba@2514:       init();
deba@2514:       startFirstPhase();
deba@2514:     }
deba@2514: 
deba@2514:     /// @}
deba@2514: 
deba@2522:     /// \name Query Functions 
deba@2522:     /// The result of the Goldberg-Tarjan algorithm can be obtained
deba@2522:     /// using these functions.
deba@2522:     /// \n
deba@2522:     /// Before the use of these functions, either run() or start() must
deba@2522:     /// be called.
deba@2514:     
deba@2514:     ///@{
deba@2514: 
deba@2514:     /// \brief Returns the value of the maximum flow.
deba@2514:     ///
deba@2514:     /// Returns the value of the maximum flow by returning the excess
deba@2514:     /// of the target node \c t. This value equals to the value of
deba@2514:     /// the maximum flow already after the first phase.
deba@2514:     Value flowValue() const {
deba@2514:       return (*_excess)[_target];
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Returns true when the node is on the source side of minimum cut.
deba@2514:     ///
deba@2514:     /// Returns true when the node is on the source side of minimum
deba@2514:     /// cut. This method can be called both after running \ref
deba@2514:     /// startFirstPhase() and \ref startSecondPhase().
deba@2514:     bool minCut(const Node& node) const {
deba@2514:       return ((*_level)[node] == _level->maxLevel()) == _phase;
deba@2514:     }
deba@2514:  
deba@2514:     /// \brief Returns a minimum value cut.
deba@2514:     ///
deba@2514:     /// Sets the \c cutMap to the characteristic vector of a minimum value
deba@2514:     /// cut. This method can be called both after running \ref
deba@2514:     /// startFirstPhase() and \ref startSecondPhase(). The result after second
deba@2514:     /// phase could be changed slightly if inexact computation is used.
deba@2514:     /// \pre The \c cutMap should be a bool-valued node-map.
deba@2514:     template <typename CutMap>
deba@2514:     void minCutMap(CutMap& cutMap) const {
deba@2514:       for (NodeIt n(_graph); n != INVALID; ++n) {
deba@2514: 	cutMap.set(n, minCut(n));
deba@2514:       }
deba@2514:     }
deba@2514: 
deba@2514:     /// \brief Returns the flow on the edge.
deba@2514:     ///
deba@2514:     /// Sets the \c flowMap to the flow on the edges. This method can
deba@2514:     /// be called after the second phase of algorithm.
deba@2514:     Value flow(const Edge& edge) const {
deba@2514:       return (*_flow)[edge];
deba@2514:     }
deba@2514: 
deba@2514:     /// @}
deba@2514: 
deba@2514:   }; 
deba@2514:   
deba@2514: } //namespace lemon
deba@2514: 
deba@2514: #endif