1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
 
     3  * This file is a part of LEMON, a generic C++ optimization library.
 
     5  * Copyright (C) 2003-2009
 
     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_SUURBALLE_H
 
    20 #define LEMON_SUURBALLE_H
 
    22 ///\ingroup shortest_path
 
    24 ///\brief An algorithm for finding arc-disjoint paths between two
 
    25 /// nodes having minimum total length.
 
    28 #include <lemon/bin_heap.h>
 
    29 #include <lemon/path.h>
 
    33   /// \addtogroup shortest_path
 
    36   /// \brief Algorithm for finding arc-disjoint paths between two nodes
 
    37   /// having minimum total length.
 
    39   /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
 
    40   /// finding arc-disjoint paths having minimum total length (cost)
 
    41   /// from a given source node to a given target node in a digraph.
 
    43   /// In fact, this implementation is the specialization of the
 
    44   /// \ref CapacityScaling "successive shortest path" algorithm.
 
    46   /// \tparam Digraph The digraph type the algorithm runs on.
 
    47   /// The default value is \c ListDigraph.
 
    48   /// \tparam LengthMap The type of the length (cost) map.
 
    49   /// The default value is <tt>Digraph::ArcMap<int></tt>.
 
    51   /// \warning Length values should be \e non-negative \e integers.
 
    53   /// \note For finding node-disjoint paths this algorithm can be used
 
    54   /// with \ref SplitNodes.
 
    56   template <typename Digraph, typename LengthMap>
 
    58   template < typename Digraph = ListDigraph,
 
    59              typename LengthMap = typename Digraph::template ArcMap<int> >
 
    63     TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
 
    65     typedef typename LengthMap::Value Length;
 
    66     typedef ConstMap<Arc, int> ConstArcMap;
 
    67     typedef typename Digraph::template NodeMap<Arc> PredMap;
 
    71     /// The type of the flow map.
 
    72     typedef typename Digraph::template ArcMap<int> FlowMap;
 
    73     /// The type of the potential map.
 
    74     typedef typename Digraph::template NodeMap<Length> PotentialMap;
 
    75     /// The type of the path structures.
 
    76     typedef SimplePath<Digraph> Path;
 
    80     /// \brief Special implementation of the Dijkstra algorithm
 
    81     /// for finding shortest paths in the residual network.
 
    83     /// \ref ResidualDijkstra is a special implementation of the
 
    84     /// \ref Dijkstra algorithm for finding shortest paths in the
 
    85     /// residual network of the digraph with respect to the reduced arc
 
    86     /// lengths and modifying the node potentials according to the
 
    87     /// distance of the nodes.
 
    88     class ResidualDijkstra
 
    90       typedef typename Digraph::template NodeMap<int> HeapCrossRef;
 
    91       typedef BinHeap<Length, HeapCrossRef> Heap;
 
    95       // The digraph the algorithm runs on
 
    96       const Digraph &_graph;
 
   100       const LengthMap &_length;
 
   101       PotentialMap &_potential;
 
   107       // The processed (i.e. permanently labeled) nodes
 
   108       std::vector<Node> _proc_nodes;
 
   116       ResidualDijkstra( const Digraph &digraph,
 
   118                         const LengthMap &length,
 
   119                         PotentialMap &potential,
 
   122         _graph(digraph), _flow(flow), _length(length), _potential(potential),
 
   123         _dist(digraph), _pred(pred), _s(s), _t(t) {}
 
   125       /// \brief Run the algorithm. It returns \c true if a path is found
 
   126       /// from the source node to the target node.
 
   128         HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
 
   129         Heap heap(heap_cross_ref);
 
   135         while (!heap.empty() && heap.top() != _t) {
 
   136           Node u = heap.top(), v;
 
   137           Length d = heap.prio() + _potential[u], nd;
 
   138           _dist[u] = heap.prio();
 
   140           _proc_nodes.push_back(u);
 
   142           // Traverse outgoing arcs
 
   143           for (OutArcIt e(_graph, u); e != INVALID; ++e) {
 
   145               v = _graph.target(e);
 
   146               switch(heap.state(v)) {
 
   148                 heap.push(v, d + _length[e] - _potential[v]);
 
   152                 nd = d + _length[e] - _potential[v];
 
   154                   heap.decrease(v, nd);
 
   158               case Heap::POST_HEAP:
 
   164           // Traverse incoming arcs
 
   165           for (InArcIt e(_graph, u); e != INVALID; ++e) {
 
   167               v = _graph.source(e);
 
   168               switch(heap.state(v)) {
 
   170                 heap.push(v, d - _length[e] - _potential[v]);
 
   174                 nd = d - _length[e] - _potential[v];
 
   176                   heap.decrease(v, nd);
 
   180               case Heap::POST_HEAP:
 
   186         if (heap.empty()) return false;
 
   188         // Update potentials of processed nodes
 
   189         Length t_dist = heap.prio();
 
   190         for (int i = 0; i < int(_proc_nodes.size()); ++i)
 
   191           _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
 
   195     }; //class ResidualDijkstra
 
   199     // The digraph the algorithm runs on
 
   200     const Digraph &_graph;
 
   202     const LengthMap &_length;
 
   204     // Arc map of the current flow
 
   207     // Node map of the current potentials
 
   208     PotentialMap *_potential;
 
   209     bool _local_potential;
 
   216     // Container to store the found paths
 
   217     std::vector< SimplePath<Digraph> > paths;
 
   222     // Implementation of the Dijkstra algorithm for finding augmenting
 
   223     // shortest paths in the residual network
 
   224     ResidualDijkstra *_dijkstra;
 
   228     /// \brief Constructor.
 
   232     /// \param digraph The digraph the algorithm runs on.
 
   233     /// \param length The length (cost) values of the arcs.
 
   234     /// \param s The source node.
 
   235     /// \param t The target node.
 
   236     Suurballe( const Digraph &digraph,
 
   237                const LengthMap &length,
 
   239       _graph(digraph), _length(length), _flow(0), _local_flow(false),
 
   240       _potential(0), _local_potential(false), _source(s), _target(t),
 
   245       if (_local_flow) delete _flow;
 
   246       if (_local_potential) delete _potential;
 
   250     /// \brief Set the flow map.
 
   252     /// This function sets the flow map.
 
   254     /// The found flow contains only 0 and 1 values. It is the union of
 
   255     /// the found arc-disjoint paths.
 
   257     /// \return \c (*this)
 
   258     Suurballe& flowMap(FlowMap &map) {
 
   267     /// \brief Set the potential map.
 
   269     /// This function sets the potential map.
 
   271     /// The potentials provide the dual solution of the underlying
 
   272     /// minimum cost flow problem.
 
   274     /// \return \c (*this)
 
   275     Suurballe& potentialMap(PotentialMap &map) {
 
   276       if (_local_potential) {
 
   278         _local_potential = false;
 
   284     /// \name Execution control
 
   285     /// The simplest way to execute the algorithm is to call the run()
 
   288     /// If you only need the flow that is the union of the found
 
   289     /// arc-disjoint paths, you may call init() and findFlow().
 
   293     /// \brief Run the algorithm.
 
   295     /// This function runs the algorithm.
 
   297     /// \param k The number of paths to be found.
 
   299     /// \return \c k if there are at least \c k arc-disjoint paths from
 
   300     /// \c s to \c t in the digraph. Otherwise it returns the number of
 
   301     /// arc-disjoint paths found.
 
   303     /// \note Apart from the return value, <tt>s.run(k)</tt> is just a
 
   304     /// shortcut of the following code.
 
   317     /// \brief Initialize the algorithm.
 
   319     /// This function initializes the algorithm.
 
   323         _flow = new FlowMap(_graph);
 
   327         _potential = new PotentialMap(_graph);
 
   328         _local_potential = true;
 
   330       for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
 
   331       for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
 
   333       _dijkstra = new ResidualDijkstra( _graph, *_flow, _length,
 
   338     /// \brief Execute the successive shortest path algorithm to find
 
   341     /// This function executes the successive shortest path algorithm to
 
   342     /// find a minimum cost flow, which is the union of \c k or less
 
   343     /// arc-disjoint paths.
 
   345     /// \return \c k if there are at least \c k arc-disjoint paths from
 
   346     /// \c s to \c t in the digraph. Otherwise it returns the number of
 
   347     /// arc-disjoint paths found.
 
   349     /// \pre \ref init() must be called before using this function.
 
   350     int findFlow(int k = 2) {
 
   351       // Find shortest paths
 
   353       while (_path_num < k) {
 
   355         if (!_dijkstra->run()) break;
 
   358         // Set the flow along the found shortest path
 
   361         while ((e = _pred[u]) != INVALID) {
 
   362           if (u == _graph.target(e)) {
 
   364             u = _graph.source(e);
 
   367             u = _graph.target(e);
 
   374     /// \brief Compute the paths from the flow.
 
   376     /// This function computes the paths from the flow.
 
   378     /// \pre \ref init() and \ref findFlow() must be called before using
 
   381       // Create the residual flow map (the union of the paths not found
 
   383       FlowMap res_flow(_graph);
 
   384       for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
 
   387       paths.resize(_path_num);
 
   388       for (int i = 0; i < _path_num; ++i) {
 
   390         while (n != _target) {
 
   391           OutArcIt e(_graph, n);
 
   392           for ( ; res_flow[e] == 0; ++e) ;
 
   393           n = _graph.target(e);
 
   402     /// \name Query Functions
 
   403     /// The results of the algorithm can be obtained using these
 
   405     /// \n The algorithm should be executed before using them.
 
   409     /// \brief Return a const reference to the arc map storing the
 
   412     /// This function returns a const reference to the arc map storing
 
   413     /// the flow that is the union of the found arc-disjoint paths.
 
   415     /// \pre \ref run() or \ref findFlow() must be called before using
 
   417     const FlowMap& flowMap() const {
 
   421     /// \brief Return a const reference to the node map storing the
 
   422     /// found potentials (the dual solution).
 
   424     /// This function returns a const reference to the node map storing
 
   425     /// the found potentials that provide the dual solution of the
 
   426     /// underlying minimum cost flow problem.
 
   428     /// \pre \ref run() or \ref findFlow() must be called before using
 
   430     const PotentialMap& potentialMap() const {
 
   434     /// \brief Return the flow on the given arc.
 
   436     /// This function returns the flow on the given arc.
 
   437     /// It is \c 1 if the arc is involved in one of the found paths,
 
   438     /// otherwise it is \c 0.
 
   440     /// \pre \ref run() or \ref findFlow() must be called before using
 
   442     int flow(const Arc& arc) const {
 
   443       return (*_flow)[arc];
 
   446     /// \brief Return the potential of the given node.
 
   448     /// This function returns the potential of the given node.
 
   450     /// \pre \ref run() or \ref findFlow() must be called before using
 
   452     Length potential(const Node& node) const {
 
   453       return (*_potential)[node];
 
   456     /// \brief Return the total length (cost) of the found paths (flow).
 
   458     /// This function returns the total length (cost) of the found paths
 
   459     /// (flow). The complexity of the function is \f$ O(e) \f$.
 
   461     /// \pre \ref run() or \ref findFlow() must be called before using
 
   463     Length totalLength() const {
 
   465       for (ArcIt e(_graph); e != INVALID; ++e)
 
   466         c += (*_flow)[e] * _length[e];
 
   470     /// \brief Return the number of the found paths.
 
   472     /// This function returns the number of the found paths.
 
   474     /// \pre \ref run() or \ref findFlow() must be called before using
 
   476     int pathNum() const {
 
   480     /// \brief Return a const reference to the specified path.
 
   482     /// This function returns a const reference to the specified path.
 
   484     /// \param i The function returns the \c i-th path.
 
   485     /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
 
   487     /// \pre \ref run() or \ref findPaths() must be called before using
 
   489     Path path(int i) const {
 
   501 #endif //LEMON_SUURBALLE_H