6 #include <hugo/unionfind.h>
9 ///\brief Kruskal's algorithm to compute a minimum cost tree
13 /// Kruskal's algorithm to find a minimum cost tree of a graph.
15 /// This function runs Kruskal's algorithm to find a minimum cost tree.
16 /// \param G The graph the algorithm runs on.
17 /// \param in This object is used to describe the edge costs. It must
18 /// be an STL 'forward container'
19 /// with value_type <tt> std::pair<Graph::Edge,X> </tt>,
20 /// where X is the type of the costs. It must contain every edge in
21 /// cost-ascending order.
22 /// \retval out This must be a writeable EdgeMap. After running the algorithm
23 /// this will contain the found minimum cost spanning tree: the value of an
24 /// edge will be set to \c true if it belongs to the tree, otherwise it will
25 /// be set to \c false. The value of each edge will be set exactly once.\n
26 /// For the sake of simplicity, there is a helper class KruskalPairVec,
28 /// simple EdgeMap to an input of this form. Alternatively, you can use
29 /// the function \ref kruskalEdgeMap to compute the minimum cost tree if
30 /// the edge costs are given by an EdgeMap.
31 /// \return The cost of the found tree.
33 template <typename Graph, typename InputEdgeOrder, typename OutBoolMap>
34 typename InputEdgeOrder::value_type::second_type
35 kruskal(Graph const& G, InputEdgeOrder const& in,
38 typedef typename InputEdgeOrder::value_type::second_type EdgeCost;
39 typedef typename Graph::template NodeMap<int> NodeIntMap;
40 typedef typename Graph::Node Node;
42 NodeIntMap comp(G, -1);
43 UnionFind<Node,NodeIntMap> uf(comp);
45 EdgeCost tot_cost = 0;
46 for (typename InputEdgeOrder::const_iterator p = in.begin();
48 if ( uf.join(G.head((*p).first),
49 G.tail((*p).first)) ) {
50 out.set((*p).first, true);
51 tot_cost += (*p).second;
54 out.set((*p).first, false);
60 /* A work-around for running Kruskal with const-reference bool maps... */
62 template<typename Map>
66 typedef typename Map::ValueType ValueType;
68 NonConstMapWr(const Map &_m) : m(_m) {}
70 template<typename KeyType>
71 void set(KeyType const& k, ValueType const &v) const { m.set(k,v); }
74 template <typename Graph, typename InputEdgeOrder, typename OutBoolMap>
76 typename InputEdgeOrder::ValueType
77 kruskal(Graph const& G, InputEdgeOrder const& edges,
78 OutBoolMap const& out_map)
80 NonConstMapWr<OutBoolMap> map_wr(out_map);
81 return kruskal(G, edges, map_wr);
85 /* ** ** Output-objektumok: egyszeruen extra bool mapek ** ** */
87 /// A writable bool-map that makes a sequence of "true" keys
89 /// A writable bool-map that creates a sequence out of keys that receives
91 /// \warning Not a regular property map, as it doesn't know its KeyType
93 template<typename Iterator>
94 class SequenceOutput {
98 typedef bool ValueType;
100 SequenceOutput(Iterator const &_it) : it(_it) {}
102 template<typename KeyType>
103 void set(KeyType const& k, bool v) const { if(v) {*it=k; ++it;} }
106 template<typename Iterator>
108 SequenceOutput<Iterator>
109 makeSequenceOutput(Iterator it) {
110 return SequenceOutput<Iterator>(it);
113 /* ** ** InputSource -ok ** ** */
115 /// Kruskal input source.
117 /// Kruskal input source.
119 template<typename Graph, typename Map>
121 : public std::vector< std::pair<typename Graph::Edge,
122 typename Map::ValueType> > {
125 typedef std::vector< std::pair<typename Graph::Edge,
126 typename Map::ValueType> > Parent;
127 typedef typename Parent::value_type value_type;
128 // typedef Key KeyType;
129 // typedef Val ValueType;
130 // typedef std::pair<Key,Val> PairType;
131 // typedef typename Parent::iterator iterator;
132 // typedef typename Parent::const_iterator const_iterator;
137 bool operator()(const value_type& a,
138 const value_type& b) {
139 return a.second < b.second;
146 // KruskalPairVec(Parent const& p) : Parent(p) {}
149 std::sort(this->begin(), this->end(), comparePair());
152 // FIXME: nem nagyon illik ez ide...
153 KruskalPairVec(Graph const& G, Map const& m) {
154 typedef typename Graph::EdgeIt EdgeIt;
157 for(EdgeIt e(G);G.valid(e);G.next(e)) {
158 // for (EdgeIt e=G.template first<EdgeIt>(); G.valid(e); G.next(e)) {
159 push_back(make_pair(e, m[e]));
164 // Key const& first(const_iterator i) const { return i->first; }
165 // Key& first(iterator i) { return i->first; }
167 // Val const& second(const_iterator i) const { return i->second; }
168 // Val& second(iterator i) { return i->second; }
172 // template <typename Map>
173 // class KruskalMapVec : public std::vector<typename Map::KeyType> {
176 // typedef typename Map::KeyType KeyType;
177 // typedef typename Map::ValueType ValueType;
179 // typedef typename std::vector<KeyType> Parent;
180 // typedef typename Parent::iterator iterator;
181 // typedef typename Parent::const_iterator const_iterator;
187 // class compareKeys {
190 // compareKeys(Map const &_m) : m(_m) {}
191 // bool operator()(KeyType const& a, KeyType const& b) {
192 // return m[a] < m[b];
198 // KruskalMapVec(Map const& _m) : m(_m) {}
201 // std::sort(begin(), end(), compareKeys(m));
204 // // FIXME: nem nagyon illik ez ide...
205 // template<typename Graph>
206 // KruskalMapVec(Graph const& G, Map const& _m) : m(_m) {
207 // typedef typename Graph::EdgeIt EdgeIt;
210 // for(EdgeIt e(G);G.valid(e);G.next(e)) {
211 // // for (EdgeIt e=G.template first<EdgeIt>(); G.valid(e); G.next(e))
217 // KeyType const& first(const_iterator i) const { return *i; }
218 // KeyType& first(iterator i) { return *i; }
220 // ValueType const& second(const_iterator i) const { return m[*i]; }
221 // ValueType& second(iterator i) { return m[*i]; }
224 /* ** ** Wrapper fuggvenyek ** ** */
227 /// \brief Wrapper to Kruskal().
228 /// Input is from an EdgeMap, output is a plain boolmap.
230 ///\todo some more words would be nice here.
232 template <typename Graph, typename EdgeCostMap, typename RetEdgeBoolMap>
234 typename EdgeCostMap::ValueType
235 kruskalEdgeMap(Graph const& G,
236 EdgeCostMap const& edge_costs,
237 RetEdgeBoolMap &ret_bool_map) {
239 typedef KruskalPairVec<Graph,EdgeCostMap> InputVec;
241 InputVec iv(G, edge_costs);
242 return kruskal(G, iv, ret_bool_map);
246 /// \brief Wrapper to Kruskal().
247 /// Input is from an EdgeMap, output is to a sequence.
249 ///\todo it does not follow the naming convention.
251 template <typename Graph, typename EdgeCostMap, typename RetIterator>
253 typename EdgeCostMap::ValueType
254 kruskalEdgeMap_IteratorOut(const Graph& G,
255 const EdgeCostMap& edge_costs,
256 RetIterator ret_iterator)
258 typedef typename EdgeCostMap::ValueType ValueType;
260 typedef SequenceOutput<RetIterator> OutMap;
261 OutMap out(ret_iterator);
263 typedef KruskalPairVec<Graph, EdgeCostMap> InputVec;
265 InputVec iv(G, edge_costs);
267 return kruskal(G, iv, out);
273 #endif //HUGO_KRUSKAL_H