# HG changeset patch # User klao # Date 1095607496 0 # Node ID 5e59c44b6ba2826dd6f7c2a181ecfc67e8b5ae26 # Parent b06bfaaca48c6397dea820585a868f0857e5dd9c Kruskal cleanup: - resolved the NonConstMapWr bug - docs added for NonConstMapWr and KruskalSequenceOut diff -r b06bfaaca48c -r 5e59c44b6ba2 src/hugo/kruskal.h --- a/src/hugo/kruskal.h Sun Sep 19 13:39:25 2004 +0000 +++ b/src/hugo/kruskal.h Sun Sep 19 15:24:56 2004 +0000 @@ -81,8 +81,18 @@ /* A work-around for running Kruskal with const-reference bool maps... */ - ///\bug What is this? Or why doesn't it work? + /// Helper class for calling kruskal with "constant" output map. + + /// Helper class for calling kruskal with output maps constructed + /// on-the-fly. /// + /// A typical examle is the following call: + /// kruskal(G, some_input, makeSequenceOutput(iterator)). + /// Here, the third argument is a temporary object (which wraps around an + /// iterator with a writable bool map interface), and thus by rules of C++ + /// is a \c const object. To enable call like this exist this class and + /// the prototype of the \ref kruskal() function with const& OUT + /// third argument. template class NonConstMapWr { const Map &m; @@ -97,9 +107,8 @@ template inline - typename IN::ValueType - kruskal(GR const& G, IN const& edges, - OUT const& out_map) + typename IN::value_type::second_type + kruskal(GR const& G, IN const& edges, OUT const& out_map) { NonConstMapWr map_wr(out_map); return kruskal(G, edges, map_wr); @@ -151,8 +160,7 @@ KruskalMapInput(GR const& G, Map const& m) { typedef typename GR::EdgeIt EdgeIt; - this->clear(); - for(EdgeIt e(G);e!=INVALID;++e) push_back(make_pair(e, m[e])); + for(EdgeIt e(G);e!=INVALID;++e) push_back(value_type(e, m[e])); sort(); } }; @@ -184,24 +192,44 @@ } - /* ** ** Output-objects: simple writable bool maps** ** */ + + /* ** ** Output-objects: simple writable bool maps ** ** */ + + /// A writable bool-map that makes a sequence of "true" keys /// A writable bool-map that creates a sequence out of keys that receives /// the value "true". + /// + /// \sa makeKruskalSequenceOutput() + /// + /// Very often, when looking for a min cost spanning tree, we want as + /// output a container containing the edges of the found tree. For this + /// purpose exist this class that wraps around an STL iterator with a + /// writable bool map interface. When a key gets value "true" this key + /// is added to sequence pointed by the iterator. + /// + /// A typical usage: + /// \code + /// std::vector v; + /// kruskal(g, input, makeKruskalSequenceOutput(back_inserter(v))); + /// \endcode + /// + /// For the most common case, when the input is given by a simple edge + /// map and the output is a sequence of the tree edges, a special + /// wrapper function exists: \ref kruskalEdgeMap_IteratorOut(). + /// /// \warning Not a regular property map, as it doesn't know its KeyType - /// \bug Missing documentation. - /// \todo This class may be of wider usage, therefore it could move to - /// maps.h + template - class SequenceOutput { + class KruskalSequenceOutput { mutable Iterator it; public: typedef bool ValueType; - SequenceOutput(Iterator const &_it) : it(_it) {} + KruskalSequenceOutput(Iterator const &_it) : it(_it) {} template void set(KeyType const& k, bool v) const { if(v) {*it=k; ++it;} } @@ -209,14 +237,17 @@ template inline - SequenceOutput - makeSequenceOutput(Iterator it) { - return SequenceOutput(it); + KruskalSequenceOutput + makeKruskalSequenceOutput(Iterator it) { + return KruskalSequenceOutput(it); } + + /* ** ** Wrapper funtions ** ** */ + /// \brief Wrapper function to kruskal(). /// Input is from an edge map, output is a plain bool map. /// @@ -239,7 +270,6 @@ /// /// \return The cost of the found tree. - template inline typename IN::ValueType @@ -284,6 +314,7 @@ /// \return The cost of the found tree. /// /// \bug its name does not follow the coding style. + template inline typename IN::ValueType @@ -291,10 +322,8 @@ const IN& in, RET out) { - SequenceOutput _out(out); - return kruskal(G, - KruskalMapInput(G, in), - _out); + KruskalSequenceOutput _out(out); + return kruskal(G, KruskalMapInput(G, in), _out); } /// @} diff -r b06bfaaca48c -r 5e59c44b6ba2 src/test/kruskal_test.cc --- a/src/test/kruskal_test.cc Sun Sep 19 13:39:25 2004 +0000 +++ b/src/test/kruskal_test.cc Sun Sep 19 15:24:56 2004 +0000 @@ -81,6 +81,15 @@ ==-31, "Total cost should be -31."); + tree_edge_vec.clear(); + + //The above test could also be coded like this: + check(kruskal(G, + makeKruskalMapInput(G, edge_cost_map), + makeKruskalSequenceOutput(back_inserter(tree_edge_vec))) + ==-31, + "Total cost should be -31."); + check(tree_edge_vec.size()==5,"The tree should have 5 edges."); check(tree_edge_vec[0]==e1 &&