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

Lots of new algorithms and cleanups of old ones

[SVN r27579]
This commit is contained in:
Douglas Gregor
2005-03-08 18:54:45 +00:00
parent 760b7f6c45
commit d3d9fdc0e5
28 changed files with 1423 additions and 193 deletions

View File

@@ -476,6 +476,13 @@ template<typename Graph> void export_in_graph();
template<typename DirectedS>
void export_basic_graph(const char* name)
{
using boost::python::class_;
using boost::python::init;
using boost::python::object;
using boost::python::range;
using boost::python::scope;
using boost::python::self;
typedef basic_graph<DirectedS> Graph;
typedef typename Graph::Vertex Vertex;
typedef typename Graph::Edge Edge;

View File

@@ -18,11 +18,12 @@
namespace boost { namespace graph { namespace python {
using namespace boost::python;
template<typename T> bool type_already_registered()
{
return objects::registered_class_object(python::type_id<T>()).get() != 0;
using boost::python::objects::registered_class_object;
using boost::python::type_id;
return registered_class_object(type_id<T>()).get() != 0;
}
template<typename Iterator>
@@ -34,15 +35,20 @@ public:
typename std::iterator_traits<Iterator>::value_type next()
{
if (first == last) objects::stop_iteration_error();
using boost::python::objects::stop_iteration_error;
if (first == last) stop_iteration_error();
return *first++;
}
static void declare(const char* name)
{
using boost::python::class_;
using boost::python::no_init;
using boost::python::objects::identity_function;
if (!type_already_registered<simple_python_iterator>())
class_<simple_python_iterator<Iterator> >(name, no_init)
.def("__iter__", objects::identity_function())
.def("__iter__", identity_function())
.def("next", &simple_python_iterator<Iterator>::next)
;
}
@@ -63,6 +69,9 @@ struct declare_readable_property_map
static void declare(const char* name)
{
using boost::python::class_;
using boost::python::no_init;
if (!type_already_registered<PropertyMap>())
class_<PropertyMap>(name, no_init)
.def("__getitem__", &getitem)
@@ -85,6 +94,9 @@ struct declare_property_map
static void declare(const char* name)
{
using boost::python::class_;
using boost::python::no_init;
if (!type_already_registered<PropertyMap>())
class_<PropertyMap>(name, no_init)
.def("__getitem__", &getitem)
@@ -130,7 +142,6 @@ struct basic_index_map
typedef typename property_traits<IndexMap>::reference reference;
typedef typename property_traits<IndexMap>::category category;
basic_index_map() {}
basic_index_map(const IndexMap& id = IndexMap())
: id(id) { }
@@ -371,6 +382,7 @@ get(edge_index_t, const basic_graph<DirectedS>& g)
} } } // end namespace boost::graph::python
#if 0
// Triggers bugs in GCC
namespace boost {
template<typename DirectedS>
struct property_map<graph::python::basic_graph<DirectedS>, vertex_index_t>

View File

@@ -0,0 +1,15 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
BGL_PYTHON_EVENT(initialize_vertex, vertex_descriptor)
BGL_PYTHON_EVENT(examine_edge, edge_descriptor)
BGL_PYTHON_EVENT(edge_relaxed, edge_descriptor)
BGL_PYTHON_EVENT(edge_not_relaxed, edge_descriptor)
BGL_PYTHON_EVENT(edge_minimized, edge_descriptor)
BGL_PYTHON_EVENT(edge_not_minimized, edge_descriptor)

View File

@@ -0,0 +1,111 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/bellman_ford_shortest_paths.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include <boost/python.hpp>
namespace boost { namespace graph { namespace python {
#define BGL_PYTHON_VISITOR bellman_ford_visitor
#define BGL_PYTHON_EVENTS_HEADER "bellman_ford_events.hpp"
#include "visitor.hpp"
#undef BGL_PYTHON_EVENTS_HEADER
#undef BGL_PYTHON_VISITOR
template<typename Graph>
void
bellman_ford_shortest_paths
(Graph& g, typename Graph::Vertex s,
const vector_property_map<typename Graph::Vertex,
typename Graph::VertexIndexMap>* in_predecessor,
const vector_property_map<double, typename Graph::VertexIndexMap>* in_distance,
const vector_property_map<double, typename Graph::EdgeIndexMap>* in_weight,
const bellman_ford_visitor<Graph>& visitor)
{
typedef vector_property_map<typename Graph::Vertex,
typename Graph::VertexIndexMap>
PredecessorMap;
typedef vector_property_map<double, typename Graph::VertexIndexMap>
DistanceMap;
typedef vector_property_map<double, typename Graph::EdgeIndexMap>
WeightMap;
PredecessorMap predecessor =
in_predecessor? *in_predecessor
: PredecessorMap(g.num_vertices(), g.get_vertex_index_map());
DistanceMap distance =
in_distance? *in_distance
: DistanceMap(g.num_vertices(), g.get_vertex_index_map());
WeightMap weight = in_weight? *in_weight
: g.template get_edge_map<double>("weight");
typedef typename bellman_ford_visitor<Graph>::default_arg default_visitor;
bool has_default_visitor = dynamic_cast<const default_visitor*>(&visitor);
if (!has_default_visitor) {
boost::bellman_ford_shortest_paths
(g,
root_vertex(s).
vertex_index_map(g.get_vertex_index_map()).
visitor(typename bellman_ford_visitor<Graph>::ref(visitor)).
predecessor_map(predecessor).
distance_map(distance).
weight_map(weight));
} else {
boost::bellman_ford_shortest_paths
(g,
root_vertex(s).
vertex_index_map(g.get_vertex_index_map()).
predecessor_map(predecessor).
distance_map(distance).
weight_map(weight));
}
}
template<typename Graph>
void export_bellman_ford_shortest_paths_in_graph()
{
bellman_ford_visitor<Graph>::declare("BellmanFordVisitor",
"DefaultBellmanFordVisitor");
}
void export_bellman_ford_shortest_paths()
{
using boost::python::arg;
using boost::python::def;
def("bellman_ford_shortest_paths", &bellman_ford_shortest_paths<Graph>,
(arg("graph"), arg("root_vertex"),
arg("predecessor_map") =
(vector_property_map<Graph::Vertex, Graph::VertexIndexMap>*)0,
arg("distance_map") =
(vector_property_map<double, Graph::VertexIndexMap>*)0,
arg("weight_map") =
(vector_property_map<double, Graph::EdgeIndexMap>*)0,
arg("visitor") = bellman_ford_visitor<Graph>::default_arg()));
def("bellman_ford_shortest_paths", &bellman_ford_shortest_paths<Digraph>,
(arg("graph"), arg("root_vertex"),
arg("predecessor_map") =
(vector_property_map<Digraph::Vertex, Digraph::VertexIndexMap>*)0,
arg("distance_map") =
(vector_property_map<double, Digraph::VertexIndexMap>*)0,
arg("weight_map") =
(vector_property_map<double, Digraph::EdgeIndexMap>*)0,
arg("visitor") = bellman_ford_visitor<Digraph>::default_arg()));
}
template void export_bellman_ford_shortest_paths_in_graph<Graph>();
template void export_bellman_ford_shortest_paths_in_graph<Digraph>();
} } } // end namespace boost::graph::python

View File

@@ -14,121 +14,120 @@ namespace boost { namespace graph { namespace python {
template<typename Graph>
void
brandes_betweenness_centrality_ve
brandes_betweenness_centrality
(Graph& g,
const vector_property_map<double, typename Graph::VertexIndexMap>& vertex_centrality,
const vector_property_map<double, typename Graph::EdgeIndexMap>& edge_centrality)
const vector_property_map<double, typename Graph::VertexIndexMap>* in_vertex_centrality,
const vector_property_map<double, typename Graph::EdgeIndexMap>* in_edge_centrality,
const vector_property_map<double, typename Graph::EdgeIndexMap>* weight)
{
brandes_betweenness_centrality
(g,
centrality_map(vertex_centrality).
edge_centrality_map(edge_centrality).
vertex_index_map(g.get_vertex_index_map()));
}
typedef vector_property_map<double, typename Graph::VertexIndexMap>
VertexCentralityMap;
template<typename Graph>
inline void
brandes_betweenness_centrality_v
(Graph& g,
const vector_property_map<double, typename Graph::VertexIndexMap>& vertex_centrality)
{
brandes_betweenness_centrality_ve(g, vertex_centrality,
g.template get_edge_map<double>("centrality"));
}
typedef vector_property_map<double, typename Graph::EdgeIndexMap>
EdgeCentralityMap;
template<typename Graph>
void
brandes_betweenness_centrality_wve
(Graph& g,
const vector_property_map<double, typename Graph::EdgeIndexMap>& weight,
const vector_property_map<double, typename Graph::VertexIndexMap>& vertex_centrality,
const vector_property_map<double, typename Graph::EdgeIndexMap>& edge_centrality)
{
brandes_betweenness_centrality
(g,
weight_map(weight).
centrality_map(vertex_centrality).
edge_centrality_map(edge_centrality).
vertex_index_map(g.get_vertex_index_map()));
}
VertexCentralityMap vertex_centrality =
in_vertex_centrality? *in_vertex_centrality
: g.template get_vertex_map<double>("centrality");
template<typename Graph>
inline void
brandes_betweenness_centrality_wv
(Graph& g,
const vector_property_map<double, typename Graph::EdgeIndexMap>& weight,
const vector_property_map<double, typename Graph::VertexIndexMap>& vertex_centrality)
{
brandes_betweenness_centrality_wve(g, weight, vertex_centrality,
g.template get_edge_map<double>("centrality"));
}
EdgeCentralityMap edge_centrality =
in_edge_centrality? *in_edge_centrality
: g.template get_edge_map<double>("centrality");
template<typename Graph>
inline void
brandes_betweenness_centrality_w
(Graph& g,
const vector_property_map<double, typename Graph::EdgeIndexMap>& weight)
{
brandes_betweenness_centrality_wv(g, weight,
g.template get_vertex_map<double>("centrality"));
}
template<typename Graph>
inline void
brandes_betweenness_centrality(Graph& g)
{
brandes_betweenness_centrality_v(g, g.template get_vertex_map<double>("centrality"));
if (weight) {
boost::brandes_betweenness_centrality
(g,
weight_map(*weight).
centrality_map(vertex_centrality).
edge_centrality_map(edge_centrality).
vertex_index_map(g.get_vertex_index_map()));
} else {
boost::brandes_betweenness_centrality
(g,
centrality_map(vertex_centrality).
edge_centrality_map(edge_centrality).
vertex_index_map(g.get_vertex_index_map()));
}
}
template<typename Graph>
void
relative_betweenness_centrality
(Graph& g,
const vector_property_map<double, typename Graph::VertexIndexMap>& centrality)
{ relative_betweenness_centrality(g, centrality); }
const vector_property_map<double, typename Graph::VertexIndexMap>* in_centrality)
{
typedef vector_property_map<double, typename Graph::VertexIndexMap>
CentralityMap;
CentralityMap centrality =
in_centrality? *in_centrality
: g.template get_vertex_map<double>("centrality");
relative_betweenness_centrality(g, centrality);
}
template<typename Graph>
double
central_point_dominance
(Graph& g,
const vector_property_map<double, typename Graph::VertexIndexMap>& centrality)
{ return boost::central_point_dominance(g, centrality); }
const vector_property_map<double, typename Graph::VertexIndexMap>* in_centrality)
{
typedef vector_property_map<double, typename Graph::VertexIndexMap>
CentralityMap;
CentralityMap centrality =
in_centrality? *in_centrality
: g.template get_vertex_map<double>("centrality");
return boost::central_point_dominance(g, centrality);
}
void export_betweenness_centrality()
{
using boost::python::arg;
using boost::python::def;
// Graph
def("brandes_betweenness_centrality",
&brandes_betweenness_centrality<Graph>);
def("brandes_betweenness_centrality",
&brandes_betweenness_centrality_v<Graph>);
def("brandes_betweenness_centrality",
&brandes_betweenness_centrality_ve<Graph>);
def("brandes_betweenness_centrality",
&brandes_betweenness_centrality_w<Graph>);
def("brandes_betweenness_centrality",
&brandes_betweenness_centrality_wv<Graph>);
def("brandes_betweenness_centrality",
&brandes_betweenness_centrality_wve<Graph>);
&brandes_betweenness_centrality<Graph>,
(arg("graph"),
arg("vertex_centrality_map") =
(vector_property_map<double, Digraph::VertexIndexMap>*)0,
arg("edge_centrality_map") =
(vector_property_map<double, Digraph::EdgeIndexMap>*)0,
arg("weight_map") =
(vector_property_map<double, Digraph::EdgeIndexMap>*)0));
def("relative_betweenness_centrality",
&relative_betweenness_centrality<Graph>);
def("central_point_dominance", &central_point_dominance<Graph>);
&relative_betweenness_centrality<Graph>,
(arg("graph"),
arg("vertex_centrality_map") =
(vector_property_map<double, Graph::VertexIndexMap>*)0));
def("central_point_dominance",
&central_point_dominance<Graph>,
(arg("graph"),
arg("vertex_centrality_map") =
(vector_property_map<double, Graph::VertexIndexMap>*)0));
// Digraph
def("brandes_betweenness_centrality",
&brandes_betweenness_centrality<Digraph>);
def("brandes_betweenness_centrality",
&brandes_betweenness_centrality_v<Digraph>);
def("brandes_betweenness_centrality",
&brandes_betweenness_centrality_ve<Digraph>);
def("brandes_betweenness_centrality",
&brandes_betweenness_centrality_w<Digraph>);
def("brandes_betweenness_centrality",
&brandes_betweenness_centrality_wv<Digraph>);
def("brandes_betweenness_centrality",
&brandes_betweenness_centrality_wve<Digraph>);
&brandes_betweenness_centrality<Digraph>,
(arg("graph"),
arg("vertex_centrality_map") =
(vector_property_map<double, Digraph::VertexIndexMap>*)0,
arg("edge_centrality_map") =
(vector_property_map<double, Digraph::EdgeIndexMap>*)0,
arg("weight_map") =
(vector_property_map<double, Digraph::EdgeIndexMap>*)0));
def("relative_betweenness_centrality",
&relative_betweenness_centrality<Digraph>);
def("central_point_dominance", &central_point_dominance<Digraph>);
&relative_betweenness_centrality<Digraph>,
(arg("graph"),
arg("vertex_centrality_map") =
(vector_property_map<double, Digraph::VertexIndexMap>*)0));
def("central_point_dominance",
&central_point_dominance<Digraph>,
(arg("graph"),
arg("vertex_centrality_map") =
(vector_property_map<double, Digraph::VertexIndexMap>*)0));
}
} } } // end namespace boost::graph::python

