doc/*: Document Python bindings

src/python/basic_graph.cpp src/python/basic_graph.hpp:
  - Add ability to record the names of vertices input via the adjacency list
    reader.

example/python/breadth_first_search.py: Building a better example


[SVN r28350]
This commit is contained in:
Douglas Gregor 2005-04-20 23:45:55 +00:00
parent efc05efebd
commit 34bc3a8786
7 changed files with 622 additions and 53 deletions

View File

@ -10,8 +10,12 @@
<body>
<div class="titlepage"></div>
<div class="refnamediv">
<h2><img src="figs/python.gif" alt="(Python)"/><span class="refentrytitle">Function
betweenness_centrality_clustering</span></h2>
<IMG SRC="../../../boost.png"
ALT="C++ Boost" width="277" height="86">
<h1><img src="figs/python.gif" alt="(Python)"/><span class="refentrytitle">Function
betweenness_centrality_clustering</span></h1>
<p>boost::betweenness_centrality_clustering &mdash; Graph
clustering based on edge betweenness centrality.</p>
</div>
@ -48,53 +52,68 @@ clustering based on edge betweenness centrality.</p>
<div class="refsect1" lang="en"><a name="id822306" id=
"id822306"></a>
<h2>Description</h2>
<div class="variablelist">
<p class="title"><b>Parameters</b></p>
<dl>
<dt><span class="term">done</span></dt>
<dd>
<p>The function object that indicates termination of the algorithm.
It must be a ternary function object thats accepts the maximum
centrality, the descriptor of the edge that will be removed, and
the graph <tt class="computeroutput">g</tt> .</p>
</dd>
<dt><span class="term">edge_centrality</span></dt>
<dd>
<p>(UTIL/OUT) The property map that will store the betweenness
centrality for each edge. When the algorithm terminates, it will
contain the edge centralities for the graph. The type of this
property map must model the ReadWritePropertyMap concept. Defaults
to an <tt class="computeroutput">iterator_property_map</tt> whose
value type is <tt class="computeroutput">Done::centrality_type</tt>
and using <tt class="computeroutput">get(edge_index, g)</tt> for
the index map.</p>
</dd>
<dt><span class="term">g</span></dt>
<dd>
<p>The graph on which clustering will be performed. The type of
this parameter (<tt class="computeroutput">MutableGraph</tt> ) must
be a model of the VertexListGraph, IncidenceGraph, EdgeListGraph,
and Mutable Graph concepts.</p>
</dd>
<dt><span class="term">vertex_index</span></dt>
<dd>
<p>(IN) The property map that maps vertices to indices in the range
[0, num_vertices(g)). This type of this property map must model the
ReadablePropertyMap concept and its value type must be an integral
type. Defaults to <tt class="computeroutput">get(vertex_index,
g)</tt> .</p>
</dd>
</dl>
</div>
<p>This algorithm implements graph clustering based on edge
betweenness centrality. It is an iterative algorithm, where in each
step it compute the edge betweenness centrality (via <a href=
"betweenness_centrality.html">brandes_betweenness_centrality) and
"betweenness_centrality.html">brandes_betweenness_centrality</a>) and
removes the edge with the maximum betweenness centrality. The
<tt class="computeroutput">done</tt> function object determines
when the algorithm terminates (the edge found when the algorithm
terminates will not be removed).</p>
</div>
<h2>Parameters</h2>
IN: <tt>const Graph&amp; g</tt>
<blockquote>
The graph object on which the algorithm will be applied. The type
<tt>Graph</tt> must be a model of <a
href="VertexListGraph.html">Vertex List Graph</a> and <a
href="IncidenceGraph.html">Incidence Graph</a>. When an edge
centrality map is supplied, it must also model <a
href="EdgeListGraph.html">Edge List Graph</a> and <a
href="MutableGraph.html">MutableGraph</a>.<br>
<b>Python</b>: The parameter is named <tt>graph</tt>.
</blockquote>
IN: <tt>Done done</tt>
<blockquote>
The function object that indicates termination of the algorithm.
It must be a ternary function object thats accepts the maximum
centrality, the descriptor of the edge that will be removed, and
the graph <tt class="computeroutput">g</tt>.<br>
<b>Python</b>: Any callable Python object will suffice.
</blockquote>
OUT/UTIL: <tt>EdgeCentralityMap edge_centrality_map</tt>
<blockquote>
This property map is used to accumulate the betweenness centrality
of each edge, and is a secondary form of output for the
algorithm. The type <tt>EdgeCentralityMap</tt> must be a model of <a
href="../../property_map/ReadWritePropertyMap.html">Read/Write
Property Map</a>, with the graph's edge descriptor type as its key
type. The value type of this property map should be the same as the
value type of the <tt>CentralityMap</tt> property map.<br>
<b>Default:</b> a <tt>dummy_property_map</tt>, which requires no
work to compute and returns no answer.<br>
<b>Python</b>: The color map must be a <tt>edge_double_map</tt> for
the graph.<br>
<b>Python default</b>: <tt>graph.get_edge_double_map("centrality")</tt>
</blockquote>
IN: <tt>VertexIndexMap vertex_index</tt>
<blockquote>
This maps each vertex to an integer in the range <tt>[0,
num_vertices(g))</tt>. This is necessary for efficient updates of the
heap data structure when an edge is relaxed. The type
<tt>VertexIndexMap</tt> must be a model of
<a href="../../property_map/ReadablePropertyMap.html">Readable Property Map</a>. The value type of the map must be an
integer type. The vertex descriptor type of the graph needs to be
usable as the key type of the map.<br>
<b>Default:</b> <tt>get(vertex_index, g)</tt><br>
<b>Python</b>: Unsupported parameter.
</blockquote>
<table xmlns:rev=
"http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width=
"100%">

View File

@ -82,6 +82,7 @@ September 27, 2000.
<ul>
<li>Version 1.33.0<br><b>New algorithms and components</b>
<ul>
<li><a href="python.html">Experimental Python bindings</a>, from Doug Gregor and Indiana University.</li>
<LI><A href="floyd_warshall_shortest.html"><TT>floyd_warshall_all_pairs_shortest_paths</TT></A>, from Lauren Foutz and Scott Hill.</LI>
<LI><A href="astar_search.html"><TT>astar_search</TT></A>, from Kristopher Beevers and Jufeng Peng.</LI>
<LI><A href="fruchterman_reingold.html"><TT>fruchterman_reingold_force_directed_layout</TT></A>, from Doug Gregor and Indiana University.</a></LI>

View File

@ -16,7 +16,7 @@
ALINK="#ff0000">
<img SRC="../../../boost.png"
ALT="C++ Boost" width="277" height="86">
<h1>Boost Graph Library: Python Bindings (<b>Experimental</b>)</h1>
<h1><img src="figs/python.gif" alt="(Python)"/>Boost Graph Library: Python Bindings (<b>Experimental</b>)</h1>
<p>The Boost Graph Library offers a wealth of graph algorithms and
data types for C++. These algorithms are flexible and efficient,
but the mechanisms employed to achieve this goal can result in
@ -28,6 +28,38 @@
efficiency, making it possible to rapidly develop useful systems
using the BGL in Python.</p>
<ul>
<li><a href="#caveats">Caveats and Warnings</a></li>
<li><a href="#building">Building the Python Bindings</a></li>
<li><a href="#Goals">Goals</a></li>
<li><a href="#documentation">Documentation style</a>
<ul>
<li><a href="#graph_types">Graph types</a>
<li><a href="#types">Types</a></li>
<li><a href="#constructors">Constructors</a></li>
<li><a href="#general">General operations</a></li>
<li><a href="#vertex_list_graph">Vertex List Graph
operations</a></li>
<li><a href="#edge_list_graph">Edge List Graph
operations</a></li>
<li><a href="#mutable_graph">Mutable Graph
operations</a></li>
<li><a href="#incidence_graph">Incidence Graph
operations</a></li>
<li><a href="#vertex_property_maps">Vertex Property
Maps</a></li>
<li><a href="#edge_property_maps">Edge Property
Maps</a></li>
<li><a href="#input_output">Input/Output operations</a></li>
</li>
<li><a href="#algorithms">Algorithms</a></li>
<li><a href="#property_maps">Property Maps</a></li>
</ul>
</li>
<li><a href="#vis">A simple visualization tool</a></li>
<li><a href="#rfc">Request for comments</a></li>
</ul>
<h2><a name="caveats">Caveats and Warnings</a></h2>
<p>The Python bindings for the Graph library are experimental at
this time. The bindings may not work (but they probably do) and we
@ -48,6 +80,28 @@
GCC are okay but Visual C++ 7.1 will crash. We're working to
resolve the situation.</p>
<h2><a name="goals">Goals</a></h2>
<p>The goal of the BGL-Python bindings is to create a set of
bindings for the majority of the BGL in Python that:
<ul>
<li>"Feel" like the BGL, but with Python syntax.</li>
<li>Allow rapid prototyping of algorithms for the BGL.</li>
<li>Allow easy porting from the BGL in Python to the BGL in
C++.</li>
<li>Permit the use of the BGL in applications for which C++ is
not particularly well suited.</li>
<li>Strike a balance between simplicity, usability, and
efficiency.</li>
</ul>
<p>Note that one goal we did not list is that the Python syntax be
perfect for Python. For instance, one might implement a graph
library in Python very differently from the way the BGL is
implemented in C++, and the Python version may be syntactically
superior. Nonetheless, having a strong syntactic correlation
between the BGL in C++ and the BGL in Python is important for this
project.</p>
<h2><a name="example1">A First Example</a></h2>
<p>Our <a
href="../example/python/biconnected_components.py">first
@ -110,8 +164,489 @@ for v in art_points:
g.write_graphviz("biconnected_components_out.dot")
</pre>
<h2><a name="documentation">Documentation style</a></h2>
<p>
<h2><a name="documentation">Documentation style</a></h2> <p>The
Python bindings for the Boost Graph Library retain essentially the
same syntax. Because of this, there is no separate documentation
for the BGL in Python: each BGL component (algorithms, data
structures, etc.) available in Python will be marked with the
Python symbol <img src="figs/python_ico.gif"
alt="(Python)">. Unless an explicit <b>Python</b> section (or
field) is present, the Python versions have precisely the same
semantics as the C++ version.</p>
<h3><a name="graph_types"/>Graph types</h3>
<p>The C++ Boost Graph Library provides several graph types that
permit the generation of a huge number of specific graph types. In
Python, the BGL only exposes two general-purpose graph
types: <tt>Graph</tt> and <tt>Digraph</tt>, for undirected and
directed graphs, respectively. Both graph types are part of
the <tt>bgl</tt> extension module for Python. These graph types
are one-size-fits-most, offering stable vertex and edge
descriptors and a core set of operations from the <a
href="adjacency_list.html"><tt>adjacency_list</tt></a> class
template. The following sections briefly describe the operations
that can be performed on both the <tt>Graph</tt>
and <tt>Digraph</tt> Python graph types, although the
documentation uses <tt>Graph</tt> in the description.</p>
<p>Unlike the C++ graph types in the BGL, the Python graph types
use object-oriented syntax. For
instance, <tt>num_vertices(g)</tt> retrieves the number of
vertices in graph <tt>g</tt> in C++, whereas the Python
equivalent is <tt>g.num_vertices()</tt>. All of the graph
operations described in the following text are methods of the
graph type.</p>
<h4><a name="types"/>Types</h4>
<pre>Graph.Vertex</pre>
<blockquote>
The type of a vertex descriptor in the graph <tt>Graph</tt> that will
be used to refer to vertices in the graph. Note that there may be
several Python objects that refer to the same vertex, which can be
compared with <tt>==</tt> and <tt>!=</tt> correctly.<br>
<b>Bug</b>: Vertex descriptors do not work properly when used in a
Python <tt>dict</tt>.
</blockquote>
<pre>Graph.Edge</pre>
<blockquote>
The type of a edge descriptor in the graph <tt>Graph</tt> that will
be used to refer to edges in the graph. Note that there may be
several Python objects that refer to the same edge, which can be
compared with <tt>==</tt> and <tt>!=</tt> correctly.<br>
<b>Bug</b>: Edge descriptors do not work properly when used in a
Python <tt>dict</tt>.
</blockquote>
<h4><a name="constructors"/>Constructors</h4>
<pre>Graph()</pre>
<blockquote>
Constructs an empty graph.
</blockquote>
<pre>Graph(edges, name_map = "")</pre>
<blockquote>
Constructs a graph from a list of edges. <tt>edges</tt> should be a
Python sequence, the elements of which should be 2-tuples containing
the source and target of the edge. The sources and targets can be of
any type that has a less-than operator defined, e.g., strings or
integers. If a non-empty string is provided for <tt>name_map</tt>,
a <tt>vertex_object_map</tt> will be created that maps from the
vertices that are created to the name used in the list of edges.
</blockquote>
<pre>Graph(filename, kind)</pre>
<blockquote>
Constructs a graph from an external file using one of the Boost Graph
Library's graph parsers. <tt>filename</tt> is a string containing the
file name. <tt>kind</tt> is an value of type <tt>bgl.file_kind</tt>,
which has one of the following values:
<ul>
<li><tt>bgl.file_kind.adjlist</tt>: Reads an adjacency-list
representation into the graph. In the file, each line represents a
single edge. On that line will be the source and target of the edge,
separated by one or more spaces.</li>
<li><tt>bgl.file_kind.graphviz</tt>: Reads a <a
href="http://www.graphviz.org">GraphViz</a> DOT file into the
graph. The DOT file must represent a graph that is directed (for
a <tt>Digraph</tt>) or undirected (for a <tt>Graph</tt>). See <a
href="#read_graphviz"><tt>read_graphviz</tt></a> for additional details.</li>
</ul>
</blockquote>
<pre>Graph(generator, seed)</pre>
<blockquote>
Constructs a graph using the random generator <tt>generator</tt> and
random seed value <tt>seed</tt> (an integer). The <tt>generator</tt>
parameter may be one of three things:
<ul>
<li><tt>bgl.<a href="erdos_renyi_generator.html">ErdosRenyi</a>(n, p)</tt>: Generates a graph
with <tt>n</tt> vertices and a probability <i>0 &lt;= <tt>p</tt> &gt;=
1</i> of having an edge between any two vertices <tt>u</tt>
and <tt>v</tt>.</li>
<li><tt>bgl.<a href="small_world_generator.html">SmallWorld</a>(n, k, p)</tt>: Generates a small-world graph
with <tt>n</tt> vertices, each of which is connected to
its <tt>k</tt> nearest neighbors (assuming one places the vertices
in a circle). With probability <tt>p</tt>, each edge in the graph is
randomly rewired.</li>
<li><tt>bgl.<a href="plod_generator.html">PowerLawOutDegree</a>(n, alpha, beta)</tt>: Generates a
scale-free graph using the Power Law Out Degree model
with <tt>n</tt> vertices. Each vertex has degree <i>beta *
x<sup>-alpha</sup></i>, where <i>x</i> is a random value between 0
and <i>n-1</i>. The value of <i>beta</i> controls the y-intercept of the
curve, so that increasing <i>beta</i> increases the average degree of
vertices. The value of <i>alpha</i> controls how steeply the curve drops
off, with larger values indicating a steeper curve. The web graph,
for instance, has <i>alpha ~ 2.72</i>.</li>
</ul>
</blockquote>
<h4><a name="general"/>General operations</h4>
<pre>is_directed()</pre>
<blockquote>
Returns <tt>True</tt> if the edges in the graph are
directed, <tt>False</tt> otherwise.
</blockquote>
<h4><a name="vertex_list_graph"/>Vertex List Graph operations</h4>
<pre>num_vertices()</pre>
<blockquote>
Returns the number of vertices in the graph.
</blockquote>
<pre>vertices</pre>
<blockquote>
Returns a sequence containing all vertices in the graph. This
sequence has a Python iterator, such that the following Python code
prints the names of all vertices in graph <tt>g</tt>:
<pre>
for v in g.vertices:
print name[v]
</pre>
</blockquote>
<h4><a name="edge_list_graph"/>Edge List Graph operations</h4>
<pre>num_edges()</pre>
<blockquote>
Returns the number of edges in the graph.
</blockquote>
<pre>edges</pre>
<blockquote>
Returns a sequence containing all edges in the graph. This
sequence has a Python iterator, such that the following Python code
prints the weights of all edges in graph <tt>g</tt>:
<pre>
for e in g.edges:
print weight[e]
</pre>
</blockquote>
<h4><a name="mutable_graph"/>Mutable Graph operations</h4>
<pre>add_vertex()</pre>
<blockquote>
Adds a new vertex to the graph and returns the descriptor of the new
vertex. Default values for all property maps attached to the graph
will be provided for this vertex.
</blockquote>
<pre>clear_vertex(v)</pre>
<blockquote>
Removes all of the incoming and outgoing edges to the
vertex <tt>v</tt>. The properties for each of the edges removed will
be removed from the property maps attached to the graph.
</blockquote>
<pre>remove_vertex(v)</pre>
<blockquote>
Removes the vertex <tt>v</tt> from the graph. Before invoking this
function, there must be no edges attached to this vertex (either
incoming or outgoing), which can be ensured by a call
to <tt>clear_vertex(v)</tt>. Properties associated with this vertex
will be removed from the property maps attached to the graph. Once
this call completes, the vertex descriptor <tt>v</tt> is considered
invalid and cannot be used again.
</blockquote>
<pre>add_edge(u, v)</pre>
<blockquote>
Add an edge <i>(u, v)</i> to the graph and returns the descriptor for
the new edge. Default values for all property maps attached to the graph
will be provided for this edge.
</blockquote>
<pre>remove_edge(e)</pre>
<blockquote>
Remove the edge <tt>e</tt> from the graph. The properties
for <tt>e</tt> will be be removed from the property maps attached to
the graph. Once this operation completes, the edge
descriptor <tt>e</tt> is considered invalid and cannot be used again.
</blockquote>
<h4><a name="incidence_graph"/>Incidence Graph operations</h4>
<pre>source(e)</pre>
<blockquote>
Returns the source of the edge <tt>e</tt>.
</blockquote>
<pre>target(e)</pre>
<blockquote>
Returns the target of the edge <tt>e</tt>.
</blockquote>
<pre>out_edges(u)</pre>
<blockquote>
Returns a sequence containing all edges outgoing
from <tt>u</tt>. This sequence has an iterator, so that the following
Python code prints the weights of all edges outgoing from
vertex <tt>u</tt> in graph <tt>g</tt>:
<pre>
for e in g.out_edges(u):
print weight[e]
</pre>
For each edge <tt>e</tt>, <tt>g.source(e) == u</tt>.
</blockquote>
<pre>out_degree(u)</pre>
<blockquote>
Returns the number of edges outgoing from vertex <tt>u</tt>.
</blockquote>
<pre>in_edges(v)</pre>
<blockquote>
Returns a sequence containing all edges incoming
to <tt>v</tt>. This sequence has an iterator, so that the following
Python code prints the weights of all edges incoming to
vertex <tt>v</tt> in graph <tt>g</tt>:
<pre>
for e in g.in_edges(u):
print weight[e]
</pre>
For each edge <tt>e</tt>, <tt>g.target(e) == v</tt>. For undirected
graphs, the <tt>in_edges</tt> will be equivalent to
the <tt>out_edges</tt>, except that the source and target will be
swapped.
</blockquote>
<pre>in_degree(u)</pre>
<blockquote>
Returns the number of edges incoming to vertex <tt>u</tt>. For
undirected graphs, <tt>g.in_degree(u) == g.in_degree(v)</tt>.
</blockquote>
<pre>adjacent_vertices(u)</pre>
<blockquote>
Returns a sequence containing all vertices adjacent to
<tt>u</tt>. This sequence has an iterator, so that the following
Python code prints the names of all vertices adjacent to
vertex <tt>u</tt> in graph <tt>g</tt>:
<pre>
for v in g.adjacent_vertices(u):
print name[v]
</pre>
The sequence of adjacent vertices for vertex <tt>u</tt> corresponds to
the targets of the outgoing edges of <tt>u</tt>.
</blockquote>
<h4><a name="vertex_property_maps"/>Vertex property maps</h4>
<pre>has_vertex_map(name)</pre>
<blockquote>
Returns <tt>True</tt> if the graph contains a vertex property map
with the name <tt>name</tt>.
</blockquote>
<pre>get_vertex_index_map()</pre>
<blockquote>
Returns a property map that maps vertex descriptors to indices in the
range <i>[0, <tt>g.num_vertices()</tt>)</i>.
</blockquote>
<pre>get_vertex_color_map()</pre>
<blockquote>
Returns a property map that maps vertex descriptors to values of the
Python type <tt>bgl.Color</tt>, which is an enumeration containing
the values <tt>white</tt>, <tt>gray</tt>, and <tt>black</tt>. If a
property map of this name already exists, its values are converted to
colors. Otherwise, a new map is created.
</blockquote>
<pre>get_vertex_double_map()</pre>
<blockquote>
Returns a property map that maps vertex descriptors to <tt>double</tt>
values. If a property map of this name already exists, its values are
converted to <tt>double</tt>s. Otherwise, a new map is created.
</blockquote>
<pre>get_vertex_int_map()</pre>
<blockquote>
Returns a property map that maps vertex descriptors to <tt>int</tt>
values. If a property map of this name already exists, its values are
converted to <tt>int</tt>s. Otherwise, a new map is created.
</blockquote>
<pre>get_vertex_string_map()</pre>
<blockquote>
Returns a property map that maps vertex descriptors to <tt>string</tt>
values. If a property map of this name already exists, its values are
converted to <tt>string</tt>s. Otherwise, a new map is created.
</blockquote>
<pre>get_vertex_object_map()</pre>
<blockquote>
Returns a property map that maps vertex descriptors to
Python <tt>object</tt>s. If a property map of this name already
exists, its values are converted to <tt>object</tt>s. Otherwise, a new
map is created.
</blockquote>
<pre>get_vertex_point_map()</pre>
<blockquote>
Returns a property map that maps vertex descriptors to values of the
Python type <tt>bgl.Point2D</tt>, which is an class
containing <tt>x</tt> and <tt>y</tt> attributes
storing <tt>double</tt> values. If a property map of this name already
exists, its values are converted to 2-D points. Otherwise, a new map
is created.<br>
<b>Bug</b>: Writing just the <tt>x</tt> or <tt>y</tt> attributes of
a <tt>bgl.Point2D</tt> object does not work at this time. However,
you can create a new <tt>bgl.Point2D</tt> object and assign it into
the property map.
</blockquote>
<h4><a name="edge_property_maps"/>Edge property maps</h4>
<pre>has_edge_map(name)</pre>
<blockquote>
Returns <tt>True</tt> if the graph contains a edge property map
with the name <tt>name</tt>.
</blockquote>
<pre>get_edge_index_map()</pre>
<blockquote>
Returns a property map that maps edge descriptors to indices in the
range <i>[0, <tt>g.num_edges()</tt>)</i>.
</blockquote>
<pre>get_edge_color_map()</pre>
<blockquote>
Returns a property map that maps edge descriptors to values of the
Python type <tt>bgl.Color</tt>, which is an enumeration containing
the values <tt>white</tt>, <tt>gray</tt>, and <tt>black</tt>. If a
property map of this name already exists, its values are converted to
colors. Otherwise, a new map is created.
</blockquote>
<pre>get_edge_double_map()</pre>
<blockquote>
Returns a property map that maps edge descriptors to <tt>double</tt>
values. If a property map of this name already exists, its values are
converted to <tt>double</tt>s. Otherwise, a new map is created.
</blockquote>
<pre>get_edge_int_map()</pre>
<blockquote>
Returns a property map that maps edge descriptors to <tt>int</tt>
values. If a property map of this name already exists, its values are
converted to <tt>int</tt>s. Otherwise, a new map is created.
</blockquote>
<pre>get_edge_string_map()</pre>
<blockquote>
Returns a property map that maps edge descriptors to <tt>string</tt>
values. If a property map of this name already exists, its values are
converted to <tt>string</tt>s. Otherwise, a new map is created.
</blockquote>
<pre>get_edge_object_map()</pre>
<blockquote>
Returns a property map that maps edge descriptors to
Python <tt>object</tt>s. If a property map of this name already
exists, its values are converted to <tt>object</tt>s. Otherwise, a new
map is created.
</blockquote>
<h4><a name="input_output"/>Input/Output operations</h4>
<a name="read_graphviz"/><pre>read_graphviz(filename, node_id = "node_id")</pre>
<blockquote>
Reads a <a href="http://www.graphviz.org">GraphViz</a> file
named <tt>filename</tt>into the graph, which is assumed to be
empty. The operation will create a <tt>vertex_string_map</tt>
named <tt>node_id</tt> that maps from vertex descriptors to the node
identifiers in the GraphViz file. All vertex and edge attributes
stored in the file will be loaded into <tt>vertex_string_map</tt>
and <tt>edge_string_map</tt> property maps, respectively. An exception
will be thrown if parsing of the GraphViz file fails.
</blockquote>
<pre>write_graphviz(filename, node_id = None)</pre>
<blockquote>
Writes the graph into a file named <tt>filename</tt> in <a
href="http://www.graphviz.org">GraphViz</a> format. All vertex and
edge attributes stored in the graph's property maps will be written to
the file. If <tt>node_id</tt> is provided, the vertex identifiers in
the GraphViz output will correspond with the names provided in the
vertex property map <tt>node_id</tt>. Otherwise, integer indices will
be used to identify nodes in the output file.
</blockquote>
<h3><a name="algorithms"/>Algorithms</h3>
<p>All algorithms available in Python operate only on the Python
graph types supplied by the BGL-Python bindings and are not
generic in the same sense as their C++ counterparts. However,
unless marked otherwise, their parameters are still customizable
from Python. See, for instance, <a
href="breadth_first_search.html"><tt>breadth_first_search</tt></a>,
which can still be provided with a customized queue and visitor
from within Python. </p>
<p>All algorithms are in the <tt>bgl</tt> extension module, at the
top level, and have the same names as in C++.</p>
<p>The parameters of BGL functions exposed to Python have the same
general data types, order, and names as in C++. If the BGL
function takes named parameters, then the names of the parameters
can be used for keyword arguments in Python. For instance:</p>
<pre>
// C++
betweenness_centrality(g, weight_map(weight).centrality_map(centrality));
# Python
bgl.betweenness_centrality(g, weight_map = weight, centrality_map = centrality);
</pre>
<p>Unless otherwise specified, all parameters documented in C++
are available in Python. If there are any differences, the
parameter documentation will contain a <b>Python</b> line
describing those differences. If the default in Python differs
from the C++ default, the parameter documentation will contain
a <b>Python default</b> line. Finally, if the algorithm's
behavior is radically different in Python, the algorithm will
contain a "Python" section. Although not available now, we would
like to rewrite the C++ examples in Python and add a "Python
Example" for each algorithm with inline examples.</p>
<h3><a name="property_maps"/>Property Maps</h3>
<p>Property maps in Python allow the same <tt>[]</tt> operator
syntax as Python dictionaries. For instance, if we have a property
map <tt>rank</tt> mapping vertices to integers, we can increment
the rank of vertex <tt>v</tt> with the following Python code:</p>
<pre>
rank[v] = rank[v] + 1
</pre>
<p>However, unlike Python dictionaries one cannot enumerate the
keys or values in a property map. Instead, you must enumerate the
vertex or edges in the graph to index into the Python property
map. This restriction follows from the C++ formulation of
property maps, which do not allow such iteration.</p>
<h2><a name="vis"/>A simple visualization tool</a></h2>
<p>The program <tt>vis.py</tt>, in the <tt>examples/python</tt>
subdirectory, is a simple Graph visualization tool written in
Python using the BGL bindings. It can load graphs, perform graph
layout, run a few graph algorithms on graphs, etc. At present, it
is not a useful program <i>per se</i> but merely an example of
what can be achieved (quickly!) using the BGL-Python bindings. To
use this program you will need to install <a
href="http://www.wxpython.org/">wxPython</a>.
<h2><a name="rfc"/>Request for comments</a></h2>
<p><b>We want YOU</b> to send it comments, questions, bug reports,
or suggestions for the BGL-Python bindings. They are experimental,
used primarily in-house for rapid prototyping of graph systems. If
you have any ideas, please post them to the <a
href="http://lists.boost.org/mailman/listinfo.cgi/boost-users">Boost-Users</a>
or <a
href="http://lists.boost.org/mailman/listinfo.cgi/boost">Boost
Developers</a> mailing lists, or e-mail me directly at <script
language="Javascript">address("cs.indiana.edu",
"dgregor")</script>.</p>
<HR>
<TABLE>

View File

@ -67,6 +67,7 @@
<LI><A href="./MutablePropertyGraph.html">Mutable Property Graph</A>
</OL>
<li><a href="../../property_map/property_map.html">The Property Map Library</a> (technically not part of the graph library, but used a lot here)
<li><img src="figs/python_ico.gif" alt="(Python)"/><a href="python.html">Python bindings</a></li>
<li><a href="./visitor_concepts.html">Visitor Concepts</a>
<OL>
<LI><img src="figs/python_ico.gif" alt="(Python)"/><a href="./BFSVisitor.html">BFS Visitor</a>

View File

@ -1,14 +1,15 @@
from bgl import *
class bfs_print_discover_visitor(Graph.BFSVisitor):
def bfs_print_discover_visitor(self, dtime_map):
Graph.BFSVisitor.__init__(self)
def discover_vertex(self, u, g):
print "Discovered vertex ",
print u
g = Graph((("r", "s"), ("r", "v"), ("s", "w"), ("w", "r"), ("w", "t"), ("w", "x"), ("x", "t"), ("t", "u"), ("x", "y"), ("u", "y")))
g = Graph((("r", "s"), ("r", "v"), ("s", "w"), ("w", "r"), ("w", "t"), ("w", "x"), ("x", "t"), ("t", "u"), ("x", "y"), ("u", "y")), "label")
iter = g.vertices.__iter__()
iter.next()
s = iter.next()
breadth_first_search(g, s, visitor=bfs_print_discover_visitor())

View File

@ -114,13 +114,17 @@ basic_graph<DirectedS>::basic_graph()
{ }
template<typename DirectedS>
basic_graph<DirectedS>::basic_graph(::boost::python::object l)
basic_graph<DirectedS>::basic_graph(boost::python::object l,
const std::string& name_map)
: inherited()
{
using boost::python::object;
std::map<object, vertex_descriptor> verts;
int len = ::boost::python::extract<int>(l.attr("__len__")());
vector_property_map<object, VertexIndexMap> name;
if (!name_map.empty()) name = get_vertex_map<object>(name_map);
for (int i = 0; i < len; ++i) {
vertex_descriptor u, v;
object up = l[i][0];
@ -128,10 +132,16 @@ basic_graph<DirectedS>::basic_graph(::boost::python::object l)
typename std::map<object, vertex_descriptor>::iterator pos;
pos = verts.find(up);
if (pos == verts.end()) u = verts[up] = add_vertex();
if (pos == verts.end()) {
u = verts[up] = add_vertex();
if (!name_map.empty()) name[u] = up;
}
else u = pos->second;
pos = verts.find(vp);
if (pos == verts.end()) v = verts[vp] = add_vertex();
if (pos == verts.end()) {
v = verts[vp] = add_vertex();
if (!name_map.empty()) name[v] = vp;
}
else v = pos->second;
add_edge(u, v);
@ -572,6 +582,7 @@ void export_basic_graph(const char* name)
class_<basic_graph<DirectedS> >(name)
// Constructors
.def(init<object>())
.def(init<object, std::string>())
.def(init<std::string, graph_file_kind>())
.def(init<erdos_renyi, std::size_t>(
(arg("generator"), arg("seed") = 1)))

View File

@ -228,7 +228,8 @@ class basic_graph
adjacency_iterator;
basic_graph();
basic_graph(::boost::python::object);
basic_graph(boost::python::object,
const std::string& name_map = std::string());
basic_graph(const std::string& filename, graph_file_kind kind);
basic_graph(erdos_renyi, int seed);
basic_graph(power_law_out_degree, int seed);