# HG changeset patch
# User Peter Kovacs <kpeter@inf.elte.hu>
# Date 1225231827 3600
# Node ID 613d47d29dc30cc4b2aa702eba457ece24c799d9
# Parent 39ff10276621ccdf7d74451efba324da4253b626
Minor doc improvements related to Suurballe (#47)
diff git a/lemon/suurballe.h b/lemon/suurballe.h
a

b


33  33  /// \addtogroup shortest_path 
34  34  /// @{ 
35  35  
36   /// \brief Implementation of an algorithm for finding arcdisjoint 
37   /// paths between two nodes having minimum total length. 
 36  /// \brief Algorithm for finding arcdisjoint paths between two nodes 
 37  /// having minimum total length. 
38  38  /// 
39  39  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for 
40  40  /// finding arcdisjoint paths having minimum total length (cost) 
41   /// from a given source node to a given target node in a directed 
42   /// digraph. 
 41  /// from a given source node to a given target node in a digraph. 
43  42  /// 
44  43  /// In fact, this implementation is the specialization of the 
45  44  /// \ref CapacityScaling "successive shortest path" algorithm. 
46  45  /// 
47   /// \tparam Digraph The directed digraph type the algorithm runs on. 
 46  /// \tparam Digraph The digraph type the algorithm runs on. 
 47  /// The default value is \c ListDigraph. 
48  48  /// \tparam LengthMap The type of the length (cost) map. 
 49  /// The default value is <tt>Digraph::ArcMap<int></tt>. 
49  50  /// 
50  51  /// \warning Length values should be \e nonnegative \e integers. 
51  52  /// 
52  53  /// \note For finding nodedisjoint paths this algorithm can be used 
53  54  /// with \ref SplitDigraphAdaptor. 
54   /// 
55   /// \author Attila Bernath and Peter Kovacs 
56   
57   template < typename Digraph, 
 55  #ifdef DOXYGEN 
 56  template <typename Digraph, typename LengthMap> 
 57  #else 
 58  template < typename Digraph = ListDigraph, 
58  59  typename LengthMap = typename Digraph::template ArcMap<int> > 
 60  #endif 
59  61  class Suurballe 
60  62  { 
61  63  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); 
… 
… 

75  77  
76  78  private: 
77  79  
78   /// \brief Special implementation of the \ref Dijkstra algorithm 
 80  /// \brief Special implementation of the Dijkstra algorithm 
79  81  /// for finding shortest paths in the residual network. 
80  82  /// 
81  83  /// \ref ResidualDijkstra is a special implementation of the 
… 
… 

90  92  
91  93  private: 
92  94  
93   // The directed digraph the algorithm runs on 
 95  // The digraph the algorithm runs on 
94  96  const Digraph &_graph; 
95  97  
96  98  // The main maps 
… 
… 

120  122  _graph(digraph), _flow(flow), _length(length), _potential(potential), 
121  123  _dist(digraph), _pred(pred), _s(s), _t(t) {} 
122  124  
123   /// \brief Runs the algorithm. Returns \c true if a path is found 
 125  /// \brief Run the algorithm. It returns \c true if a path is found 
124  126  /// from the source node to the target node. 
125  127  bool run() { 
126  128  HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP); 
… 
… 

129  131  _pred[_s] = INVALID; 
130  132  _proc_nodes.clear(); 
131  133  
132   // Processing nodes 
 134  // Process nodes 
133  135  while (!heap.empty() && heap.top() != _t) { 
134  136  Node u = heap.top(), v; 
135  137  Length d = heap.prio() + _potential[u], nd; 
… 
… 

137  139  heap.pop(); 
138  140  _proc_nodes.push_back(u); 
139  141  
140   // Traversing outgoing arcs 
 142  // Traverse outgoing arcs 
141  143  for (OutArcIt e(_graph, u); e != INVALID; ++e) { 
142  144  if (_flow[e] == 0) { 
143  145  v = _graph.target(e); 
… 
… 

159  161  } 
160  162  } 
161  163  
162   // Traversing incoming arcs 
 164  // Traverse incoming arcs 
163  165  for (InArcIt e(_graph, u); e != INVALID; ++e) { 
164  166  if (_flow[e] == 1) { 
165  167  v = _graph.source(e); 
… 
… 

183  185  } 
184  186  if (heap.empty()) return false; 
185  187  
186   // Updating potentials of processed nodes 
 188  // Update potentials of processed nodes 
187  189  Length t_dist = heap.prio(); 
188  190  for (int i = 0; i < int(_proc_nodes.size()); ++i) 
189  191  _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]]  t_dist; 
… 
… 

194  196  
195  197  private: 
196  198  
197   // The directed digraph the algorithm runs on 
 199  // The digraph the algorithm runs on 
198  200  const Digraph &_graph; 
199  201  // The length map 
200  202  const LengthMap &_length; 
… 
… 

227  229  /// 
228  230  /// Constructor. 
229  231  /// 
230   /// \param digraph The directed digraph the algorithm runs on. 
 232  /// \param digraph The digraph the algorithm runs on. 
231  233  /// \param length The length (cost) values of the arcs. 
232  234  /// \param s The source node. 
233  235  /// \param t The target node. 
… 
… 

245  247  delete _dijkstra; 
246  248  } 
247  249  
248   /// \brief Sets the flow map. 
 250  /// \brief Set the flow map. 
