# 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 &&