2
0
mirror of https://github.com/boostorg/graph.git synced 2026-01-28 07:12:14 +00:00

Finalize BFS

[SVN r27547]
This commit is contained in:
Douglas Gregor
2005-03-03 20:40:06 +00:00
parent 961a7d09cc
commit d31c4b5a04
5 changed files with 51 additions and 137 deletions

View File

@@ -523,7 +523,10 @@ void export_basic_graph(const char* name)
::declare("vertex_string_map");
declare_property_map<vector_property_map<object, VertexIndexMap> >
::declare("vertex_object_map");
declare_property_map<vector_property_map<default_color_type,
VertexIndexMap> >
::declare("vertex_color_map");
// Edge property maps
declare_readable_property_map<EdgeIndexMap>
::declare("edge_index_map");
@@ -537,6 +540,8 @@ void export_basic_graph(const char* name)
::declare("edge_string_map");
declare_property_map<vector_property_map<object, EdgeIndexMap> >
::declare("edge_object_map");
declare_property_map<vector_property_map<default_color_type, EdgeIndexMap> >
::declare("edge_color_map");
}
} } } // end namespace boost::graph::python

View File

@@ -0,0 +1,9 @@
BGL_PYTHON_EVENT(initialize_vertex, vertex_descriptor)
BGL_PYTHON_EVENT(discover_vertex, vertex_descriptor)
BGL_PYTHON_EVENT(examine_vertex, vertex_descriptor)
BGL_PYTHON_EVENT(examine_edge, edge_descriptor)
BGL_PYTHON_EVENT(tree_edge, edge_descriptor)
BGL_PYTHON_EVENT(non_tree_edge, edge_descriptor)
BGL_PYTHON_EVENT(gray_target, edge_descriptor)
BGL_PYTHON_EVENT(black_target, edge_descriptor)
BGL_PYTHON_EVENT(finish_vertex, vertex_descriptor)

View File