249  251  /// 
250   /// Sets the flow map. 
 252  /// This function sets the flow map. 
251  253  /// 
252  254  /// The found flow contains only 0 and 1 values. It is the union of 
253  255  /// the found arcdisjoint paths. 
… 
… 

262  264  return *this; 
263  265  } 
264  266  
265   /// \brief Sets the potential map. 
 267  /// \brief Set the potential map. 
266  268  /// 
267   /// Sets the potential map. 
 269  /// This function sets the potential map. 
268  270  /// 
269  271  /// The potentials provide the dual solution of the underlying 
270  272  /// minimum cost flow problem. 
… 
… 

288  290  
289  291  /// @{ 
290  292  
291   /// \brief Runs the algorithm. 
 293  /// \brief Run the algorithm. 
292  294  /// 
293   /// Runs the algorithm. 
 295  /// This function runs the algorithm. 
294  296  /// 
295  297  /// \param k The number of paths to be found. 
296  298  /// 
297   /// \return \c k if there are at least \c k arcdisjoint paths 
298   /// from \c s to \c t. Otherwise it returns the number of 
 299  /// \return \c k if there are at least \c k arcdisjoint paths from 
 300  /// \c s to \c t in the digraph. Otherwise it returns the number of 
299  301  /// arcdisjoint paths found. 
300  302  /// 
301  303  /// \note Apart from the return value, <tt>s.run(k)</tt> is just a 
… 
… 

312  314  return _path_num; 
313  315  } 
314  316  
315   /// \brief Initializes the algorithm. 
 317  /// \brief Initialize the algorithm. 
316  318  /// 
317   /// Initializes the algorithm. 
 319  /// This function initializes the algorithm. 
318  320  void init() { 
319   // Initializing maps 
 321  // Initialize maps 
320  322  if (!_flow) { 
321  323  _flow = new FlowMap(_graph); 
322  324  _local_flow = true; 
… 
… 

333  335  _source, _target ); 
334  336  } 
335  337  
336   /// \brief Executes the successive shortest path algorithm to find 
 338  /// \brief Execute the successive shortest path algorithm to find 
337  339  /// an optimal flow. 
338  340  /// 
339   /// Executes the successive shortest path algorithm to find a 
340   /// minimum cost flow, which is the union of \c k or less 
 341  /// This function executes the successive shortest path algorithm to 
 342  /// find a minimum cost flow, which is the union of \c k or less 
341  343  /// arcdisjoint paths. 
342  344  /// 
343   /// \return \c k if there are at least \c k arcdisjoint paths 
344   /// from \c s to \c t. Otherwise it returns the number of 
 345  /// \return \c k if there are at least \c k arcdisjoint paths from 
 346  /// \c s to \c t in the digraph. Otherwise it returns the number of 
