43 /// @{ |
43 /// @{ |
44 |
44 |
45 /// Kruskal's algorithm to find a minimum cost tree of a graph. |
45 /// Kruskal's algorithm to find a minimum cost tree of a graph. |
46 |
46 |
47 /// This function runs Kruskal's algorithm to find a minimum cost tree. |
47 /// This function runs Kruskal's algorithm to find a minimum cost tree. |
48 /// \param G The graph the algorithm runs on. The algorithm considers the |
48 /// \param g The graph the algorithm runs on. The algorithm considers the |
49 /// graph to be undirected, the direction of the edges are not used. |
49 /// graph to be undirected, the direction of the edges are not used. |
50 /// |
50 /// |
51 /// \param in This object is used to describe the edge costs. It must |
51 /// \param in This object is used to describe the edge costs. It must |
52 /// be an STL compatible 'Forward Container' |
52 /// be an STL compatible 'Forward Container' |
53 /// with <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, |
53 /// with <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, |
74 /// <tt>Edge</tt>s belonging to a certain <tt>UndirEdge</tt>. |
74 /// <tt>Edge</tt>s belonging to a certain <tt>UndirEdge</tt>. |
75 /// (\ref kruskalEdgeMap() and \ref KruskalMapInput are kind enough to do so.) |
75 /// (\ref kruskalEdgeMap() and \ref KruskalMapInput are kind enough to do so.) |
76 |
76 |
77 template <class GR, class IN, class OUT> |
77 template <class GR, class IN, class OUT> |
78 typename IN::value_type::second_type |
78 typename IN::value_type::second_type |
79 kruskal(GR const& G, IN const& in, |
79 kruskal(GR const& g, IN const& in, |
80 OUT& out) |
80 OUT& out) |
81 { |
81 { |
82 typedef typename IN::value_type::second_type EdgeCost; |
82 typedef typename IN::value_type::second_type EdgeCost; |
83 typedef typename GR::template NodeMap<int> NodeIntMap; |
83 typedef typename GR::template NodeMap<int> NodeIntMap; |
84 typedef typename GR::Node Node; |
84 typedef typename GR::Node Node; |
85 |
85 |
86 NodeIntMap comp(G, -1); |
86 NodeIntMap comp(g, -1); |
87 UnionFind<Node,NodeIntMap> uf(comp); |
87 UnionFind<Node,NodeIntMap> uf(comp); |
88 |
88 |
89 EdgeCost tot_cost = 0; |
89 EdgeCost tot_cost = 0; |
90 for (typename IN::const_iterator p = in.begin(); |
90 for (typename IN::const_iterator p = in.begin(); |
91 p!=in.end(); ++p ) { |
91 p!=in.end(); ++p ) { |
92 if ( uf.join(G.target((*p).first), |
92 if ( uf.join(g.target((*p).first), |
93 G.source((*p).first)) ) { |
93 g.source((*p).first)) ) { |
94 out.set((*p).first, true); |
94 out.set((*p).first, true); |
95 tot_cost += (*p).second; |
95 tot_cost += (*p).second; |
96 } |
96 } |
97 else { |
97 else { |
98 out.set((*p).first, false); |
98 out.set((*p).first, false); |
107 |
107 |
108 /// Helper class for calling kruskal with output maps constructed |
108 /// Helper class for calling kruskal with output maps constructed |
109 /// on-the-fly. |
109 /// on-the-fly. |
110 /// |
110 /// |
111 /// A typical examle is the following call: |
111 /// A typical examle is the following call: |
112 /// <tt>kruskal(G, some_input, makeSequenceOutput(iterator))</tt>. |
112 /// <tt>kruskal(g, some_input, makeSequenceOutput(iterator))</tt>. |
113 /// Here, the third argument is a temporary object (which wraps around an |
113 /// Here, the third argument is a temporary object (which wraps around an |
114 /// iterator with a writable bool map interface), and thus by rules of C++ |
114 /// iterator with a writable bool map interface), and thus by rules of C++ |
115 /// is a \c const object. To enable call like this exist this class and |
115 /// is a \c const object. To enable call like this exist this class and |
116 /// the prototype of the \ref kruskal() function with <tt>const& OUT</tt> |
116 /// the prototype of the \ref kruskal() function with <tt>const& OUT</tt> |
117 /// third argument. |
117 /// third argument. |
128 }; |
128 }; |
129 |
129 |
130 template <class GR, class IN, class OUT> |
130 template <class GR, class IN, class OUT> |
131 inline |
131 inline |
132 typename IN::value_type::second_type |
132 typename IN::value_type::second_type |
133 kruskal(GR const& G, IN const& edges, OUT const& out_map) |
133 kruskal(GR const& g, IN const& edges, OUT const& out_map) |
134 { |
134 { |
135 NonConstMapWr<OUT> map_wr(out_map); |
135 NonConstMapWr<OUT> map_wr(out_map); |
136 return kruskal(G, edges, map_wr); |
136 return kruskal(g, edges, map_wr); |
137 } |
137 } |
138 |
138 |
139 /* ** ** Input-objects ** ** */ |
139 /* ** ** Input-objects ** ** */ |
140 |
140 |
141 /// Kruskal's input source. |
141 /// Kruskal's input source. |
173 } |
173 } |
174 }; |
174 }; |
175 |
175 |
176 template<class _GR> |
176 template<class _GR> |
177 typename enable_if<typename _GR::UndirTag,void>::type |
177 typename enable_if<typename _GR::UndirTag,void>::type |
178 fillWithEdges(const _GR& G, const Map& m,dummy<0> = 0) |
178 fillWithEdges(const _GR& g, const Map& m,dummy<0> = 0) |
179 { |
179 { |
180 for(typename GR::UndirEdgeIt e(G);e!=INVALID;++e) |
180 for(typename GR::UndirEdgeIt e(g);e!=INVALID;++e) |
181 push_back(value_type(typename GR::Edge(e,true), m[e])); |
181 push_back(value_type(typename GR::Edge(e,true), m[e])); |
182 } |
182 } |
183 |
183 |
184 template<class _GR> |
184 template<class _GR> |
185 typename disable_if<typename _GR::UndirTag,void>::type |
185 typename disable_if<typename _GR::UndirTag,void>::type |
186 fillWithEdges(const _GR& G, const Map& m,dummy<1> = 1) |
186 fillWithEdges(const _GR& g, const Map& m,dummy<1> = 1) |
187 { |
187 { |
188 for(typename GR::EdgeIt e(G);e!=INVALID;++e) |
188 for(typename GR::EdgeIt e(g);e!=INVALID;++e) |
189 push_back(value_type(e, m[e])); |
189 push_back(value_type(e, m[e])); |
190 } |
190 } |
191 |
191 |
192 |
192 |
193 public: |
193 public: |
194 |
194 |
195 void sort() { |
195 void sort() { |
196 std::sort(this->begin(), this->end(), comparePair()); |
196 std::sort(this->begin(), this->end(), comparePair()); |
197 } |
197 } |
198 |
198 |
199 KruskalMapInput(GR const& G, Map const& m) { |
199 KruskalMapInput(GR const& g, Map const& m) { |
200 fillWithEdges(G,m); |
200 fillWithEdges(g,m); |
201 sort(); |
201 sort(); |
202 } |
202 } |
203 }; |
203 }; |
204 |
204 |
205 /// Creates a KruskalMapInput object for \ref kruskal() |
205 /// Creates a KruskalMapInput object for \ref kruskal() |
209 /// to explicitly give the type of the parameters. |
209 /// to explicitly give the type of the parameters. |
210 /// |
210 /// |
211 /// In most cases you possibly |
211 /// In most cases you possibly |
212 /// want to use the function kruskalEdgeMap() instead. |
212 /// want to use the function kruskalEdgeMap() instead. |
213 /// |
213 /// |
214 ///\param G The type of the graph the algorithm runs on. |
214 ///\param g The type of the graph the algorithm runs on. |
215 ///\param m An edge map containing the cost of the edges. |
215 ///\param m An edge map containing the cost of the edges. |
216 ///\par |
216 ///\par |
217 ///The cost type can be any type satisfying the |
217 ///The cost type can be any type satisfying the |
218 ///STL 'LessThan Comparable' |
218 ///STL 'LessThan Comparable' |
219 ///concept if it also has an operator+() implemented. (It is necessary for |
219 ///concept if it also has an operator+() implemented. (It is necessary for |
289 /// Input is from an edge map, output is a plain bool map. |
289 /// Input is from an edge map, output is a plain bool map. |
290 /// |
290 /// |
291 /// Wrapper function to kruskal(). |
291 /// Wrapper function to kruskal(). |
292 /// Input is from an edge map, output is a plain bool map. |
292 /// Input is from an edge map, output is a plain bool map. |
293 /// |
293 /// |
294 ///\param G The type of the graph the algorithm runs on. |
294 ///\param g The type of the graph the algorithm runs on. |
295 ///\param in An edge map containing the cost of the edges. |
295 ///\param in An edge map containing the cost of the edges. |
296 ///\par |
296 ///\par |
297 ///The cost type can be any type satisfying the |
297 ///The cost type can be any type satisfying the |
298 ///STL 'LessThan Comparable' |
298 ///STL 'LessThan Comparable' |
299 ///concept if it also has an operator+() implemented. (It is necessary for |
299 ///concept if it also has an operator+() implemented. (It is necessary for |
308 /// \return The cost of the found tree. |
308 /// \return The cost of the found tree. |
309 |
309 |
310 template <class GR, class IN, class RET> |
310 template <class GR, class IN, class RET> |
311 inline |
311 inline |
312 typename IN::Value |
312 typename IN::Value |
313 kruskalEdgeMap(GR const& G, |
313 kruskalEdgeMap(GR const& g, |
314 IN const& in, |
314 IN const& in, |
315 RET &out) { |
315 RET &out) { |
316 return kruskal(G, |
316 return kruskal(g, |
317 KruskalMapInput<GR,IN>(G,in), |
317 KruskalMapInput<GR,IN>(g,in), |
318 out); |
318 out); |
319 } |
319 } |
320 |
320 |
321 /// \brief Wrapper function to kruskal(). |
321 /// \brief Wrapper function to kruskal(). |
322 /// Input is from an edge map, output is an STL Sequence. |
322 /// Input is from an edge map, output is an STL Sequence. |
323 /// |
323 /// |
324 /// Wrapper function to kruskal(). |
324 /// Wrapper function to kruskal(). |
325 /// Input is from an edge map, output is an STL Sequence. |
325 /// Input is from an edge map, output is an STL Sequence. |
326 /// |
326 /// |
327 ///\param G The type of the graph the algorithm runs on. |
327 ///\param g The type of the graph the algorithm runs on. |
328 ///\param in An edge map containing the cost of the edges. |
328 ///\param in An edge map containing the cost of the edges. |
329 ///\par |
329 ///\par |
330 ///The cost type can be any type satisfying the |
330 ///The cost type can be any type satisfying the |
331 ///STL 'LessThan Comparable' |
331 ///STL 'LessThan Comparable' |
332 ///concept if it also has an operator+() implemented. (It is necessary for |
332 ///concept if it also has an operator+() implemented. (It is necessary for |
333 ///computing the total cost of the tree). |
333 ///computing the total cost of the tree). |
334 /// |
334 /// |
335 /// \retval out This must be an iteraror of an STL Container with |
335 /// \retval out This must be an iteraror of an STL Container with |
336 /// <tt>GR::Edge</tt> as its <tt>value_type</tt>. |
336 /// <tt>GR::Edge</tt> as its <tt>value_type</tt>. |
337 /// The algorithm copies the elements of the found tree into this sequence. |
337 /// The algorithm copies the elements of the found tree into this sequence. |
338 /// For example, if we know that the spanning tree of the graph \c G has |
338 /// For example, if we know that the spanning tree of the graph \c g has |
339 /// say 53 edges then |
339 /// say 53 edges then |
340 /// we can put its edges into a STL vector \c tree with a code like this. |
340 /// we can put its edges into a STL vector \c tree with a code like this. |
341 /// \code |
341 /// \code |
342 /// std::vector<Edge> tree(53); |
342 /// std::vector<Edge> tree(53); |
343 /// kruskalEdgeMap_IteratorOut(G,cost,tree.begin()); |
343 /// kruskalEdgeMap_IteratorOut(g,cost,tree.begin()); |
344 /// \endcode |
344 /// \endcode |
345 /// Or if we don't know in advance the size of the tree, we can write this. |
345 /// Or if we don't know in advance the size of the tree, we can write this. |
346 /// \code |
346 /// \code |
347 /// std::vector<Edge> tree; |
347 /// std::vector<Edge> tree; |
348 /// kruskalEdgeMap_IteratorOut(G,cost,std::back_inserter(tree)); |
348 /// kruskalEdgeMap_IteratorOut(g,cost,std::back_inserter(tree)); |
349 /// \endcode |
349 /// \endcode |
350 /// |
350 /// |
351 /// \return The cost of the found tree. |
351 /// \return The cost of the found tree. |
352 /// |
352 /// |
353 /// \bug its name does not follow the coding style. |
353 /// \bug its name does not follow the coding style. |
354 |
354 |
355 template <class GR, class IN, class RET> |
355 template <class GR, class IN, class RET> |
356 inline |
356 inline |
357 typename IN::Value |
357 typename IN::Value |
358 kruskalEdgeMap_IteratorOut(const GR& G, |
358 kruskalEdgeMap_IteratorOut(const GR& g, |
359 const IN& in, |
359 const IN& in, |
360 RET out) |
360 RET out) |
361 { |
361 { |
362 KruskalSequenceOutput<RET> _out(out); |
362 KruskalSequenceOutput<RET> _out(out); |
363 return kruskal(G, KruskalMapInput<GR,IN>(G, in), _out); |
363 return kruskal(g, KruskalMapInput<GR,IN>(g, in), _out); |
364 } |
364 } |
365 |
365 |
366 /// @} |
366 /// @} |
367 |
367 |
368 } //namespace lemon |
368 } //namespace lemon |