# HG changeset patch # User beckerjc # Date 1082229597 0 # Node ID 42c660f587025a7ae23b2deb024e23e5ad97504b # Parent b63ea19e502eb9795373c1b05aef2af73a79125a Kruskal lenyegeben kesz. Kell meg dokumentalni, meg meg egy par jol hasznalhato wrapper fv. Es valamit meg kene csinalni azzal, hogy nem const ref. a kimeno boolmap, viszont sokszor "on-the-fly" akarjuk megkonstrualni (es ilyenkor persze a const-os mapet is lehet set-elni...) diff -r b63ea19e502e -r 42c660f58702 src/work/johanna/kruskal.h --- a/src/work/johanna/kruskal.h Sat Apr 17 13:15:53 2004 +0000 +++ b/src/work/johanna/kruskal.h Sat Apr 17 19:19:57 2004 +0000 @@ -2,165 +2,75 @@ #ifndef HUGO_KRUSKAL_H #define HUGO_KRUSKAL_H -#include "unionfind.h" #include +#include +#include namespace hugo { - template - typename EdgeCostMap::ValueType - kruskal1(Graph const& G, EdgeCostMap const& edge_costs, - RetEdgeBoolMap &ret_bool_map); + /// Kruskal's algorithm to compute a minimum cost tree - template - typename EdgeCostMap::ValueType - kruskal2(Graph const& G, EdgeCostMap const& edge_costs, - RetIterator ret_iterator); + template + typename InputEdgeOrder::ValueType + Kruskal(Graph const& G, InputEdgeOrder const& edges, + OutBoolMap& out_map) + { + typedef typename InputEdgeOrder::ValueType EdgeCost; + typedef typename Graph::NodeMap NodeIntMap; + typedef typename Graph::Node Node; - // FIXME: ret_iterator nem lehet referencia!!! + NodeIntMap comp_map(G, -1); + UnionFind uf(comp_map); + + EdgeCost tot_cost = 0; + for (typename InputEdgeOrder::const_iterator p = edges.begin(); + p!=edges.end(); ++p ) { + if ( uf.joinComponents(G.head(edges.first(p)), + G.tail(edges.first(p))) ) { + out_map.set(edges.first(p), true); + tot_cost += edges.second(p); + } + else { + out_map.set(edges.first(p), false); + } + } + return tot_cost; + } - template - typename EdgeCostPairVec::value_type::second_type - kruskal3(Graph const& G, EdgeCostPairVec const& edge_cost_pair_vec, - RetEdgeBoolMap &ret_bool_map); - template - typename EdgeCostPairVec::value_type::second_type - kruskal4(Graph const& G, EdgeCostPairVec const& edge_cost_pair_vec, - RetIterator &ret_iterator); + + /* ** ** Output-objektumok: egyszeruen extra bool mapek ** ** */ + + /// A writable bool-map that makes a sequence of "true" keys - template - int - kruskal5(Graph const& G, EdgePairVec const& edge_pair_vec, - RetEdgeBoolMap &ret_bool_map); + /// A writable bool-map that creates a sequence out of keys that receive + /// the value "true". + /// \warning Not a regular property map, as it doesn't know its KeyType - template - int - kruskal6(Graph const& G, EdgePairVec const& edge_pair_vec, - RetIterator &ret_iterator); - - - template - typename EdgeCostMap::ValueType - kruskal7(Graph const& G, EdgeCostMap const& edge_costs, - RetEdgeBoolMap &ret_bool_map, RetIterator &ret_iterator); - - template - typename EdgeCostPairVec::value_type::second_type - kruskal8(Graph const& G, EdgeCostPairVec const& edge_cost_pair_vec, - RetEdgeBoolMap &ret_bool_map, RetIterator &ret_iterator); - - template - int - kruskal9(Graph const& G, EdgePairVec const& edge_pair_vec, - RetEdgeBoolMap &ret_bool_map, RetIterator &ret_iterator); - - - - - template - class MinCostTreeKruskal - { - - typedef typename Graph::EdgeIt EdgeIt; - typedef typename Graph::Edge Edge; + template + class SequenceOutput { + Iterator it; public: - typedef typename InputEdgeOrder::ValueType EdgeCost; - - private: - Graph const &G; - InputEdgeOrder const &edges; - OutputObserver &out_obs; + typedef bool ValueType; - public: + SequenceOutput(Iterator const &_it) : it(_it) {} - - MinCostTreeKruskal(Graph const& _G, InputEdgeOrder const& _edges, - OutputObserver& _out_obs) : - G(_G), edges(_edges), out_obs(_out_obs) {} - - - EdgeCost run() - { - typedef typename Graph::NodeMap NodeIntMap; - typedef typename Graph::Node Node; - NodeIntMap comp_map(G, -1); - UnionFind uf(comp_map); - - EdgeCost tot_cost = 0; - for (typename InputEdgeOrder::const_iterator p = edges.begin(); - p!=edges.end(); ++p ) { - if ( uf.joinComponents(G.head(edges.first(p)), - G.tail(edges.first(p))) ) { - out_obs.setTrue(edges.first(p)); - tot_cost += edges.second(p); - } - else { - out_obs.setFalse(edges.first(p)); - } - } - return tot_cost; - } - + template + void set(KeyType const& k, bool v) { if(v) {*it=k; ++it;} } }; - - /* ** ** Output-objektumok (Observerek (?)) ** ** */ - - template - class BoolMapOutput { - BoolMap &bm; - typedef typename BoolMap::KeyType KeyType; - - public: - BoolMapOutput(BoolMap &_bm) : bm(_bm) {} - - void setTrue(KeyType const& k) { bm.set(k, true); } - void setFalse(KeyType const& k) { bm.set(k, false); } - }; - - template - class SequenceOutput { - Iterator ⁢ - - public: - SequenceOutput(Iterator &_it) : it(_it) {} - - template - void setTrue(KeyType const& k) { *it=k; ++it; } - template - void setFalse(KeyType const& k) {} - }; - - template - class CombinedOutput : BoolMapOutput, SequenceOutput { - typedef BoolMapOutput BMO; - typedef SequenceOutput SO; - public: - CombinedOutput(BoolMap &_bm, Iterator &_it) : - BMO(_bm), SO(_it) {} - - template - void setTrue(KeyType const& k) { - BMO::setTrue(k); - SO::setTrue(k); - } - template - void setFalse(KeyType const& k) { - BMO::setFalse(k); - SO::setFalse(k); - } - }; - + template + inline + SequenceOutput + makeSequenceOutput(Iterator it) { + return SequenceOutput(it); + } /* ** ** InputSource -ok ** ** */ template - class PairVec : public std::vector< std::pair > { + class KruskalPairVec : public std::vector< std::pair > { public: typedef std::vector< std::pair > Parent; @@ -171,9 +81,7 @@ typedef typename Parent::iterator iterator; typedef typename Parent::const_iterator const_iterator; - private: - class comparePair { public: bool operator()(PairType const& a, PairType const& b) { @@ -184,7 +92,7 @@ public: // FIXME: kell ez? - // PairVec(Parent const& p) : Parent(p) {} + // KruskalPairVec(Parent const& p) : Parent(p) {} void sort() { std::sort(begin(), end(), comparePair()); @@ -192,19 +100,17 @@ // FIXME: nem nagyon illik ez ide... template - void readGraphEdgeMap(Graph const& G, Map const& m) { + KruskalPairVec(Graph const& G, Map const& m) { typedef typename Graph::EdgeIt EdgeIt; clear(); - for (EdgeIt e=G.template first(); G.valid(e); G.next(e)) { + FOR_EACH_LOC(EdgeIt, e, G) { + // for (EdgeIt e=G.template first(); G.valid(e); G.next(e)) { push_back(make_pair(e, m[e])); } - sort(); } - int alma() { return 5; /* FIXME */ } - Key const& first(const_iterator i) const { return i->first; } Key& first(iterator i) { return i->first; } @@ -212,38 +118,93 @@ Val& second(iterator i) { return i->second; } }; + + template + class KruskalMapVec : public std::vector { + public: + + typedef typename Map::KeyType KeyType; + typedef typename Map::ValueType ValueType; + + typedef typename std::vector Parent; + typedef typename Parent::iterator iterator; + typedef typename Parent::const_iterator const_iterator; + + private: + + const Map &m; + + class compareKeys { + const Map &m; + public: + compareKeys(Map const &_m) : m(_m) {} + bool operator()(KeyType const& a, KeyType const& b) { + return m[a] < m[b]; + } + }; + + public: + + KruskalMapVec(Map const& _m) : m(_m) {} + + void sort() { + std::sort(begin(), end(), compareKeys(m)); + } + + // FIXME: nem nagyon illik ez ide... + template + KruskalMapVec(Graph const& G, Map const& _m) : m(_m) { + typedef typename Graph::EdgeIt EdgeIt; + + clear(); + FOR_EACH_LOC(EdgeIt, e, G) { + // for (EdgeIt e=G.template first(); G.valid(e); G.next(e)) { + push_back(e); + } + sort(); + } + + KeyType const& first(const_iterator i) const { return *i; } + KeyType& first(iterator i) { return *i; } + + ValueType const& second(const_iterator i) const { return m[*i]; } + ValueType& second(iterator i) { return m[*i]; } + }; + /* ** ** Wrapper fuggvenyek ** ** */ + + /// \brief Wrapper to Kruskal(). + /// Input is from an EdgeMap, output is a plain boolmap. template typename EdgeCostMap::ValueType - kruskal1(Graph const& G, EdgeCostMap const& edge_costs, - RetEdgeBoolMap &ret_bool_map) { - typedef BoolMapOutput OutObs; - OutObs out(ret_bool_map); + Kruskal_EdgeCostMapIn_BoolMapOut(Graph const& G, + EdgeCostMap const& edge_costs, + RetEdgeBoolMap &ret_bool_map) { - typedef PairVec + typedef KruskalPairVec InputVec; - InputVec iv; - iv.readGraphEdgeMap(G, edge_costs); + InputVec iv(G, edge_costs); - MinCostTreeKruskal mctk(G, iv, out); - return mctk.run(); + return Kruskal(G, iv, ret_bool_map); } + + /// \brief Wrapper to Kruskal(). + /// Input is from an EdgeMap, output is to a sequence. template typename EdgeCostMap::ValueType - kruskal2(Graph const& G, EdgeCostMap const& edge_costs, - RetIterator ret_iterator) { - typedef SequenceOutput OutObs; - OutObs out(ret_iterator); + Kruskal_EdgeCostMapIn_IteratorOut(Graph const& G, + EdgeCostMap const& edge_costs, + RetIterator ret_iterator) { + typedef SequenceOutput OutMap; + OutMap out(ret_iterator); - typedef PairVec + typedef KruskalPairVec InputVec; - InputVec iv; - iv.readGraphEdgeMap(G, edge_costs); + InputVec iv(G, edge_costs); - MinCostTreeKruskal mctk(G, iv, out); - return mctk.run(); + return Kruskal(G, iv, out); } diff -r b63ea19e502e -r 42c660f58702 src/work/johanna/kruskal_test.cc --- a/src/work/johanna/kruskal_test.cc Sat Apr 17 13:15:53 2004 +0000 +++ b/src/work/johanna/kruskal_test.cc Sat Apr 17 19:19:57 2004 +0000 @@ -71,7 +71,7 @@ cout << "Uniform 2-es koltseggel: " - << kruskal1(G, edge_cost_map, tree_map) + << Kruskal_EdgeCostMapIn_BoolMapOut(G, edge_cost_map, tree_map) << endl; @@ -89,7 +89,8 @@ vector tree_edge_vec; cout << "Nemkonst koltseggel (-31): " - << kruskal2(G, edge_cost_map, back_inserter(tree_edge_vec)) + << Kruskal_EdgeCostMapIn_IteratorOut(G, edge_cost_map, + back_inserter(tree_edge_vec)) << endl; int i = 1; @@ -98,6 +99,21 @@ cout << i << ". el: " << *e << endl; } + tree_edge_vec.clear(); + SequenceOutput< back_insert_iterator< vector > > + vec_filler(back_inserter(tree_edge_vec)); + cout << "Nemkonst koltseggel tarhatekonyabban: " + << Kruskal(G, + KruskalMapVec(G, edge_cost_map), + vec_filler) + << endl; + + i = 1; + for(vector::iterator e = tree_edge_vec.begin(); + e != tree_edge_vec.end(); ++e, ++i) { + cout << i << ". el: " << *e << endl; + } + // typedef MinCostTreeKruskal MCTK; diff -r b63ea19e502e -r 42c660f58702 src/work/johanna/unionfind.h --- a/src/work/johanna/unionfind.h Sat Apr 17 13:15:53 2004 +0000 +++ b/src/work/johanna/unionfind.h Sat Apr 17 19:19:57 2004 +0000 @@ -24,7 +24,7 @@ int whichComponent(T a) { - int comp0 = map.get(a); + int comp0 = map[a]; if (comp0 < 0) { return insertNewElement(a); }