6 #include <hugo/unionfind.h>
9 @defgroup spantree Minimum Cost Spanning Tree Algorithms
10 \brief This group containes the algorithms for finding a minimum cost spanning
17 ///\brief Kruskal's algorithm to compute a minimum cost tree
21 /// \addtogroup spantree
24 /// Kruskal's algorithm to find a minimum cost tree of a graph.
26 /// This function runs Kruskal's algorithm to find a minimum cost tree.
27 /// \param G The graph the algorithm runs on.
28 /// \param in This object is used to describe the edge costs. It must
29 /// be an STL 'forward container'
30 /// with value_type <tt> std::pair<Graph::Edge,X> </tt>,
31 /// where X is the type of the costs. It must contain every edge in
32 /// cost-ascending order.
33 /// \retval out This must be a writeable EdgeMap. After running the algorithm
34 /// this will contain the found minimum cost spanning tree: the value of an
35 /// edge will be set to \c true if it belongs to the tree, otherwise it will
36 /// be set to \c false. The value of each edge will be set exactly once.\n
37 /// For the sake of simplicity, there is a helper class KruskalPairVec,
39 /// simple EdgeMap to an input of this form. Alternatively, you can use
40 /// the function \ref kruskalEdgeMap to compute the minimum cost tree if
41 /// the edge costs are given by an EdgeMap.
42 /// \return The cost of the found tree.
44 template <typename Graph, typename InputEdgeOrder, typename OutBoolMap>
45 typename InputEdgeOrder::value_type::second_type
46 kruskal(Graph const& G, InputEdgeOrder const& in,
49 typedef typename InputEdgeOrder::value_type::second_type EdgeCost;
50 typedef typename Graph::template NodeMap<int> NodeIntMap;
51 typedef typename Graph::Node Node;
53 NodeIntMap comp(G, -1);
54 UnionFind<Node,NodeIntMap> uf(comp);
56 EdgeCost tot_cost = 0;
57 for (typename InputEdgeOrder::const_iterator p = in.begin();
59 if ( uf.join(G.head((*p).first),
60 G.tail((*p).first)) ) {
61 out.set((*p).first, true);
62 tot_cost += (*p).second;
65 out.set((*p).first, false);
71 /* A work-around for running Kruskal with const-reference bool maps... */
73 template<typename Map>
77 typedef typename Map::ValueType ValueType;
79 NonConstMapWr(const Map &_m) : m(_m) {}
81 template<typename KeyType>
82 void set(KeyType const& k, ValueType const &v) const { m.set(k,v); }
85 template <typename Graph, typename InputEdgeOrder, typename OutBoolMap>
87 typename InputEdgeOrder::ValueType
88 kruskal(Graph const& G, InputEdgeOrder const& edges,
89 OutBoolMap const& out_map)
91 NonConstMapWr<OutBoolMap> map_wr(out_map);
92 return kruskal(G, edges, map_wr);
96 /* ** ** Output-objektumok: egyszeruen extra bool mapek ** ** */
98 /// A writable bool-map that makes a sequence of "true" keys
100 /// A writable bool-map that creates a sequence out of keys that receives
101 /// the value "true".
102 /// \warning Not a regular property map, as it doesn't know its KeyType
104 template<typename Iterator>
105 class SequenceOutput {
109 typedef bool ValueType;
111 SequenceOutput(Iterator const &_it) : it(_it) {}
113 template<typename KeyType>
114 void set(KeyType const& k, bool v) const { if(v) {*it=k; ++it;} }
117 template<typename Iterator>
119 SequenceOutput<Iterator>
120 makeSequenceOutput(Iterator it) {
121 return SequenceOutput<Iterator>(it);
124 /* ** ** InputSource -ok ** ** */
126 /// Kruskal input source.
128 /// Kruskal input source.
130 template<typename Graph, typename Map>
131 class KruskalMapInput
132 : public std::vector< std::pair<typename Graph::Edge,
133 typename Map::ValueType> > {
136 typedef std::vector< std::pair<typename Graph::Edge,
137 typename Map::ValueType> > Parent;
138 typedef typename Parent::value_type value_type;
139 // typedef Key KeyType;
140 // typedef Val ValueType;
141 // typedef std::pair<Key,Val> PairType;
142 // typedef typename Parent::iterator iterator;
143 // typedef typename Parent::const_iterator const_iterator;
148 bool operator()(const value_type& a,
149 const value_type& b) {
150 return a.second < b.second;
157 // KruskalMapInput(Parent const& p) : Parent(p) {}
160 std::sort(this->begin(), this->end(), comparePair());
163 // FIXME: nem nagyon illik ez ide...
164 KruskalMapInput(Graph const& G, Map const& m) {
165 typedef typename Graph::EdgeIt EdgeIt;
168 for(EdgeIt e(G);G.valid(e);G.next(e)) {
169 // for (EdgeIt e=G.template first<EdgeIt>(); G.valid(e); G.next(e)) {
170 push_back(make_pair(e, m[e]));
175 // Key const& first(const_iterator i) const { return i->first; }
176 // Key& first(iterator i) { return i->first; }
178 // Val const& second(const_iterator i) const { return i->second; }
179 // Val& second(iterator i) { return i->second; }
183 // template<typename Graph, typename Map>
184 // class KruskalMapVec {
187 // typedef std::pair<typename Map::KeyType, Map::ValueType> value_type;
189 // typedef std::vector<KeyType> Container;
190 // Container container;
191 // std::vector<typename Map::KeyType> container
197 // Container::iterator i;
199 // iterator &operator ++() {++i;return *this;}
200 // valuetype operator *() {return value_type(container(i),m[container(i)]);}
201 // bool operator==(iterator b) {return i==b.i;}
203 // iterator(Container::iterator _i) i(_i) {}
205 // class const_iterator
207 // Container::const_iterator i;
209 // iterator &operator ++() {++i;return *this;}
210 // valuetype operator *() {return value_type(container(i),m[container(i)]);}
211 // bool operator==(iterator b) {return i==b.i;}
212 // const_iterator() {}
213 // const_iterator(Container::iterator _i) i(_i) {}
216 // iterator begin() { return iterator(container.begin());}
217 // const_iterator begin() const { return iterator(container.begin());}
218 // iterator end() { return iterator(container.end());}
219 // const_iterator end() const { return iterator(container.end());}
223 // class compareKeys {
226 // compareKeys(Map const &_m) : m(_m) {}
227 // bool operator()(KeyType const& a, KeyType const& b) {
228 // return m[a] < m[b];
234 // KruskalMapVec(Map const& _m) : m(_m) {}
237 // std::sort(begin(), end(), compareKeys(m));
240 // // FIXME: nem nagyon illik ez ide...
241 // template<typename Graph>
242 // KruskalMapVec(Graph const& G, Map const& _m) : m(_m) {
243 // typedef typename Graph::EdgeIt EdgeIt;
246 // for(EdgeIt e(G);G.valid(e);G.next(e)) {
247 // // for (EdgeIt e=G.template first<EdgeIt>(); G.valid(e); G.next(e))
253 // KeyType const& first(const_iterator i) const { return *i; }
254 // KeyType& first(iterator i) { return *i; }
256 // ValueType const& second(const_iterator i) const { return m[*i]; }
257 // ValueType& second(iterator i) { return m[*i]; }
261 /* ** ** Wrapper fuggvenyek ** ** */
264 /// \brief Wrapper to Kruskal().
265 /// Input is from an EdgeMap, output is a plain boolmap.
267 ///\todo some more words would be nice here.
269 template <typename Graph, typename EdgeCostMap, typename RetEdgeBoolMap>
271 typename EdgeCostMap::ValueType
272 kruskalEdgeMap(Graph const& G,
273 EdgeCostMap const& edge_costs,
274 RetEdgeBoolMap &ret_bool_map) {
276 typedef KruskalMapInput<Graph,EdgeCostMap> InputVec;
278 InputVec iv(G, edge_costs);
279 return kruskal(G, iv, ret_bool_map);
283 /// \brief Wrapper to Kruskal().
284 /// Input is from an EdgeMap, output is to a sequence.
286 ///\todo it does not follow the naming convention.
288 template <typename Graph, typename EdgeCostMap, typename RetIterator>
290 typename EdgeCostMap::ValueType
291 kruskalEdgeMap_IteratorOut(const Graph& G,
292 const EdgeCostMap& edge_costs,
293 RetIterator ret_iterator)
295 typedef typename EdgeCostMap::ValueType ValueType;
297 typedef SequenceOutput<RetIterator> OutMap;
298 OutMap out(ret_iterator);
300 typedef KruskalMapInput<Graph, EdgeCostMap> InputVec;
302 InputVec iv(G, edge_costs);
304 return kruskal(G, iv, out);
311 #endif //HUGO_KRUSKAL_H