COIN-OR::LEMON - Graph Library

source: lemon-1.2/lemon/suurballe.h @ 854:9a7e4e606f83

Last change on this file since 854:9a7e4e606f83 was 854:9a7e4e606f83, checked in by Peter Kovacs <kpeter@…>, 15 years ago

Add a fullInit() function to Suurballe (#181, #323)
to provide faster handling of multiple targets.
A start() function is also added, just for the sake of
convenience.

File size: 19.4 KB
RevLine 
[440]1/* -*- mode: C++; indent-tabs-mode: nil; -*-
[345]2 *
[440]3 * This file is a part of LEMON, a generic C++ optimization library.
[345]4 *
[440]5 * Copyright (C) 2003-2009
[345]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_SUURBALLE_H
20#define LEMON_SUURBALLE_H
21
22///\ingroup shortest_path
23///\file
24///\brief An algorithm for finding arc-disjoint paths between two
25/// nodes having minimum total length.
26
27#include <vector>
[623]28#include <limits>
[345]29#include <lemon/bin_heap.h>
30#include <lemon/path.h>
[519]31#include <lemon/list_graph.h>
[854]32#include <lemon/dijkstra.h>
[519]33#include <lemon/maps.h>
[345]34
35namespace lemon {
36
37  /// \addtogroup shortest_path
38  /// @{
39
[346]40  /// \brief Algorithm for finding arc-disjoint paths between two nodes
41  /// having minimum total length.
[345]42  ///
43  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
44  /// finding arc-disjoint paths having minimum total length (cost)
[346]45  /// from a given source node to a given target node in a digraph.
[345]46  ///
[623]47  /// Note that this problem is a special case of the \ref min_cost_flow
48  /// "minimum cost flow problem". This implementation is actually an
49  /// efficient specialized version of the \ref CapacityScaling
[853]50  /// "successive shortest path" algorithm directly for this problem.
[623]51  /// Therefore this class provides query functions for flow values and
52  /// node potentials (the dual solution) just like the minimum cost flow
53  /// algorithms.
[345]54  ///
[559]55  /// \tparam GR The digraph type the algorithm runs on.
[623]56  /// \tparam LEN The type of the length map.
57  /// The default value is <tt>GR::ArcMap<int></tt>.
[345]58  ///
[852]59  /// \warning Length values should be \e non-negative.
[345]60  ///
[853]61  /// \note For finding \e node-disjoint paths, this algorithm can be used
[623]62  /// along with the \ref SplitNodes adaptor.
[346]63#ifdef DOXYGEN
[559]64  template <typename GR, typename LEN>
[346]65#else
[623]66  template < typename GR,
[559]67             typename LEN = typename GR::template ArcMap<int> >
[346]68#endif
[345]69  class Suurballe
70  {
[559]71    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
[345]72
73    typedef ConstMap<Arc, int> ConstArcMap;
[559]74    typedef typename GR::template NodeMap<Arc> PredMap;
[345]75
76  public:
77
[559]78    /// The type of the digraph the algorithm runs on.
79    typedef GR Digraph;
80    /// The type of the length map.
81    typedef LEN LengthMap;
82    /// The type of the lengths.
83    typedef typename LengthMap::Value Length;
[623]84#ifdef DOXYGEN
85    /// The type of the flow map.
86    typedef GR::ArcMap<int> FlowMap;
87    /// The type of the potential map.
88    typedef GR::NodeMap<Length> PotentialMap;
89#else
[345]90    /// The type of the flow map.
91    typedef typename Digraph::template ArcMap<int> FlowMap;
92    /// The type of the potential map.
93    typedef typename Digraph::template NodeMap<Length> PotentialMap;
[623]94#endif
95
[345]96    /// The type of the path structures.
[623]97    typedef SimplePath<GR> Path;
[345]98
99  private:
[440]100
[854]101    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
102    typedef BinHeap<Length, HeapCrossRef> Heap;
103
[623]104    // ResidualDijkstra is a special implementation of the
105    // Dijkstra algorithm for finding shortest paths in the
106    // residual network with respect to the reduced arc lengths
107    // and modifying the node potentials according to the
108    // distance of the nodes.
[345]109    class ResidualDijkstra
110    {
111    private:
112
113      const Digraph &_graph;
[853]114      const LengthMap &_length;
[345]115      const FlowMap &_flow;
[853]116      PotentialMap &_pi;
[345]117      PredMap &_pred;
118      Node _s;
119      Node _t;
[853]120     
121      PotentialMap _dist;
122      std::vector<Node> _proc_nodes;
[345]123
124    public:
125
[853]126      // Constructor
127      ResidualDijkstra(Suurballe &srb) :
128        _graph(srb._graph), _length(srb._length),
129        _flow(*srb._flow), _pi(*srb._potential), _pred(srb._pred),
130        _s(srb._s), _t(srb._t), _dist(_graph) {}
131       
132      // Run the algorithm and return true if a path is found
133      // from the source node to the target node.
134      bool run(int cnt) {
135        return cnt == 0 ? startFirst() : start();
136      }
[345]137
[853]138    private:
139   
140      // Execute the algorithm for the first time (the flow and potential
141      // functions have to be identically zero).
142      bool startFirst() {
[345]143        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
144        Heap heap(heap_cross_ref);
145        heap.push(_s, 0);
146        _pred[_s] = INVALID;
147        _proc_nodes.clear();
148
[346]149        // Process nodes
[345]150        while (!heap.empty() && heap.top() != _t) {
151          Node u = heap.top(), v;
[853]152          Length d = heap.prio(), dn;
[345]153          _dist[u] = heap.prio();
[853]154          _proc_nodes.push_back(u);
[345]155          heap.pop();
[853]156
157          // Traverse outgoing arcs
158          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
159            v = _graph.target(e);
160            switch(heap.state(v)) {
161              case Heap::PRE_HEAP:
162                heap.push(v, d + _length[e]);
163                _pred[v] = e;
164                break;
165              case Heap::IN_HEAP:
166                dn = d + _length[e];
167                if (dn < heap[v]) {
168                  heap.decrease(v, dn);
169                  _pred[v] = e;
170                }
171                break;
172              case Heap::POST_HEAP:
173                break;
174            }
175          }
176        }
177        if (heap.empty()) return false;
178
179        // Update potentials of processed nodes
180        Length t_dist = heap.prio();
181        for (int i = 0; i < int(_proc_nodes.size()); ++i)
182          _pi[_proc_nodes[i]] = _dist[_proc_nodes[i]] - t_dist;
183        return true;
184      }
185
186      // Execute the algorithm.
187      bool start() {
188        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
189        Heap heap(heap_cross_ref);
190        heap.push(_s, 0);
191        _pred[_s] = INVALID;
192        _proc_nodes.clear();
193
194        // Process nodes
195        while (!heap.empty() && heap.top() != _t) {
196          Node u = heap.top(), v;
197          Length d = heap.prio() + _pi[u], dn;
198          _dist[u] = heap.prio();
[345]199          _proc_nodes.push_back(u);
[853]200          heap.pop();
[345]201
[346]202          // Traverse outgoing arcs
[345]203          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
204            if (_flow[e] == 0) {
205              v = _graph.target(e);
206              switch(heap.state(v)) {
[853]207                case Heap::PRE_HEAP:
208                  heap.push(v, d + _length[e] - _pi[v]);
[345]209                  _pred[v] = e;
[853]210                  break;
211                case Heap::IN_HEAP:
212                  dn = d + _length[e] - _pi[v];
213                  if (dn < heap[v]) {
214                    heap.decrease(v, dn);
215                    _pred[v] = e;
216                  }
217                  break;
218                case Heap::POST_HEAP:
219                  break;
[345]220              }
221            }
222          }
223
[346]224          // Traverse incoming arcs
[345]225          for (InArcIt e(_graph, u); e != INVALID; ++e) {
226            if (_flow[e] == 1) {
227              v = _graph.source(e);
228              switch(heap.state(v)) {
[853]229                case Heap::PRE_HEAP:
230                  heap.push(v, d - _length[e] - _pi[v]);
[345]231                  _pred[v] = e;
[853]232                  break;
233                case Heap::IN_HEAP:
234                  dn = d - _length[e] - _pi[v];
235                  if (dn < heap[v]) {
236                    heap.decrease(v, dn);
237                    _pred[v] = e;
238                  }
239                  break;
240                case Heap::POST_HEAP:
241                  break;
[345]242              }
243            }
244          }
245        }
246        if (heap.empty()) return false;
247
[346]248        // Update potentials of processed nodes
[345]249        Length t_dist = heap.prio();
250        for (int i = 0; i < int(_proc_nodes.size()); ++i)
[853]251          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
[345]252        return true;
253      }
254
255    }; //class ResidualDijkstra
256
257  private:
258
[346]259    // The digraph the algorithm runs on
[345]260    const Digraph &_graph;
261    // The length map
262    const LengthMap &_length;
[440]263
[345]264    // Arc map of the current flow
265    FlowMap *_flow;
266    bool _local_flow;
267    // Node map of the current potentials
268    PotentialMap *_potential;
269    bool _local_potential;
270
271    // The source node
[853]272    Node _s;
[345]273    // The target node
[853]274    Node _t;
[345]275
276    // Container to store the found paths
[853]277    std::vector<Path> _paths;
[345]278    int _path_num;
279
280    // The pred arc map
281    PredMap _pred;
[854]282   
283    // Data for full init
284    PotentialMap *_init_dist;
285    PredMap *_init_pred;
286    bool _full_init;
[345]287
288  public:
289
290    /// \brief Constructor.
291    ///
292    /// Constructor.
293    ///
[623]294    /// \param graph The digraph the algorithm runs on.
[345]295    /// \param length The length (cost) values of the arcs.
[623]296    Suurballe( const Digraph &graph,
297               const LengthMap &length ) :
298      _graph(graph), _length(length), _flow(0), _local_flow(false),
[854]299      _potential(0), _local_potential(false), _pred(graph),
300      _init_dist(0), _init_pred(0)
[852]301    {}
[345]302
303    /// Destructor.
304    ~Suurballe() {
305      if (_local_flow) delete _flow;
306      if (_local_potential) delete _potential;
[854]307      delete _init_dist;
308      delete _init_pred;
[345]309    }
310
[346]311    /// \brief Set the flow map.
[345]312    ///
[346]313    /// This function sets the flow map.
[623]314    /// If it is not used before calling \ref run() or \ref init(),
315    /// an instance will be allocated automatically. The destructor
316    /// deallocates this automatically allocated map, of course.
[345]317    ///
[623]318    /// The found flow contains only 0 and 1 values, since it is the
319    /// union of the found arc-disjoint paths.
[345]320    ///
[559]321    /// \return <tt>(*this)</tt>
[345]322    Suurballe& flowMap(FlowMap &map) {
323      if (_local_flow) {
324        delete _flow;
325        _local_flow = false;
326      }
327      _flow = &map;
328      return *this;
329    }
330
[346]331    /// \brief Set the potential map.
[345]332    ///
[346]333    /// This function sets the potential map.
[623]334    /// If it is not used before calling \ref run() or \ref init(),
335    /// an instance will be allocated automatically. The destructor
336    /// deallocates this automatically allocated map, of course.
[345]337    ///
[623]338    /// The node potentials provide the dual solution of the underlying
339    /// \ref min_cost_flow "minimum cost flow problem".
[345]340    ///
[559]341    /// \return <tt>(*this)</tt>
[345]342    Suurballe& potentialMap(PotentialMap &map) {
343      if (_local_potential) {
344        delete _potential;
345        _local_potential = false;
346      }
347      _potential = &map;
348      return *this;
349    }
350
[584]351    /// \name Execution Control
[345]352    /// The simplest way to execute the algorithm is to call the run()
[854]353    /// function.\n
354    /// If you need to execute the algorithm many times using the same
355    /// source node, then you may call fullInit() once and start()
356    /// for each target node.\n
[345]357    /// If you only need the flow that is the union of the found
[854]358    /// arc-disjoint paths, then you may call findFlow() instead of
359    /// start().
[345]360
361    /// @{
362
[346]363    /// \brief Run the algorithm.
[345]364    ///
[346]365    /// This function runs the algorithm.
[345]366    ///
[623]367    /// \param s The source node.
368    /// \param t The target node.
[345]369    /// \param k The number of paths to be found.
370    ///
[346]371    /// \return \c k if there are at least \c k arc-disjoint paths from
372    /// \c s to \c t in the digraph. Otherwise it returns the number of
[345]373    /// arc-disjoint paths found.
374    ///
[623]375    /// \note Apart from the return value, <tt>s.run(s, t, k)</tt> is
376    /// just a shortcut of the following code.
[345]377    /// \code
[623]378    ///   s.init(s);
[854]379    ///   s.start(t, k);
[345]380    /// \endcode
[623]381    int run(const Node& s, const Node& t, int k = 2) {
382      init(s);
[854]383      start(t, k);
[345]384      return _path_num;
385    }
386
[346]387    /// \brief Initialize the algorithm.
[345]388    ///
[854]389    /// This function initializes the algorithm with the given source node.
[623]390    ///
391    /// \param s The source node.
392    void init(const Node& s) {
[853]393      _s = s;
[623]394
[346]395      // Initialize maps
[345]396      if (!_flow) {
397        _flow = new FlowMap(_graph);
398        _local_flow = true;
399      }
400      if (!_potential) {
401        _potential = new PotentialMap(_graph);
402        _local_potential = true;
403      }
[854]404      _full_init = false;
405    }
406
407    /// \brief Initialize the algorithm and perform Dijkstra.
408    ///
409    /// This function initializes the algorithm and performs a full
410    /// Dijkstra search from the given source node. It makes consecutive
411    /// executions of \ref start() "start(t, k)" faster, since they
412    /// have to perform %Dijkstra only k-1 times.
413    ///
414    /// This initialization is usually worth using instead of \ref init()
415    /// if the algorithm is executed many times using the same source node.
416    ///
417    /// \param s The source node.
418    void fullInit(const Node& s) {
419      // Initialize maps
420      init(s);
421      if (!_init_dist) {
422        _init_dist = new PotentialMap(_graph);
423      }
424      if (!_init_pred) {
425        _init_pred = new PredMap(_graph);
426      }
427
428      // Run a full Dijkstra
429      typename Dijkstra<Digraph, LengthMap>
430        ::template SetStandardHeap<Heap>
431        ::template SetDistMap<PotentialMap>
432        ::template SetPredMap<PredMap>
433        ::Create dijk(_graph, _length);
434      dijk.distMap(*_init_dist).predMap(*_init_pred);
435      dijk.run(s);
436     
437      _full_init = true;
438    }
439
440    /// \brief Execute the algorithm.
441    ///
442    /// This function executes the algorithm.
443    ///
444    /// \param t The target node.
445    /// \param k The number of paths to be found.
446    ///
447    /// \return \c k if there are at least \c k arc-disjoint paths from
448    /// \c s to \c t in the digraph. Otherwise it returns the number of
449    /// arc-disjoint paths found.
450    ///
451    /// \note Apart from the return value, <tt>s.start(t, k)</tt> is
452    /// just a shortcut of the following code.
453    /// \code
454    ///   s.findFlow(t, k);
455    ///   s.findPaths();
456    /// \endcode
457    int start(const Node& t, int k = 2) {
458      findFlow(t, k);
459      findPaths();
460      return _path_num;
[345]461    }
462
[623]463    /// \brief Execute the algorithm to find an optimal flow.
[345]464    ///
[346]465    /// This function executes the successive shortest path algorithm to
[623]466    /// find a minimum cost flow, which is the union of \c k (or less)
[345]467    /// arc-disjoint paths.
468    ///
[623]469    /// \param t The target node.
470    /// \param k The number of paths to be found.
471    ///
[346]472    /// \return \c k if there are at least \c k arc-disjoint paths from
[623]473    /// the source node to the given node \c t in the digraph.
474    /// Otherwise it returns the number of arc-disjoint paths found.
[345]475    ///
476    /// \pre \ref init() must be called before using this function.
[623]477    int findFlow(const Node& t, int k = 2) {
[853]478      _t = t;
479      ResidualDijkstra dijkstra(*this);
[854]480     
481      // Initialization
482      for (ArcIt e(_graph); e != INVALID; ++e) {
483        (*_flow)[e] = 0;
484      }
485      if (_full_init) {
486        for (NodeIt n(_graph); n != INVALID; ++n) {
487          (*_potential)[n] = (*_init_dist)[n];
488        }
489        Node u = _t;
490        Arc e;
491        while ((e = (*_init_pred)[u]) != INVALID) {
492          (*_flow)[e] = 1;
493          u = _graph.source(e);
494        }       
495        _path_num = 1;
496      } else {
497        for (NodeIt n(_graph); n != INVALID; ++n) {
498          (*_potential)[n] = 0;
499        }
500        _path_num = 0;
501      }
[623]502
[346]503      // Find shortest paths
[345]504      while (_path_num < k) {
[346]505        // Run Dijkstra
[853]506        if (!dijkstra.run(_path_num)) break;
[345]507        ++_path_num;
508
[346]509        // Set the flow along the found shortest path
[853]510        Node u = _t;
[345]511        Arc e;
512        while ((e = _pred[u]) != INVALID) {
513          if (u == _graph.target(e)) {
514            (*_flow)[e] = 1;
515            u = _graph.source(e);
516          } else {
517            (*_flow)[e] = 0;
518            u = _graph.target(e);
519          }
520        }
521      }
522      return _path_num;
523    }
[440]524
[346]525    /// \brief Compute the paths from the flow.
[345]526    ///
[853]527    /// This function computes arc-disjoint paths from the found minimum
528    /// cost flow, which is the union of them.
[345]529    ///
530    /// \pre \ref init() and \ref findFlow() must be called before using
531    /// this function.
532    void findPaths() {
533      FlowMap res_flow(_graph);
[346]534      for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
[345]535
[853]536      _paths.clear();
537      _paths.resize(_path_num);
[345]538      for (int i = 0; i < _path_num; ++i) {
[853]539        Node n = _s;
540        while (n != _t) {
[345]541          OutArcIt e(_graph, n);
542          for ( ; res_flow[e] == 0; ++e) ;
543          n = _graph.target(e);
[853]544          _paths[i].addBack(e);
[345]545          res_flow[e] = 0;
546        }
547      }
548    }
549
550    /// @}
551
552    /// \name Query Functions
[346]553    /// The results of the algorithm can be obtained using these
[345]554    /// functions.
555    /// \n The algorithm should be executed before using them.
556
557    /// @{
558
[623]559    /// \brief Return the total length of the found paths.
560    ///
561    /// This function returns the total length of the found paths, i.e.
562    /// the total cost of the found flow.
563    /// The complexity of the function is O(e).
564    ///
565    /// \pre \ref run() or \ref findFlow() must be called before using
566    /// this function.
567    Length totalLength() const {
568      Length c = 0;
569      for (ArcIt e(_graph); e != INVALID; ++e)
570        c += (*_flow)[e] * _length[e];
571      return c;
572    }
573
574    /// \brief Return the flow value on the given arc.
575    ///
576    /// This function returns the flow value on the given arc.
577    /// It is \c 1 if the arc is involved in one of the found arc-disjoint
578    /// paths, otherwise it is \c 0.
579    ///
580    /// \pre \ref run() or \ref findFlow() must be called before using
581    /// this function.
582    int flow(const Arc& arc) const {
583      return (*_flow)[arc];
584    }
585
586    /// \brief Return a const reference to an arc map storing the
[345]587    /// found flow.
588    ///
[623]589    /// This function returns a const reference to an arc map storing
[346]590    /// the flow that is the union of the found arc-disjoint paths.
[345]591    ///
[346]592    /// \pre \ref run() or \ref findFlow() must be called before using
593    /// this function.
[345]594    const FlowMap& flowMap() const {
595      return *_flow;
596    }
597
[346]598    /// \brief Return the potential of the given node.
[345]599    ///
[346]600    /// This function returns the potential of the given node.
[623]601    /// The node potentials provide the dual solution of the
602    /// underlying \ref min_cost_flow "minimum cost flow problem".
[345]603    ///
[346]604    /// \pre \ref run() or \ref findFlow() must be called before using
605    /// this function.
[345]606    Length potential(const Node& node) const {
607      return (*_potential)[node];
608    }
609
[623]610    /// \brief Return a const reference to a node map storing the
611    /// found potentials (the dual solution).
[345]612    ///
[623]613    /// This function returns a const reference to a node map storing
614    /// the found potentials that provide the dual solution of the
615    /// underlying \ref min_cost_flow "minimum cost flow problem".
[345]616    ///
[346]617    /// \pre \ref run() or \ref findFlow() must be called before using
618    /// this function.
[623]619    const PotentialMap& potentialMap() const {
620      return *_potential;
[345]621    }
622
[346]623    /// \brief Return the number of the found paths.
[345]624    ///
[346]625    /// This function returns the number of the found paths.
[345]626    ///
[346]627    /// \pre \ref run() or \ref findFlow() must be called before using
628    /// this function.
[345]629    int pathNum() const {
630      return _path_num;
631    }
632
[346]633    /// \brief Return a const reference to the specified path.
[345]634    ///
[346]635    /// This function returns a const reference to the specified path.
[345]636    ///
[623]637    /// \param i The function returns the <tt>i</tt>-th path.
[345]638    /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
639    ///
[346]640    /// \pre \ref run() or \ref findPaths() must be called before using
641    /// this function.
[851]642    const Path& path(int i) const {
[853]643      return _paths[i];
[345]644    }
645
646    /// @}
647
648  }; //class Suurballe
649
650  ///@}
651
652} //namespace lemon
653
654#endif //LEMON_SUURBALLE_H
Note: See TracBrowser for help on using the repository browser.