From d31c4b5a046beefff665c16b02b18c0385e4fe41 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 3 Mar 2005 20:40:06 +0000 Subject: [PATCH] Finalize BFS [SVN r27547] --- src/python/basic_graph.cpp | 7 +- src/python/bfs_events.hpp | 9 ++ src/python/breadth_first_search.cpp | 164 +++++-------------------- src/python/dijkstra_shortest_paths.cpp | 2 - src/python/module.cpp | 6 + 5 files changed, 51 insertions(+), 137 deletions(-) create mode 100644 src/python/bfs_events.hpp diff --git a/src/python/basic_graph.cpp b/src/python/basic_graph.cpp index 6557681b..60c80825 100644 --- a/src/python/basic_graph.cpp +++ b/src/python/basic_graph.cpp @@ -523,7 +523,10 @@ void export_basic_graph(const char* name) ::declare("vertex_string_map"); declare_property_map > ::declare("vertex_object_map"); - + declare_property_map > + ::declare("vertex_color_map"); + // Edge property maps declare_readable_property_map ::declare("edge_index_map"); @@ -537,6 +540,8 @@ void export_basic_graph(const char* name) ::declare("edge_string_map"); declare_property_map > ::declare("edge_object_map"); + declare_property_map > + ::declare("edge_color_map"); } } } } // end namespace boost::graph::python diff --git a/src/python/bfs_events.hpp b/src/python/bfs_events.hpp new file mode 100644 index 00000000..3aa52b02 --- /dev/null +++ b/src/python/bfs_events.hpp @@ -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) diff --git a/src/python/breadth_first_search.cpp b/src/python/breadth_first_search.cpp index e0a5865b..af8e3c7e 100644 --- a/src/python/breadth_first_search.cpp +++ b/src/python/breadth_first_search.cpp @@ -5,136 +5,52 @@ namespace boost { namespace graph { namespace python { -template -class bfs_visitor -{ - public: - typedef typename graph_traits::vertex_descriptor vertex_descriptor; - typedef typename graph_traits::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 -class bfs_visitor_wrap - : public bfs_visitor, - public boost::python::wrapper > -{ - public: - typedef typename bfs_visitor::vertex_descriptor vertex_descriptor; - typedef typename bfs_visitor::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::Name(x, g); \ - } \ - \ - void default_##Name(Descriptor x, const Graph& g) const \ - { this->bfs_visitor::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 -struct wrap_bfs_visitor_ref -{ - typedef typename graph_traits::vertex_descriptor vertex_descriptor; - typedef typename graph_traits::edge_descriptor edge_descriptor; - - wrap_bfs_visitor_ref(const bfs_visitor& 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& v; -}; - -template - class default_bfs_visitor : public bfs_visitor {}; +#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 void -breadth_first_search_qv +breadth_first_search_qvs (const Graph& g, typename Graph::Vertex s, python_queue& Q, - const bfs_visitor& visitor) + const bfs_visitor& visitor, + const vector_property_map* in_color) { + typedef vector_property_map ColorMap; + + ColorMap color = + in_color? *in_color : ColorMap(g.num_vertices(), g.get_vertex_index_map()); + typedef typename python_queue::default_queue default_queue_type; bool has_default_buffer = dynamic_cast(&Q); bool has_default_visitor = - dynamic_cast*>(&visitor); + dynamic_cast::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(visitor))); + color_map(color). + visitor(typename bfs_visitor::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(visitor))); + (g, s, Q, typename bfs_visitor::ref(visitor), color); } } } @@ -143,45 +59,25 @@ void export_breadth_first_search() { using boost::python::arg; - def("breadth_first_search", &breadth_first_search_qv, + def("breadth_first_search", &breadth_first_search_qvs, (arg("graph"), "root_vertex", arg("buffer") = python_queue::default_queue(), - arg("visitor") = default_bfs_visitor())); + arg("visitor") = bfs_visitor::default_arg(), + arg("color_map") = + (vector_property_map*)0)); - def("breadth_first_search", &breadth_first_search_qv, + def("breadth_first_search", &breadth_first_search_qvs, (arg("graph"), "root_vertex", arg("buffer") = python_queue::default_queue(), - arg("visitor") = default_bfs_visitor())); + arg("visitor") = bfs_visitor::default_arg(), + arg("color_map") = + (vector_property_map*)0)); } template void export_breadth_first_search_in_graph() { - using boost::python::arg; - - // BFS visitor - class_, boost::noncopyable>("BFSVisitor") - .def("initialize_vertex", &bfs_visitor::initialize_vertex, - &bfs_visitor_wrap::default_initialize_vertex) - .def("examine_vertex", &bfs_visitor::examine_vertex, - &bfs_visitor_wrap::default_examine_vertex) - .def("examine_edge", &bfs_visitor::examine_edge, - &bfs_visitor_wrap::default_examine_edge) - .def("tree_edge", &bfs_visitor::tree_edge, - &bfs_visitor_wrap::default_tree_edge) - .def("non_tree_edge", &bfs_visitor::non_tree_edge, - &bfs_visitor_wrap::default_non_tree_edge) - .def("gray_target", &bfs_visitor::gray_target, - &bfs_visitor_wrap::default_gray_target) - .def("black_target", &bfs_visitor::black_target, - &bfs_visitor_wrap::default_black_target) - .def("finish_vertex", &bfs_visitor::finish_vertex, - &bfs_visitor_wrap::default_finish_vertex) - ; - - class_, bases > > - ("DefaultBFSVisitor", no_init); - + bfs_visitor::declare("BFSVisitor", "DefaultBFSVisitor"); python_queue::declare("VertexQueue", "DefaultVertexQueue"); } diff --git a/src/python/dijkstra_shortest_paths.cpp b/src/python/dijkstra_shortest_paths.cpp index a63478f2..f35afbe7 100644 --- a/src/python/dijkstra_shortest_paths.cpp +++ b/src/python/dijkstra_shortest_paths.cpp @@ -65,8 +65,6 @@ dijkstra_shortest_paths template void export_dijkstra_shortest_paths_in_graph() { - using boost::python::arg; - dijkstra_visitor::declare("DijkstraVisitor", "DefaultDijkstraVisitor"); } diff --git a/src/python/module.cpp b/src/python/module.cpp index ba30594a..81d01e40 100644 --- a/src/python/module.cpp +++ b/src/python/module.cpp @@ -29,6 +29,12 @@ BOOST_PYTHON_MODULE(bgl) .value("graphviz", gfk_graphviz) ; + enum_("Color") + .value("white", color_traits::white()) + .value("gray", color_traits::gray()) + .value("black", color_traits::black()) + ; + export_Graph(); export_Digraph(); export_betweenness_centrality();