I want to create a minimum spanning tree from vertices with edge weights and traverse the graph in depth-first order. I can build the graph and the minimum spanning tree but I am failing at writing the custom visitor.
#include <iostream>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/kruskal_min_spanning_tree.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/graph_traits.hpp>
#include <vector>
#include <string>
typedef boost::property<boost::edge_weight_t, double> EdgeWeightProperty;
typedef boost::adjacency_list <
boost::listS,
boost::vecS,
boost::undirectedS,
boost::no_property,
EdgeWeightProperty> MyGraph;
typedef MyGraph::edge_descriptor Edge;
class MyVisitor : public boost::default_dfs_visitor
{
public:
void tree_edge(Edge e, const MyGraph& g) const {
}
};
void mst() {
MyGraph g;
boost::add_edge(0, 1, 0.7, g);
boost::add_edge(0, 2, 0.1, g);
boost::add_edge(1, 2, 0.3, g);
boost::add_edge(1, 0, 0.7, g);
boost::add_edge(1, 3, 0.8, g);
boost::add_edge(1, 4, 0.2, g);
boost::add_edge(2, 1, 0.3, g);
boost::add_edge(2, 0, 0.1, g);
boost::add_edge(2, 5, 0.1, g);
boost::add_edge(2, 4, 0.5, g);
boost::add_edge(3, 1, 0.8, g);
boost::add_edge(4, 1, 0.2, g);
boost::add_edge(4, 2, 0.5, g);
boost::add_edge(5, 2, 0.1, g);
std::list <Edge> spanning_tree;
boost::kruskal_minimum_spanning_tree(g, std::back_inserter(spanning_tree));
// the following two lines are failing
MyVisitor vis();
boost::depth_first_search(spanning_tree, visitor(vis));
}
int main(int argc, char** argv)
{
mst();
std::cin.get();
return (0);
}
I would like to access the vertices and edge weights in the custom visitor. Is this possible? I saw this post: boost minimum spanning tree, how to do depth first? but I would prefer to not build a separate weight map.
Additionally, is it possible to iterate in depth-first order through the tree with boost tools without writing a custom visitor?
That is a function declaration. See Most Vexing Parse
That calls the graph algorithm on a
std::list<Edge>
.depth_first_search
requires a graph that models the right graph concepts:The std::list models neither.
Suggestion
You could build a graph including just the edges from the MST set. The answer to the question you linked to tries that.
However, it seems easier and more efficient to create a
filtered_graph<>
view of the same graph, so that the edge properties are simply available through the same mechanism.First, let's prefer to get the MST edges in a
set<>
instead of alist<>
:The interesting thing you'll note is that
InSpanning
is also a function object that be used as a filtering predicate forfiltering_graph
:Now you can call de DFS:
I've tweaked the visitor slightly:
Note:
MyGraph
type anymore (because the filtered_graph has a different type).Live Demo
Live On Coliru
Prints