View File

@@ -52,6 +52,7 @@ articulation_points(const Graph& g)
void export_biconnected_components()
{
using boost::python::arg;
using boost::python::def;
def("biconnected_components", &biconnected_components<Graph>,
(arg("graph"),

View File

@@ -21,7 +21,7 @@ namespace boost { namespace graph { namespace python {
template<typename Graph>
void
breadth_first_search_qvs
breadth_first_search
(const Graph& g,
typename Graph::Vertex s,
python_queue<typename Graph::Vertex>& Q,
@@ -63,23 +63,74 @@ breadth_first_search_qvs
}
}
template<typename Graph>
void
breadth_first_visit
(const Graph& g,
typename Graph::Vertex s,
python_queue<typename Graph::Vertex>& Q,
const bfs_visitor<Graph>& visitor,
const vector_property_map<default_color_type,
typename Graph::VertexIndexMap>& color)
{
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<typename bfs_visitor<Graph>::default_arg const*>(&visitor);
if (has_default_buffer) {
if (has_default_visitor) {
boost::breadth_first_visit(g, s, color_map(color));
} else {
boost::breadth_first_visit
(g, s,
color_map(color).
visitor(typename bfs_visitor<Graph>::ref(visitor)));
}
} else {
if (has_default_visitor) {
boost::breadth_first_visit(g, s,
buffer(Q).
color_map(color));
} else {
boost::breadth_first_visit
(g, s, Q, typename bfs_visitor<Graph>::ref(visitor), color);
}
}
}
void export_breadth_first_search()
{
using boost::python::arg;
using boost::python::def;
def("breadth_first_search", &breadth_first_search_qvs<Graph>,
def("breadth_first_search", &breadth_first_search<Graph>,
(arg("graph"), "root_vertex",
arg("buffer") = python_queue<Graph::Vertex>::default_queue(),
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_qvs<Digraph>,
def("breadth_first_visit", &breadth_first_visit<Graph>,
(arg("graph"), "root_vertex",
arg("buffer") = python_queue<Graph::Vertex>::default_queue(),
arg("visitor") = bfs_visitor<Graph>::default_arg(),
arg("color_map")));
def("breadth_first_search", &breadth_first_search<Digraph>,
(arg("graph"), "root_vertex",
arg("buffer") = python_queue<Digraph::Vertex>::default_queue(),
arg("visitor") = bfs_visitor<Digraph>::default_arg(),
arg("color_map") =
(vector_property_map<default_color_type, Digraph::VertexIndexMap>*)0));
def("breadth_first_visit", &breadth_first_visit<Digraph>,
(arg("graph"), "root_vertex",
arg("buffer") = python_queue<Digraph::Vertex>::default_queue(),
arg("visitor") = bfs_visitor<Digraph>::default_arg(),
arg("color_map")));
}
template<typename Graph>

View File

@@ -0,0 +1,45 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/circle_layout.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include "point2d.hpp"
namespace boost { namespace graph { namespace python {
template<typename Graph>
void
circle_graph_layout
(Graph& g,
const vector_property_map<point2d, typename Graph::VertexIndexMap>* in_pos,
double radius)
{
typedef vector_property_map<point2d, typename Graph::VertexIndexMap>
PositionMap;
PositionMap pos =
in_pos? *in_pos : g.template get_vertex_map<point2d>("position");
circle_graph_layout(g, pos, radius);
}
void export_circle_graph_layout()
{
using boost::python::arg;
using boost::python::def;
def("circle_graph_layout",
&circle_graph_layout<Graph>,
(arg("graph"),
arg("position") =
(vector_property_map<point2d, Graph::VertexIndexMap>*)0,
arg("radius") = 250.0));
}
} } } // end namespace boost::graph::python

View File

@@ -0,0 +1,51 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/connected_components.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include <boost/python.hpp>
namespace boost { namespace graph { namespace python {
template<typename Graph>
int
connected_components
(Graph& g,
const vector_property_map<int, typename Graph::VertexIndexMap>* in_component,
const vector_property_map<default_color_type,
typename Graph::VertexIndexMap>* in_color)
{
typedef vector_property_map<int, typename Graph::VertexIndexMap> ComponentMap;
typedef vector_property_map<default_color_type,
typename Graph::VertexIndexMap> ColorMap;
ComponentMap component =
in_component? *in_component : g.template get_vertex_map<int>("component");
ColorMap color =
in_color? *in_color : ColorMap(g.num_vertices(), g.get_vertex_index_map());
return boost::connected_components(g, component, color_map(color));
}
void export_connected_components()
{
using boost::python::arg;
using boost::python::def;
def("connected_components", &connected_components<Graph>,
(arg("graph"),
arg("component_map") =
(vector_property_map<int, Graph::VertexIndexMap>*)0,
arg("color_map") =
(vector_property_map<default_color_type, Graph::VertexIndexMap>*)0));
}
} } } // end namespace boost::graph::python

View File

@@ -0,0 +1,103 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/dag_shortest_paths.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include <boost/python.hpp>
#include "dijkstra_visitor.hpp"
namespace boost { namespace graph { namespace python {
template<typename Graph>
void
dag_shortest_paths
(Graph& g, typename Graph::Vertex s,
const vector_property_map<typename Graph::Vertex,
typename Graph::VertexIndexMap>* in_predecessor,
const vector_property_map<double, typename Graph::VertexIndexMap>* in_distance,
const vector_property_map<double, typename Graph::EdgeIndexMap>* in_weight,
const dijkstra_visitor<Graph>& visitor)
{
typedef vector_property_map<typename Graph::Vertex,
typename Graph::VertexIndexMap>
PredecessorMap;
typedef vector_property_map<double, typename Graph::VertexIndexMap>
DistanceMap;
typedef vector_property_map<double, typename Graph::EdgeIndexMap>
WeightMap;
PredecessorMap predecessor =
in_predecessor? *in_predecessor
: PredecessorMap(g.num_vertices(), g.get_vertex_index_map());
DistanceMap distance =
in_distance? *in_distance
: DistanceMap(g.num_vertices(), g.get_vertex_index_map());
WeightMap weight = in_weight? *in_weight
: g.template get_edge_map<double>("weight");
typedef typename dijkstra_visitor<Graph>::default_arg default_visitor;
bool has_default_visitor = dynamic_cast<const default_visitor*>(&visitor);
if (!has_default_visitor) {
boost::dag_shortest_paths
(g, s,
vertex_index_map(g.get_vertex_index_map()).
visitor(typename dijkstra_visitor<Graph>::ref(visitor)).
predecessor_map(predecessor).
distance_map(distance).
weight_map(weight));
} else {
boost::dag_shortest_paths
(g, s,
vertex_index_map(g.get_vertex_index_map()).
predecessor_map(predecessor).
distance_map(distance).
weight_map(weight));
}
}
template<typename Graph>
void export_dag_shortest_paths_in_graph()
{
dijkstra_visitor<Graph>::declare("DijkstraVisitor",
"DefaultDijkstraVisitor");
}
void export_dag_shortest_paths()
{
using boost::python::arg;
using boost::python::def;
def("dag_shortest_paths", &dag_shortest_paths<Graph>,
(arg("graph"), arg("root_vertex"),
arg("predecessor_map") =
(vector_property_map<Graph::Vertex, Graph::VertexIndexMap>*)0,
arg("distance_map") =
(vector_property_map<double, Graph::VertexIndexMap>*)0,
arg("weight_map") =
(vector_property_map<double, Graph::EdgeIndexMap>*)0,
arg("visitor") = dijkstra_visitor<Graph>::default_arg()));
def("dag_shortest_paths", &dag_shortest_paths<Digraph>,
(arg("graph"), arg("root_vertex"),
arg("predecessor_map") =
(vector_property_map<Digraph::Vertex, Digraph::VertexIndexMap>*)0,
arg("distance_map") =
(vector_property_map<double, Digraph::VertexIndexMap>*)0,
arg("weight_map") =
(vector_property_map<double, Digraph::EdgeIndexMap>*)0,
arg("visitor") = dijkstra_visitor<Digraph>::default_arg()));
}
template void export_dag_shortest_paths_in_graph<Graph>();
template void export_dag_shortest_paths_in_graph<Digraph>();
} } } // end namespace boost::graph::python

View File

@@ -0,0 +1,156 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/undirected_dfs.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include "queue.hpp"
namespace boost { namespace graph { namespace python {
#define BGL_PYTHON_VISITOR dfs_visitor
#define BGL_PYTHON_EVENTS_HEADER "dfs_events.hpp"
#include "visitor.hpp"
#undef BGL_PYTHON_EVENTS_HEADER
#undef BGL_PYTHON_VISITOR
template<typename Graph>
void
depth_first_search
(const Graph& g,
const dfs_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());
bool has_default_visitor =
dynamic_cast<typename dfs_visitor<Graph>::default_arg const*>(&visitor);
if (has_default_visitor) {
boost::depth_first_search(g, boost::dfs_visitor<>(), color);
} else {
boost::depth_first_search(g, typename dfs_visitor<Graph>::ref(visitor),
color);
}
}
template<typename Graph>
void
depth_first_visit
(const Graph& g,
typename Graph::Vertex s,
const dfs_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());
bool has_default_visitor =
dynamic_cast<typename dfs_visitor<Graph>::default_arg const*>(&visitor);
if (has_default_visitor) {
boost::depth_first_visit(g, s, boost::dfs_visitor<>(), color);
} else {
boost::depth_first_visit(g, s, typename dfs_visitor<Graph>::ref(visitor),
color);
}
}
template<typename Graph>
void
undirected_dfs
(const Graph& g,
const dfs_visitor<Graph>& visitor,
const vector_property_map<default_color_type,
typename Graph::VertexIndexMap>* in_color,
const vector_property_map<default_color_type,
typename Graph::EdgeIndexMap>* in_edge_color)
{
typedef vector_property_map<default_color_type,
typename Graph::VertexIndexMap> ColorMap;
typedef vector_property_map<default_color_type,
typename Graph::EdgeIndexMap> EdgeColorMap;
ColorMap color =
in_color? *in_color : ColorMap(g.num_vertices(), g.get_vertex_index_map());
EdgeColorMap edge_color =
in_edge_color? *in_edge_color
: EdgeColorMap(g.num_edges(), g.get_edge_index_map());
bool has_default_visitor =
dynamic_cast<typename dfs_visitor<Graph>::default_arg const*>(&visitor);
if (has_default_visitor) {
boost::undirected_dfs(g, boost::dfs_visitor<>(), color, edge_color);
} else {
boost::undirected_dfs(g, typename dfs_visitor<Graph>::ref(visitor),
color, edge_color);
}
}
void export_depth_first_search()
{
using boost::python::arg;
using boost::python::def;
def("depth_first_search", &depth_first_search<Graph>,
(arg("graph"),
arg("visitor") = dfs_visitor<Graph>::default_arg(),
arg("color_map") =
(vector_property_map<default_color_type, Graph::VertexIndexMap>*)0));
def("depth_first_visit", &depth_first_visit<Graph>,
(arg("graph"),
arg("root_vertex"),
arg("visitor") = dfs_visitor<Graph>::default_arg(),
arg("color_map") =
(vector_property_map<default_color_type, Graph::VertexIndexMap>*)0));
def("undirected_dfs", &undirected_dfs<Graph>,
(arg("graph"),
arg("visitor") = dfs_visitor<Graph>::default_arg(),
arg("color_map") =
(vector_property_map<default_color_type, Graph::VertexIndexMap>*)0,
arg("edge_color_map") =
(vector_property_map<default_color_type, Graph::EdgeIndexMap>*)0));
def("depth_first_search", &depth_first_search<Digraph>,
(arg("graph"),
arg("visitor") = dfs_visitor<Digraph>::default_arg(),
arg("color_map") =
(vector_property_map<default_color_type, Digraph::VertexIndexMap>*)0));
def("depth_first_visit", &depth_first_visit<Digraph>,
(arg("graph"),
arg("root_vertex"),
arg("visitor") = dfs_visitor<Digraph>::default_arg(),
arg("color_map") =
(vector_property_map<default_color_type, Digraph::VertexIndexMap>*)0));
}
template<typename Graph>
void export_depth_first_search_in_graph()
{
dfs_visitor<Graph>::declare("DFSVisitor", "DefaultDFSVisitor");
}
template void export_depth_first_search_in_graph<Graph>();
template void export_depth_first_search_in_graph<Digraph>();
} } } // end namespace boost::graph::python

18
src/python/dfs_events.hpp Normal file
View File

@@ -0,0 +1,18 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
BGL_PYTHON_EVENT(initialize_vertex, vertex_descriptor)
BGL_PYTHON_EVENT(start_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(back_edge, edge_descriptor)
BGL_PYTHON_EVENT(forward_or_cross_edge, edge_descriptor)
BGL_PYTHON_EVENT(finish_vertex, vertex_descriptor)

View File

@@ -10,15 +10,10 @@
#include "graph.hpp"
#include "digraph.hpp"
#include <boost/python.hpp>
#include "dijkstra_visitor.hpp"
namespace boost { namespace graph { namespace python {
#define BGL_PYTHON_VISITOR dijkstra_visitor
#define BGL_PYTHON_EVENTS_HEADER "dijkstra_events.hpp"
#include "visitor.hpp"
#undef BGL_PYTHON_EVENTS_HEADER
#undef BGL_PYTHON_VISITOR
template<typename Graph>
void
dijkstra_shortest_paths
@@ -69,7 +64,6 @@ dijkstra_shortest_paths
}
}
template<typename Graph>
void export_dijkstra_shortest_paths_in_graph()
{
@@ -80,7 +74,7 @@ void export_dijkstra_shortest_paths_in_graph()
void export_dijkstra_shortest_paths()
{
using boost::python::arg;
using boost::python::def;
def("dijkstra_shortest_paths", &dijkstra_shortest_paths<Graph>,
(arg("graph"), arg("root_vertex"),

View File

@@ -6,18 +6,15 @@
// Authors: Douglas Gregor
// Andrew Lumsdaine
#ifndef BOOST_GRAPH_PYTHON_DONE_HPP
#define BOOST_GRAPH_PYTHON_DONE_HPP
#ifndef BOOST_GRAPH_PYTHON_DIJKSTRA_VISITOR_HPP
#define BOOST_GRAPH_PYTHON_DIJKSTRA_VISITOR_HPP
namespace boost { namespace graph { namespace python {
class done
{
public:
virtual ~done() { }
virtual bool operator()() const = 0;
};
#define BGL_PYTHON_VISITOR dijkstra_visitor
#define BGL_PYTHON_EVENTS_HEADER "dijkstra_events.hpp"
#include "visitor.hpp"
#undef BGL_PYTHON_EVENTS_HEADER
#undef BGL_PYTHON_VISITOR
} } } // end namespace boost::graph::python
#endif // BOOST_GRAPH_PYTHON_DONE_HPP
#endif BOOST_GRAPH_PYTHON_DIJKSTRA_VISITOR_HPP

View File

@@ -1,32 +0,0 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include "done.hpp"
#include <boost/python.hpp>
namespace boost { namespace graph { namespace python {
using namespace boost::python;
class done_wrap : public done, public wrapper<done>
{
public:
bool operator()() const
{
return this->get_override("__call__")();
}
};
void export_done()
{
class_<done_wrap, boost::noncopyable>("Done")
.def("__call__", pure_virtual(&done::operator()))
;
}
} } } // end namespace boost::graph::python

View File

@@ -7,19 +7,130 @@
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/fruchterman_reingold.hpp>
#include <boost/graph/random_layout.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include "point2d.hpp"
#include <boost/random/linear_congruential.hpp>
#include <ctime>
namespace boost { namespace graph { namespace python {
template<typename F, typename Result = double>
struct python_or_functor
{
explicit python_or_functor(boost::python::object callable, const F& f = F())
: callable(callable), f(f) { }
// For cooling
Result operator()()
{
using boost::python::object;
using boost::python::extract;
if (callable != object()) return extract<Result>(callable());
else return f();
}
// For the attractive_force
template<typename Graph>
Result
operator()(typename graph_traits<Graph>::edge_descriptor e,
double k, double dist, const Graph& g) const
{
using boost::python::object;
using boost::python::extract;
if (callable != object()) return extract<Result>(callable(e, k, dist, g));
else return f(e, k, dist, g);
}
// For the repulsive_force
template<typename Graph>
Result
operator()(typename graph_traits<Graph>::vertex_descriptor u,
typename graph_traits<Graph>::vertex_descriptor v,
double k, double dist, const Graph& g) const
{
using boost::python::object;
using boost::python::extract;
if (callable != object())
return extract<Result>(callable(u, v, k, dist, g));
else return f(u, v, k, dist, g);
}
private:
boost::python::object callable;
F f;
};
template<typename Graph>
void
fruchterman_reingold_force_directed_layout
(Graph& g,
const vector_property_map<point2d, typename Graph::VertexIndexMap>* in_pos,
double width, double height,
)
boost::python::object attractive_force,
boost::python::object repulsive_force,
// TBD: force pairs?
boost::python::object cooling,
bool progressive)
{
using boost::python::object;
typedef vector_property_map<point2d, typename Graph::VertexIndexMap>
PositionMap;
PositionMap pos =
in_pos? *in_pos : g.template get_vertex_map<point2d>("position");
if (!progressive) {
minstd_rand gen(std::time(0));
random_graph_layout(g, pos, -width/2, width/2, -height/2, height/2, gen);
}
python_or_functor<linear_cooling<double> > cool(cooling, 100);
if (attractive_force != object() || repulsive_force != object()) {
python_or_functor<square_distance_attractive_force> fa(attractive_force);
python_or_functor<square_distance_repulsive_force> fr(repulsive_force);
boost::fruchterman_reingold_force_directed_layout
(g, pos, width, height,
boost::vertex_index_map(g.get_vertex_index_map()).
attractive_force(fa).repulsive_force(fr).
cooling(cool));
} else {
if (cooling != object()) {
boost::fruchterman_reingold_force_directed_layout
(g, pos, width, height,
boost::vertex_index_map(g.get_vertex_index_map()).
cooling(cool));
} else {
boost::fruchterman_reingold_force_directed_layout
(g, pos, width, height,
vertex_index_map(g.get_vertex_index_map()));
}
}
}
void export_fruchterman_reingold_force_directed_layout()
{
using boost::python::arg;
using boost::python::def;
using boost::python::object;
def("fruchterman_reingold_force_directed_layout",
&fruchterman_reingold_force_directed_layout<Graph>,
(arg("graph"),
arg("position") =
(vector_property_map<point2d, Graph::VertexIndexMap>*)0,
arg("width") = 500.0,
arg("height") = 500.0,
arg("attractive_force") = object(),
arg("repulsive_force") = object(),
arg("cooling") = object(),
arg("progressive") = false));
}
} } } // end namespace boost::graph::python

View File

@@ -0,0 +1,68 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/incremental_components.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include <boost/python.hpp>
namespace boost { namespace graph { namespace python {
template<typename Graph>
class IncrementalComponents
{
public:
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef vector_property_map<vertex_descriptor,
typename Graph::VertexIndexMap> ParentMap;
typedef vector_property_map<std::size_t,
typename Graph::VertexIndexMap> RankMap;
IncrementalComponents(const Graph& g)
: ds(RankMap(num_vertices(g), g.get_vertex_index_map()),
ParentMap(num_vertices(g), g.get_vertex_index_map()))
{
initialize_incremental_components(g, ds);
incremental_components(g, ds);
}
void make_set(vertex_descriptor u) { ds.make_set(u); }
void union_set(vertex_descriptor u, vertex_descriptor v)
{ ds.union_set(u, v); }
bool same_component(vertex_descriptor u, vertex_descriptor v)
{ return boost::same_component(u, v, ds); }
private:
disjoint_sets<RankMap, ParentMap> ds;
};
template<typename Graph>
std::auto_ptr<IncrementalComponents<Graph> >
incremental_components(Graph& g)
{
typedef std::auto_ptr<IncrementalComponents<Graph> > result_type;
return result_type(new IncrementalComponents<Graph>(g));
}
void export_incremental_components()
{
using boost::python::arg;
using boost::python::def;
using boost::python::class_;
using boost::python::no_init;
class_<IncrementalComponents<Graph> >("IncrementalComponents", no_init)
.def("make_set", &IncrementalComponents<Graph>::make_set)
.def("union_set", &IncrementalComponents<Graph>::union_set)
.def("same_component", &IncrementalComponents<Graph>::same_component)
;
def("incremental_components", &incremental_components<Graph>);
}
} } } // end namespace boost::graph::python

View File

@@ -0,0 +1,80 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/isomorphism.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include <boost/python.hpp>
namespace boost { namespace graph { namespace python {
template<typename Vertex>
struct py_vertex_invariant
{
explicit py_vertex_invariant(boost::python::object invariant)
: invariant(invariant) { }
int operator()(const Vertex& v1, const Vertex& v2)
{ return boost::python::extract<int>(invariant(v1, v2)); }
private:
boost::python::object invariant;
};
template<typename Graph>
bool
isomorphism
(Graph& g1,
Graph& g2,
const vector_property_map<typename Graph::Vertex,
typename Graph::VertexIndexMap>* in_iso,
boost::python::object invariant)
{
typedef typename Graph::Vertex Vertex;
typedef vector_property_map<Vertex, typename Graph::VertexIndexMap> IsoMap;
IsoMap iso =
in_iso? *in_iso
: IsoMap(num_vertices(g1), g1.get_vertex_index_map());
if (invariant != boost::python::object())
return boost::isomorphism
(g1, g2,
isomorphism_map(iso).
vertex_invariant(py_vertex_invariant<Vertex>(invariant)).
vertex_index1_map(g1.get_vertex_index_map()).
vertex_index2_map(g2.get_vertex_index_map()));
else
return boost::isomorphism
(g1, g2,
isomorphism_map(iso).
vertex_index1_map(g1.get_vertex_index_map()).
vertex_index2_map(g2.get_vertex_index_map()));
}
void export_isomorphism()
{
using boost::python::arg;
using boost::python::def;
using boost::python::object;
def("isomorphism", &isomorphism<Graph>,
(arg("graph"),
arg("isomorphism_map") =
(vector_property_map<Graph::Vertex, Graph::VertexIndexMap>*)0,
arg("vertex_invariant") = object()));
def("isomorphism", &isomorphism<Digraph>,
(arg("graph"),
arg("isomorphism_map") =
(vector_property_map<Digraph::Vertex, Digraph::VertexIndexMap>*)0,
arg("vertex_invariant") = object()));
}
} } } // end namespace boost::graph::python

View File

@@ -0,0 +1,80 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/kamada_kawai_spring_layout.hpp>
#include <boost/graph/circle_layout.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include "point2d.hpp"
#include <boost/graph/iteration_macros.hpp>
namespace boost { namespace graph { namespace python {
template<typename Graph>
void
kamada_kawai_spring_layout
(Graph& g,
const vector_property_map<point2d, typename Graph::VertexIndexMap>* in_pos,
const vector_property_map<double, typename Graph::EdgeIndexMap>* in_weight,
double side_length,
boost::python::object done,
double spring_constant,
bool progressive)
{
using boost::python::object;
typedef vector_property_map<point2d, typename Graph::VertexIndexMap>
PositionMap;
typedef vector_property_map<double, typename Graph::EdgeIndexMap>
WeightMap;
PositionMap pos =
in_pos? *in_pos : g.template get_vertex_map<point2d>("position");
WeightMap weight =
in_weight? *in_weight : WeightMap(num_edges(g), g.get_edge_index_map());
// If we weren't give a weight map, assume unweighted edges
if (!in_weight) BGL_FORALL_EDGES_T(e, g, Graph) put(weight, e, 1.0);
if (!progressive) circle_graph_layout(g, pos, side_length/2);
if (done != object()) {
boost::kamada_kawai_spring_layout(g, pos, weight,
boost::side_length(side_length), done,
spring_constant,
g.get_vertex_index_map());
} else {
boost::kamada_kawai_spring_layout(g, pos, weight,
boost::side_length(side_length),
layout_tolerance<double>(),
spring_constant,
g.get_vertex_index_map());
}
}
void export_kamada_kawai_spring_layout()
{
using boost::python::arg;
using boost::python::def;
using boost::python::object;
def("kamada_kawai_spring_layout",
&kamada_kawai_spring_layout<Graph>,
(arg("graph"),
arg("position") =
(vector_property_map<point2d, Graph::VertexIndexMap>*)0,
arg("weight") =
(vector_property_map<double, Graph::EdgeIndexMap>*)0,
arg("side_length") = 500.0,
arg("done") = object(),
arg("spring_constant") = 1.0,
arg("progressive") = false));
}
} } } // end namespace boost::graph::python

View File

@@ -0,0 +1,53 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/kruskal_min_spanning_tree.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include <boost/python.hpp>
#include <list>
#include <iterator>
namespace boost { namespace graph { namespace python {
template<typename Graph>
boost::python::list
kruskal_minimum_spanning_tree
(Graph& g,
const vector_property_map<double, typename Graph::EdgeIndexMap>* in_weight)
{
typedef vector_property_map<double, typename Graph::EdgeIndexMap> WeightMap;
WeightMap weight =
in_weight? *in_weight : g.template get_edge_map<double>("weight");
std::list<typename Graph::Edge> mst_edges;
boost::kruskal_minimum_spanning_tree
(g,
std::back_inserter(mst_edges),
vertex_index_map(g.get_vertex_index_map()).
weight_map(weight));
boost::python::list result;
for (typename std::list<typename Graph::Edge>::iterator i
= mst_edges.begin(); i != mst_edges.end(); ++i)
result.append(*i);
return result;
}
void export_kruskal_minimum_spanning_tree()
{
using boost::python::arg;
using boost::python::def;
def("kruskal_minimum_spanning_tree", &kruskal_minimum_spanning_tree<Graph>,
(arg("graph"),
arg("weight_map") =
(vector_property_map<double, Graph::EdgeIndexMap>*)0));
}
} } } // end namespace boost::graph::python

View File

@@ -10,7 +10,7 @@
#include "graph.hpp"
#include "digraph.hpp"
#include <boost/python.hpp>
// #include "point2d.hpp"
#include "point2d.hpp"
namespace boost { namespace graph { namespace python {
@@ -18,22 +18,47 @@ extern void export_Graph();
extern void export_Digraph();
extern void export_betweenness_centrality();
extern void export_page_rank();
extern void export_done();
extern void export_breadth_first_search();
extern void export_depth_first_search();
extern void export_dijkstra_shortest_paths();
extern void export_bellman_ford_shortest_paths();
extern void export_dag_shortest_paths();
extern void export_prim_minimum_spanning_tree();
template<typename Graph> void export_breadth_first_search_in_graph();
template<typename Graph> void export_depth_first_search_in_graph();
template<typename Graph> void export_dijkstra_shortest_paths_in_graph();
template<typename Graph> void export_dag_shortest_paths_in_graph();
template<typename Graph> void export_bellman_ford_shortest_paths_in_graph();
template<typename Graph> void export_prim_minimum_spanning_tree_in_graph();
extern void export_connected_components();
extern void export_strong_components();
extern void export_biconnected_components();
extern void export_incremental_components();
extern void export_topological_sort();
extern void export_circle_graph_layout();
extern void export_fruchterman_reingold_force_directed_layout();
extern void export_kamada_kawai_spring_layout();
extern void export_kruskal_minimum_spanning_tree();
extern void export_transitive_closure();
//extern void export_transpose_graph();
extern void export_isomorphism();
template<typename Graph>
void export_in_graph()
{
export_breadth_first_search_in_graph<Graph>();
export_depth_first_search_in_graph<Graph>();
export_dijkstra_shortest_paths_in_graph<Graph>();
export_bellman_ford_shortest_paths_in_graph<Graph>();
export_dag_shortest_paths_in_graph<Graph>();
export_prim_minimum_spanning_tree_in_graph<Graph>();
}
BOOST_PYTHON_MODULE(bgl)
{
using boost::python::class_;
using boost::python::enum_;
enum_<graph_file_kind>("file_kind")
.value("adjlist", gfk_adjlist)
.value("graphviz", gfk_graphviz)
@@ -45,21 +70,39 @@ BOOST_PYTHON_MODULE(bgl)
.value("black", color_traits<default_color_type>::black())
;
#if 0
class_<point2d>("Point2D")
.def("x", &point2d::x)
.def("y", &point2d::y)
.def_readwrite("x", &point2d::x)
.def_readwrite("y", &point2d::y)
;
#endif
export_Graph();
export_Digraph();
export_betweenness_centrality();
export_page_rank();
export_done();
// Core Algorithm Patterns
export_breadth_first_search();
export_depth_first_search();
// Shortest Paths Algorithms
export_dijkstra_shortest_paths();
export_biconnected_components();
export_bellman_ford_shortest_paths();
export_dag_shortest_paths();
// Minimum Spanning Tree Algorithms
export_kruskal_minimum_spanning_tree();
export_prim_minimum_spanning_tree();
// Connected Components Algorithms
export_connected_components();
export_strong_components();
export_biconnected_components();
export_incremental_components();
// Layout Algorithms
export_circle_graph_layout();
export_fruchterman_reingold_force_directed_layout();
export_kamada_kawai_spring_layout();
// Other algorithms
export_topological_sort();
export_transitive_closure();
// export_transpose_graph();
export_isomorphism();
}
template void export_in_graph<Graph>();

View File

@@ -8,67 +8,73 @@
// Andrew Lumsdaine
#include "digraph.hpp"
#include <boost/graph/page_rank.hpp>
#include "done.hpp"
namespace boost { namespace graph { namespace python {
template<typename Graph>
void
page_rank_ri
page_rank_iterations
(Graph& g,
const vector_property_map<double, typename Graph::VertexIndexMap>& rank,
const vector_property_map<double, typename Graph::VertexIndexMap>* in_rank,
int iterations)
{
boost::graph::page_rank(g, rank, graph::n_iterations(20));
}
typedef vector_property_map<double, typename Graph::VertexIndexMap>
RankMap;
template<typename Graph>
void
page_rank_i(Graph& g, int iterations)
{
boost::graph::page_rank(g, g.template get_vertex_map<double>("rank"),
graph::n_iterations(20));
RankMap rank =
in_rank? *in_rank : g.template get_vertex_map<double>("pagerank");
boost::graph::page_rank(g, rank, graph::n_iterations(20));
}
struct page_rank_wrap_done
{
page_rank_wrap_done(const done& d) : d(d) { }
page_rank_wrap_done(boost::python::object done) : done(done) { }
template<typename RankMap, typename Graph>
bool
operator()(const RankMap&, const Graph&) const
operator()(const RankMap& rank, const Graph& g) const
{
return d();
using boost::python::extract;
return extract<bool>(done(rank, g));
}
const done& d;
private:
boost::python::object done;
};
template<typename Graph>
void
page_rank_rd
page_rank_done
(Graph& g,
const vector_property_map<double, typename Graph::VertexIndexMap>& rank,
const done& d)
const vector_property_map<double, typename Graph::VertexIndexMap>* in_rank,
boost::python::object done)
{
boost::graph::page_rank(g, rank, page_rank_wrap_done(d));
}
typedef vector_property_map<double, typename Graph::VertexIndexMap>
RankMap;
template<typename Graph>
void page_rank_d(Graph& g, const done& d)
{
boost::graph::page_rank(g, g.template get_vertex_map<double>("rank"),
page_rank_wrap_done(d));
RankMap rank =
in_rank? *in_rank : g.template get_vertex_map<double>("pagerank");
boost::graph::page_rank(g, rank, wrap_pr_done(done));
}
void export_page_rank()
{
def("page_rank", &page_rank_i<Digraph>);
def("page_rank", &page_rank_ri<Digraph>);
def("page_rank", &page_rank_rd<Digraph>);
def("page_rank", &page_rank_d<Digraph>);
using boost::python::arg;
using boost::python::def;
def("page_rank", &page_rank_iterations<Digraph>,
(arg("graph"),
arg("rank_map") =
(vector_property_map<double, Digraph::VertexIndexMap>*)0,
arg("iterations") = 20));
def("page_rank", &page_rank_iterations<Digraph>,
(arg("graph"),
arg("rank_map") =
(vector_property_map<double, Digraph::VertexIndexMap>*)0,
arg("done")));
}

View File

@@ -0,0 +1,105 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/prim_minimum_spanning_tree.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include <boost/python.hpp>
#include "dijkstra_visitor.hpp"
namespace boost { namespace graph { namespace python {
template<typename Graph>
void
prim_minimum_spanning_tree
(Graph& g, typename Graph::Vertex s,
const vector_property_map<typename Graph::Vertex,
typename Graph::VertexIndexMap>* in_predecessor,
const vector_property_map<double, typename Graph::VertexIndexMap>* in_distance,
const vector_property_map<double, typename Graph::EdgeIndexMap>* in_weight,
const dijkstra_visitor<Graph>& visitor)
{
typedef vector_property_map<typename Graph::Vertex,
typename Graph::VertexIndexMap>
PredecessorMap;
typedef vector_property_map<double, typename Graph::VertexIndexMap>
DistanceMap;
typedef vector_property_map<double, typename Graph::EdgeIndexMap>
WeightMap;
PredecessorMap predecessor =
in_predecessor? *in_predecessor
: PredecessorMap(g.num_vertices(), g.get_vertex_index_map());
DistanceMap distance =
in_distance? *in_distance
: DistanceMap(g.num_vertices(), g.get_vertex_index_map());
WeightMap weight = in_weight? *in_weight
: g.template get_edge_map<double>("weight");
typedef typename dijkstra_visitor<Graph>::default_arg default_visitor;
bool has_default_visitor = dynamic_cast<const default_visitor*>(&visitor);
if (!has_default_visitor) {
boost::prim_minimum_spanning_tree
(g,
predecessor,
root_vertex(s).
vertex_index_map(g.get_vertex_index_map()).
visitor(typename dijkstra_visitor<Graph>::ref(visitor)).
distance_map(distance).
weight_map(weight));
} else {
boost::prim_minimum_spanning_tree
(g,
predecessor,
root_vertex(s).
vertex_index_map(g.get_vertex_index_map()).
distance_map(distance).
weight_map(weight));
}
}
template<typename Graph>
void export_prim_minimum_spanning_tree_in_graph()
{
dijkstra_visitor<Graph>::declare("DijkstraVisitor",
"DefaultDijkstraVisitor");
}
void export_prim_minimum_spanning_tree()
{
using boost::python::arg;
using boost::python::def;
def("prim_minimum_spanning_tree", &prim_minimum_spanning_tree<Graph>,
(arg("graph"), arg("root_vertex"),
arg("predecessor_map") =
(vector_property_map<Graph::Vertex, Graph::VertexIndexMap>*)0,
arg("distance_map") =
(vector_property_map<double, Graph::VertexIndexMap>*)0,
arg("weight_map") =
(vector_property_map<double, Graph::EdgeIndexMap>*)0,
arg("visitor") = dijkstra_visitor<Graph>::default_arg()));
def("prim_minimum_spanning_tree", &prim_minimum_spanning_tree<Digraph>,
(arg("graph"), arg("root_vertex"),
arg("predecessor_map") =
(vector_property_map<Digraph::Vertex, Digraph::VertexIndexMap>*)0,
arg("distance_map") =
(vector_property_map<double, Digraph::VertexIndexMap>*)0,
arg("weight_map") =
(vector_property_map<double, Digraph::EdgeIndexMap>*)0,
arg("visitor") = dijkstra_visitor<Digraph>::default_arg()));
}
template void export_prim_minimum_spanning_tree_in_graph<Graph>();
template void export_prim_minimum_spanning_tree_in_graph<Digraph>();
} } } // end namespace boost::graph::python

View File

@@ -43,9 +43,14 @@ class python_queue
static void declare(const char* name, const char* default_name)
{
using namespace boost::python;
using boost::python::objects::registered_class_object;
using boost::python::type_id;
using boost::python::class_;
using boost::python::bases;
using boost::python::no_init;
using boost::python::pure_virtual;
if (objects::registered_class_object(type_id<wrap>()).get() == 0) {
if (registered_class_object(type_id<wrap>()).get() == 0) {
class_<wrap, boost::noncopyable>(name)
.def("empty", pure_virtual(&python_queue<T>::empty))
.def("top", pure_virtual(&python_queue<T>::top))
@@ -54,7 +59,7 @@ class python_queue
;
}
if (objects::registered_class_object(type_id<default_queue>()).get() == 0)
if (registered_class_object(type_id<default_queue>()).get() == 0)
{
class_<default_queue, bases<python_queue> >(default_name, no_init);
}

View File

@@ -0,0 +1,42 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/strong_components.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include <boost/python.hpp>
namespace boost { namespace graph { namespace python {
template<typename Graph>
int
strong_components
(Graph& g,
const vector_property_map<int, typename Graph::VertexIndexMap>* in_component)
{
typedef vector_property_map<int, typename Graph::VertexIndexMap> ComponentMap;
ComponentMap component =
in_component? *in_component : g.template get_vertex_map<int>("component");
return boost::strong_components (g, component,
vertex_index_map(g.get_vertex_index_map()));
}
void export_strong_components()
{
using boost::python::arg;
using boost::python::def;
def("strong_components", &strong_components<Digraph>,
(arg("graph"),
arg("component_map") =
(vector_property_map<int, Digraph::VertexIndexMap>*)0));
}
} } } // end namespace boost::graph::python

View File

@@ -0,0 +1,55 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/topological_sort.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include <boost/python.hpp>
#include <list>
#include <iterator>
namespace boost { namespace graph { namespace python {
template<typename Graph>
boost::python::list
topological_sort
(const Graph& g,
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());
std::list<typename Graph::Vertex> topo_order;
boost::python::list result;
boost::topological_sort(g, std::back_inserter(topo_order), color_map(color));
for (typename std::list<typename Graph::Vertex>::iterator i
= topo_order.begin(); i != topo_order.end(); ++i)
result.append(*i);
return result;
}
void export_topological_sort()
{
using boost::python::arg;
using boost::python::def;
def("topological_sort", &topological_sort<Graph>,
(arg("graph"),
arg("color_map") =
(vector_property_map<default_color_type, Graph::VertexIndexMap>*)0));
def("topological_sort", &topological_sort<Digraph>,
(arg("graph"),
arg("color_map") =
(vector_property_map<default_color_type, Digraph::VertexIndexMap>*)0));
}
} } } // end namespace boost::graph::python

View File

@@ -0,0 +1,45 @@
// Copyright 2005 The Trustees of Indiana University.
// Use, modification and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Authors: Douglas Gregor
// Andrew Lumsdaine
#include <boost/graph/transitive_closure.hpp>
#include "graph.hpp"
#include "digraph.hpp"
#include <boost/python.hpp>
#include <list>
#include <iterator>
namespace boost { namespace graph { namespace python {
template<typename Graph>
std::auto_ptr<Graph>
transitive_closure
(const Graph& g,
const vector_property_map<typename Graph::Vertex,
typename Graph::VertexIndexMap>* g_to_tc_map)
{
std::auto_ptr<Graph> tc(new Graph);
if (g_to_tc_map)
boost::transitive_closure(g, *tc, *g_to_tc_map, g.get_vertex_index_map());
else
boost::transitive_closure(g, *tc,
vertex_index_map(g.get_vertex_index_map()));
return tc;
}
void export_transitive_closure()
{
using boost::python::arg;
using boost::python::def;
def("transitive_closure", &transitive_closure<Digraph>,
(arg("graph"),
arg("g_to_tc_map") =
(vector_property_map<Graph::Vertex, Digraph::VertexIndexMap>*)0));
}
} } } // end namespace boost::graph::python

View File

@@ -20,9 +20,9 @@ class BGL_PYTHON_VISITOR
#define BGL_PYTHON_EVENT(Name,Descriptor) \
void Name(Descriptor x, const Graph& g) const \
{ \
if (override f = this->get_override(#Name)) \
if (boost::python::override f = this->get_override(#Name)) \
f(x, boost::cref(g)); \
else BGL_PYTHON_VISITOR<Graph>::Name(x, g); \
else BGL_PYTHON_VISITOR<Graph>::Name(x, g); \
} \
\
void default_##Name(Descriptor x, const Graph& g) const \
@@ -62,6 +62,15 @@ class BGL_PYTHON_VISITOR
static void declare(const char* name, const char* default_name)
{
using boost::python::class_;
using boost::python::bases;
using boost::python::no_init;
using boost::python::objects::registered_class_object;
using boost::python::type_id;
if (registered_class_object(type_id<wrap>()).get() != 0)
return;
#define BGL_PYTHON_EVENT(Name, Descriptor) \
.def(#Name, &BGL_PYTHON_VISITOR<Graph>::Name, &wrap::default_##Name)
class_<wrap, boost::noncopyable>(name)