COIN-OR::LEMON - Graph Library

source: lemon-0.x/lemon/dinitz_sleator_tarjan.h @ 2522:616c019215c4

Last change on this file since 2522:616c019215c4 was 2522:616c019215c4, checked in by Balazs Dezso, 12 years ago

Performance bug in Preflow
The initial relabeling moved each node to the lowest level
Doc bug fix

File size: 19.6 KB
Line 
1/* -*- C++ -*-
2 *
3 * This file is a part of LEMON, a generic C++ optimization library
4 *
5 * Copyright (C) 2003-2007
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 *
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.
12 *
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
15 * purpose.
16 *
17 */
18
19#ifndef LEMON_DINITZ_SLEATOR_TARJAN_H
20#define LEMON_DINITZ_SLEATOR_TARJAN_H
21
22/// \file
23/// \ingroup max_flow
24/// \brief Implementation the dynamic tree data structure of Sleator
25/// and Tarjan.
26
27#include <lemon/graph_utils.h>
28#include <lemon/tolerance.h>
29#include <lemon/dynamic_tree.h>
30
31#include <vector>
32#include <limits>
33#include <fstream>
34
35
36namespace lemon {
37
38  /// \brief Default traits class of DinitzSleatorTarjan class.
39  ///
40  /// Default traits class of DinitzSleatorTarjan class.
41  /// \param _Graph Graph type.
42  /// \param _CapacityMap Type of capacity map.
43  template <typename _Graph, typename _CapacityMap>
44  struct DinitzSleatorTarjanDefaultTraits {
45
46    /// \brief The graph type the algorithm runs on.
47    typedef _Graph Graph;
48
49    /// \brief The type of the map that stores the edge capacities.
50    ///
51    /// The type of the map that stores the edge capacities.
52    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
53    typedef _CapacityMap CapacityMap;
54
55    /// \brief The type of the length of the edges.
56    typedef typename CapacityMap::Value Value;
57
58    /// \brief The map type that stores the flow values.
59    ///
60    /// The map type that stores the flow values.
61    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
62    typedef typename Graph::template EdgeMap<Value> FlowMap;
63
64    /// \brief Instantiates a FlowMap.
65    ///
66    /// This function instantiates a \ref FlowMap.
67    /// \param graph The graph, to which we would like to define the flow map.
68    static FlowMap* createFlowMap(const Graph& graph) {
69      return new FlowMap(graph);
70    }
71
72    /// \brief The tolerance used by the algorithm
73    ///
74    /// The tolerance used by the algorithm to handle inexact computation.
75    typedef Tolerance<Value> Tolerance;
76
77  };
78
79  /// \ingroup max_flow
80  ///
81  /// \brief Dinitz-Sleator-Tarjan algorithms class.
82  ///
83  /// This class provides an implementation of the \e
84  /// Dinitz-Sleator-Tarjan \e algorithm producing a flow of maximum
85  /// value in a directed graph. The DinitzSleatorTarjan algorithm is
86  /// the fastest known max flow algorithms wich using blocking
87  /// flow. It is an improvement of the Dinitz algorithm by using the
88  /// \ref DynamicTree "dynamic tree" data structure of Sleator and
89  /// Tarjan.
90  ///
91  /// This blocking flow algorithms builds a layered graph according
92  /// to \ref Bfs "breadth-first search" distance from the target node
93  /// in the reversed residual graph. The layered graph contains each
94  /// residual edge which steps one level down. After that the
95  /// algorithm constructs a blocking flow on the layered graph and
96  /// augments the overall flow with it. The number of the levels in
97  /// the layered graph is strictly increasing in each augmenting
98  /// phase therefore the number of the augmentings is at most
99  /// \f$n-1\f$.  The length of each phase is at most
100  /// \f$O(m\log(n))\f$, that the overall time complexity is
101  /// \f$O(nm\log(n))\f$.
102  ///
103  /// \param _Graph The directed graph type the algorithm runs on.
104  /// \param _CapacityMap The capacity map type.
105  /// \param _Traits Traits class to set various data types used by
106  /// the algorithm.  The default traits class is \ref
107  /// DinitzSleatorTarjanDefaultTraits.  See \ref
108  /// DinitzSleatorTarjanDefaultTraits for the documentation of a
109  /// Dinitz-Sleator-Tarjan traits class.
110  ///
111  /// \author Tamas Hamori and Balazs Dezso
112#ifdef DOXYGEN
113  template <typename _Graph, typename _CapacityMap, typename _Traits>
114#else
115  template <typename _Graph,
116            typename _CapacityMap = typename _Graph::template EdgeMap<int>,
117            typename _Traits =
118            DinitzSleatorTarjanDefaultTraits<_Graph, _CapacityMap> >
119#endif
120  class DinitzSleatorTarjan {
121  public:
122
123    typedef _Traits Traits;
124    typedef typename Traits::Graph Graph;
125    typedef typename Traits::CapacityMap CapacityMap;
126    typedef typename Traits::Value Value;
127
128    typedef typename Traits::FlowMap FlowMap;
129    typedef typename Traits::Tolerance Tolerance;
130
131
132  private:
133
134    GRAPH_TYPEDEFS(typename Graph);
135
136
137    typedef typename Graph::template NodeMap<int> LevelMap;
138    typedef typename Graph::template NodeMap<int> IntNodeMap;
139    typedef typename Graph::template NodeMap<Edge> EdgeNodeMap;
140    typedef DynamicTree<Value, IntNodeMap, Tolerance, false> DynTree;
141
142  private:
143   
144    const Graph& _graph;
145    const CapacityMap* _capacity;
146
147    Node _source, _target;
148
149    FlowMap* _flow;
150    bool _local_flow;
151
152    IntNodeMap* _level;
153    EdgeNodeMap* _dt_edges;
154   
155    IntNodeMap* _dt_index;
156    DynTree* _dt;
157
158    std::vector<Node> _queue;
159
160    Tolerance _tolerance;
161   
162    Value _flow_value;
163    Value _max_value;
164
165
166  public:
167
168    typedef DinitzSleatorTarjan Create;
169
170    ///\name Named template parameters
171
172    ///@{
173
174    template <typename _FlowMap>
175    struct DefFlowMapTraits : public Traits {
176      typedef _FlowMap FlowMap;
177      static FlowMap *createFlowMap(const Graph&) {
178        throw UninitializedParameter();
179      }
180    };
181
182    /// \brief \ref named-templ-param "Named parameter" for setting
183    /// FlowMap type
184    ///
185    /// \ref named-templ-param "Named parameter" for setting FlowMap
186    /// type
187    template <typename _FlowMap>
188    struct DefFlowMap
189      : public DinitzSleatorTarjan<Graph, CapacityMap,
190                              DefFlowMapTraits<_FlowMap> > {
191      typedef DinitzSleatorTarjan<Graph, CapacityMap,
192                             DefFlowMapTraits<_FlowMap> > Create;
193    };
194
195    template <typename _Elevator>
196    struct DefElevatorTraits : public Traits {
197      typedef _Elevator Elevator;
198      static Elevator *createElevator(const Graph&, int) {
199        throw UninitializedParameter();
200      }
201    };
202
203    /// @}
204
205    /// \brief \ref Exception for the case when the source equals the target.
206    ///
207    /// \ref Exception for the case when the source equals the target.
208    ///
209    class InvalidArgument : public lemon::LogicError {
210    public:
211      virtual const char* what() const throw() {
212        return "lemon::DinitzSleatorTarjan::InvalidArgument";
213      }
214    };
215
216    /// \brief The constructor of the class.
217    ///
218    /// The constructor of the class.
219    /// \param graph The directed graph the algorithm runs on.
220    /// \param capacity The capacity of the edges.
221    /// \param source The source node.
222    /// \param target The target node.
223    DinitzSleatorTarjan(const Graph& graph, const CapacityMap& capacity,
224                        Node source, Node target)
225      : _graph(graph), _capacity(&capacity),
226        _source(source), _target(target),
227        _flow(0), _local_flow(false),
228        _level(0), _dt_edges(0),
229        _dt_index(0), _dt(0), _queue(),
230        _tolerance(), _flow_value(), _max_value()
231    {
232      if (_source == _target) {
233        throw InvalidArgument();
234      }
235    }
236
237    /// \brief Destrcutor.
238    ///
239    /// Destructor.
240    ~DinitzSleatorTarjan() {
241      destroyStructures();
242    }
243
244    /// \brief Sets the capacity map.
245    ///
246    /// Sets the capacity map.
247    /// \return \c (*this)
248    DinitzSleatorTarjan& capacityMap(const CapacityMap& map) {
249      _capacity = &map;
250      return *this;
251    }
252
253    /// \brief Sets the flow map.
254    ///
255    /// Sets the flow map.
256    /// \return \c (*this)
257    DinitzSleatorTarjan& flowMap(FlowMap& map) {
258      if (_local_flow) {
259        delete _flow;
260        _local_flow = false;
261      }
262      _flow = &map;
263      return *this;
264    }
265
266    /// \brief Returns the flow map.
267    ///
268    /// \return The flow map.
269    const FlowMap& flowMap() {
270      return *_flow;
271    }
272
273    /// \brief Sets the source node.
274    ///
275    /// Sets the source node.
276    /// \return \c (*this)
277    DinitzSleatorTarjan& source(const Node& node) {
278      _source = node;
279      return *this;
280    }
281
282    /// \brief Sets the target node.
283    ///
284    /// Sets the target node.
285    /// \return \c (*this)
286    DinitzSleatorTarjan& target(const Node& node) {
287      _target = node;
288      return *this;
289    }
290
291    /// \brief Sets the tolerance used by algorithm.
292    ///
293    /// Sets the tolerance used by algorithm.
294    DinitzSleatorTarjan& tolerance(const Tolerance& tolerance) const {
295      _tolerance = tolerance;
296      if (_dt) {
297        _dt.tolerance(_tolerance);
298      }
299      return *this;
300    }
301
302    /// \brief Returns the tolerance used by algorithm.
303    ///
304    /// Returns the tolerance used by algorithm.
305    const Tolerance& tolerance() const {
306      return tolerance;
307    }
308
309  private:
310       
311    void createStructures() {
312      if (!_flow) {
313        _flow = Traits::createFlowMap(_graph);
314        _local_flow = true;
315      }
316      if (!_level) {
317        _level = new LevelMap(_graph);
318      }
319      if (!_dt_index && !_dt) {
320        _dt_index = new IntNodeMap(_graph);
321        _dt = new DynTree(*_dt_index, _tolerance);
322      }
323      if (!_dt_edges) {
324        _dt_edges = new EdgeNodeMap(_graph);
325      }
326      _queue.resize(countNodes(_graph));
327      _max_value = _dt->maxValue();
328    }
329
330    void destroyStructures() {
331      if (_local_flow) {
332        delete _flow;
333      }
334      if (_level) {
335        delete _level;
336      }
337      if (_dt) {
338        delete _dt;
339      }
340      if (_dt_index) {
341        delete _dt_index;
342      }
343      if (_dt_edges) {
344        delete _dt_edges;
345      }
346    }
347
348    bool createLayeredGraph() {
349
350      for (NodeIt n(_graph); n != INVALID; ++n) {
351        _level->set(n, -2);
352      }
353     
354      int level = 0;
355
356      _queue[0] = _target;
357      _level->set(_target, level);
358
359      int first = 0, last = 1, limit = 0;
360     
361      while (first != last && (*_level)[_source] == -2) {
362        if (first == limit) {
363          limit = last;
364          ++level;
365        }
366       
367        Node n = _queue[first++];
368         
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);
375          _queue[last++] = v;
376        }
377       
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);
384          _queue[last++] = v;
385        }
386      }
387      return (*_level)[_source] != -2;
388    }
389
390    void initEdges() {
391      for (NodeIt n(_graph); n != INVALID; ++n) {
392        _graph.firstOut((*_dt_edges)[n], n);
393      }
394    }
395       
396   
397    void augmentPath() {
398      Value rem;
399      Node n = _dt->findCost(_source, rem);
400      _flow_value += rem;
401      _dt->addCost(_source, - rem);
402
403      _dt->cut(n);
404      _dt->addCost(n, _max_value);
405
406      Edge e = (*_dt_edges)[n];
407      if (_graph.source(e) == n) {
408        _flow->set(e, (*_capacity)[e]);
409       
410        _graph.nextOut(e);
411        if (e == INVALID) {
412          _graph.firstIn(e, n);
413        }
414      } else {
415        _flow->set(e, 0);
416        _graph.nextIn(e);
417      }
418      _dt_edges->set(n, e);
419
420    }
421
422    bool advance(Node n) {
423      Edge e = (*_dt_edges)[n];
424      if (e == INVALID) return false;
425
426      Node u;
427      Value rem;     
428      if (_graph.source(e) == n) {
429        u = _graph.target(e);
430        while ((*_level)[n] != (*_level)[u] + 1 ||
431               !_tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
432          _graph.nextOut(e);
433          if (e == INVALID) break;
434          u = _graph.target(e);
435        }
436        if (e != INVALID) {
437          rem = (*_capacity)[e] - (*_flow)[e];
438        } else {
439          _graph.firstIn(e, n);
440          if (e == INVALID) {
441            _dt_edges->set(n, INVALID);
442            return false;
443          }
444          u = _graph.source(e);
445          while ((*_level)[n] != (*_level)[u] + 1 ||
446                 !_tolerance.positive((*_flow)[e])) {
447            _graph.nextIn(e);
448            if (e == INVALID) {
449              _dt_edges->set(n, INVALID);
450              return false;
451            }
452            u = _graph.source(e);
453          }
454          rem = (*_flow)[e];
455        }
456      } else {
457        u = _graph.source(e);
458        while ((*_level)[n] != (*_level)[u] + 1 ||
459               !_tolerance.positive((*_flow)[e])) {
460          _graph.nextIn(e);
461          if (e == INVALID) {
462            _dt_edges->set(n, INVALID);
463            return false;
464          }
465          u = _graph.source(e);
466        }
467        rem = (*_flow)[e];
468      }
469
470      _dt->addCost(n, - std::numeric_limits<Value>::max());
471      _dt->addCost(n, rem);
472      _dt->link(n, u);
473      _dt_edges->set(n, e);
474      return true;
475    }
476
477    void retreat(Node n) {
478      _level->set(n, -1);
479     
480      for (OutEdgeIt e(_graph, n); e != INVALID; ++e) {
481        Node u = _graph.target(e);
482        if ((*_dt_edges)[u] == e && _dt->findRoot(u) == n) {
483          Value rem;
484          _dt->findCost(u, rem);
485          _flow->set(e, rem);
486          _dt->cut(u);
487          _dt->addCost(u, - rem);
488          _dt->addCost(u, _max_value);
489        }
490      }
491      for (InEdgeIt e(_graph, n); e != INVALID; ++e) {
492        Node u = _graph.source(e);
493        if ((*_dt_edges)[u] == e && _dt->findRoot(u) == n) {
494          Value rem;
495          _dt->findCost(u, rem);
496          _flow->set(e, (*_capacity)[e] - rem);
497          _dt->cut(u);
498          _dt->addCost(u, - rem);
499          _dt->addCost(u, _max_value);
500        }
501      }
502    }
503
504    void extractTrees() {
505      for (NodeIt n(_graph); n != INVALID; ++n) {
506       
507        Node w = _dt->findRoot(n);
508     
509        while (w != n) {
510     
511          Value rem;     
512          Node u = _dt->findCost(n, rem);
513
514          _dt->cut(u);
515          _dt->addCost(u, - rem);
516          _dt->addCost(u, _max_value);
517         
518          Edge e = (*_dt_edges)[u];
519          _dt_edges->set(u, INVALID);
520         
521          if (u == _graph.source(e)) {
522            _flow->set(e, (*_capacity)[e] - rem);
523          } else {
524            _flow->set(e, rem);
525          }
526         
527          w = _dt->findRoot(n);
528        }     
529      }
530    }
531
532
533  public:
534   
535    /// \name Execution control The simplest way to execute the
536    /// algorithm is to use the \c run() member functions.
537    /// \n
538    /// If you need more control on initial solution or
539    /// execution then you have to call one \ref init() function and then
540    /// the start() or multiple times the \c augment() member function. 
541   
542    ///@{
543
544    /// \brief Initializes the algorithm
545    ///
546    /// It sets the flow to empty flow.
547    void init() {
548      createStructures();
549
550      _dt->clear();
551      for (NodeIt n(_graph); n != INVALID; ++n) {
552        _dt->makeTree(n);
553        _dt->addCost(n, _max_value);
554      }
555
556      for (EdgeIt it(_graph); it != INVALID; ++it) {
557        _flow->set(it, 0);
558      }
559      _flow_value = 0;
560    }
561   
562    /// \brief Initializes the algorithm
563    ///
564    /// Initializes the flow to the \c flowMap. The \c flowMap should
565    /// contain a feasible flow, ie. in each node excluding the source
566    /// and the target the incoming flow should be equal to the
567    /// outgoing flow.
568    template <typename FlowMap>
569    void flowInit(const FlowMap& flowMap) {
570      createStructures();
571
572      _dt->clear();
573      for (NodeIt n(_graph); n != INVALID; ++n) {
574        _dt->makeTree(n);
575        _dt->addCost(n, _max_value);
576      }
577
578      for (EdgeIt e(_graph); e != INVALID; ++e) {
579        _flow->set(e, flowMap[e]);
580      }
581      _flow_value = 0;
582      for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
583        _flow_value += (*_flow)[jt];
584      }
585      for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
586        _flow_value -= (*_flow)[jt];
587      }
588    }
589
590    /// \brief Initializes the algorithm
591    ///
592    /// Initializes the flow to the \c flowMap. The \c flowMap should
593    /// contain a feasible flow, ie. in each node excluding the source
594    /// and the target the incoming flow should be equal to the
595    /// outgoing flow. 
596    /// \return %False when the given flowMap does not contain
597    /// feasible flow.
598    template <typename FlowMap>
599    bool checkedFlowInit(const FlowMap& flowMap) {
600      createStructures();
601
602      _dt->clear();
603      for (NodeIt n(_graph); n != INVALID; ++n) {
604        _dt->makeTree(n);
605        _dt->addCost(n, _max_value);
606      }
607
608      for (EdgeIt e(_graph); e != INVALID; ++e) {
609        _flow->set(e, flowMap[e]);
610      }
611      for (NodeIt it(_graph); it != INVALID; ++it) {
612        if (it == _source || it == _target) continue;
613        Value outFlow = 0;
614        for (OutEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
615          outFlow += (*_flow)[jt];
616        }
617        Value inFlow = 0;
618        for (InEdgeIt jt(_graph, it); jt != INVALID; ++jt) {
619          inFlow += (*_flow)[jt];
620        }
621        if (_tolerance.different(outFlow, inFlow)) {
622          return false;
623        }
624      }
625      for (EdgeIt it(_graph); it != INVALID; ++it) {
626        if (_tolerance.less((*_flow)[it], 0)) return false;
627        if (_tolerance.less((*_capacity)[it], (*_flow)[it])) return false;
628      }
629      _flow_value = 0;
630      for (OutEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
631        _flow_value += (*_flow)[jt];
632      }
633      for (InEdgeIt jt(_graph, _source); jt != INVALID; ++jt) {
634        _flow_value -= (*_flow)[jt];
635      }
636      return true;
637    }
638
639    /// \brief Executes the algorithm
640    ///
641    /// It runs augmenting phases by adding blocking flow until the
642    /// optimal solution is reached.
643    void start() {
644      while (augment());
645    }
646
647    /// \brief Augments the flow with a blocking flow on a layered
648    /// graph.
649    ///
650    /// This function builds a layered graph and then find a blocking
651    /// flow on this graph. The number of the levels in the layered
652    /// graph is strictly increasing in each augmenting phase
653    /// therefore the number of the augmentings is at most \f$ n-1
654    /// \f$.  The length of each phase is at most \f$ O(m \log(n))
655    /// \f$, that the overall time complexity is \f$ O(nm \log(n)) \f$.
656    /// \return %False when there is not residual path between the
657    /// source and the target so the current flow is a feasible and
658    /// optimal solution.
659    bool augment() {
660      Node n;
661
662      if (createLayeredGraph()) {
663       
664        Timer bf_timer;
665        initEdges();
666
667        n = _dt->findRoot(_source);
668        while (true) {
669          Edge e;
670          if (n == _target) {
671            augmentPath();
672          } else if (!advance(n)) {
673            if (n != _source) {
674              retreat(n);
675            } else {
676              break;
677            }
678          }
679          n = _dt->findRoot(_source);
680        }     
681        extractTrees();
682
683        return true;
684      } else {
685        return false;
686      }
687    }
688   
689    /// \brief runs the algorithm.
690    ///
691    /// It is just a shorthand for:
692    ///
693    ///\code
694    /// ek.init();
695    /// ek.start();
696    ///\endcode
697    void run() {
698      init();
699      start();
700    }
701
702    /// @}
703
704    /// \name Query Functions
705    /// The result of the Dinitz-Sleator-Tarjan algorithm can be
706    /// obtained using these functions.
707    /// \n
708    /// Before the use of these functions,
709    /// either run() or start() must be called.
710   
711    ///@{
712
713    /// \brief Returns the value of the maximum flow.
714    ///
715    /// Returns the value of the maximum flow by returning the excess
716    /// of the target node \c t. This value equals to the value of
717    /// the maximum flow already after the first phase.
718    Value flowValue() const {
719      return _flow_value;
720    }
721
722
723    /// \brief Returns the flow on the edge.
724    ///
725    /// Sets the \c flowMap to the flow on the edges. This method can
726    /// be called after the second phase of algorithm.
727    Value flow(const Edge& edge) const {
728      return (*_flow)[edge];
729    }
730
731    /// \brief Returns true when the node is on the source side of minimum cut.
732    ///
733
734    /// Returns true when the node is on the source side of minimum
735    /// cut. This method can be called both after running \ref
736    /// startFirstPhase() and \ref startSecondPhase().
737    bool minCut(const Node& node) const {
738      return (*_level)[node] == -2;
739    }
740
741    /// \brief Returns a minimum value cut.
742    ///
743    /// Sets \c cut to the characteristic vector of a minimum value cut
744    /// It simply calls the minMinCut member.
745    /// \retval cut Write node bool map.
746    template <typename CutMap>
747    void minCutMap(CutMap& cutMap) const {
748      for (NodeIt n(_graph); n != INVALID; ++n) {
749        cutMap.set(n, (*_level)[n] == -2);
750      }
751      cutMap.set(_source, true);
752    }   
753
754    /// @}
755
756  };
757}
758
759#endif
Note: See TracBrowser for help on using the repository browser.