34 ///\ingroup spantree |
34 ///\ingroup spantree |
35 ///\file |
35 ///\file |
36 ///\brief Kruskal's algorithm to compute a minimum cost tree |
36 ///\brief Kruskal's algorithm to compute a minimum cost tree |
37 /// |
37 /// |
38 ///Kruskal's algorithm to compute a minimum cost tree. |
38 ///Kruskal's algorithm to compute a minimum cost tree. |
|
39 /// |
|
40 ///\todo The file still needs some clean-up. |
39 |
41 |
40 namespace lemon { |
42 namespace lemon { |
41 |
43 |
42 /// \addtogroup spantree |
44 /// \addtogroup spantree |
43 /// @{ |
45 /// @{ |
44 |
46 |
45 /// Kruskal's algorithm to find a minimum cost tree of a graph. |
47 /// Kruskal's algorithm to find a minimum cost tree of a graph. |
46 |
48 |
47 /// This function runs Kruskal's algorithm to find a minimum cost tree. |
49 /// This function runs Kruskal's algorithm to find a minimum cost tree. |
|
50 /// Due to hard C++ hacking, it accepts various input and output types. |
|
51 /// |
48 /// \param g The graph the algorithm runs on. |
52 /// \param g The graph the algorithm runs on. |
49 /// It can be either \ref concept::StaticGraph "directed" or |
53 /// It can be either \ref concept::StaticGraph "directed" or |
50 /// \ref concept::UndirStaticGraph "undirected". |
54 /// \ref concept::UndirStaticGraph "undirected". |
51 /// If the graph is directed, the algorithm consider it to be |
55 /// If the graph is directed, the algorithm consider it to be |
52 /// undirected by disregarding the direction of the edges. |
56 /// undirected by disregarding the direction of the edges. |
53 /// |
57 /// |
54 /// \param in This object is used to describe the edge costs. It must |
58 /// \param in This object is used to describe the edge costs. It can be one |
55 /// be an STL compatible 'Forward Container' |
59 /// of the following choices. |
|
60 /// - An STL compatible 'Forward Container' |
56 /// with <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, |
61 /// with <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, |
57 /// where X is the type of the costs. It must contain every edge in |
62 /// where \c X is the type of the costs. The pairs indicates the edges along |
58 /// cost-ascending order. |
63 /// with the assigned cost. <em>They must be in a |
59 ///\par |
64 /// cost-ascending order.</em> |
60 /// For the sake of simplicity, there is a helper class KruskalMapInput, |
65 /// - Any readable Edge map. The values of the map indicate the edge costs. |
61 /// which converts a |
66 /// |
62 /// simple edge map to an input of this form. Alternatively, you can use |
67 /// \retval out Here we also have a choise. |
63 /// the function \ref kruskalEdgeMap to compute the minimum cost tree if |
68 /// - Is can be a writable \c bool edge map. |
64 /// the edge costs are given by an edge map. |
|
65 /// |
|
66 /// \retval out This must be a writable \c bool edge map. |
|
67 /// After running the algorithm |
69 /// After running the algorithm |
68 /// this will contain the found minimum cost spanning tree: the value of an |
70 /// this will contain the found minimum cost spanning tree: the value of an |
69 /// edge will be set to \c true if it belongs to the tree, otherwise it will |
71 /// edge will be set to \c true if it belongs to the tree, otherwise it will |
70 /// be set to \c false. The value of each edge will be set exactly once. |
72 /// be set to \c false. The value of each edge will be set exactly once. |
|
73 /// - It can also be an iteraror of an STL Container with |
|
74 /// <tt>GR::Edge</tt> as its <tt>value_type</tt>. |
|
75 /// The algorithm copies the elements of the found tree into this sequence. |
|
76 /// For example, if we know that the spanning tree of the graph \c g has |
|
77 /// say 53 edges then |
|
78 /// we can put its edges into a STL vector \c tree with a code like this. |
|
79 /// \code |
|
80 /// std::vector<Edge> tree(53); |
|
81 /// kruskal(g,cost,tree.begin()); |
|
82 /// \endcode |
|
83 /// Or if we don't know in advance the size of the tree, we can write this. |
|
84 /// \code |
|
85 /// std::vector<Edge> tree; |
|
86 /// kruskal(g,cost,std::back_inserter(tree)); |
|
87 /// \endcode |
71 /// |
88 /// |
72 /// \return The cost of the found tree. |
89 /// \return The cost of the found tree. |
73 /// |
90 /// |
74 /// \todo Discuss the case of undirected graphs: In this case the algorithm |
91 /// \todo Discuss the case of undirected graphs: In this case the algorithm |
75 /// also require <tt>Edge</tt>s instead of <tt>UndirEdge</tt>s, as some |
92 /// also require <tt>Edge</tt>s instead of <tt>UndirEdge</tt>s, as some |
76 /// people would expect. So, one should be careful not to add both of the |
93 /// people would expect. So, one should be careful not to add both of the |
77 /// <tt>Edge</tt>s belonging to a certain <tt>UndirEdge</tt>. |
94 /// <tt>Edge</tt>s belonging to a certain <tt>UndirEdge</tt>. |
78 /// (\ref kruskalEdgeMap() and \ref KruskalMapInput are kind enough to do so.) |
95 /// (\ref kruskalEdgeMap() and \ref KruskalMapInput are kind enough to do so.) |
79 |
96 |
|
97 #ifdef DOXYGEN |
80 template <class GR, class IN, class OUT> |
98 template <class GR, class IN, class OUT> |
81 typename IN::value_type::second_type |
99 typename IN::value_type::second_type |
82 kruskal(GR const& g, IN const& in, |
100 kruskal(GR const& g, IN const& in, |
83 OUT& out) |
101 OUT& out) |
|
102 #else |
|
103 template <class GR, class IN, class OUT> |
|
104 typename IN::value_type::second_type |
|
105 kruskal(GR const& g, IN const& in, |
|
106 OUT& out, |
|
107 // typename IN::value_type::first_type = typename GR::Edge() |
|
108 // ,typename OUT::Key = OUT::Key() |
|
109 // //,typename OUT::Key = typename GR::Edge() |
|
110 const typename IN::value_type::first_type * = |
|
111 (const typename IN::value_type::first_type *)(0), |
|
112 const typename OUT::Key * = (const typename OUT::Key *)(0) |
|
113 ) |
|
114 #endif |
84 { |
115 { |
85 typedef typename IN::value_type::second_type EdgeCost; |
116 typedef typename IN::value_type::second_type EdgeCost; |
86 typedef typename GR::template NodeMap<int> NodeIntMap; |
117 typedef typename GR::template NodeMap<int> NodeIntMap; |
87 typedef typename GR::Node Node; |
118 typedef typename GR::Node Node; |
88 |
119 |
131 }; |
167 }; |
132 |
168 |
133 template <class GR, class IN, class OUT> |
169 template <class GR, class IN, class OUT> |
134 inline |
170 inline |
135 typename IN::value_type::second_type |
171 typename IN::value_type::second_type |
136 kruskal(GR const& g, IN const& edges, OUT const& out_map) |
172 kruskal(GR const& g, IN const& edges, OUT const& out_map, |
|
173 // typename IN::value_type::first_type = typename GR::Edge(), |
|
174 // typename OUT::Key = GR::Edge() |
|
175 const typename IN::value_type::first_type * = |
|
176 (const typename IN::value_type::first_type *)(0), |
|
177 const typename OUT::Key * = (const typename OUT::Key *)(0) |
|
178 ) |
137 { |
179 { |
138 NonConstMapWr<OUT> map_wr(out_map); |
180 NonConstMapWr<OUT> map_wr(out_map); |
139 return kruskal(g, edges, map_wr); |
181 return kruskal(g, edges, map_wr); |
140 } |
182 } |
141 |
183 |
142 /* ** ** Input-objects ** ** */ |
184 /* ** ** Input-objects ** ** */ |
143 |
185 |
144 /// Kruskal's input source. |
186 /// Kruskal's input source. |
145 |
187 |
146 /// Kruskal's input source. |
188 /// Kruskal's input source. |
147 /// |
189 /// |
148 /// In most cases you possibly want to use the \ref kruskalEdgeMap() instead. |
190 /// In most cases you possibly want to use the \ref kruskalEdgeMap() instead. |
149 /// |
191 /// |
150 /// \sa makeKruskalMapInput() |
192 /// \sa makeKruskalMapInput() |
284 |
327 |
285 |
328 |
286 |
329 |
287 /* ** ** Wrapper funtions ** ** */ |
330 /* ** ** Wrapper funtions ** ** */ |
288 |
331 |
289 |
332 // \brief Wrapper function to kruskal(). |
290 |
333 // Input is from an edge map, output is a plain bool map. |
291 /// \brief Wrapper function to kruskal(). |
334 // |
292 /// Input is from an edge map, output is a plain bool map. |
335 // Wrapper function to kruskal(). |
293 /// |
336 // Input is from an edge map, output is a plain bool map. |
294 /// Wrapper function to kruskal(). |
337 // |
295 /// Input is from an edge map, output is a plain bool map. |
338 // \param g The type of the graph the algorithm runs on. |
296 /// |
339 // \param in An edge map containing the cost of the edges. |
297 ///\param g The type of the graph the algorithm runs on. |
340 // \par |
298 ///\param in An edge map containing the cost of the edges. |
341 // The cost type can be any type satisfying the |
299 ///\par |
342 // STL 'LessThan Comparable' |
300 ///The cost type can be any type satisfying the |
343 // concept if it also has an operator+() implemented. (It is necessary for |
301 ///STL 'LessThan Comparable' |
344 // computing the total cost of the tree). |
302 ///concept if it also has an operator+() implemented. (It is necessary for |
345 // |
303 ///computing the total cost of the tree). |
346 // \retval out This must be a writable \c bool edge map. |
304 /// |
347 // After running the algorithm |
305 /// \retval out This must be a writable \c bool edge map. |
348 // this will contain the found minimum cost spanning tree: the value of an |
306 /// After running the algorithm |
349 // edge will be set to \c true if it belongs to the tree, otherwise it will |
307 /// this will contain the found minimum cost spanning tree: the value of an |
350 // be set to \c false. The value of each edge will be set exactly once. |
308 /// edge will be set to \c true if it belongs to the tree, otherwise it will |
351 // |
309 /// be set to \c false. The value of each edge will be set exactly once. |
352 // \return The cost of the found tree. |
310 /// |
|
311 /// \return The cost of the found tree. |
|
312 |
353 |
313 template <class GR, class IN, class RET> |
354 template <class GR, class IN, class RET> |
314 inline |
355 inline |
315 typename IN::Value |
356 typename IN::Value |
316 kruskalEdgeMap(GR const& g, |
357 kruskal(GR const& g, |
317 IN const& in, |
358 IN const& in, |
318 RET &out) { |
359 RET &out, |
|
360 // typename IN::Key = typename GR::Edge(), |
|
361 //typename IN::Key = typename IN::Key (), |
|
362 // typename RET::Key = typename GR::Edge() |
|
363 const typename IN::Key * = (const typename IN::Key *)(0), |
|
364 const typename RET::Key * = (const typename RET::Key *)(0) |
|
365 ) |
|
366 { |
319 return kruskal(g, |
367 return kruskal(g, |
320 KruskalMapInput<GR,IN>(g,in), |
368 KruskalMapInput<GR,IN>(g,in), |
321 out); |
369 out); |
322 } |
370 } |
323 |
371 |
324 /// \brief Wrapper function to kruskal(). |
372 // \brief Wrapper function to kruskal(). |
325 /// Input is from an edge map, output is an STL Sequence. |
373 // Input is from an edge map, output is an STL Sequence. |
326 /// |
374 // |
327 /// Wrapper function to kruskal(). |
375 // Wrapper function to kruskal(). |
328 /// Input is from an edge map, output is an STL Sequence. |
376 // Input is from an edge map, output is an STL Sequence. |
329 /// |
377 // |
330 ///\param g The type of the graph the algorithm runs on. |
378 // \param g The type of the graph the algorithm runs on. |
331 ///\param in An edge map containing the cost of the edges. |
379 // \param in An edge map containing the cost of the edges. |
332 ///\par |
380 // \par |
333 ///The cost type can be any type satisfying the |
381 // The cost type can be any type satisfying the |
334 ///STL 'LessThan Comparable' |
382 // STL 'LessThan Comparable' |
335 ///concept if it also has an operator+() implemented. (It is necessary for |
383 // concept if it also has an operator+() implemented. (It is necessary for |
336 ///computing the total cost of the tree). |
384 // computing the total cost of the tree). |
337 /// |
385 // |
338 /// \retval out This must be an iteraror of an STL Container with |
386 // \retval out This must be an iteraror of an STL Container with |
339 /// <tt>GR::Edge</tt> as its <tt>value_type</tt>. |
387 // <tt>GR::Edge</tt> as its <tt>value_type</tt>. |
340 /// The algorithm copies the elements of the found tree into this sequence. |
388 // The algorithm copies the elements of the found tree into this sequence. |
341 /// For example, if we know that the spanning tree of the graph \c g has |
389 // For example, if we know that the spanning tree of the graph \c g has |
342 /// say 53 edges then |
390 // say 53 edges then |
343 /// we can put its edges into a STL vector \c tree with a code like this. |
391 // we can put its edges into a STL vector \c tree with a code like this. |
344 /// \code |
392 // \code |
345 /// std::vector<Edge> tree(53); |
393 // std::vector<Edge> tree(53); |
346 /// kruskalEdgeMap_IteratorOut(g,cost,tree.begin()); |
394 // kruskalEdgeMap_IteratorOut(g,cost,tree.begin()); |
347 /// \endcode |
395 // \endcode |
348 /// Or if we don't know in advance the size of the tree, we can write this. |
396 // Or if we don't know in advance the size of the tree, we can write this. |
349 /// \code |
397 // \code |
350 /// std::vector<Edge> tree; |
398 // std::vector<Edge> tree; |
351 /// kruskalEdgeMap_IteratorOut(g,cost,std::back_inserter(tree)); |
399 // kruskalEdgeMap_IteratorOut(g,cost,std::back_inserter(tree)); |
352 /// \endcode |
400 // \endcode |
353 /// |
401 // |
354 /// \return The cost of the found tree. |
402 // \return The cost of the found tree. |
355 /// |
403 // |
356 /// \bug its name does not follow the coding style. |
404 // \bug its name does not follow the coding style. |
357 |
405 |
358 template <class GR, class IN, class RET> |
406 template <class GR, class IN, class RET> |
359 inline |
407 inline |
360 typename IN::Value |
408 typename IN::Value |
361 kruskalEdgeMap_IteratorOut(const GR& g, |
409 kruskal(const GR& g, |
362 const IN& in, |
410 const IN& in, |
363 RET out) |
411 RET out, |
|
412 //,typename RET::value_type = typename GR::Edge() |
|
413 //,typename RET::value_type = typename RET::value_type() |
|
414 const typename RET::value_type * = |
|
415 (const typename RET::value_type *)(0) |
|
416 ) |
364 { |
417 { |
365 KruskalSequenceOutput<RET> _out(out); |
418 KruskalSequenceOutput<RET> _out(out); |
366 return kruskal(g, KruskalMapInput<GR,IN>(g, in), _out); |
419 return kruskal(g, KruskalMapInput<GR,IN>(g, in), _out); |
367 } |
420 } |
368 |
421 |
369 /// @} |
422 /// @} |
370 |
423 |
371 } //namespace lemon |
424 } //namespace lemon |
372 |
425 |
373 #endif //LEMON_KRUSKAL_H |
426 #endif //LEMON_KRUSKAL_H |