32 /// \param G The graph the algorithm runs on. The algorithm considers the |
33 /// \param G The graph the algorithm runs on. The algorithm considers the |
33 /// graph to be undirected, the direction of the edges are not used. |
34 /// graph to be undirected, the direction of the edges are not used. |
34 /// |
35 /// |
35 /// \param in This object is used to describe the edge costs. It must |
36 /// \param in This object is used to describe the edge costs. It must |
36 /// be an STL compatible 'Forward Container' |
37 /// be an STL compatible 'Forward Container' |
37 /// with <tt>std::pair<Graph::Edge,X></tt> as its <tt>value_type</tt>, |
38 /// with <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, |
38 /// where X is the type of the costs. It must contain every edge in |
39 /// where X is the type of the costs. It must contain every edge in |
39 /// cost-ascending order. |
40 /// cost-ascending order. |
40 ///\par |
41 ///\par |
41 /// For the sake of simplicity, there is a helper class KruskalMapInput, |
42 /// For the sake of simplicity, there is a helper class KruskalMapInput, |
42 /// which converts a |
43 /// which converts a |
50 /// edge will be set to \c true if it belongs to the tree, otherwise it will |
51 /// edge will be set to \c true if it belongs to the tree, otherwise it will |
51 /// be set to \c false. The value of each edge will be set exactly once. |
52 /// be set to \c false. The value of each edge will be set exactly once. |
52 /// |
53 /// |
53 /// \return The cost of the found tree. |
54 /// \return The cost of the found tree. |
54 |
55 |
55 template <typename Graph, typename InputEdgeOrder, typename OutBoolMap> |
56 template <class GR, class IN, class OUT> |
56 typename InputEdgeOrder::value_type::second_type |
57 typename IN::value_type::second_type |
57 kruskal(Graph const& G, InputEdgeOrder const& in, |
58 kruskal(GR const& G, IN const& in, |
58 OutBoolMap& out) |
59 OUT& out) |
59 { |
60 { |
60 typedef typename InputEdgeOrder::value_type::second_type EdgeCost; |
61 typedef typename IN::value_type::second_type EdgeCost; |
61 typedef typename Graph::template NodeMap<int> NodeIntMap; |
62 typedef typename GR::template NodeMap<int> NodeIntMap; |
62 typedef typename Graph::Node Node; |
63 typedef typename GR::Node Node; |
63 |
64 |
64 NodeIntMap comp(G, -1); |
65 NodeIntMap comp(G, -1); |
65 UnionFind<Node,NodeIntMap> uf(comp); |
66 UnionFind<Node,NodeIntMap> uf(comp); |
66 |
67 |
67 EdgeCost tot_cost = 0; |
68 EdgeCost tot_cost = 0; |
68 for (typename InputEdgeOrder::const_iterator p = in.begin(); |
69 for (typename IN::const_iterator p = in.begin(); |
69 p!=in.end(); ++p ) { |
70 p!=in.end(); ++p ) { |
70 if ( uf.join(G.head((*p).first), |
71 if ( uf.join(G.head((*p).first), |
71 G.tail((*p).first)) ) { |
72 G.tail((*p).first)) ) { |
72 out.set((*p).first, true); |
73 out.set((*p).first, true); |
73 tot_cost += (*p).second; |
74 tot_cost += (*p).second; |
81 |
82 |
82 /* A work-around for running Kruskal with const-reference bool maps... */ |
83 /* A work-around for running Kruskal with const-reference bool maps... */ |
83 |
84 |
84 ///\bug What is this? Or why doesn't it work? |
85 ///\bug What is this? Or why doesn't it work? |
85 /// |
86 /// |
86 template<typename Map> |
87 template<class Map> |
87 class NonConstMapWr { |
88 class NonConstMapWr { |
88 const Map &m; |
89 const Map &m; |
89 public: |
90 public: |
90 typedef typename Map::ValueType ValueType; |
91 typedef typename Map::ValueType ValueType; |
91 |
92 |
92 NonConstMapWr(const Map &_m) : m(_m) {} |
93 NonConstMapWr(const Map &_m) : m(_m) {} |
93 |
94 |
94 template<typename KeyType> |
95 template<class KeyType> |
95 void set(KeyType const& k, ValueType const &v) const { m.set(k,v); } |
96 void set(KeyType const& k, ValueType const &v) const { m.set(k,v); } |
96 }; |
97 }; |
97 |
98 |
98 template <typename Graph, typename InputEdgeOrder, typename OutBoolMap> |
99 template <class GR, class IN, class OUT> |
99 inline |
100 inline |
100 typename InputEdgeOrder::ValueType |
101 typename IN::ValueType |
101 kruskal(Graph const& G, InputEdgeOrder const& edges, |
102 kruskal(GR const& G, IN const& edges, |
102 OutBoolMap const& out_map) |
103 OUT const& out_map) |
103 { |
104 { |
104 NonConstMapWr<OutBoolMap> map_wr(out_map); |
105 NonConstMapWr<OUT> map_wr(out_map); |
105 return kruskal(G, edges, map_wr); |
106 return kruskal(G, edges, map_wr); |
106 } |
107 } |
107 |
108 |
108 /* ** ** Input-objects ** ** */ |
109 /* ** ** Input-objects ** ** */ |
109 |
110 |
113 /// |
114 /// |
114 /// In most cases you possibly want to use the \ref kruskalEdgeMap() instead. |
115 /// In most cases you possibly want to use the \ref kruskalEdgeMap() instead. |
115 /// |
116 /// |
116 /// \sa makeKruskalMapInput() |
117 /// \sa makeKruskalMapInput() |
117 /// |
118 /// |
118 ///\param Graph The type of the graph the algorithm runs on. |
119 ///\param GR The type of the graph the algorithm runs on. |
119 ///\param Map An edge map containing the cost of the edges. |
120 ///\param Map An edge map containing the cost of the edges. |
120 ///\par |
121 ///\par |
121 ///The cost type can be any type satisfying |
122 ///The cost type can be any type satisfying |
122 ///the STL 'LessThan comparable' |
123 ///the STL 'LessThan comparable' |
123 ///concept if it also has an operator+() implemented. (It is necessary for |
124 ///concept if it also has an operator+() implemented. (It is necessary for |
124 ///computing the total cost of the tree). |
125 ///computing the total cost of the tree). |
125 /// |
126 /// |
126 template<typename Graph, typename Map> |
127 template<class GR, class Map> |
127 class KruskalMapInput |
128 class KruskalMapInput |
128 : public std::vector< std::pair<typename Graph::Edge, |
129 : public std::vector< std::pair<typename GR::Edge, |
129 typename Map::ValueType> > { |
130 typename Map::ValueType> > { |
130 |
131 |
131 public: |
132 public: |
132 typedef std::vector< std::pair<typename Graph::Edge, |
133 typedef std::vector< std::pair<typename GR::Edge, |
133 typename Map::ValueType> > Parent; |
134 typename Map::ValueType> > Parent; |
134 typedef typename Parent::value_type value_type; |
135 typedef typename Parent::value_type value_type; |
135 |
136 |
136 private: |
137 private: |
137 class comparePair { |
138 class comparePair { |
146 |
147 |
147 void sort() { |
148 void sort() { |
148 std::sort(this->begin(), this->end(), comparePair()); |
149 std::sort(this->begin(), this->end(), comparePair()); |
149 } |
150 } |
150 |
151 |
151 KruskalMapInput(Graph const& G, Map const& m) { |
152 KruskalMapInput(GR const& G, Map const& m) { |
152 typedef typename Graph::EdgeIt EdgeIt; |
153 typedef typename GR::EdgeIt EdgeIt; |
153 |
154 |
154 this->clear(); |
155 this->clear(); |
155 for(EdgeIt e(G);e!=INVALID;++e) push_back(make_pair(e, m[e])); |
156 for(EdgeIt e(G);e!=INVALID;++e) push_back(make_pair(e, m[e])); |
156 sort(); |
157 sort(); |
157 } |
158 } |
174 ///concept if it also has an operator+() implemented. (It is necessary for |
175 ///concept if it also has an operator+() implemented. (It is necessary for |
175 ///computing the total cost of the tree). |
176 ///computing the total cost of the tree). |
176 /// |
177 /// |
177 ///\return An appropriate input source for \ref kruskal(). |
178 ///\return An appropriate input source for \ref kruskal(). |
178 /// |
179 /// |
179 template<typename Graph, typename Map> |
180 template<class GR, class Map> |
180 inline |
181 inline |
181 KruskalMapInput<Graph,Map> makeKruskalMapInput(const Graph &G,const Map &m) |
182 KruskalMapInput<GR,Map> makeKruskalMapInput(const GR &G,const Map &m) |
182 { |
183 { |
183 return KruskalMapInput<Graph,Map>(G,m); |
184 return KruskalMapInput<GR,Map>(G,m); |
184 } |
185 } |
185 |
186 |
186 |
187 |
187 /* ** ** Output-objects: simple writable bool maps** ** */ |
188 /* ** ** Output-objects: simple writable bool maps** ** */ |
188 |
189 |
192 /// the value "true". |
193 /// the value "true". |
193 /// \warning Not a regular property map, as it doesn't know its KeyType |
194 /// \warning Not a regular property map, as it doesn't know its KeyType |
194 /// \bug Missing documentation. |
195 /// \bug Missing documentation. |
195 /// \todo This class may be of wider usage, therefore it could move to |
196 /// \todo This class may be of wider usage, therefore it could move to |
196 /// <tt>maps.h</tt> |
197 /// <tt>maps.h</tt> |
197 template<typename Iterator> |
198 template<class Iterator> |
198 class SequenceOutput { |
199 class SequenceOutput { |
199 mutable Iterator it; |
200 mutable Iterator it; |
200 |
201 |
201 public: |
202 public: |
202 typedef bool ValueType; |
203 typedef bool ValueType; |
205 |
206 |
206 template<typename KeyType> |
207 template<typename KeyType> |
207 void set(KeyType const& k, bool v) const { if(v) {*it=k; ++it;} } |
208 void set(KeyType const& k, bool v) const { if(v) {*it=k; ++it;} } |
208 }; |
209 }; |
209 |
210 |
210 template<typename Iterator> |
211 template<class Iterator> |
211 inline |
212 inline |
212 SequenceOutput<Iterator> |
213 SequenceOutput<Iterator> |
213 makeSequenceOutput(Iterator it) { |
214 makeSequenceOutput(Iterator it) { |
214 return SequenceOutput<Iterator>(it); |
215 return SequenceOutput<Iterator>(it); |
215 } |
216 } |
238 /// be set to \c false. The value of each edge will be set exactly once. |
239 /// be set to \c false. The value of each edge will be set exactly once. |
239 /// |
240 /// |
240 /// \return The cost of the found tree. |
241 /// \return The cost of the found tree. |
241 |
242 |
242 |
243 |
243 template <typename Graph, typename EdgeCostMap, typename RetEdgeBoolMap> |
244 template <class GR, class IN, class RET> |
244 inline |
245 inline |
245 typename EdgeCostMap::ValueType |
246 typename IN::ValueType |
246 kruskalEdgeMap(Graph const& G, |
247 kruskalEdgeMap(GR const& G, |
247 EdgeCostMap const& in, |
248 IN const& in, |
248 RetEdgeBoolMap &out) { |
249 RET &out) { |
249 return kruskal(G, |
250 return kruskal(G, |
250 KruskalMapInput<Graph,EdgeCostMap>(G,in), |
251 KruskalMapInput<GR,IN>(G,in), |
251 out); |
252 out); |
252 } |
253 } |
253 |
254 |
254 /// \brief Wrapper function to kruskal(). |
255 /// \brief Wrapper function to kruskal(). |
255 /// Input is from an edge map, output is an STL Sequence. |
256 /// Input is from an edge map, output is an STL Sequence. |
264 ///STL 'LessThan Comparable' |
265 ///STL 'LessThan Comparable' |
265 ///concept if it also has an operator+() implemented. (It is necessary for |
266 ///concept if it also has an operator+() implemented. (It is necessary for |
266 ///computing the total cost of the tree). |
267 ///computing the total cost of the tree). |
267 /// |
268 /// |
268 /// \retval out This must be an iteraror of an STL Container with |
269 /// \retval out This must be an iteraror of an STL Container with |
269 /// <tt>Graph::Edge</tt> as its <tt>value_type</tt>. |
270 /// <tt>GR::Edge</tt> as its <tt>value_type</tt>. |
270 /// The algorithm copies the elements of the found tree into this sequence. |
271 /// The algorithm copies the elements of the found tree into this sequence. |
271 /// For example, if we know that the spanning tree of the graph \c G has |
272 /// For example, if we know that the spanning tree of the graph \c G has |
272 /// say 53 edges then |
273 /// say 53 edges then |
273 /// we can put its edges into a vector \c tree with a code like this. |
274 /// we can put its edges into a STL vector \c tree with a code like this. |
274 /// \code |
275 /// \code |
275 /// std::vector<Edge> tree(53); |
276 /// std::vector<Edge> tree(53); |
276 /// kruskalEdgeMap_IteratorOut(G,cost,tree.begin()); |
277 /// kruskalEdgeMap_IteratorOut(G,cost,tree.begin()); |
277 /// \endcode |
278 /// \endcode |
278 /// Or if we don't know in advance the size of the tree, we can write this. |
279 /// Or if we don't know in advance the size of the tree, we can write this. |
282 /// \endcode |
283 /// \endcode |
283 /// |
284 /// |
284 /// \return The cost of the found tree. |
285 /// \return The cost of the found tree. |
285 /// |
286 /// |
286 /// \bug its name does not follow the coding style. |
287 /// \bug its name does not follow the coding style. |
287 template <typename Graph, typename EdgeCostMap, typename RetIterator> |
288 template <class GR, class IN, class RET> |
288 inline |
289 inline |
289 typename EdgeCostMap::ValueType |
290 typename IN::ValueType |
290 kruskalEdgeMap_IteratorOut(const Graph& G, |
291 kruskalEdgeMap_IteratorOut(const GR& G, |
291 const EdgeCostMap& in, |
292 const IN& in, |
292 RetIterator out) |
293 RET out) |
293 { |
294 { |
294 SequenceOutput<RetIterator> _out(out); |
295 SequenceOutput<RET> _out(out); |
295 return kruskal(G, |
296 return kruskal(G, |
296 KruskalMapInput<Graph, EdgeCostMap>(G, in), |
297 KruskalMapInput<GR,IN>(G, in), |
297 _out); |
298 _out); |
298 } |
299 } |
299 |
300 |
300 /// @} |
301 /// @} |
301 |
302 |