43 |
43 |
44 // Kruskal for directed graphs. |
44 // Kruskal for directed graphs. |
45 |
45 |
46 template <typename Digraph, typename In, typename Out> |
46 template <typename Digraph, typename In, typename Out> |
47 typename disable_if<lemon::UndirectedTagIndicator<Digraph>, |
47 typename disable_if<lemon::UndirectedTagIndicator<Digraph>, |
48 typename In::value_type::second_type >::type |
48 typename In::value_type::second_type >::type |
49 kruskal(const Digraph& digraph, const In& in, Out& out,dummy<0> = 0) { |
49 kruskal(const Digraph& digraph, const In& in, Out& out,dummy<0> = 0) { |
50 typedef typename In::value_type::second_type Value; |
50 typedef typename In::value_type::second_type Value; |
51 typedef typename Digraph::template NodeMap<int> IndexMap; |
51 typedef typename Digraph::template NodeMap<int> IndexMap; |
52 typedef typename Digraph::Node Node; |
52 typedef typename Digraph::Node Node; |
53 |
53 |
54 IndexMap index(digraph); |
54 IndexMap index(digraph); |
55 UnionFind<IndexMap> uf(index); |
55 UnionFind<IndexMap> uf(index); |
56 for (typename Digraph::NodeIt it(digraph); it != INVALID; ++it) { |
56 for (typename Digraph::NodeIt it(digraph); it != INVALID; ++it) { |
57 uf.insert(it); |
57 uf.insert(it); |
58 } |
58 } |
59 |
59 |
60 Value tree_value = 0; |
60 Value tree_value = 0; |
61 for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) { |
61 for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) { |
62 if (uf.join(digraph.target(it->first),digraph.source(it->first))) { |
62 if (uf.join(digraph.target(it->first),digraph.source(it->first))) { |
63 out.set(it->first, true); |
63 out.set(it->first, true); |
64 tree_value += it->second; |
64 tree_value += it->second; |
72 |
72 |
73 // Kruskal for undirected graphs. |
73 // Kruskal for undirected graphs. |
74 |
74 |
75 template <typename Graph, typename In, typename Out> |
75 template <typename Graph, typename In, typename Out> |
76 typename enable_if<lemon::UndirectedTagIndicator<Graph>, |
76 typename enable_if<lemon::UndirectedTagIndicator<Graph>, |
77 typename In::value_type::second_type >::type |
77 typename In::value_type::second_type >::type |
78 kruskal(const Graph& graph, const In& in, Out& out,dummy<1> = 1) { |
78 kruskal(const Graph& graph, const In& in, Out& out,dummy<1> = 1) { |
79 typedef typename In::value_type::second_type Value; |
79 typedef typename In::value_type::second_type Value; |
80 typedef typename Graph::template NodeMap<int> IndexMap; |
80 typedef typename Graph::template NodeMap<int> IndexMap; |
81 typedef typename Graph::Node Node; |
81 typedef typename Graph::Node Node; |
82 |
82 |
83 IndexMap index(graph); |
83 IndexMap index(graph); |
84 UnionFind<IndexMap> uf(index); |
84 UnionFind<IndexMap> uf(index); |
85 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) { |
85 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) { |
86 uf.insert(it); |
86 uf.insert(it); |
87 } |
87 } |
88 |
88 |
89 Value tree_value = 0; |
89 Value tree_value = 0; |
90 for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) { |
90 for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) { |
91 if (uf.join(graph.u(it->first),graph.v(it->first))) { |
91 if (uf.join(graph.u(it->first),graph.v(it->first))) { |
92 out.set(it->first, true); |
92 out.set(it->first, true); |
93 tree_value += it->second; |
93 tree_value += it->second; |
102 |
102 |
103 template <typename Sequence> |
103 template <typename Sequence> |
104 struct PairComp { |
104 struct PairComp { |
105 typedef typename Sequence::value_type Value; |
105 typedef typename Sequence::value_type Value; |
106 bool operator()(const Value& left, const Value& right) { |
106 bool operator()(const Value& left, const Value& right) { |
107 return left.second < right.second; |
107 return left.second < right.second; |
108 } |
108 } |
109 }; |
109 }; |
110 |
110 |
111 template <typename In, typename Enable = void> |
111 template <typename In, typename Enable = void> |
112 struct SequenceInputIndicator { |
112 struct SequenceInputIndicator { |
113 static const bool value = false; |
113 static const bool value = false; |
114 }; |
114 }; |
115 |
115 |
116 template <typename In> |
116 template <typename In> |
117 struct SequenceInputIndicator<In, |
117 struct SequenceInputIndicator<In, |
118 typename exists<typename In::value_type::first_type>::type> { |
118 typename exists<typename In::value_type::first_type>::type> { |
119 static const bool value = true; |
119 static const bool value = true; |
120 }; |
120 }; |
121 |
121 |
122 template <typename In, typename Enable = void> |
122 template <typename In, typename Enable = void> |
123 struct MapInputIndicator { |
123 struct MapInputIndicator { |
124 static const bool value = false; |
124 static const bool value = false; |
125 }; |
125 }; |
126 |
126 |
127 template <typename In> |
127 template <typename In> |
128 struct MapInputIndicator<In, |
128 struct MapInputIndicator<In, |
129 typename exists<typename In::Value>::type> { |
129 typename exists<typename In::Value>::type> { |
130 static const bool value = true; |
130 static const bool value = true; |
131 }; |
131 }; |
132 |
132 |
133 template <typename In, typename Enable = void> |
133 template <typename In, typename Enable = void> |
134 struct SequenceOutputIndicator { |
134 struct SequenceOutputIndicator { |
135 static const bool value = false; |
135 static const bool value = false; |
136 }; |
136 }; |
137 |
137 |
138 template <typename Out> |
138 template <typename Out> |
139 struct SequenceOutputIndicator<Out, |
139 struct SequenceOutputIndicator<Out, |
140 typename exists<typename Out::value_type>::type> { |
140 typename exists<typename Out::value_type>::type> { |
141 static const bool value = true; |
141 static const bool value = true; |
142 }; |
142 }; |
143 |
143 |
144 template <typename Out, typename Enable = void> |
144 template <typename Out, typename Enable = void> |
145 struct MapOutputIndicator { |
145 struct MapOutputIndicator { |
146 static const bool value = false; |
146 static const bool value = false; |
147 }; |
147 }; |
148 |
148 |
149 template <typename Out> |
149 template <typename Out> |
150 struct MapOutputIndicator<Out, |
150 struct MapOutputIndicator<Out, |
151 typename exists<typename Out::Value>::type> { |
151 typename exists<typename Out::Value>::type> { |
152 static const bool value = true; |
152 static const bool value = true; |
153 }; |
153 }; |
154 |
154 |
155 template <typename In, typename InEnable = void> |
155 template <typename In, typename InEnable = void> |
156 struct KruskalValueSelector {}; |
156 struct KruskalValueSelector {}; |
157 |
157 |
158 template <typename In> |
158 template <typename In> |
159 struct KruskalValueSelector<In, |
159 struct KruskalValueSelector<In, |
160 typename enable_if<SequenceInputIndicator<In>, void>::type> |
160 typename enable_if<SequenceInputIndicator<In>, void>::type> |
161 { |
161 { |
162 typedef typename In::value_type::second_type Value; |
162 typedef typename In::value_type::second_type Value; |
163 }; |
163 }; |
164 |
164 |
165 template <typename In> |
165 template <typename In> |
166 struct KruskalValueSelector<In, |
166 struct KruskalValueSelector<In, |
167 typename enable_if<MapInputIndicator<In>, void>::type> |
167 typename enable_if<MapInputIndicator<In>, void>::type> |
168 { |
168 { |
169 typedef typename In::Value Value; |
169 typedef typename In::Value Value; |
170 }; |
170 }; |
171 |
171 |
172 template <typename Graph, typename In, typename Out, |
172 template <typename Graph, typename In, typename Out, |
173 typename InEnable = void> |
173 typename InEnable = void> |
174 struct KruskalInputSelector {}; |
174 struct KruskalInputSelector {}; |
175 |
175 |
176 template <typename Graph, typename In, typename Out, |
176 template <typename Graph, typename In, typename Out, |
177 typename InEnable = void> |
177 typename InEnable = void> |
178 struct KruskalOutputSelector {}; |
178 struct KruskalOutputSelector {}; |
179 |
179 |
180 template <typename Graph, typename In, typename Out> |
180 template <typename Graph, typename In, typename Out> |
181 struct KruskalInputSelector<Graph, In, Out, |
181 struct KruskalInputSelector<Graph, In, Out, |
182 typename enable_if<SequenceInputIndicator<In>, void>::type > |
182 typename enable_if<SequenceInputIndicator<In>, void>::type > |
183 { |
183 { |
184 typedef typename In::value_type::second_type Value; |
184 typedef typename In::value_type::second_type Value; |
185 |
185 |
186 static Value kruskal(const Graph& graph, const In& in, Out& out) { |
186 static Value kruskal(const Graph& graph, const In& in, Out& out) { |
187 return KruskalOutputSelector<Graph, In, Out>:: |
187 return KruskalOutputSelector<Graph, In, Out>:: |
190 |
190 |
191 }; |
191 }; |
192 |
192 |
193 template <typename Graph, typename In, typename Out> |
193 template <typename Graph, typename In, typename Out> |
194 struct KruskalInputSelector<Graph, In, Out, |
194 struct KruskalInputSelector<Graph, In, Out, |
195 typename enable_if<MapInputIndicator<In>, void>::type > |
195 typename enable_if<MapInputIndicator<In>, void>::type > |
196 { |
196 { |
197 typedef typename In::Value Value; |
197 typedef typename In::Value Value; |
198 static Value kruskal(const Graph& graph, const In& in, Out& out) { |
198 static Value kruskal(const Graph& graph, const In& in, Out& out) { |
199 typedef typename In::Key MapArc; |
199 typedef typename In::Key MapArc; |
200 typedef typename In::Value Value; |
200 typedef typename In::Value Value; |
201 typedef typename ItemSetTraits<Graph, MapArc>::ItemIt MapArcIt; |
201 typedef typename ItemSetTraits<Graph, MapArc>::ItemIt MapArcIt; |
202 typedef std::vector<std::pair<MapArc, Value> > Sequence; |
202 typedef std::vector<std::pair<MapArc, Value> > Sequence; |
203 Sequence seq; |
203 Sequence seq; |
204 |
204 |
205 for (MapArcIt it(graph); it != INVALID; ++it) { |
205 for (MapArcIt it(graph); it != INVALID; ++it) { |
206 seq.push_back(std::make_pair(it, in[it])); |
206 seq.push_back(std::make_pair(it, in[it])); |
207 } |
207 } |
208 |
208 |
209 std::sort(seq.begin(), seq.end(), PairComp<Sequence>()); |
209 std::sort(seq.begin(), seq.end(), PairComp<Sequence>()); |
252 /// \ingroup spantree |
252 /// \ingroup spantree |
253 /// |
253 /// |
254 /// \brief Kruskal algorithm to find a minimum cost spanning tree of |
254 /// \brief Kruskal algorithm to find a minimum cost spanning tree of |
255 /// a graph. |
255 /// a graph. |
256 /// |
256 /// |
257 /// This function runs Kruskal's algorithm to find a minimum cost |
257 /// This function runs Kruskal's algorithm to find a minimum cost |
258 /// spanning tree. |
258 /// spanning tree. |
259 /// Due to some C++ hacking, it accepts various input and output types. |
259 /// Due to some C++ hacking, it accepts various input and output types. |
260 /// |
260 /// |
261 /// \param g The graph the algorithm runs on. |
261 /// \param g The graph the algorithm runs on. |
262 /// It can be either \ref concepts::Digraph "directed" or |
262 /// It can be either \ref concepts::Digraph "directed" or |
263 /// \ref concepts::Graph "undirected". |
263 /// \ref concepts::Graph "undirected". |
264 /// If the graph is directed, the algorithm consider it to be |
264 /// If the graph is directed, the algorithm consider it to be |
265 /// undirected by disregarding the direction of the arcs. |
265 /// undirected by disregarding the direction of the arcs. |
266 /// |
266 /// |
267 /// \param in This object is used to describe the arc/edge costs. |
267 /// \param in This object is used to describe the arc/edge costs. |
268 /// It can be one of the following choices. |
268 /// It can be one of the following choices. |
269 /// - An STL compatible 'Forward Container' with |
269 /// - An STL compatible 'Forward Container' with |
270 /// <tt>std::pair<GR::Arc,X></tt> or |
270 /// <tt>std::pair<GR::Arc,X></tt> or |
271 /// <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, where |
271 /// <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, where |
272 /// \c X is the type of the costs. The pairs indicates the arcs/edges |
272 /// \c X is the type of the costs. The pairs indicates the arcs/edges |
273 /// along with the assigned cost. <em>They must be in a |
273 /// along with the assigned cost. <em>They must be in a |
274 /// cost-ascending order.</em> |
274 /// cost-ascending order.</em> |
275 /// - Any readable arc/edge map. The values of the map indicate the |
275 /// - Any readable arc/edge map. The values of the map indicate the |
276 /// arc/edge costs. |
276 /// arc/edge costs. |
277 /// |
277 /// |
278 /// \retval out Here we also have a choice. |
278 /// \retval out Here we also have a choice. |
279 /// - It can be a writable \c bool arc/edge map. After running the |
279 /// - It can be a writable \c bool arc/edge map. After running the |
280 /// algorithm it will contain the found minimum cost spanning |
280 /// algorithm it will contain the found minimum cost spanning |
305 /// |
305 /// |
306 |
306 |
307 #ifdef DOXYGEN |
307 #ifdef DOXYGEN |
308 template <class Graph, class In, class Out> |
308 template <class Graph, class In, class Out> |
309 Value kruskal(GR const& g, const In& in, Out& out) |
309 Value kruskal(GR const& g, const In& in, Out& out) |
310 #else |
310 #else |
311 template <class Graph, class In, class Out> |
311 template <class Graph, class In, class Out> |
312 inline typename _kruskal_bits::KruskalValueSelector<In>::Value |
312 inline typename _kruskal_bits::KruskalValueSelector<In>::Value |
313 kruskal(const Graph& graph, const In& in, Out& out) |
313 kruskal(const Graph& graph, const In& in, Out& out) |
314 #endif |
314 #endif |
315 { |
315 { |
316 return _kruskal_bits::KruskalInputSelector<Graph, In, Out>:: |
316 return _kruskal_bits::KruskalInputSelector<Graph, In, Out>:: |
317 kruskal(graph, in, out); |
317 kruskal(graph, in, out); |
318 } |
318 } |
319 |
319 |
320 |
320 |
321 |
321 |
322 |
322 |
323 template <class Graph, class In, class Out> |
323 template <class Graph, class In, class Out> |
324 inline typename _kruskal_bits::KruskalValueSelector<In>::Value |
324 inline typename _kruskal_bits::KruskalValueSelector<In>::Value |
325 kruskal(const Graph& graph, const In& in, const Out& out) |
325 kruskal(const Graph& graph, const In& in, const Out& out) |
326 { |
326 { |
327 return _kruskal_bits::KruskalInputSelector<Graph, In, const Out>:: |
327 return _kruskal_bits::KruskalInputSelector<Graph, In, const Out>:: |
328 kruskal(graph, in, out); |
328 kruskal(graph, in, out); |
329 } |
329 } |
330 |
330 |
331 } //namespace lemon |
331 } //namespace lemon |
332 |
332 |
333 #endif //LEMON_KRUSKAL_H |
333 #endif //LEMON_KRUSKAL_H |