345  347  /// arcdisjoint paths found. 
346  348  /// 
347  349  /// \pre \ref init() must be called before using this function. 
348  350  int findFlow(int k = 2) { 
349   // Finding shortest paths 
 351  // Find shortest paths 
350  352  _path_num = 0; 
351  353  while (_path_num < k) { 
352   // Running Dijkstra 
 354  // Run Dijkstra 
353  355  if (!_dijkstra>run()) break; 
354  356  ++_path_num; 
355  357  
356   // Setting the flow along the found shortest path 
 358  // Set the flow along the found shortest path 
357  359  Node u = _target; 
358  360  Arc e; 
359  361  while ((e = _pred[u]) != INVALID) { 
… 
… 

369  371  return _path_num; 
370  372  } 
371  373  
372   /// \brief Computes the paths from the flow. 
 374  /// \brief Compute the paths from the flow. 
373  375  /// 
374   /// Computes the paths from the flow. 
 376  /// This function computes the paths from the flow. 
375  377  /// 
376  378  /// \pre \ref init() and \ref findFlow() must be called before using 
377  379  /// this function. 
378  380  void findPaths() { 
379   // Creating the residual flow map (the union of the paths not 
380   // found so far) 
 381  // Create the residual flow map (the union of the paths not found 
 382  // so far) 
381  383  FlowMap res_flow(_graph); 
382   for(ArcIt a(_graph);a!=INVALID;++a) res_flow[a]=(*_flow)[a]; 
 384  for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a]; 
383  385  
384  386  paths.clear(); 
385  387  paths.resize(_path_num); 
… 
… 

398  400  /// @} 
399  401  
400  402  /// \name Query Functions 
401   /// The result of the algorithm can be obtained using these 
 403  /// The results of the algorithm can be obtained using these 
402  404  /// functions. 
403  405  /// \n The algorithm should be executed before using them. 
404  406  
405  407  /// @{ 
406  408  
407   /// \brief Returns a const reference to the arc map storing the 
 409  /// \brief Return a const reference to the arc map storing the 
408  410  /// found flow. 
409  411  /// 
410   /// Returns a const reference to the arc map storing the flow that 
411   /// is the union of the found arcdisjoint paths. 
 412  /// This function returns a const reference to the arc map storing 
 413  /// the flow that is the union of the found arcdisjoint paths. 
412  414  /// 
413   /// \pre \ref run() or findFlow() must be called before using this 
414   /// function. 
 415  /// \pre \ref run() or \ref findFlow() must be called before using 
 416  /// this function. 
415  417  const FlowMap& flowMap() const { 
416  418  return *_flow; 
417  419  } 
418  420  
419   /// \brief Returns a const reference to the node map storing the 
 421  /// \brief Return a const reference to the node map storing the 
420  422  /// found potentials (the dual solution). 
421  423  /// 
422   /// Returns a const reference to the node map storing the found 
423   /// potentials that provide the dual solution of the underlying 
424   /// minimum cost flow problem. 
 424  /// This function returns a const reference to the node map storing 
 425  /// the found potentials that provide the dual solution of the 
 426  /// underlying minimum cost flow problem. 
425  427  /// 
426   /// \pre \ref run() or findFlow() must be called before using this 
427   /// function. 
 428  /// \pre \ref run() or \ref findFlow() must be called before using 
 429  /// this function. 
428  430  const PotentialMap& potentialMap() const { 
429  431  return *_potential; 
430  432  } 
431  433  
432   /// \brief Returns the flow on the given arc. 
 434  /// \brief Return the flow on the given arc. 
433  435  /// 
434   /// Returns the flow on the given arc. 
 436  /// This function returns the flow on the given arc. 
435  437  /// It is \c 1 if the arc is involved in one of the found paths, 
436  438  /// otherwise it is \c 0. 
437  439  /// 
438   /// \pre \ref run() or findFlow() must be called before using this 
439   /// function. 
 440  /// \pre \ref run() or \ref findFlow() must be called before using 
 441  /// this function. 
440  442  int flow(const Arc& arc) const { 
441  443  return (*_flow)[arc]; 
442  444  } 
443  445  
444   /// \brief Returns the potential of the given node. 
 446  /// \brief Return the potential of the given node. 
445  447  /// 
446   /// Returns the potential of the given node. 
 448  /// This function returns the potential of the given node. 
447  449  /// 
448   /// \pre \ref run() or findFlow() must be called before using this 
449   /// function. 
 450  /// \pre \ref run() or \ref findFlow() must be called before using 
 451  /// this function. 
450  452  Length potential(const Node& node) const { 
451  453  return (*_potential)[node]; 
452  454  } 
453  455  
454   /// \brief Returns the total length (cost) of the found paths (flow). 
 456  /// \brief Return the total length (cost) of the found paths (flow). 
455  457  /// 
456   /// Returns the total length (cost) of the found paths (flow). 
457   /// The complexity of the function is \f$ O(e) \f$. 
 458  /// This function returns the total length (cost) of the found paths 
 459  /// (flow). The complexity of the function is \f$ O(e) \f$. 
458  460  /// 
459   /// \pre \ref run() or findFlow() must be called before using this 
460   /// function. 
 461  /// \pre \ref run() or \ref findFlow() must be called before using 
 462  /// this function. 
461  463  Length totalLength() const { 
462  464  Length c = 0; 
463  465  for (ArcIt e(_graph); e != INVALID; ++e) 
… 
… 

465  467  return c; 
466  468  } 
467  469  
468   /// \brief Returns the number of the found paths. 
 470  /// \brief Return the number of the found paths. 
469  471  /// 
470   /// Returns the number of the found paths. 
 472  /// This function returns the number of the found paths. 
471  473  /// 
472   /// \pre \ref run() or findFlow() must be called before using this 
473   /// function. 
 474  /// \pre \ref run() or \ref findFlow() must be called before using 
 475  /// this function. 
474  476  int pathNum() const { 
475  477  return _path_num; 
476  478  } 
477  479  
478   /// \brief Returns a const reference to the specified path. 
 480  /// \brief Return a const reference to the specified path. 
479  481  /// 
480   /// Returns a const reference to the specified path. 
 482  /// This function returns a const reference to the specified path. 
481  483  /// 
482  484  /// \param i The function returns the \c ith path. 
483  485  /// \c i must be between \c 0 and <tt>%pathNum()1</tt>. 
484  486  /// 
485   /// \pre \ref run() or findPaths() must be called before using this 
486   /// function. 
 487  /// \pre \ref run() or \ref findPaths() must be called before using 
 488  /// this function. 
487  489  Path path(int i) const { 
488  490  return paths[i]; 
489  491  } 
diff git a/test/suurballe_test.cc b/test/suurballe_test.cc
a

b


28  28  
29  29  using namespace lemon; 
30  30  
31   // Checks the feasibility of the flow 
 31  // Check the feasibility of the flow 
32  32  template <typename Digraph, typename FlowMap> 
33  33  bool checkFlow( const Digraph& gr, const FlowMap& flow, 
34  34  typename Digraph::Node s, typename Digraph::Node t, 
… 
… 

52  52  return true; 
53  53  } 
54  54  
55   // Checks the optimalitiy of the flow 
 55  // Check the optimalitiy of the flow 
56  56  template < typename Digraph, typename CostMap, 
57  57  typename FlowMap, typename PotentialMap > 
58  58  bool checkOptimality( const Digraph& gr, const CostMap& cost, 
59  59  const FlowMap& flow, const PotentialMap& pi ) 
60  60  { 
61   // Checking the Complementary Slackness optimality condition 
 61  // Check the "Complementary Slackness" optimality condition 
62  62  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); 
63  63  bool opt = true; 
64  64  for (ArcIt e(gr); e != INVALID; ++e) { 
… 
… 

71  71  return opt; 
72  72  } 
73  73  
74   // Checks a path 
75   template < typename Digraph, typename Path > 
 74  // Check a path 
 75  template <typename Digraph, typename Path> 
76  76  bool checkPath( const Digraph& gr, const Path& path, 
77  77  typename Digraph::Node s, typename Digraph::Node t) 
78  78  { 
79   // Checking the Complementary Slackness optimality condition 
 79  // Check the "Complementary Slackness" optimality condition 
80  80  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph); 
81  81  Node n = s; 
82  82  for (int i = 0; i < path.length(); ++i) { 
… 
… 

91  91  { 
92  92  DIGRAPH_TYPEDEFS(ListDigraph); 
93  93  
94   // Reading the test digraph 
 94  // Read the test digraph 
95  95  ListDigraph digraph; 
96  96  ListDigraph::ArcMap<int> length(digraph); 
97  97  Node source, target; 
… 
… 

111  111  run(); 
112  112  input.close(); 
113  113  
114   // Finding 2 paths 
 114  // Find 2 paths 
115  115  { 
116  116  Suurballe<ListDigraph> suurballe(digraph, length, source, target); 
117  117  check(suurballe.run(2) == 2, "Wrong number of paths"); 
… 
… 

126  126  "Wrong path"); 
127  127  } 
128  128  
129   // Finding 3 paths 
 129  // Find 3 paths 
130  130  { 
131  131  Suurballe<ListDigraph> suurballe(digraph, length, source, target); 
132  132  check(suurballe.run(3) == 3, "Wrong number of paths"); 
… 
… 

141  141  "Wrong path"); 
142  142  } 
143  143  
144   // Finding 5 paths (only 3 can be found) 
 144  // Find 5 paths (only 3 can be found) 
145  145  { 
146  146  Suurballe<ListDigraph> suurballe(digraph, length, source, target); 
147  147  check(suurballe.run(5) == 3, "Wrong number of paths"); 