lemon/suurballe.h
changeset 357 2f64c4a692a8
child 358 7f26c4b32651
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/lemon/suurballe.h	Tue Oct 28 18:39:53 2008 +0000
     1.3 @@ -0,0 +1,499 @@
     1.4 +/* -*- C++ -*-
     1.5 + *
     1.6 + * This file is a part of LEMON, a generic C++ optimization library
     1.7 + *
     1.8 + * Copyright (C) 2003-2008
     1.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    1.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
    1.11 + *
    1.12 + * Permission to use, modify and distribute this software is granted
    1.13 + * provided that this copyright notice appears in all copies. For
    1.14 + * precise terms see the accompanying LICENSE file.
    1.15 + *
    1.16 + * This software is provided "AS IS" with no warranty of any kind,
    1.17 + * express or implied, and with no claim as to its suitability for any
    1.18 + * purpose.
    1.19 + *
    1.20 + */
    1.21 +
    1.22 +#ifndef LEMON_SUURBALLE_H
    1.23 +#define LEMON_SUURBALLE_H
    1.24 +
    1.25 +///\ingroup shortest_path
    1.26 +///\file
    1.27 +///\brief An algorithm for finding arc-disjoint paths between two
    1.28 +/// nodes having minimum total length.
    1.29 +
    1.30 +#include <vector>
    1.31 +#include <lemon/bin_heap.h>
    1.32 +#include <lemon/path.h>
    1.33 +
    1.34 +namespace lemon {
    1.35 +
    1.36 +  /// \addtogroup shortest_path
    1.37 +  /// @{
    1.38 +
    1.39 +  /// \brief Implementation of an algorithm for finding arc-disjoint
    1.40 +  /// paths between two nodes having minimum total length.
    1.41 +  ///
    1.42 +  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
    1.43 +  /// finding arc-disjoint paths having minimum total length (cost)
    1.44 +  /// from a given source node to a given target node in a directed
    1.45 +  /// digraph.
    1.46 +  ///
    1.47 +  /// In fact, this implementation is the specialization of the
    1.48 +  /// \ref CapacityScaling "successive shortest path" algorithm.
    1.49 +  ///
    1.50 +  /// \tparam Digraph The directed digraph type the algorithm runs on.
    1.51 +  /// \tparam LengthMap The type of the length (cost) map.
    1.52 +  ///
    1.53 +  /// \warning Length values should be \e non-negative \e integers.
    1.54 +  ///
    1.55 +  /// \note For finding node-disjoint paths this algorithm can be used
    1.56 +  /// with \ref SplitDigraphAdaptor.
    1.57 +  ///
    1.58 +  /// \author Attila Bernath and Peter Kovacs
    1.59 +  
    1.60 +  template < typename Digraph, 
    1.61 +             typename LengthMap = typename Digraph::template ArcMap<int> >
    1.62 +  class Suurballe
    1.63 +  {
    1.64 +    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
    1.65 +
    1.66 +    typedef typename LengthMap::Value Length;
    1.67 +    typedef ConstMap<Arc, int> ConstArcMap;
    1.68 +    typedef typename Digraph::template NodeMap<Arc> PredMap;
    1.69 +
    1.70 +  public:
    1.71 +
    1.72 +    /// The type of the flow map.
    1.73 +    typedef typename Digraph::template ArcMap<int> FlowMap;
    1.74 +    /// The type of the potential map.
    1.75 +    typedef typename Digraph::template NodeMap<Length> PotentialMap;
    1.76 +    /// The type of the path structures.
    1.77 +    typedef SimplePath<Digraph> Path;
    1.78 +
    1.79 +  private:
    1.80 +  
    1.81 +    /// \brief Special implementation of the \ref Dijkstra algorithm
    1.82 +    /// for finding shortest paths in the residual network.
    1.83 +    ///
    1.84 +    /// \ref ResidualDijkstra is a special implementation of the
    1.85 +    /// \ref Dijkstra algorithm for finding shortest paths in the
    1.86 +    /// residual network of the digraph with respect to the reduced arc
    1.87 +    /// lengths and modifying the node potentials according to the
    1.88 +    /// distance of the nodes.
    1.89 +    class ResidualDijkstra
    1.90 +    {
    1.91 +      typedef typename Digraph::template NodeMap<int> HeapCrossRef;
    1.92 +      typedef BinHeap<Length, HeapCrossRef> Heap;
    1.93 +
    1.94 +    private:
    1.95 +
    1.96 +      // The directed digraph the algorithm runs on
    1.97 +      const Digraph &_graph;
    1.98 +
    1.99 +      // The main maps
   1.100 +      const FlowMap &_flow;
   1.101 +      const LengthMap &_length;
   1.102 +      PotentialMap &_potential;
   1.103 +
   1.104 +      // The distance map
   1.105 +      PotentialMap _dist;
   1.106 +      // The pred arc map
   1.107 +      PredMap &_pred;
   1.108 +      // The processed (i.e. permanently labeled) nodes
   1.109 +      std::vector<Node> _proc_nodes;
   1.110 +      
   1.111 +      Node _s;
   1.112 +      Node _t;
   1.113 +
   1.114 +    public:
   1.115 +
   1.116 +      /// Constructor.
   1.117 +      ResidualDijkstra( const Digraph &digraph,
   1.118 +                        const FlowMap &flow,
   1.119 +                        const LengthMap &length,
   1.120 +                        PotentialMap &potential,
   1.121 +                        PredMap &pred,
   1.122 +                        Node s, Node t ) :
   1.123 +        _graph(digraph), _flow(flow), _length(length), _potential(potential),
   1.124 +        _dist(digraph), _pred(pred), _s(s), _t(t) {}
   1.125 +
   1.126 +      /// \brief Runs the algorithm. Returns \c true if a path is found
   1.127 +      /// from the source node to the target node.
   1.128 +      bool run() {
   1.129 +        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
   1.130 +        Heap heap(heap_cross_ref);
   1.131 +        heap.push(_s, 0);
   1.132 +        _pred[_s] = INVALID;
   1.133 +        _proc_nodes.clear();
   1.134 +
   1.135 +        // Processing nodes
   1.136 +        while (!heap.empty() && heap.top() != _t) {
   1.137 +          Node u = heap.top(), v;
   1.138 +          Length d = heap.prio() + _potential[u], nd;
   1.139 +          _dist[u] = heap.prio();
   1.140 +          heap.pop();
   1.141 +          _proc_nodes.push_back(u);
   1.142 +
   1.143 +          // Traversing outgoing arcs
   1.144 +          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
   1.145 +            if (_flow[e] == 0) {
   1.146 +              v = _graph.target(e);
   1.147 +              switch(heap.state(v)) {
   1.148 +              case Heap::PRE_HEAP:
   1.149 +                heap.push(v, d + _length[e] - _potential[v]);
   1.150 +                _pred[v] = e;
   1.151 +                break;
   1.152 +              case Heap::IN_HEAP:
   1.153 +                nd = d + _length[e] - _potential[v];
   1.154 +                if (nd < heap[v]) {
   1.155 +                  heap.decrease(v, nd);
   1.156 +                  _pred[v] = e;
   1.157 +                }
   1.158 +                break;
   1.159 +              case Heap::POST_HEAP:
   1.160 +                break;
   1.161 +              }
   1.162 +            }
   1.163 +          }
   1.164 +
   1.165 +          // Traversing incoming arcs
   1.166 +          for (InArcIt e(_graph, u); e != INVALID; ++e) {
   1.167 +            if (_flow[e] == 1) {
   1.168 +              v = _graph.source(e);
   1.169 +              switch(heap.state(v)) {
   1.170 +              case Heap::PRE_HEAP:
   1.171 +                heap.push(v, d - _length[e] - _potential[v]);
   1.172 +                _pred[v] = e;
   1.173 +                break;
   1.174 +              case Heap::IN_HEAP:
   1.175 +                nd = d - _length[e] - _potential[v];
   1.176 +                if (nd < heap[v]) {
   1.177 +                  heap.decrease(v, nd);
   1.178 +                  _pred[v] = e;
   1.179 +                }
   1.180 +                break;
   1.181 +              case Heap::POST_HEAP:
   1.182 +                break;
   1.183 +              }
   1.184 +            }
   1.185 +          }
   1.186 +        }
   1.187 +        if (heap.empty()) return false;
   1.188 +
   1.189 +        // Updating potentials of processed nodes
   1.190 +        Length t_dist = heap.prio();
   1.191 +        for (int i = 0; i < int(_proc_nodes.size()); ++i)
   1.192 +          _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
   1.193 +        return true;
   1.194 +      }
   1.195 +
   1.196 +    }; //class ResidualDijkstra
   1.197 +
   1.198 +  private:
   1.199 +
   1.200 +    // The directed digraph the algorithm runs on
   1.201 +    const Digraph &_graph;
   1.202 +    // The length map
   1.203 +    const LengthMap &_length;
   1.204 +    
   1.205 +    // Arc map of the current flow
   1.206 +    FlowMap *_flow;
   1.207 +    bool _local_flow;
   1.208 +    // Node map of the current potentials
   1.209 +    PotentialMap *_potential;
   1.210 +    bool _local_potential;
   1.211 +
   1.212 +    // The source node
   1.213 +    Node _source;
   1.214 +    // The target node
   1.215 +    Node _target;
   1.216 +
   1.217 +    // Container to store the found paths
   1.218 +    std::vector< SimplePath<Digraph> > paths;
   1.219 +    int _path_num;
   1.220 +
   1.221 +    // The pred arc map
   1.222 +    PredMap _pred;
   1.223 +    // Implementation of the Dijkstra algorithm for finding augmenting
   1.224 +    // shortest paths in the residual network
   1.225 +    ResidualDijkstra *_dijkstra;
   1.226 +
   1.227 +  public:
   1.228 +
   1.229 +    /// \brief Constructor.
   1.230 +    ///
   1.231 +    /// Constructor.
   1.232 +    ///
   1.233 +    /// \param digraph The directed digraph the algorithm runs on.
   1.234 +    /// \param length The length (cost) values of the arcs.
   1.235 +    /// \param s The source node.
   1.236 +    /// \param t The target node.
   1.237 +    Suurballe( const Digraph &digraph,
   1.238 +               const LengthMap &length,
   1.239 +               Node s, Node t ) :
   1.240 +      _graph(digraph), _length(length), _flow(0), _local_flow(false),
   1.241 +      _potential(0), _local_potential(false), _source(s), _target(t),
   1.242 +      _pred(digraph) {}
   1.243 +
   1.244 +    /// Destructor.
   1.245 +    ~Suurballe() {
   1.246 +      if (_local_flow) delete _flow;
   1.247 +      if (_local_potential) delete _potential;
   1.248 +      delete _dijkstra;
   1.249 +    }
   1.250 +
   1.251 +    /// \brief Sets the flow map.
   1.252 +    ///
   1.253 +    /// Sets the flow map.
   1.254 +    ///
   1.255 +    /// The found flow contains only 0 and 1 values. It is the union of
   1.256 +    /// the found arc-disjoint paths.
   1.257 +    ///
   1.258 +    /// \return \c (*this)
   1.259 +    Suurballe& flowMap(FlowMap &map) {
   1.260 +      if (_local_flow) {
   1.261 +        delete _flow;
   1.262 +        _local_flow = false;
   1.263 +      }
   1.264 +      _flow = &map;
   1.265 +      return *this;
   1.266 +    }
   1.267 +
   1.268 +    /// \brief Sets the potential map.
   1.269 +    ///
   1.270 +    /// Sets the potential map.
   1.271 +    ///
   1.272 +    /// The potentials provide the dual solution of the underlying 
   1.273 +    /// minimum cost flow problem.
   1.274 +    ///
   1.275 +    /// \return \c (*this)
   1.276 +    Suurballe& potentialMap(PotentialMap &map) {
   1.277 +      if (_local_potential) {
   1.278 +        delete _potential;
   1.279 +        _local_potential = false;
   1.280 +      }
   1.281 +      _potential = &map;
   1.282 +      return *this;
   1.283 +    }
   1.284 +
   1.285 +    /// \name Execution control
   1.286 +    /// The simplest way to execute the algorithm is to call the run()
   1.287 +    /// function.
   1.288 +    /// \n
   1.289 +    /// If you only need the flow that is the union of the found
   1.290 +    /// arc-disjoint paths, you may call init() and findFlow().
   1.291 +
   1.292 +    /// @{
   1.293 +
   1.294 +    /// \brief Runs the algorithm.
   1.295 +    ///
   1.296 +    /// Runs the algorithm.
   1.297 +    ///
   1.298 +    /// \param k The number of paths to be found.
   1.299 +    ///
   1.300 +    /// \return \c k if there are at least \c k arc-disjoint paths
   1.301 +    /// from \c s to \c t. Otherwise it returns the number of
   1.302 +    /// arc-disjoint paths found.
   1.303 +    ///
   1.304 +    /// \note Apart from the return value, <tt>s.run(k)</tt> is just a
   1.305 +    /// shortcut of the following code.
   1.306 +    /// \code
   1.307 +    ///   s.init();
   1.308 +    ///   s.findFlow(k);
   1.309 +    ///   s.findPaths();
   1.310 +    /// \endcode
   1.311 +    int run(int k = 2) {
   1.312 +      init();
   1.313 +      findFlow(k);
   1.314 +      findPaths();
   1.315 +      return _path_num;
   1.316 +    }
   1.317 +
   1.318 +    /// \brief Initializes the algorithm.
   1.319 +    ///
   1.320 +    /// Initializes the algorithm.
   1.321 +    void init() {
   1.322 +      // Initializing maps
   1.323 +      if (!_flow) {
   1.324 +        _flow = new FlowMap(_graph);
   1.325 +        _local_flow = true;
   1.326 +      }
   1.327 +      if (!_potential) {
   1.328 +        _potential = new PotentialMap(_graph);
   1.329 +        _local_potential = true;
   1.330 +      }
   1.331 +      for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
   1.332 +      for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
   1.333 +
   1.334 +      _dijkstra = new ResidualDijkstra( _graph, *_flow, _length, 
   1.335 +                                        *_potential, _pred,
   1.336 +                                        _source, _target );
   1.337 +    }
   1.338 +
   1.339 +    /// \brief Executes the successive shortest path algorithm to find
   1.340 +    /// an optimal flow.
   1.341 +    ///
   1.342 +    /// Executes the successive shortest path algorithm to find a
   1.343 +    /// minimum cost flow, which is the union of \c k or less
   1.344 +    /// arc-disjoint paths.
   1.345 +    ///
   1.346 +    /// \return \c k if there are at least \c k arc-disjoint paths
   1.347 +    /// from \c s to \c t. Otherwise it returns the number of
   1.348 +    /// arc-disjoint paths found.
   1.349 +    ///
   1.350 +    /// \pre \ref init() must be called before using this function.
   1.351 +    int findFlow(int k = 2) {
   1.352 +      // Finding shortest paths
   1.353 +      _path_num = 0;
   1.354 +      while (_path_num < k) {
   1.355 +        // Running Dijkstra
   1.356 +        if (!_dijkstra->run()) break;
   1.357 +        ++_path_num;
   1.358 +
   1.359 +        // Setting the flow along the found shortest path
   1.360 +        Node u = _target;
   1.361 +        Arc e;
   1.362 +        while ((e = _pred[u]) != INVALID) {
   1.363 +          if (u == _graph.target(e)) {
   1.364 +            (*_flow)[e] = 1;
   1.365 +            u = _graph.source(e);
   1.366 +          } else {
   1.367 +            (*_flow)[e] = 0;
   1.368 +            u = _graph.target(e);
   1.369 +          }
   1.370 +        }
   1.371 +      }
   1.372 +      return _path_num;
   1.373 +    }
   1.374 +    
   1.375 +    /// \brief Computes the paths from the flow.
   1.376 +    ///
   1.377 +    /// Computes the paths from the flow.
   1.378 +    ///
   1.379 +    /// \pre \ref init() and \ref findFlow() must be called before using
   1.380 +    /// this function.
   1.381 +    void findPaths() {
   1.382 +      // Creating the residual flow map (the union of the paths not
   1.383 +      // found so far)
   1.384 +      FlowMap res_flow(_graph);
   1.385 +      for(ArcIt a(_graph);a!=INVALID;++a) res_flow[a]=(*_flow)[a];
   1.386 +
   1.387 +      paths.clear();
   1.388 +      paths.resize(_path_num);
   1.389 +      for (int i = 0; i < _path_num; ++i) {
   1.390 +        Node n = _source;
   1.391 +        while (n != _target) {
   1.392 +          OutArcIt e(_graph, n);
   1.393 +          for ( ; res_flow[e] == 0; ++e) ;
   1.394 +          n = _graph.target(e);
   1.395 +          paths[i].addBack(e);
   1.396 +          res_flow[e] = 0;
   1.397 +        }
   1.398 +      }
   1.399 +    }
   1.400 +
   1.401 +    /// @}
   1.402 +
   1.403 +    /// \name Query Functions
   1.404 +    /// The result of the algorithm can be obtained using these
   1.405 +    /// functions.
   1.406 +    /// \n The algorithm should be executed before using them.
   1.407 +
   1.408 +    /// @{
   1.409 +
   1.410 +    /// \brief Returns a const reference to the arc map storing the
   1.411 +    /// found flow.
   1.412 +    ///
   1.413 +    /// Returns a const reference to the arc map storing the flow that
   1.414 +    /// is the union of the found arc-disjoint paths.
   1.415 +    ///
   1.416 +    /// \pre \ref run() or findFlow() must be called before using this
   1.417 +    /// function.
   1.418 +    const FlowMap& flowMap() const {
   1.419 +      return *_flow;
   1.420 +    }
   1.421 +
   1.422 +    /// \brief Returns a const reference to the node map storing the
   1.423 +    /// found potentials (the dual solution).
   1.424 +    ///
   1.425 +    /// Returns a const reference to the node map storing the found
   1.426 +    /// potentials that provide the dual solution of the underlying 
   1.427 +    /// minimum cost flow problem.
   1.428 +    ///
   1.429 +    /// \pre \ref run() or findFlow() must be called before using this
   1.430 +    /// function.
   1.431 +    const PotentialMap& potentialMap() const {
   1.432 +      return *_potential;
   1.433 +    }
   1.434 +
   1.435 +    /// \brief Returns the flow on the given arc.
   1.436 +    ///
   1.437 +    /// Returns the flow on the given arc.
   1.438 +    /// It is \c 1 if the arc is involved in one of the found paths,
   1.439 +    /// otherwise it is \c 0.
   1.440 +    ///
   1.441 +    /// \pre \ref run() or findFlow() must be called before using this
   1.442 +    /// function.
   1.443 +    int flow(const Arc& arc) const {
   1.444 +      return (*_flow)[arc];
   1.445 +    }
   1.446 +
   1.447 +    /// \brief Returns the potential of the given node.
   1.448 +    ///
   1.449 +    /// Returns the potential of the given node.
   1.450 +    ///
   1.451 +    /// \pre \ref run() or findFlow() must be called before using this
   1.452 +    /// function.
   1.453 +    Length potential(const Node& node) const {
   1.454 +      return (*_potential)[node];
   1.455 +    }
   1.456 +
   1.457 +    /// \brief Returns the total length (cost) of the found paths (flow).
   1.458 +    ///
   1.459 +    /// Returns the total length (cost) of the found paths (flow).
   1.460 +    /// The complexity of the function is \f$ O(e) \f$.
   1.461 +    ///
   1.462 +    /// \pre \ref run() or findFlow() must be called before using this
   1.463 +    /// function.
   1.464 +    Length totalLength() const {
   1.465 +      Length c = 0;
   1.466 +      for (ArcIt e(_graph); e != INVALID; ++e)
   1.467 +        c += (*_flow)[e] * _length[e];
   1.468 +      return c;
   1.469 +    }
   1.470 +
   1.471 +    /// \brief Returns the number of the found paths.
   1.472 +    ///
   1.473 +    /// Returns the number of the found paths.
   1.474 +    ///
   1.475 +    /// \pre \ref run() or findFlow() must be called before using this
   1.476 +    /// function.
   1.477 +    int pathNum() const {
   1.478 +      return _path_num;
   1.479 +    }
   1.480 +
   1.481 +    /// \brief Returns a const reference to the specified path.
   1.482 +    ///
   1.483 +    /// Returns a const reference to the specified path.
   1.484 +    ///
   1.485 +    /// \param i The function returns the \c i-th path.
   1.486 +    /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
   1.487 +    ///
   1.488 +    /// \pre \ref run() or findPaths() must be called before using this
   1.489 +    /// function.
   1.490 +    Path path(int i) const {
   1.491 +      return paths[i];
   1.492 +    }
   1.493 +
   1.494 +    /// @}
   1.495 +
   1.496 +  }; //class Suurballe
   1.497 +
   1.498 +  ///@}
   1.499 +
   1.500 +} //namespace lemon
   1.501 +
   1.502 +#endif //LEMON_SUURBALLE_H