lemon/suurballe.h
changeset 2597 91e2b6a4b96e
parent 2553 bfced05fa852
equal deleted inserted replaced
9:c319f355fd92 10:eaaf6faf6da8
    19 #ifndef LEMON_SUURBALLE_H
    19 #ifndef LEMON_SUURBALLE_H
    20 #define LEMON_SUURBALLE_H
    20 #define LEMON_SUURBALLE_H
    21 
    21 
    22 ///\ingroup shortest_path
    22 ///\ingroup shortest_path
    23 ///\file
    23 ///\file
    24 ///\brief An algorithm for finding k paths of minimal total length.
    24 ///\brief An algorithm for finding edge-disjoint paths between two
    25 
    25 /// nodes having minimum total length.
    26 
    26 
    27 #include <lemon/maps.h>
       
    28 #include <vector>
    27 #include <vector>
       
    28 #include <lemon/bin_heap.h>
    29 #include <lemon/path.h>
    29 #include <lemon/path.h>
    30 #include <lemon/ssp_min_cost_flow.h>
       
    31 
    30 
    32 namespace lemon {
    31 namespace lemon {
    33 
    32 
    34 /// \addtogroup shortest_path
    33   /// \addtogroup shortest_path
    35 /// @{
    34   /// @{
    36 
    35 
    37   ///\brief Implementation of an algorithm for finding k edge-disjoint
    36   /// \brief Implementation of an algorithm for finding edge-disjoint
    38   /// paths between 2 nodes of minimal total length
    37   /// paths between two nodes having minimum total length.
    39   ///
    38   ///
    40   /// The class \ref lemon::Suurballe implements
    39   /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
    41   /// an algorithm for finding k edge-disjoint paths
    40   /// finding edge-disjoint paths having minimum total length (cost)
    42   /// from a given source node to a given target node in an
    41   /// from a given source node to a given target node in a directed
    43   /// edge-weighted directed graph having minimal total weight (length).
    42   /// graph.
    44   ///
    43   ///
    45   ///\warning Length values should be nonnegative!
    44   /// In fact, this implementation is the specialization of the
    46   /// 
    45   /// \ref CapacityScaling "successive shortest path" algorithm.
    47   ///\param Graph The directed graph type the algorithm runs on.
    46   ///
    48   ///\param LengthMap The type of the length map (values should be nonnegative).
    47   /// \tparam Graph The directed graph type the algorithm runs on.
    49   ///
    48   /// \tparam LengthMap The type of the length (cost) map.
    50   ///\note It it questionable whether it is correct to call this method after
    49   ///
    51   ///%Suurballe for it is just a special case of Edmonds' and Karp's algorithm
    50   /// \warning Length values should be \e non-negative \e integers.
    52   ///for finding minimum cost flows. In fact, this implementation just
    51   ///
    53   ///wraps the SspMinCostFlow algorithms. The paper of both %Suurballe and
    52   /// \note For finding node-disjoint paths this algorithm can be used
    54   ///Edmonds-Karp published in 1972, therefore it is possibly right to
    53   /// with \ref SplitGraphAdaptor.
    55   ///state that they are
    54   ///
    56   ///independent results. Most frequently this special case is referred as
    55   /// \author Attila Bernath and Peter Kovacs
    57   ///%Suurballe method in the literature, especially in communication
    56   
    58   ///network context.
    57   template < typename Graph, 
    59   ///\author Attila Bernath
    58              typename LengthMap = typename Graph::template EdgeMap<int> >
    60   template <typename Graph, typename LengthMap>
    59   class Suurballe
    61   class Suurballe{
    60   {
    62 
    61     GRAPH_TYPEDEFS(typename Graph);
    63 
    62 
    64     typedef typename LengthMap::Value Length;
    63     typedef typename LengthMap::Value Length;
       
    64     typedef ConstMap<Edge, int> ConstEdgeMap;
       
    65     typedef typename Graph::template NodeMap<Edge> PredMap;
       
    66 
       
    67   public:
       
    68 
       
    69     /// The type of the flow map.
       
    70     typedef typename Graph::template EdgeMap<int> FlowMap;
       
    71     /// The type of the potential map.
       
    72     typedef typename Graph::template NodeMap<Length> PotentialMap;
       
    73     /// The type of the path structures.
       
    74     typedef SimplePath<Graph> Path;
       
    75 
       
    76   private:
       
    77   
       
    78     /// \brief Special implementation of the \ref Dijkstra algorithm
       
    79     /// for finding shortest paths in the residual network.
       
    80     ///
       
    81     /// \ref ResidualDijkstra is a special implementation of the
       
    82     /// \ref Dijkstra algorithm for finding shortest paths in the
       
    83     /// residual network of the graph with respect to the reduced edge
       
    84     /// lengths and modifying the node potentials according to the
       
    85     /// distance of the nodes.
       
    86     class ResidualDijkstra
       
    87     {
       
    88       typedef typename Graph::template NodeMap<int> HeapCrossRef;
       
    89       typedef BinHeap<Length, HeapCrossRef> Heap;
       
    90 
       
    91     private:
       
    92 
       
    93       // The directed graph the algorithm runs on
       
    94       const Graph &_graph;
       
    95 
       
    96       // The main maps
       
    97       const FlowMap &_flow;
       
    98       const LengthMap &_length;
       
    99       PotentialMap &_potential;
       
   100 
       
   101       // The distance map
       
   102       PotentialMap _dist;
       
   103       // The pred edge map
       
   104       PredMap &_pred;
       
   105       // The processed (i.e. permanently labeled) nodes
       
   106       std::vector<Node> _proc_nodes;
       
   107       
       
   108       Node _s;
       
   109       Node _t;
       
   110 
       
   111     public:
       
   112 
       
   113       /// Constructor.
       
   114       ResidualDijkstra( const Graph &graph,
       
   115                         const FlowMap &flow,
       
   116                         const LengthMap &length,
       
   117                         PotentialMap &potential,
       
   118                         PredMap &pred,
       
   119                         Node s, Node t ) :
       
   120         _graph(graph), _flow(flow), _length(length), _potential(potential),
       
   121         _dist(graph), _pred(pred), _s(s), _t(t) {}
       
   122 
       
   123       /// \brief Runs the algorithm. Returns \c true if a path is found
       
   124       /// from the source node to the target node.
       
   125       bool run() {
       
   126         HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
       
   127         Heap heap(heap_cross_ref);
       
   128         heap.push(_s, 0);
       
   129         _pred[_s] = INVALID;
       
   130         _proc_nodes.clear();
       
   131 
       
   132         // Processing nodes
       
   133         while (!heap.empty() && heap.top() != _t) {
       
   134           Node u = heap.top(), v;
       
   135           Length d = heap.prio() + _potential[u], nd;
       
   136           _dist[u] = heap.prio();
       
   137           heap.pop();
       
   138           _proc_nodes.push_back(u);
       
   139 
       
   140           // Traversing outgoing edges
       
   141           for (OutEdgeIt e(_graph, u); e != INVALID; ++e) {
       
   142             if (_flow[e] == 0) {
       
   143               v = _graph.target(e);
       
   144               switch(heap.state(v)) {
       
   145               case Heap::PRE_HEAP:
       
   146                 heap.push(v, d + _length[e] - _potential[v]);
       
   147                 _pred[v] = e;
       
   148                 break;
       
   149               case Heap::IN_HEAP:
       
   150                 nd = d + _length[e] - _potential[v];
       
   151                 if (nd < heap[v]) {
       
   152                   heap.decrease(v, nd);
       
   153                   _pred[v] = e;
       
   154                 }
       
   155                 break;
       
   156               case Heap::POST_HEAP:
       
   157                 break;
       
   158               }
       
   159             }
       
   160           }
       
   161 
       
   162           // Traversing incoming edges
       
   163           for (InEdgeIt e(_graph, u); e != INVALID; ++e) {
       
   164             if (_flow[e] == 1) {
       
   165               v = _graph.source(e);
       
   166               switch(heap.state(v)) {
       
   167               case Heap::PRE_HEAP:
       
   168                 heap.push(v, d - _length[e] - _potential[v]);
       
   169                 _pred[v] = e;
       
   170                 break;
       
   171               case Heap::IN_HEAP:
       
   172                 nd = d - _length[e] - _potential[v];
       
   173                 if (nd < heap[v]) {
       
   174                   heap.decrease(v, nd);
       
   175                   _pred[v] = e;
       
   176                 }
       
   177                 break;
       
   178               case Heap::POST_HEAP:
       
   179                 break;
       
   180               }
       
   181             }
       
   182           }
       
   183         }
       
   184         if (heap.empty()) return false;
       
   185 
       
   186         // Updating potentials of processed nodes
       
   187         Length t_dist = heap.prio();
       
   188         for (int i = 0; i < int(_proc_nodes.size()); ++i)
       
   189           _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
       
   190         return true;
       
   191       }
       
   192 
       
   193     }; //class ResidualDijkstra
       
   194 
       
   195   private:
       
   196 
       
   197     // The directed graph the algorithm runs on
       
   198     const Graph &_graph;
       
   199     // The length map
       
   200     const LengthMap &_length;
    65     
   201     
    66     typedef typename Graph::Node Node;
   202     // Edge map of the current flow
    67     typedef typename Graph::NodeIt NodeIt;
   203     FlowMap *_flow;
    68     typedef typename Graph::Edge Edge;
   204     bool _local_flow;
    69     typedef typename Graph::OutEdgeIt OutEdgeIt;
   205     // Node map of the current potentials
    70     typedef typename Graph::template EdgeMap<int> EdgeIntMap;
   206     PotentialMap *_potential;
    71 
   207     bool _local_potential;
    72     typedef ConstMap<Edge,int> ConstMap;
   208 
    73 
   209     // The source node
    74     const Graph& G;
   210     Node _source;
    75 
   211     // The target node
    76     Node s;
   212     Node _target;
    77     Node t;
   213 
    78 
   214     // Container to store the found paths
    79     //Auxiliary variables
   215     std::vector< SimplePath<Graph> > paths;
    80     //This is the capacity map for the mincostflow problem
   216     int _path_num;
    81     ConstMap const1map;
   217 
    82     //This MinCostFlow instance will actually solve the problem
   218     // The pred edge map
    83     SspMinCostFlow<Graph, LengthMap, ConstMap> min_cost_flow;
   219     PredMap _pred;
    84 
   220     // Implementation of the Dijkstra algorithm for finding augmenting
    85     //Container to store found paths
   221     // shortest paths in the residual network
    86     std::vector<SimplePath<Graph> > paths;
   222     ResidualDijkstra *_dijkstra;
    87 
   223 
    88   public :
   224   public:
    89 
   225 
    90 
   226     /// \brief Constructor.
    91     /// \brief The constructor of the class.
   227     ///
    92     ///
   228     /// Constructor.
    93     /// \param _G The directed graph the algorithm runs on. 
   229     ///
    94     /// \param _length The length (weight or cost) of the edges. 
   230     /// \param graph The directed graph the algorithm runs on.
    95     /// \param _s Source node.
   231     /// \param length The length (cost) values of the edges.
    96     /// \param _t Target node.
   232     /// \param s The source node.
    97     Suurballe(Graph& _G, LengthMap& _length, Node _s, Node _t) : 
   233     /// \param t The target node.
    98       G(_G), s(_s), t(_t), const1map(1), 
   234     Suurballe( const Graph &graph,
    99       min_cost_flow(_G, _length, const1map, _s, _t) { }
   235                const LengthMap &length,
       
   236                Node s, Node t ) :
       
   237       _graph(graph), _length(length), _flow(0), _local_flow(false),
       
   238       _potential(0), _local_potential(false), _source(s), _target(t),
       
   239       _pred(graph) {}
       
   240 
       
   241     /// Destructor.
       
   242     ~Suurballe() {
       
   243       if (_local_flow) delete _flow;
       
   244       if (_local_potential) delete _potential;
       
   245       delete _dijkstra;
       
   246     }
       
   247 
       
   248     /// \brief Sets the flow map.
       
   249     ///
       
   250     /// Sets the flow map.
       
   251     ///
       
   252     /// The found flow contains only 0 and 1 values. It is the union of
       
   253     /// the found edge-disjoint paths.
       
   254     ///
       
   255     /// \return \c (*this)
       
   256     Suurballe& flowMap(FlowMap &map) {
       
   257       if (_local_flow) {
       
   258         delete _flow;
       
   259         _local_flow = false;
       
   260       }
       
   261       _flow = &map;
       
   262       return *this;
       
   263     }
       
   264 
       
   265     /// \brief Sets the potential map.
       
   266     ///
       
   267     /// Sets the potential map.
       
   268     ///
       
   269     /// The potentials provide the dual solution of the underlying 
       
   270     /// minimum cost flow problem.
       
   271     ///
       
   272     /// \return \c (*this)
       
   273     Suurballe& potentialMap(PotentialMap &map) {
       
   274       if (_local_potential) {
       
   275         delete _potential;
       
   276         _local_potential = false;
       
   277       }
       
   278       _potential = &map;
       
   279       return *this;
       
   280     }
       
   281 
       
   282     /// \name Execution control
       
   283     /// The simplest way to execute the algorithm is to call the run()
       
   284     /// function.
       
   285     /// \n
       
   286     /// If you only need the flow that is the union of the found
       
   287     /// edge-disjoint paths, you may call init() and findFlow().
       
   288 
       
   289     /// @{
   100 
   290 
   101     /// \brief Runs the algorithm.
   291     /// \brief Runs the algorithm.
   102     ///
   292     ///
   103     /// Runs the algorithm.
   293     /// Runs the algorithm.
   104     /// Returns k if there are at least k edge-disjoint paths from s to t.
   294     ///
   105     /// Otherwise it returns the number of edge-disjoint paths found 
   295     /// \param k The number of paths to be found.
   106     /// from s to t.
   296     ///
   107     ///
   297     /// \return \c k if there are at least \c k edge-disjoint paths
   108     /// \param k How many paths are we looking for?
   298     /// from \c s to \c t. Otherwise it returns the number of
   109     ///
   299     /// edge-disjoint paths found.
   110     int run(int k) {
   300     ///
   111       int i = min_cost_flow.run(k);
   301     /// \note Apart from the return value, <tt>s.run(k)</tt> is just a
   112 
   302     /// shortcut of the following code.
   113       //Let's find the paths
   303     /// \code
   114       //We put the paths into stl vectors (as an inner representation). 
   304     ///   s.init();
   115       //In the meantime we lose the information stored in 'reversed'.
   305     ///   s.findFlow(k);
   116       //We suppose the lengths to be positive now.
   306     ///   s.findPaths();
   117 
   307     /// \endcode
   118       //We don't want to change the flow of min_cost_flow, so we make a copy
   308     int run(int k = 2) {
   119       //The name here suggests that the flow has only 0/1 values.
   309       init();
   120       EdgeIntMap reversed(G); 
   310       findFlow(k);
   121 
   311       findPaths();
   122       for(typename Graph::EdgeIt e(G); e!=INVALID; ++e) 
   312       return _path_num;
   123 	reversed[e] = min_cost_flow.getFlow()[e];
   313     }
   124       
   314 
       
   315     /// \brief Initializes the algorithm.
       
   316     ///
       
   317     /// Initializes the algorithm.
       
   318     void init() {
       
   319       // Initializing maps
       
   320       if (!_flow) {
       
   321         _flow = new FlowMap(_graph);
       
   322         _local_flow = true;
       
   323       }
       
   324       if (!_potential) {
       
   325         _potential = new PotentialMap(_graph);
       
   326         _local_potential = true;
       
   327       }
       
   328       for (EdgeIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
       
   329       for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
       
   330 
       
   331       _dijkstra = new ResidualDijkstra( _graph, *_flow, _length, 
       
   332                                         *_potential, _pred,
       
   333                                         _source, _target );
       
   334     }
       
   335 
       
   336     /// \brief Executes the successive shortest path algorithm to find
       
   337     /// an optimal flow.
       
   338     ///
       
   339     /// Executes the successive shortest path algorithm to find a
       
   340     /// minimum cost flow, which is the union of \c k or less
       
   341     /// edge-disjoint paths.
       
   342     ///
       
   343     /// \return \c k if there are at least \c k edge-disjoint paths
       
   344     /// from \c s to \c t. Otherwise it returns the number of
       
   345     /// edge-disjoint paths found.
       
   346     ///
       
   347     /// \pre \ref init() must be called before using this function.
       
   348     int findFlow(int k = 2) {
       
   349       // Finding shortest paths
       
   350       _path_num = 0;
       
   351       while (_path_num < k) {
       
   352         // Running Dijkstra
       
   353         if (!_dijkstra->run()) break;
       
   354         ++_path_num;
       
   355 
       
   356         // Setting the flow along the found shortest path
       
   357         Node u = _target;
       
   358         Edge e;
       
   359         while ((e = _pred[u]) != INVALID) {
       
   360           if (u == _graph.target(e)) {
       
   361             (*_flow)[e] = 1;
       
   362             u = _graph.source(e);
       
   363           } else {
       
   364             (*_flow)[e] = 0;
       
   365             u = _graph.target(e);
       
   366           }
       
   367         }
       
   368       }
       
   369       return _path_num;
       
   370     }
       
   371     
       
   372     /// \brief Computes the paths from the flow.
       
   373     ///
       
   374     /// Computes the paths from the flow.
       
   375     ///
       
   376     /// \pre \ref init() and \ref findFlow() must be called before using
       
   377     /// this function.
       
   378     void findPaths() {
       
   379       // Creating the residual flow map (the union of the paths not
       
   380       // found so far)
       
   381       FlowMap res_flow(*_flow);
       
   382 
   125       paths.clear();
   383       paths.clear();
   126       paths.resize(k);
   384       paths.resize(_path_num);
   127       for (int j=0; j<i; ++j){
   385       for (int i = 0; i < _path_num; ++i) {
   128 	Node n=s;
   386         Node n = _source;
   129 
   387         while (n != _target) {
   130 	while (n!=t){
   388           OutEdgeIt e(_graph, n);
   131 
   389           for ( ; res_flow[e] == 0; ++e) ;
   132 	  OutEdgeIt e(G, n);
   390           n = _graph.target(e);
   133 	  
   391           paths[i].addBack(e);
   134 	  while (!reversed[e]){
   392           res_flow[e] = 0;
   135 	    ++e;
   393         }
   136 	  }
   394       }
   137 	  n = G.target(e);
   395     }
   138 	  paths[j].addBack(e);
   396 
   139 	  reversed[e] = 1-reversed[e];
   397     /// @}
   140 	}
   398 
   141 	
   399     /// \name Query Functions
   142       }
   400     /// The result of the algorithm can be obtained using these
   143       return i;
   401     /// functions.
   144     }
   402     /// \n The algorithm should be executed before using them.
   145 
   403 
   146     
   404     /// @{
   147     /// \brief Returns the total length of the paths.
   405 
   148     ///
   406     /// \brief Returns a const reference to the edge map storing the
   149     /// This function gives back the total length of the found paths.
   407     /// found flow.
   150     Length totalLength(){
   408     ///
   151       return min_cost_flow.totalLength();
   409     /// Returns a const reference to the edge map storing the flow that
   152     }
   410     /// is the union of the found edge-disjoint paths.
   153 
   411     ///
   154     /// \brief Returns the found flow.
   412     /// \pre \ref run() or findFlow() must be called before using this
   155     ///
   413     /// function.
   156     /// This function returns a const reference to the EdgeMap \c flow.
   414     const FlowMap& flowMap() const {
   157     const EdgeIntMap &getFlow() const { return min_cost_flow.flow;}
   415       return *_flow;
   158 
   416     }
   159     /// \brief Returns the optimal dual solution
   417 
   160     ///
   418     /// \brief Returns a const reference to the node map storing the
   161     /// This function returns a const reference to the NodeMap \c
   419     /// found potentials (the dual solution).
   162     /// potential (the dual solution).
   420     ///
   163     const EdgeIntMap &getPotential() const { return min_cost_flow.potential;}
   421     /// Returns a const reference to the node map storing the found
   164 
   422     /// potentials that provide the dual solution of the underlying 
   165     /// \brief Checks whether the complementary slackness holds.
   423     /// minimum cost flow problem.
   166     ///
   424     ///
   167     /// This function checks, whether the given solution is optimal.
   425     /// \pre \ref run() or findFlow() must be called before using this
   168     /// Currently this function only checks optimality, doesn't bother
   426     /// function.
   169     /// with feasibility.  It is meant for testing purposes.
   427     const PotentialMap& potentialMap() const {
   170     bool checkComplementarySlackness(){
   428       return *_potential;
   171       return min_cost_flow.checkComplementarySlackness();
   429     }
   172     }
   430 
   173 
   431     /// \brief Returns the flow on the given edge.
   174     typedef SimplePath<Graph> Path; 
   432     ///
   175 
   433     /// Returns the flow on the given edge.
   176     /// \brief Read the found paths.
   434     /// It is \c 1 if the edge is involved in one of the found paths,
   177     ///
   435     /// otherwise it is \c 0.
   178     /// This function gives back the \c j-th path in argument p.
   436     ///
   179     /// Assumes that \c run() has been run and nothing has changed
   437     /// \pre \ref run() or findFlow() must be called before using this
   180     /// since then.
   438     /// function.
   181     ///
   439     int flow(const Edge& edge) const {
   182     /// \warning It is assumed that \c p is constructed to be a path
   440       return (*_flow)[edge];
   183     /// of graph \c G.  If \c j is not less than the result of
   441     }
   184     /// previous \c run, then the result here will be an empty path
   442 
   185     /// (\c j can be 0 as well).
   443     /// \brief Returns the potential of the given node.
   186     ///
   444     ///
   187     /// \param j Which path you want to get from the found paths (in a
   445     /// Returns the potential of the given node.
   188     /// real application you would get the found paths iteratively).
   446     ///
   189     Path path(int j) const {
   447     /// \pre \ref run() or findFlow() must be called before using this
   190       return paths[j];
   448     /// function.
   191     }
   449     Length potential(const Node& node) const {
   192 
   450       return (*_potential)[node];
   193     /// \brief Gives back the number of the paths.
   451     }
   194     ///
   452 
   195     /// Gives back the number of the constructed paths.
   453     /// \brief Returns the total length (cost) of the found paths (flow).
       
   454     ///
       
   455     /// Returns the total length (cost) of the found paths (flow).
       
   456     /// The complexity of the function is \f$ O(e) \f$.
       
   457     ///
       
   458     /// \pre \ref run() or findFlow() must be called before using this
       
   459     /// function.
       
   460     Length totalLength() const {
       
   461       Length c = 0;
       
   462       for (EdgeIt e(_graph); e != INVALID; ++e)
       
   463         c += (*_flow)[e] * _length[e];
       
   464       return c;
       
   465     }
       
   466 
       
   467     /// \brief Returns the number of the found paths.
       
   468     ///
       
   469     /// Returns the number of the found paths.
       
   470     ///
       
   471     /// \pre \ref run() or findFlow() must be called before using this
       
   472     /// function.
   196     int pathNum() const {
   473     int pathNum() const {
   197       return paths.size();
   474       return _path_num;
   198     }
   475     }
       
   476 
       
   477     /// \brief Returns a const reference to the specified path.
       
   478     ///
       
   479     /// Returns a const reference to the specified path.
       
   480     ///
       
   481     /// \param i The function returns the \c i-th path.
       
   482     /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
       
   483     ///
       
   484     /// \pre \ref run() or findPaths() must be called before using this
       
   485     /// function.
       
   486     Path path(int i) const {
       
   487       return paths[i];
       
   488     }
       
   489 
       
   490     /// @}
   199 
   491 
   200   }; //class Suurballe
   492   }; //class Suurballe
   201 
   493 
   202   ///@}
   494   ///@}
   203 
   495