COIN-OR::LEMON - Graph Library

source: lemon/lemon/suurballe.h @ 930:5df6a8f29d5e

Last change on this file since 930:5df6a8f29d5e was 927: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 
[463]1/* -*- mode: C++; indent-tabs-mode: nil; -*-
[357]2 *
[463]3 * This file is a part of LEMON, a generic C++ optimization library.
[357]4 *
[463]5 * Copyright (C) 2003-2009
[357]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>
[670]28#include <limits>
[357]29#include <lemon/bin_heap.h>
30#include <lemon/path.h>
[566]31#include <lemon/list_graph.h>
[927]32#include <lemon/dijkstra.h>
[566]33#include <lemon/maps.h>
[357]34
35namespace lemon {
36
37  /// \addtogroup shortest_path
38  /// @{
39
[358]40  /// \brief Algorithm for finding arc-disjoint paths between two nodes
41  /// having minimum total length.
[357]42  ///
43  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
44  /// finding arc-disjoint paths having minimum total length (cost)
[358]45  /// from a given source node to a given target node in a digraph.
[357]46  ///
[670]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
[926]50  /// "successive shortest path" algorithm directly for this problem.
[670]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.
[357]54  ///
[606]55  /// \tparam GR The digraph type the algorithm runs on.
[670]56  /// \tparam LEN The type of the length map.
57  /// The default value is <tt>GR::ArcMap<int></tt>.
[357]58  ///
[925]59  /// \warning Length values should be \e non-negative.
[357]60  ///
[926]61  /// \note For finding \e node-disjoint paths, this algorithm can be used
[670]62  /// along with the \ref SplitNodes adaptor.
[358]63#ifdef DOXYGEN
[606]64  template <typename GR, typename LEN>
[358]65#else
[670]66  template < typename GR,
[606]67             typename LEN = typename GR::template ArcMap<int> >
[358]68#endif
[357]69  class Suurballe
70  {
[606]71    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
[357]72
73    typedef ConstMap<Arc, int> ConstArcMap;
[606]74    typedef typename GR::template NodeMap<Arc> PredMap;
[357]75
76  public:
77
[606]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;
[670]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
[357]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;
[670]94#endif
95
[357]96    /// The type of the path structures.
[670]97    typedef SimplePath<GR> Path;
[357]98
99  private:
[463]100
[927]101    typedef typename Digraph::template NodeMap<int> HeapCrossRef;
102    typedef BinHeap<Length, HeapCrossRef> Heap;
103
[670]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.
[357]109    class ResidualDijkstra
110    {
111    private:
112
113      const Digraph &_graph;
[926]114      const LengthMap &_length;
[357]115      const FlowMap &_flow;
[926]116      PotentialMap &_pi;
[357]117      PredMap &_pred;
118      Node _s;
119      Node _t;
[926]120     
121      PotentialMap _dist;
122      std::vector<Node> _proc_nodes;
[357]123
124    public:
125
[926]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      }
[357]137
[926]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() {
[357]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
[358]149        // Process nodes
[357]150        while (!heap.empty() && heap.top() != _t) {
151          Node u = heap.top(), v;
[926]152          Length d = heap.prio(), dn;
[357]153          _dist[u] = heap.prio();
[926]154          _proc_nodes.push_back(u);
[357]155          heap.pop();
[926]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();
[357]199          _proc_nodes.push_back(u);
[926]200          heap.pop();
[357]201
[358]202          // Traverse outgoing arcs
[357]203          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
204            if (_flow[e] == 0) {
205              v = _graph.target(e);
206              switch(heap.state(v)) {
[926]207                case Heap::PRE_HEAP:
208                  heap.push(v, d + _length[e] - _pi[v]);
[357]209                  _pred[v] = e;
[926]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;
[357]220              }
221            }
222          }
223
[358]224          // Traverse incoming arcs
[357]225          for (InArcIt e(_graph, u); e != INVALID; ++e) {
226            if (_flow[e] == 1) {
227              v = _graph.source(e);
228              switch(heap.state(v)) {
[926]229                case Heap::PRE_HEAP:
230                  heap.push(v, d - _length[e] - _pi[v]);
[357]231                  _pred[v] = e;
[926]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;
[357]242              }
243            }
244          }
245        }
246        if (heap.empty()) return false;
247
[358]248        // Update potentials of processed nodes
[357]249        Length t_dist = heap.prio();
250        for (int i = 0; i < int(_proc_nodes.size()); ++i)
[926]251          _pi[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
[357]252        return true;
253      }
254
255    }; //class ResidualDijkstra
256
257  private:
258
[358]259    // The digraph the algorithm runs on
[357]260    const Digraph &_graph;
261    // The length map
262    const LengthMap &_length;
[463]263
[357]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
[926]272    Node _s;
[357]273    // The target node
[926]274    Node _t;
[357]275
276    // Container to store the found paths
[926]277    std::vector<Path> _paths;
[357]278    int _path_num;
279
280    // The pred arc map
281    PredMap _pred;
[927]282   
283    // Data for full init
284    PotentialMap *_init_dist;
285    PredMap *_init_pred;
286    bool _full_init;
[357]287
288  public:
289
290    /// \brief Constructor.
291    ///
292    /// Constructor.
293    ///
[670]294    /// \param graph The digraph the algorithm runs on.
[357]295    /// \param length The length (cost) values of the arcs.
[670]296    Suurballe( const Digraph &graph,
297               const LengthMap &length ) :
298      _graph(graph), _length(length), _flow(0), _local_flow(false),
[927]299      _potential(0), _local_potential(false), _pred(graph),
300      _init_dist(0), _init_pred(0)
[925]301    {}
[357]302
303    /// Destructor.
304    ~Suurballe() {
305      if (_local_flow) delete _flow;
306      if (_local_potential) delete _potential;
[927]307      delete _init_dist;
308      delete _init_pred;
[357]309    }
310
[358]311    /// \brief Set the flow map.
[357]312    ///
[358]313    /// This function sets the flow map.
[670]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.
[357]317    ///
[670]318    /// The found flow contains only 0 and 1 values, since it is the
319    /// union of the found arc-disjoint paths.
[357]320    ///
[606]321    /// \return <tt>(*this)</tt>
[357]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
[358]331    /// \brief Set the potential map.
[357]332    ///
[358]333    /// This function sets the potential map.
[670]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.
[357]337    ///
[670]338    /// The node potentials provide the dual solution of the underlying
339    /// \ref min_cost_flow "minimum cost flow problem".
[357]340    ///
[606]341    /// \return <tt>(*this)</tt>
[357]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
[631]351    /// \name Execution Control
[357]352    /// The simplest way to execute the algorithm is to call the run()
[927]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
[357]357    /// If you only need the flow that is the union of the found
[927]358    /// arc-disjoint paths, then you may call findFlow() instead of
359    /// start().
[357]360
361    /// @{
362
[358]363    /// \brief Run the algorithm.
[357]364    ///
[358]365    /// This function runs the algorithm.
[357]366    ///
[670]367    /// \param s The source node.
368    /// \param t The target node.
[357]369    /// \param k The number of paths to be found.
370    ///
[358]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
[357]373    /// arc-disjoint paths found.
374    ///
[670]375    /// \note Apart from the return value, <tt>s.run(s, t, k)</tt> is
376    /// just a shortcut of the following code.
[357]377    /// \code
[670]378    ///   s.init(s);
[927]379    ///   s.start(t, k);
[357]380    /// \endcode
[670]381    int run(const Node& s, const Node& t, int k = 2) {
382      init(s);
[927]383      start(t, k);
[357]384      return _path_num;
385    }
386
[358]387    /// \brief Initialize the algorithm.
[357]388    ///
[927]389    /// This function initializes the algorithm with the given source node.
[670]390    ///
391    /// \param s The source node.
392    void init(const Node& s) {
[926]393      _s = s;
[670]394
[358]395      // Initialize maps
[357]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      }
[927]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;
[357]461    }
462
[670]463    /// \brief Execute the algorithm to find an optimal flow.
[357]464    ///
[358]465    /// This function executes the successive shortest path algorithm to
[670]466    /// find a minimum cost flow, which is the union of \c k (or less)
[357]467    /// arc-disjoint paths.
468    ///
[670]469    /// \param t The target node.
470    /// \param k The number of paths to be found.
471    ///
[358]472    /// \return \c k if there are at least \c k arc-disjoint paths from
[670]473    /// the source node to the given node \c t in the digraph.
474    /// Otherwise it returns the number of arc-disjoint paths found.
[357]475    ///
476    /// \pre \ref init() must be called before using this function.
[670]477    int findFlow(const Node& t, int k = 2) {
[926]478      _t = t;
479      ResidualDijkstra dijkstra(*this);
[927]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      }
[670]502
[358]503      // Find shortest paths
[357]504      while (_path_num < k) {
[358]505        // Run Dijkstra
[926]506        if (!dijkstra.run(_path_num)) break;
[357]507        ++_path_num;
508
[358]509        // Set the flow along the found shortest path
[926]510        Node u = _t;
[357]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    }
[463]524
[358]525    /// \brief Compute the paths from the flow.
[357]526    ///
[926]527    /// This function computes arc-disjoint paths from the found minimum
528    /// cost flow, which is the union of them.
[357]529    ///
530    /// \pre \ref init() and \ref findFlow() must be called before using
531    /// this function.
532    void findPaths() {
533      FlowMap res_flow(_graph);
[358]534      for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
[357]535
[926]536      _paths.clear();
537      _paths.resize(_path_num);
[357]538      for (int i = 0; i < _path_num; ++i) {
[926]539        Node n = _s;
540        while (n != _t) {
[357]541          OutArcIt e(_graph, n);
542          for ( ; res_flow[e] == 0; ++e) ;
543          n = _graph.target(e);
[926]544          _paths[i].addBack(e);
[357]545          res_flow[e] = 0;
546        }
547      }
548    }
549
550    /// @}
551
552    /// \name Query Functions
[358]553    /// The results of the algorithm can be obtained using these
[357]554    /// functions.
555    /// \n The algorithm should be executed before using them.
556
557    /// @{
558
[670]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
[357]587    /// found flow.
588    ///
[670]589    /// This function returns a const reference to an arc map storing
[358]590    /// the flow that is the union of the found arc-disjoint paths.
[357]591    ///
[358]592    /// \pre \ref run() or \ref findFlow() must be called before using
593    /// this function.
[357]594    const FlowMap& flowMap() const {
595      return *_flow;
596    }
597
[358]598    /// \brief Return the potential of the given node.
[357]599    ///
[358]600    /// This function returns the potential of the given node.
[670]601    /// The node potentials provide the dual solution of the
602    /// underlying \ref min_cost_flow "minimum cost flow problem".
[357]603    ///
[358]604    /// \pre \ref run() or \ref findFlow() must be called before using
605    /// this function.
[357]606    Length potential(const Node& node) const {
607      return (*_potential)[node];
608    }
609
[670]610    /// \brief Return a const reference to a node map storing the
611    /// found potentials (the dual solution).
[357]612    ///
[670]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".
[357]616    ///
[358]617    /// \pre \ref run() or \ref findFlow() must be called before using
618    /// this function.
[670]619    const PotentialMap& potentialMap() const {
620      return *_potential;
[357]621    }
622
[358]623    /// \brief Return the number of the found paths.
[357]624    ///
[358]625    /// This function returns the number of the found paths.
[357]626    ///
[358]627    /// \pre \ref run() or \ref findFlow() must be called before using
628    /// this function.
[357]629    int pathNum() const {
630      return _path_num;
631    }
632
[358]633    /// \brief Return a const reference to the specified path.
[357]634    ///
[358]635    /// This function returns a const reference to the specified path.
[357]636    ///
[670]637    /// \param i The function returns the <tt>i</tt>-th path.
[357]638    /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
639    ///
[358]640    /// \pre \ref run() or \ref findPaths() must be called before using
641    /// this function.
[924]642    const Path& path(int i) const {
[926]643      return _paths[i];
[357]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.