@@ -5,136 +5,52 @@
namespace boost { namespace graph { namespace python {
template<typename Graph>
class bfs_visitor
{
public:
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
virtual ~bfs_visitor() {}
virtual void initialize_vertex(vertex_descriptor s, const Graph& g) const {}
virtual void discover_vertex(vertex_descriptor u, const Graph& g) const {}
virtual void examine_vertex(vertex_descriptor s, const Graph& g) const {}
virtual void examine_edge(edge_descriptor e, const Graph& g) const {}
virtual void tree_edge(edge_descriptor e, const Graph& g) const {}
virtual void non_tree_edge(edge_descriptor e, const Graph& g) const {}
virtual void gray_target(edge_descriptor e, const Graph& g) const {}
virtual void black_target(edge_descriptor e, const Graph& g) const {}
virtual void finish_vertex(vertex_descriptor s, const Graph& g) const {}
};
template<typename Graph>
class bfs_visitor_wrap
: public bfs_visitor<Graph>,
public boost::python::wrapper<bfs_visitor<Graph> >
{
public:
typedef typename bfs_visitor<Graph>::vertex_descriptor vertex_descriptor;
typedef typename bfs_visitor<Graph>::edge_descriptor edge_descriptor;
#define BGL_PYTHON_EVENT(Name,Descriptor) \
void Name(Descriptor x, const Graph& g) const \
{ \
if (override f = this->get_override(#Name)) \
f(x, boost::cref(g)); \
else bfs_visitor<Graph>::Name(x, g); \
} \
\
void default_##Name(Descriptor x, const Graph& g) const \
{ this->bfs_visitor<Graph>::Name(x, g); }
BGL_PYTHON_EVENT(initialize_vertex, vertex_descriptor)
BGL_PYTHON_EVENT(examine_vertex, vertex_descriptor)
BGL_PYTHON_EVENT(examine_edge, edge_descriptor)
BGL_PYTHON_EVENT(tree_edge, edge_descriptor)
BGL_PYTHON_EVENT(non_tree_edge, edge_descriptor)
BGL_PYTHON_EVENT(gray_target, edge_descriptor)
BGL_PYTHON_EVENT(black_target, edge_descriptor)
BGL_PYTHON_EVENT(finish_vertex, vertex_descriptor)
#undef BGL_PYTHON_EVENT
};
template<typename Graph>
struct wrap_bfs_visitor_ref
{
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
wrap_bfs_visitor_ref(const bfs_visitor<Graph>& v) : v(v) { }
void initialize_vertex(vertex_descriptor s, const Graph& g) const
{ v.initialize_vertex(s, g); }
void discover_vertex(vertex_descriptor u, const Graph& g) const
{ v.discover_vertex(u, g); }
void examine_vertex(vertex_descriptor u, const Graph& g) const
{ v.examine_vertex(u, g); }
void examine_edge(edge_descriptor e, const Graph& g) const
{ v.examine_edge(e, g); }
void tree_edge(edge_descriptor e, const Graph& g) const
{ v.tree_edge(e, g); }
void non_tree_edge(edge_descriptor e, const Graph& g) const
{ v.non_tree_edge(e, g); }
void gray_target(edge_descriptor e, const Graph& g) const
{ v.gray_target(e, g); }
void black_target(edge_descriptor e, const Graph& g) const
{ v.black_target(e, g); }
void finish_vertex(vertex_descriptor u, const Graph& g) const
{ v.finish_vertex(u, g); }
private:
const bfs_visitor<Graph>& v;
};
template<typename Graph>
class default_bfs_visitor : public bfs_visitor<Graph> {};
#define BGL_PYTHON_VISITOR bfs_visitor
#define BGL_PYTHON_EVENTS_HEADER "bfs_events.hpp"
#include "visitor.hpp"
#undef BGL_PYTHON_EVENTS_HEADER
#undef BGL_PYTHON_VISITOR
template<typename Graph>
void
breadth_first_search_qv
breadth_first_search_qvs
(const Graph& g,
typename Graph::Vertex s,
python_queue<typename Graph::Vertex>& Q,
const bfs_visitor<Graph>& visitor)
const bfs_visitor<Graph>& visitor,
const vector_property_map<default_color_type,
typename Graph::VertexIndexMap>* in_color)
{
typedef vector_property_map<default_color_type,
typename Graph::VertexIndexMap> ColorMap;
ColorMap color =
in_color? *in_color : ColorMap(g.num_vertices(), g.get_vertex_index_map());
typedef typename python_queue<typename Graph::Vertex>::default_queue
default_queue_type;
bool has_default_buffer = dynamic_cast<default_queue_type*>(&Q);
bool has_default_visitor =
dynamic_cast<const default_bfs_visitor<Graph>*>(&visitor);
dynamic_cast<typename bfs_visitor<Graph>::default_arg const*>(&visitor);
if (has_default_buffer) {
if (has_default_visitor) {
boost::breadth_first_search(g, s,
vertex_index_map(g.get_vertex_index_map()));
boost::breadth_first_search(g, s, color_map(color));
} else {
boost::breadth_first_search
(g, s,
vertex_index_map(g.get_vertex_index_map()).
visitor(wrap_bfs_visitor_ref<Graph>(visitor)));
color_map(color).
visitor(typename bfs_visitor<Graph>::ref(visitor)));
}
} else {
if (has_default_visitor) {
boost::breadth_first_search(g, s,
buffer(Q).
vertex_index_map(g.get_vertex_index_map()));
color_map(color));
} else {
boost::breadth_first_search
(g, s,
buffer(Q).
vertex_index_map(g.get_vertex_index_map()).
visitor(wrap_bfs_visitor_ref<Graph>(visitor)));
(g, s, Q, typename bfs_visitor<Graph>::ref(visitor), color);
}
}
}
@@ -143,45 +59,25 @@ void export_breadth_first_search()
{
using boost::python::arg;
def("breadth_first_search", &breadth_first_search_qv<Graph>,
def("breadth_first_search", &breadth_first_search_qvs<Graph>,
(arg("graph"), "root_vertex",
arg("buffer") = python_queue<Graph::Vertex>::default_queue(),
arg("visitor") = default_bfs_visitor<Graph>()));
arg("visitor") = bfs_visitor<Graph>::default_arg(),
arg("color_map") =
(vector_property_map<default_color_type, Graph::VertexIndexMap>*)0));
def("breadth_first_search", &breadth_first_search_qv<Digraph>,
def("breadth_first_search", &breadth_first_search_qvs<Digraph>,
(arg("graph"), "root_vertex",
arg("buffer") = python_queue<Digraph::Vertex>::default_queue(),
arg("visitor") = default_bfs_visitor<Digraph>()));
arg("visitor") = bfs_visitor<Digraph>::default_arg(),
arg("color_map") =
(vector_property_map<default_color_type, Digraph::VertexIndexMap>*)0));
}
template<typename Graph>
void export_breadth_first_search_in_graph()
{
using boost::python::arg;
// BFS visitor
class_<bfs_visitor_wrap<Graph>, boost::noncopyable>("BFSVisitor")
.def("initialize_vertex", &bfs_visitor<Graph>::initialize_vertex,
&bfs_visitor_wrap<Graph>::default_initialize_vertex)
.def("examine_vertex", &bfs_visitor<Graph>::examine_vertex,
&bfs_visitor_wrap<Graph>::default_examine_vertex)
.def("examine_edge", &bfs_visitor<Graph>::examine_edge,
&bfs_visitor_wrap<Graph>::default_examine_edge)
.def("tree_edge", &bfs_visitor<Graph>::tree_edge,
&bfs_visitor_wrap<Graph>::default_tree_edge)
.def("non_tree_edge", &bfs_visitor<Graph>::non_tree_edge,
&bfs_visitor_wrap<Graph>::default_non_tree_edge)
.def("gray_target", &bfs_visitor<Graph>::gray_target,
&bfs_visitor_wrap<Graph>::default_gray_target)
.def("black_target", &bfs_visitor<Graph>::black_target,
&bfs_visitor_wrap<Graph>::default_black_target)
.def("finish_vertex", &bfs_visitor<Graph>::finish_vertex,
&bfs_visitor_wrap<Graph>::default_finish_vertex)
;
class_<default_bfs_visitor<Graph>, bases<bfs_visitor<Graph> > >
("DefaultBFSVisitor", no_init);
bfs_visitor<Graph>::declare("BFSVisitor", "DefaultBFSVisitor");
python_queue<typename Graph::Vertex>::declare("VertexQueue",
"DefaultVertexQueue");
}

View File

@@ -65,8 +65,6 @@ dijkstra_shortest_paths
template<typename Graph>
void export_dijkstra_shortest_paths_in_graph()
{
using boost::python::arg;
dijkstra_visitor<Graph>::declare("DijkstraVisitor",
"DefaultDijkstraVisitor");
}

View File

@@ -29,6 +29,12 @@ BOOST_PYTHON_MODULE(bgl)
.value("graphviz", gfk_graphviz)
;
enum_<default_color_type>("Color")
.value("white", color_traits<default_color_type>::white())
.value("gray", color_traits<default_color_type>::gray())
.value("black", color_traits<default_color_type>::black())
;
export_Graph();
export_Digraph();
export_betweenness_centrality();