3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2007
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
19 #ifndef LEMON_DINITZ_SLEATOR_TARJAN_H
20 #define LEMON_DINITZ_SLEATOR_TARJAN_H
24 /// \brief Implementation the dynamic tree data structure of Sleator
27 #include <lemon/time_measure.h>
29 #include <lemon/graph_utils.h>
30 #include <lemon/tolerance.h>
31 #include <lemon/graph_adaptor.h>
32 #include <lemon/bfs.h>
33 #include <lemon/edge_set.h>
34 #include <lemon/dynamic_tree.h>
43 /// \brief Default traits class of DinitzSleatorTarjan class.
45 /// Default traits class of DinitzSleatorTarjan class.
46 /// \param _Graph Graph type.
47 /// \param _CapacityMap Type of capacity map.
48 template <typename _Graph, typename _CapacityMap>
49 struct DinitzSleatorTarjanDefaultTraits {
51 /// \brief The graph type the algorithm runs on.
54 /// \brief The type of the map that stores the edge capacities.
56 /// The type of the map that stores the edge capacities.
57 /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
58 typedef _CapacityMap CapacityMap;
60 /// \brief The type of the length of the edges.
61 typedef typename CapacityMap::Value Value;
63 /// \brief The map type that stores the flow values.
65 /// The map type that stores the flow values.
66 /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
67 typedef typename Graph::template EdgeMap<Value> FlowMap;
69 /// \brief Instantiates a FlowMap.
71 /// This function instantiates a \ref FlowMap.
72 /// \param graph The graph, to which we would like to define the flow map.
73 static FlowMap* createFlowMap(const Graph& graph) {
74 return new FlowMap(graph);
77 /// \brief The tolerance used by the algorithm
79 /// The tolerance used by the algorithm to handle inexact computation.
80 typedef Tolerance<Value> Tolerance;
86 /// \brief Dinitz-Sleator-Tarjan algorithms class.
88 /// This class provides an implementation of the \e
89 /// Dinitz-Sleator-Tarjan \e algorithm producing a flow of maximum
90 /// value in a directed graph. The DinitzSleatorTarjan algorithm is
91 /// the fastest known max flow algorithms wich using blocking
92 /// flow. It is an improvement of the Dinitz algorithm by using the
93 /// \ref DynamicTree "dynamic tree" data structure of Sleator and
96 /// This blocking flow algorithms builds a layered graph according
97 /// to \ref Bfs "breadth-first search" distance from the target node
98 /// in the reversed residual graph. The layered graph contains each
99 /// residual edge which steps one level down. After that the
100 /// algorithm constructs a blocking flow on the layered graph and
101 /// augments the overall flow with it. The number of the levels in
102 /// the layered graph is strictly increasing in each augmenting
103 /// phase therefore the number of the augmentings is at most
104 /// \f$n-1\f$. The length of each phase is at most
105 /// \f$O(m\log(n))\f$, that the overall time complexity is
106 /// \f$O(nm\log(n))\f$.
108 /// \param _Graph The directed graph type the algorithm runs on.
109 /// \param _CapacityMap The capacity map type.
110 /// \param _Traits Traits class to set various data types used by
111 /// the algorithm. The default traits class is \ref
112 /// DinitzSleatorTarjanDefaultTraits. See \ref
113 /// DinitzSleatorTarjanDefaultTraits for the documentation of a
114 /// Dinitz-Sleator-Tarjan traits class.
116 /// \author Tamas Hamori and Balazs Dezso
118 template <typename _Graph, typename _CapacityMap, typename _Traits>
120 template <typename _Graph,
121 typename _CapacityMap = typename _Graph::template EdgeMap<int>,
123 DinitzSleatorTarjanDefaultTraits<_Graph, _CapacityMap> >
125 class DinitzSleatorTarjan {
128 typedef _Traits Traits;
129 typedef typename Traits::Graph Graph;
130 typedef typename Traits::CapacityMap CapacityMap;
131 typedef typename Traits::Value Value;
133 typedef typename Traits::FlowMap FlowMap;
134 typedef typename Traits::Tolerance Tolerance;
139 GRAPH_TYPEDEFS(typename Graph);
142 typedef typename Graph::template NodeMap<int> LevelMap;
143 typedef typename Graph::template NodeMap<int> IntNodeMap;
144 typedef typename Graph::template NodeMap<Edge> EdgeNodeMap;
145 typedef DynamicTree<Value, IntNodeMap, Tolerance, false> DynTree;
150 const CapacityMap* _capacity;
152 Node _source, _target;
158 EdgeNodeMap* _dt_edges;
160 IntNodeMap* _dt_index;
163 Tolerance _tolerance;
171 typedef DinitzSleatorTarjan Create;
173 ///\name Named template parameters
177 template <typename _FlowMap>
178 struct DefFlowMapTraits : public Traits {
179 typedef _FlowMap FlowMap;
180 static FlowMap *createFlowMap(const Graph&) {
181 throw UninitializedParameter();
185 /// \brief \ref named-templ-param "Named parameter" for setting
188 /// \ref named-templ-param "Named parameter" for setting FlowMap
190 template <typename _FlowMap>
192 : public DinitzSleatorTarjan<Graph, CapacityMap,
193 DefFlowMapTraits<_FlowMap> > {
194 typedef DinitzSleatorTarjan<Graph, CapacityMap,
195 DefFlowMapTraits<_FlowMap> > Create;
198 template <typename _Elevator>
199 struct DefElevatorTraits : public Traits {
200 typedef _Elevator Elevator;
201 static Elevator *createElevator(const Graph&, int) {
202 throw UninitializedParameter();
208 /// \brief \ref Exception for the case when the source equals the target.
210 /// \ref Exception for the case when the source equals the target.
212 class InvalidArgument : public lemon::LogicError {
214 virtual const char* what() const throw() {
215 return "lemon::DinitzSleatorTarjan::InvalidArgument";
219 /// \brief The constructor of the class.
221 /// The constructor of the class.
222 /// \param graph The directed graph the algorithm runs on.
223 /// \param capacity The capacity of the edges.
224 /// \param source The source node.
225 /// \param target The target node.
226 DinitzSleatorTarjan(const Graph& graph, const CapacityMap& capacity,
227 Node source, Node target)
228 : _graph(graph), _capacity(&capacity),
229 _source(source), _target(target),
230 _flow(0), _local_flow(false),
231 _level(0), _dt_edges(0),
232 _dt_index(0), _dt(0),
233 _tolerance(), _flow_value(), _max_value()
235 if (_source == _target) {
236 throw InvalidArgument();
240 /// \brief Destrcutor.
243 ~DinitzSleatorTarjan() {
247 /// \brief Sets the capacity map.
249 /// Sets the capacity map.
250 /// \return \c (*this)
251 DinitzSleatorTarjan& capacityMap(const CapacityMap& map) {
256 /// \brief Sets the flow map.
258 /// Sets the flow map.
259 /// \return \c (*this)
260 DinitzSleatorTarjan& flowMap(FlowMap& map) {
269 /// \brief Returns the flow map.
271 /// \return The flow map.
272 const FlowMap& flowMap() {
276 /// \brief Sets the source node.
278 /// Sets the source node.
279 /// \return \c (*this)
280 DinitzSleatorTarjan& source(const Node& node) {
285 /// \brief Sets the target node.
287 /// Sets the target node.
288 /// \return \c (*this)
289 DinitzSleatorTarjan& target(const Node& node) {
294 /// \brief Sets the tolerance used by algorithm.
296 /// Sets the tolerance used by algorithm.
297 DinitzSleatorTarjan& tolerance(const Tolerance& tolerance) const {
298 _tolerance = tolerance;
300 _dt.tolerance(_tolerance);
305 /// \brief Returns the tolerance used by algorithm.
307 /// Returns the tolerance used by algorithm.
308 const Tolerance& tolerance() const {
314 void createStructures() {
316 _flow = Traits::createFlowMap(_graph);
320 _level = new LevelMap(_graph);
322 if (!_dt_index && !_dt) {
323 _dt_index = new IntNodeMap(_graph);
324 _dt = new DynTree(*_dt_index, _tolerance);
327 _dt_edges = new EdgeNodeMap(_graph);
329 _max_value = _dt->maxValue();
332 void destroyStructures() {
350 bool createLayeredGraph() {
352 for (NodeIt n(_graph); n != INVALID; ++n) {
358 std::vector<Node> queue;
359 queue.push_back(_target);
360 _level->set(_target, level);
362 while ((*_level)[_source] == -2 && !queue.empty()) {
363 std::vector<Node> nqueue;
366 for (int i = 0; i < int(queue.size()); ++i) {
369 for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
370 Node v = _graph.target(e);
371 if ((*_level)[v] != -2) continue;
372 Value rem = (*_flow)[e];
373 if (!_tolerance.positive(rem)) continue;
374 _level->set(v, level);
378 for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
379 Node v = _graph.source(e);
380 if ((*_level)[v] != -2) continue;
381 Value rem = (*_capacity)[e] - (*_flow)[e];
382 if (!_tolerance.positive(rem)) continue;
383 _level->set(v, level);
391 return (*_level)[_source] != -2;
395 for (NodeIt n(_graph); n != INVALID; ++n) {
396 _graph.firstOut((*_dt_edges)[n], n);
403 Node n = _dt->findCost(_source, rem);
405 _dt->addCost(_source, - rem);
408 _dt->addCost(n, _max_value);
410 Edge e = (*_dt_edges)[n];
411 if (_graph.source(e) == n) {
412 _flow->set(e, (*_capacity)[e]);
416 _graph.firstIn(e, n);
422 _dt_edges->set(n, e);
426 bool advance(Node n) {
427 Edge e = (*_dt_edges)[n];
428 if (e == INVALID) return false;
432 if (_graph.source(e) == n) {
433 u = _graph.target(e);
434 while ((*_level)[n] != (*_level)[u] + 1 ||
435 !_tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
437 if (e == INVALID) break;
438 u = _graph.target(e);
441 rem = (*_capacity)[e] - (*_flow)[e];
443 _graph.firstIn(e, n);
445 _dt_edges->set(n, INVALID);
448 u = _graph.source(e);
449 while ((*_level)[n] != (*_level)[u] + 1 ||
450 !_tolerance.positive((*_flow)[e])) {
453 _dt_edges->set(n, INVALID);
456 u = _graph.source(e);
461 u = _graph.source(e);
462 while ((*_level)[n] != (*_level)[u] + 1 ||
463 !_tolerance.positive((*_flow)[e])) {
466 _dt_edges->set(n, INVALID);
469 u = _graph.source(e);
474 _dt->addCost(n, - std::numeric_limits<Value>::max());
475 _dt->addCost(n, rem);
477 _dt_edges->set(n, e);
481 void retreat(Node n) {
484 for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
485 Node u = _graph.target(e);
486 if ((*_dt_edges)[u] == e && _dt->findRoot(u) == n) {
488 _dt->findCost(u, rem);
491 _dt->addCost(u, - rem);
492 _dt->addCost(u, _max_value);
495 for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
496 Node u = _graph.source(e);
497 if ((*_dt_edges)[u] == e && _dt->findRoot(u) == n) {
499 _dt->findCost(u, rem);
500 _flow->set(e, (*_capacity)[e] - rem);
502 _dt->addCost(u, - rem);
503 _dt->addCost(u, _max_value);
508 void extractTrees() {
509 for (NodeIt n(_graph); n != INVALID; ++n) {
511 Node w = _dt->findRoot(n);
516 Node u = _dt->findCost(n, rem);
519 _dt->addCost(u, - rem);
520 _dt->addCost(u, _max_value);
522 Edge e = (*_dt_edges)[u];
523 _dt_edges->set(u, INVALID);
525 if (u == _graph.source(e)) {
526 _flow->set(e, (*_capacity)[e] - rem);
531 w = _dt->findRoot(n);
539 /// \name Execution control The simplest way to execute the
540 /// algorithm is to use the \c run() member functions.
542 /// If you need more control on initial solution or
543 /// execution then you have to call one \ref init() function and then
544 /// the start() or multiple times the \c augment() member function.
548 /// \brief Initializes the algorithm
550 /// It sets the flow to empty flow.
555 for (NodeIt n(_graph); n != INVALID; ++n) {
557 _dt->addCost(n, _max_value);
560 for (EdgeIt it(_graph); it != INVALID; ++it) {
566 /// \brief Initializes the algorithm
568 /// Initializes the flow to the \c flowMap. The \c flowMap should
569 /// contain a feasible flow, ie. in each node excluding the source
570 /// and the target the incoming flow should be equal to the
572 template <typename FlowMap>
573 void flowInit(const FlowMap& flowMap) {
577 for (NodeIt n(_graph); n != INVALID; ++n) {
579 _dt->addCost(n, _max_value);
582 for (EdgeIt e(_graph); e != INVALID; ++e) {
583 _flow->set(e, flowMap[e]);
586 for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
587 _flow_value += (*_flow)[jt];
589 for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
590 _flow_value -= (*_flow)[jt];
594 /// \brief Initializes the algorithm
596 /// Initializes the flow to the \c flowMap. The \c flowMap should
597 /// contain a feasible flow, ie. in each node excluding the source
598 /// and the target the incoming flow should be equal to the
600 /// \return %False when the given flowMap does not contain
602 template <typename FlowMap>
603 bool checkedFlowInit(const FlowMap& flowMap) {
607 for (NodeIt n(_graph); n != INVALID; ++n) {
609 _dt->addCost(n, _max_value);
612 for (EdgeIt e(_graph); e != INVALID; ++e) {
613 _flow->set(e, flowMap[e]);
615 for (NodeIt it(_graph); it != INVALID; ++it) {
616 if (it == _source || it == _target) continue;
618 for (OutEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
619 outFlow += (*_flow)[jt];
622 for (InEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
623 inFlow += (*_flow)[jt];
625 if (_tolerance.different(outFlow, inFlow)) {
629 for (EdgeIt it(_graph); it != INVALID; ++it) {
630 if (_tolerance.less((*_flow)[it], 0)) return false;
631 if (_tolerance.less((*_capacity)[it], (*_flow)[it])) return false;
634 for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
635 _flow_value += (*_flow)[jt];
637 for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
638 _flow_value -= (*_flow)[jt];
643 /// \brief Executes the algorithm
645 /// It runs augmenting phases by adding blocking flow until the
646 /// optimal solution is reached.
651 /// \brief Augments the flow with a blocking flow on a layered
654 /// This function builds a layered graph and then find a blocking
655 /// flow on this graph. The number of the levels in the layered
656 /// graph is strictly increasing in each augmenting phase
657 /// therefore the number of the augmentings is at most \f$ n-1
658 /// \f$. The length of each phase is at most \f$ O(m \log(n))
659 /// \f$, that the overall time complexity is \f$ O(nm \log(n)) \f$.
660 /// \return %False when there is not residual path between the
661 /// source and the target so the current flow is a feasible and
662 /// optimal solution.
666 if (createLayeredGraph()) {
671 n = _dt->findRoot(_source);
676 } else if (!advance(n)) {
683 n = _dt->findRoot(_source);
693 /// \brief runs the algorithm.
695 /// It is just a shorthand for:
708 /// \name Query Functions
709 /// The result of the %Dijkstra algorithm can be obtained using these
711 /// Before the use of these functions,
712 /// either run() or start() must be called.
716 /// \brief Returns the value of the maximum flow.
718 /// Returns the value of the maximum flow by returning the excess
719 /// of the target node \c t. This value equals to the value of
720 /// the maximum flow already after the first phase.
721 Value flowValue() const {
726 /// \brief Returns the flow on the edge.
728 /// Sets the \c flowMap to the flow on the edges. This method can
729 /// be called after the second phase of algorithm.
730 Value flow(const Edge& edge) const {
731 return (*_flow)[edge];
734 /// \brief Returns true when the node is on the source side of minimum cut.
737 /// Returns true when the node is on the source side of minimum
738 /// cut. This method can be called both after running \ref
739 /// startFirstPhase() and \ref startSecondPhase().
740 bool minCut(const Node& node) const {
741 return (*_level)[node] == -2;
744 /// \brief Returns a minimum value cut.
746 /// Sets \c cut to the characteristic vector of a minimum value cut
747 /// It simply calls the minMinCut member.
748 /// \retval cut Write node bool map.
749 template <typename CutMap>
750 void minCutMap(CutMap& cutMap) const {
751 for (NodeIt n(_graph); n != INVALID; ++n) {
752 cutMap.set(n, (*_level)[n] == -2);
754 cutMap.set(_source, true);