mirror of
https://github.com/boostorg/graph.git
synced 2026-07-21 13:23:42 +00:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e5d7b1b2b0 | |||
| b2d857aca9 | |||
| cbe45d215b | |||
| 716a8111d0 | |||
| cb2b20d574 | |||
| 3b4f924529 | |||
| 3dbdd2c52b | |||
| 9b1f71c1d5 | |||
| 43c1f8a033 | |||
| 4063919a57 | |||
| 9a074a7e51 | |||
| f027c1c895 | |||
| 2e7f8349c5 | |||
| e1e2b225b1 | |||
| 97f5379094 | |||
| 41e0867907 | |||
| e62876d483 | |||
| 70d4967318 | |||
| 6777fb6f8f | |||
| 7a615168e2 | |||
| 85f275a7e0 | |||
| 9d25102143 | |||
| e341b7a672 | |||
| 0452c06499 | |||
| 8f1cebb377 | |||
| 47da7dd548 | |||
| 2c69bbae8a |
@@ -1,61 +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
|
||||
|
||||
subproject libs/graph/build/python ;
|
||||
|
||||
SEARCH on python.jam = $(BOOST_BUILD_PATH) ;
|
||||
include python.jam ;
|
||||
|
||||
extension bgl
|
||||
: # Sources
|
||||
../../src/python/module.cpp
|
||||
# Graph types
|
||||
../../src/python/graph.cpp
|
||||
../../src/python/digraph.cpp
|
||||
# Graph I/O
|
||||
../../src/python/graphviz.cpp
|
||||
# Graph algorithms
|
||||
# Core Algorithm Patterns
|
||||
../../src/python/breadth_first_search.cpp
|
||||
../../src/python/depth_first_search.cpp
|
||||
# Shortest Paths Algorithms
|
||||
../../src/python/dijkstra_shortest_paths.cpp
|
||||
../../src/python/bellman_ford_shortest_paths.cpp
|
||||
../../src/python/dag_shortest_paths.cpp
|
||||
# Minimum Spanning Tree Algorithms
|
||||
../../src/python/kruskal_min_spanning_tree.cpp
|
||||
../../src/python/prim_minimum_spanning_tree.cpp
|
||||
# Connected Components Algorithms
|
||||
../../src/python/connected_components.cpp
|
||||
../../src/python/strong_components.cpp
|
||||
../../src/python/biconnected_components.cpp
|
||||
../../src/python/incremental_components.cpp
|
||||
# ...
|
||||
# Other algorithms
|
||||
../../src/python/topological_sort.cpp
|
||||
../../src/python/transitive_closure.cpp
|
||||
# ../../src/python/transpose_graph.cpp Need copy_graph to work, first
|
||||
../../src/python/isomorphism.cpp
|
||||
../../src/python/betweenness_centrality.cpp
|
||||
../../src/python/sequential_vertex_coloring.cpp
|
||||
# Sparse Matrix Ordering
|
||||
../../src/python/cuthill_mckee_ordering.cpp
|
||||
../../src/python/king_ordering.cpp
|
||||
# ../../src/python/minimum_degree_ordering.cpp
|
||||
../../src/python/circle_layout.cpp
|
||||
../../src/python/fruchterman_reingold.cpp
|
||||
../../src/python/kamada_kawai_spring_layout.cpp
|
||||
../../src/python/page_rank.cpp
|
||||
# Pickling support
|
||||
../../src/python/pickle.cpp
|
||||
<dll>../../../python/build/boost_python
|
||||
<lib>../bgl-viz
|
||||
: # Default build
|
||||
<debug-symbols>off
|
||||
;
|
||||
@@ -156,6 +156,7 @@ when there is a negative cycle in the graph.
|
||||
<li><a href="./bellman_visitor.html"><tt>bellman_visitor</tt></a>
|
||||
</ul>
|
||||
|
||||
<a name="python"></a>
|
||||
<h3>Python</h3>
|
||||
|
||||
To implement a model of the <tt>BellmanFordVisitor</tt> concept in Python,
|
||||
|
||||
@@ -174,6 +174,7 @@ all the out-edges of <tt>u</tt> have been examined.
|
||||
<li><a href="./dfs_visitor.html"><tt>dfs_visitor</tt></a>
|
||||
</ul>
|
||||
|
||||
<a name="python"></a>
|
||||
<h3>Python</h3>
|
||||
|
||||
To implement a model of the <tt>DFSVisitor</tt> concept in Python,
|
||||
|
||||
@@ -184,6 +184,7 @@ search tree and all of the adjacent vertices have been discovered
|
||||
<li><a href="./dijkstra_visitor.html"><tt>dijkstra_visitor</tt></a>
|
||||
</ul>
|
||||
|
||||
<a name="python"></a>
|
||||
<h3>Python</h3>
|
||||
|
||||
To implement a model of the <tt>DijkstraVisitor</tt> concept in Python,
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace boost {
|
||||
template <class Graph, class VertexDescriptor, class OutEdgeIter>
|
||||
class adjacency_iterator_generator {
|
||||
public:
|
||||
typedef <a href="../../utility/iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> type;
|
||||
typedef <a href="../../iterator/doc/iterator_adaptor.html">iterator_adaptor</a><...> type;
|
||||
};
|
||||
}
|
||||
</pre>
|
||||
|
||||
@@ -380,6 +380,11 @@ Software--Practice & Experience, 21 (11), pp. 1129-1164, 1991.
|
||||
<em>An automatic reordering scheme for simultaneous equations derived from network analysis.</em><br>
|
||||
Int. J. Numer. Methods Engrg. 2, pp. 523-533, 1970.
|
||||
|
||||
<p></p><dt><a name="palmer2000">63</a>
|
||||
<dd>C. Palmer and J. Steffan<br>
|
||||
<em>Generating Network Topologies That Obey Power Laws</em><br>
|
||||
Proceedings of GLOBECOM. November, 2000.
|
||||
|
||||
</dl>
|
||||
|
||||
<br>
|
||||
|
||||
@@ -242,7 +242,7 @@ UTIL: <tt>buffer(Buffer& Q)</tt>
|
||||
<b>Default:</b> <tt>boost::queue</tt><br>
|
||||
|
||||
<b>Python</b>: The buffer must derive from the <a
|
||||
href="./Buffer.html#python">Buffer</a> type for the graph.
|
||||
href="./Buffer.html">Buffer</a> type for the graph.
|
||||
|
||||
</blockquote>
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ UTIL: <tt>buffer(Buffer& Q)</tt>
|
||||
<b>Default:</b> <tt>boost::queue</tt><br>
|
||||
|
||||
<b>Python</b>: The buffer must derive from the <a
|
||||
href="./Buffer.html#python">Buffer</a> type for the graph.
|
||||
href="./Buffer.html">Buffer</a> type for the graph.
|
||||
</blockquote>
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -26,9 +26,9 @@
|
||||
<ul>
|
||||
|
||||
<li>Dynamic graph algorithms such as described in <a
|
||||
href="http://citeseer.nj.nec.com/eppstein99dynamic.html">Dynamic Graph
|
||||
href="http://citeseer.ist.psu.edu/eppstein99dynamic.html">Dynamic Graph
|
||||
Algorithms</a> and <a
|
||||
href="http://citeseer.nj.nec.com/alberts98software.html">A Software
|
||||
href="http://citeseer.ist.psu.edu/alberts98software.html">A Software
|
||||
Library of Dynamic Graph Algorithms</a>.
|
||||
|
||||
<li>Polish up code/docs for pending items and champion the formal
|
||||
|
||||
@@ -83,7 +83,7 @@ The goal of the Cuthill-Mckee (and reverse Cuthill-Mckee) ordering
|
||||
algorithm[<A
|
||||
HREF="bibliography.html#george81:__sparse_pos_def">14</A>, <A
|
||||
HREF="bibliography.html#cuthill69:reducing_bandwith">43</A>, <a
|
||||
href="bibliography.html#liu75:rcm">44</a>, <a
|
||||
href="bibliography.html#liu75:anal_cm_rcm">44</a>, <a
|
||||
href="bibliography.html#george71:fem">45</a> ] is to reduce the <a
|
||||
href="./bandwidth.html">bandwidth</a> of a graph by reordering the
|
||||
indices assigned to each vertex. The Cuthill-Mckee ordering algorithm
|
||||
|
||||
@@ -54,7 +54,7 @@ than either the Dijkstra or Bellman-Ford algorithm.
|
||||
Use breadth-first search instead of this algorithm
|
||||
when all edge weights are equal to one. For the definition of the
|
||||
shortest-path problem see Section <A
|
||||
HREF="graph_theory_review.html#sec:shortest-path-algorithms">Shortest-Paths
|
||||
HREF="graph_theory_review.html#sec:shortest-paths-algorithms">Shortest-Paths
|
||||
Algorithms</A> for some background to the shortest-path problem.
|
||||
</P>
|
||||
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
|
||||
<P>
|
||||
<PRE>
|
||||
template <class <a href="./IncidenceGraph.html">IncidenceGraph</a>, class <a href="./DFSVisitor.html">DFSVisitor</a>, class <a href="#ColorMap">ColorMap</a>>
|
||||
template <class <a href="./IncidenceGraph.html">IncidenceGraph</a>, class <a href="./DFSVisitor.html">DFSVisitor</a>, class ColorMap>
|
||||
void depth_first_visit(IncidenceGraph& g,
|
||||
typename graph_traits<IncidenceGraph>::vertex_descriptor s,
|
||||
DFSVisitor& vis, ColorMap color)
|
||||
|
||||
template <class <a href="./IncidenceGraph.html">IncidenceGraph</a>, class <a href="./DFSVisitor.html">DFSVisitor</a>, class <a href="#ColorMap">ColorMap</a>,
|
||||
template <class <a href="./IncidenceGraph.html">IncidenceGraph</a>, class <a href="./DFSVisitor.html">DFSVisitor</a>, class ColorMap,
|
||||
class TerminatorFunc>
|
||||
void depth_first_visit(IncidenceGraph& g,
|
||||
typename graph_traits<IncidenceGraph>::vertex_descriptor s,
|
||||
|
||||
@@ -37,14 +37,14 @@ dijkstra_shortest_paths(Graph& g,
|
||||
template <typename Graph, typename <a href="DijkstraVisitor.html">DijkstraVisitor</a>,
|
||||
typename PredecessorMap, typename DistanceMap,
|
||||
typename WeightMap, typename VertexIndexMap, typename <a href="http://www.sgi.com/tech/stl/BinaryPredicate.html">CompareFunction</a>, typename <a href="http://www.sgi.com/tech/stl/BinaryFunction.html">CombineFunction</a>,
|
||||
typename DistInf, typename DistZero>
|
||||
typename DistInf, typename DistZero, typename ColorMap = <i>default</i>>
|
||||
void dijkstra_shortest_paths
|
||||
(const Graph& g,
|
||||
typename graph_traits<Graph>::vertex_descriptor s,
|
||||
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
|
||||
VertexIndexMap index_map,
|
||||
CompareFunction compare, CombineFunction combine, DistInf inf, DistZero zero,
|
||||
DijkstraVisitor vis)
|
||||
DijkstraVisitor vis, ColorMap color = <i>default</i>)
|
||||
</PRE>
|
||||
|
||||
<P>
|
||||
@@ -56,7 +56,7 @@ algorithm for the case when some edge weights are negative. Use
|
||||
breadth-first search instead of Dijkstra's algorithm when all edge
|
||||
weights are equal to one. For the definition of the shortest-path
|
||||
problem see Section <A
|
||||
HREF="graph_theory_review.html#sec:shortest-path-algorithms">Shortest-Paths
|
||||
HREF="graph_theory_review.html#sec:shortest-paths-algorithms">Shortest-Paths
|
||||
Algorithms</A> for some background to the shortest-path problem.
|
||||
</P>
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ the reader has some previous acquaintance with graph algorithms, this
|
||||
chapter should be enough to get started. If the reader has no
|
||||
previous background in graph algorithms we suggest a more thorough
|
||||
introduction such as <a
|
||||
href="http://www.toc.lcs.mit.edu/~clr/">Introduction to Algorithms</a>
|
||||
href="http://toc.lcs.mit.edu/~clr/">Introduction to Algorithms</a>
|
||||
by Cormen, Leiserson, and Rivest.
|
||||
|
||||
<P>
|
||||
|
||||
@@ -80,6 +80,12 @@ September 27, 2000.
|
||||
<h2>Changes by version</h2>
|
||||
<a name="by-version">
|
||||
<ul>
|
||||
<li>Version 1.33.1<br><b>Bug Fixes</b>
|
||||
<ul>
|
||||
<li><a href="fruchterman_reingold.html"><TT>fruchterman_reingold_force_directed_layout</TT></A>: Fixed enumeration of grid-force pairs, which caused some odd graph formations along grid lines.</li>
|
||||
<li><a href="king_ordering.html"><tt>king_ordering</tt></a> and <a
|
||||
href="cuthill_mckee_ordering.html"><tt>cuthill_mckee_ordering</tt></a>: Fixed bug that caused failures with the multi-component version of these algorithms.</li>
|
||||
</ul></li>
|
||||
<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>
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace boost {
|
||||
template <class Graph, class VertexDescriptor, class InEdgeIter>
|
||||
class inv_adjacency_iterator_generator {
|
||||
public:
|
||||
typedef <a href="../../utility/iterator_adaptors.htm#iterator_adaptor">iterator_adaptor</a><...> type;
|
||||
typedef <a href="../../iterator/doc/iterator_adaptor.html">iterator_adaptor</a><...> type;
|
||||
};
|
||||
}
|
||||
</pre>
|
||||
|
||||
@@ -95,7 +95,7 @@ IN: <tt>const Graph& g</tt>
|
||||
IN: <tt>OutputIterator spanning_tree_edges</tt>
|
||||
<blockquote>
|
||||
The edges of the minimum spanning tree are output to this <a
|
||||
href="http:www.sgi.com/tech/stl/OutputIterator.html">Output
|
||||
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
|
||||
Iterator</a>.<br>
|
||||
|
||||
<b>Python</b>: This parameter is not used in Python. Instead, a
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Struct template layout_tolerance</title></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><table cellpadding="2" width="100%"><td valign="top"><img src="../../../boost.png" alt="boost.png (6897 bytes)" width="277" height="86"></td><td align="center"><a href="../../../index.htm">Home</a></td><td align="center"><a href="../../libraries.htm">Libraries</a></td><td align="center"><a href="../../../people/people.htm">People</a></td><td align="center"><a href="../../../more/faq.htm">FAQ</a></td><td align="center"><a href="../../../more/index.htm">More</a></td></table><hr><div class="refentry" lang="en"><a name="struct.boost.layout_tolerance"></a><div class="titlepage"><div></div><div></div></div><div class="refnamediv"><h2><span class="refentrytitle">Struct template layout_tolerance</span></h2><p>boost::layout_tolerance — Determines when to terminate layout of a particular graph based on a given relative tolerance. </p></div><h2 xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="refsynopsisdiv-title">Synopsis</h2><div xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" class="refsynopsisdiv"><pre class="synopsis"><span class="bold"><b>template</b></span><<span class="bold"><b>typename</b></span> T = double>
|
||||
<span class="bold"><b>struct</b></span> layout_tolerance {
|
||||
<span class="emphasis"><em>// <a href="layout_tolerance.html#struct.boost.layout_toleranceconstruct-copy-destruct">construct/copy/destruct</a></em></span>
|
||||
<span class="emphasis"><em>// <a href="layout_tolerance.html#layout_toleranceconstruct-copy-destruct">construct/copy/destruct</a></em></span>
|
||||
<a href="layout_tolerance.html#id103752-bb">layout_tolerance</a>(<span class="bold"><b>const</b></span> T & = T(0.001));
|
||||
|
||||
<span class="emphasis"><em>// <a href="layout_tolerance.html#id103692-bb">public member functions</a></em></span>
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<BR Clear>
|
||||
|
||||
<H1><A NAME="sec:mmd">
|
||||
<img src="figs/python.gif" alt="(Python)"/>
|
||||
<TT>minimum_degree_ordering</TT>
|
||||
</H1>
|
||||
|
||||
|
||||
@@ -57,7 +57,8 @@ public:
|
||||
</PRE>
|
||||
|
||||
<p> This class template implements a generator for scale-free graphs
|
||||
using the Power Law Out Degree (PLOD) algorithm, suitable for
|
||||
using the Power Law Out Degree (PLOD) algorithm
|
||||
[<a href="bibliography.html#palmer2000">63</a>], suitable for
|
||||
initializing an <a
|
||||
href="adjacency_list.html"><tt>adjacency_list</tt></a> or other graph
|
||||
structure with iterator-based initialization. A scale-free graph
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
<li><a href="http://www.ddj.com/articles/2000/0009/0009toc.htm">Dr. Dobb's Sept. 2000 Article</a></a></li>
|
||||
<li><a href="http://www.acm.org/pubs/citations/proceedings/oops/320384/p399-siek/">OOPSLA'99 GGCL Paper</a></li>
|
||||
<li>Lie-Quan Lee's Master's Thesis about GGCL<a href="http://www.lsc.nd.edu/downloads/research/ggcl/papers/thesis.ps">(ps)</a> <a href="http://www.lsc.nd.edu/downloads/research/ggcl/papers/thesis.pdf">(pdf)</a></li>
|
||||
<li>Dietmar Kühl's Master's Thesis: <a href="ftp://ftp.informatik.uni-konstanz.de/pub/algo/personal/kuehl/da.ps.gz">Design Pattern for the Implementation of Graph Algorithms</a></li>
|
||||
<li><a href="http://www.acl.lanl.gov/iscope99/">ISCOPE'99</a> Sparse Matrix Ordering <a href="./iscope99.pdf">(pdf)</a></li>
|
||||
<li><a href="http://www.dietmar-kuehl.de/generic-graph-algorithms.pdf">Dietmar Kühl's Master's Thesis: Design Pattern for the Implementation of Graph Algorithms</a></li>
|
||||
<li>ISCOPE'99 Sparse Matrix Ordering <a href="./iscope99.pdf">(pdf)</a></li>
|
||||
<li><a href="http://www.oonumerics.org/tmpw00/">C++ Template Workshop 2000</a>, Concept Checking</li>
|
||||
</ul>
|
||||
|
||||
|
||||
+5
-625
@@ -23,635 +23,15 @@
|
||||
long compile times that slow the development cycle.</p>
|
||||
|
||||
<p>The Python bindings are build using the <a
|
||||
href="../../python/doc">Boost.Python</a> library. The bindings are
|
||||
href="../../python/doc/index.html">Boost.Python</a> library. The bindings are
|
||||
meant to strike a balance of usability, flexibility, and
|
||||
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
|
||||
will not attempt to provide backward compatibility if the
|
||||
interfaces change. If you have any ideas </p>
|
||||
|
||||
<h2><a name="building">Building the Python Bindings</a></h2>
|
||||
<p>To build the Python bindings, change to
|
||||
the <tt>libs/graph/build/python</tt> subdirectory of Boost and
|
||||
then follow the <a
|
||||
href="../../../more/getting_started.html#Build_Install">Boost
|
||||
Build Instructions</a> to build the Python extension module. The
|
||||
end result will be a dynamic library (DLL, .so, etc.) that can be
|
||||
loaded into Python via "<tt>import bgl</tt>". <b>Note</b>: For
|
||||
this build to succeed, the graph library must work flawlessly on
|
||||
the compile, <i>including the new GraphViz parser</i>, which tends
|
||||
to break many compilers. Visual C++ 7.1 and recent versions of the
|
||||
GCC and Intel compilers are known to work.</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. It is <b>strongly</b> recommended that you build with
|
||||
release mode, e.g., <tt>bjam -sBUILD=release</tt>.</p>
|
||||
|
||||
<h2><a name="example1">A First Example</a></h2>
|
||||
<p>Our <a
|
||||
href="../example/python/biconnected_components.py">first
|
||||
example</a> illustrates the use of BGL graphs, graph
|
||||
algorithms, and property maps from Python. The initial
|
||||
step is to load the BGL-Python bindings:</p>
|
||||
<pre>
|
||||
from bgl import *
|
||||
</pre>
|
||||
|
||||
<p>Next, we load a GraphViz file containing the description of a
|
||||
sample graph. The <tt>Graph</tt> type is an undirected
|
||||
graph; <tt>file_kind</tt> is an enumerator with only two
|
||||
potential values: <tt>adjlist</tt>, for an adjacency-list
|
||||
representation, or <tt>graphviz</tt>, for a GraphViz file.</p>
|
||||
|
||||
<pre>
|
||||
g = Graph("biconnected_components.dot", file_kind.graphviz)
|
||||
</pre>
|
||||
|
||||
<p>Assuming no exceptions have been thrown, we will have an
|
||||
undirected graph loaded. We can immediately
|
||||
call <tt>biconnected_components</tt> to compute the biconnected
|
||||
components within the graph:</p>
|
||||
|
||||
<pre>
|
||||
art_points = biconnected_components(g, g.get_edge_int_map("label"))
|
||||
</pre>
|
||||
|
||||
<p>There are several interesting parts of the preceeding line. We
|
||||
call the <a
|
||||
href="biconnected_components.html"><tt>biconnected_components</tt></a>
|
||||
algorithm with two parameters. The first is just the graph
|
||||
itself. The second parameter is a property map from edges to an
|
||||
integer value, which will be stored in the graph under the name
|
||||
"label". Finally, the return value
|
||||
of <tt>biconnected_components</tt> is a Python list containing the
|
||||
articulation points of the graph.</p>
|
||||
|
||||
<p>Other kinds of property maps are available. In this case, we
|
||||
create two property maps attaching strings to the vertices of the
|
||||
graph. We then iterate over all vertices of the graph to set
|
||||
default values for each vertex property.</p>
|
||||
|
||||
<pre>
|
||||
v_color = g.get_vertex_string_map("fillcolor")
|
||||
v_style = g.get_vertex_string_map("style")
|
||||
for v in g.vertices:
|
||||
v_color[v] = "white"
|
||||
v_style[v] = "filled"
|
||||
</pre>
|
||||
|
||||
<p>Lastly, we mark all of the articulation points red and write
|
||||
out the result in GraphViz format.</p>
|
||||
|
||||
<pre>
|
||||
for v in art_points:
|
||||
v_color[v] = "red"
|
||||
|
||||
g.write_graphviz("biconnected_components_out.dot")
|
||||
</pre>
|
||||
|
||||
<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 <= <tt>p</tt> >=
|
||||
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>
|
||||
<p>The BGL graph types can be pickled from Python. Additional
|
||||
file-based formats are also available for use.</p>
|
||||
|
||||
<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>
|
||||
|
||||
<p>The Python bindings for the BGL are now part of a <a
|
||||
href="http://www.osl.iu.edu/~dgregor/bgl-python/">separate
|
||||
project</a>. They are no longer available within the Boost
|
||||
tree.</p>
|
||||
<HR>
|
||||
<TABLE>
|
||||
<TR valign=top>
|
||||
|
||||
@@ -68,10 +68,10 @@ For version 1:
|
||||
See <A
|
||||
href="http://www.boost.org/libs/graph/example/cuthill_mckee_ordering.cpp"><TT>example/sloan_ordering.cpp</TT></A>.
|
||||
<H3>See Also</H3>
|
||||
<p><http://www.boost.org/libs/graph/doc/sloan_start_end_vertices.html><a href="http://www.boost.org/libs/graph/doc/sloan_start_end_vertices.html">sloan_start_end_vertices</a></http:>,
|
||||
<p><a href="http://www.boost.org/libs/graph/doc/sloan_start_end_vertices.htm">sloan_start_end_vertices</a>,
|
||||
<A
|
||||
href="http://www.boost.org/libs/graph/doc/bandwidth.html">bandwidth</A>, <a href="http://www.boost.org/libs/graph/doc/profile.html">profile</a>,
|
||||
<a href="http://www.boost.org/libs/graph/doc/wavefront.html">wavefront</a> and
|
||||
href="http://www.boost.org/libs/graph/doc/bandwidth.html">bandwidth</A>, <a href="http://www.boost.org/libs/graph/doc/profile.htm">profile</a>,
|
||||
<a href="http://www.boost.org/libs/graph/doc/wavefront.htm">wavefront</a> and
|
||||
<TT>degree_property_map</TT> in <TT>boost/graph/properties.hpp</TT>. </p>
|
||||
<p>[1] S. W. Sloan, <i>An algorithm for profile and wavefront reduction of sparse
|
||||
matrices</i>, Int. j. numer. methods eng., <b>23</b>, 239 - 251 (1986)</p>
|
||||
|
||||
+31
-29
@@ -70,10 +70,10 @@
|
||||
<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>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><a href="./DFSVisitor.html">DFS Visitor</a>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><a href="./DFSVisitor.html"><a href="./DijkstraVisitor.html">Dijkstra Visitor</a>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><a href="./BellmanFordVisitor.html">Bellman Ford Visitor</a>
|
||||
<LI><a href="./BFSVisitor.html">BFS Visitor</a>
|
||||
<LI><a href="./DFSVisitor.html">DFS Visitor</a>
|
||||
<LI><a href="./DFSVisitor.html"><a href="./DijkstraVisitor.html">Dijkstra Visitor</a>
|
||||
<LI><a href="./BellmanFordVisitor.html">Bellman Ford Visitor</a>
|
||||
<LI><a href="AStarVisitor.html">A* Visitor</a></LI>
|
||||
<LI><a href="./EventVisitor.html">Event Visitor</a>
|
||||
</OL>
|
||||
@@ -127,39 +127,39 @@
|
||||
<LI><a href="./bgl_named_params.html"><tt>bgl_named_params</tt></a>
|
||||
<LI>Core Algorithm Patterns
|
||||
<OL>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A href="./breadth_first_search.html"><tt>breadth_first_search</tt></A>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A href="./breadth_first_search.html"><A href="./breadth_first_visit.html"><tt>breadth_first_visit</tt></A>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A
|
||||
<LI><A href="./breadth_first_search.html"><tt>breadth_first_search</tt></A>
|
||||
<LI><A href="./breadth_first_search.html"><A href="./breadth_first_visit.html"><tt>breadth_first_visit</tt></A>
|
||||
<LI><A
|
||||
href="./depth_first_search.html"><tt>depth_first_search</tt></A>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A href="./depth_first_visit.html"><tt>depth_first_visit</tt></A>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A
|
||||
<LI><A href="./depth_first_visit.html"><tt>depth_first_visit</tt></A>
|
||||
<LI><A
|
||||
href="./undirected_dfs.html"><tt>undirected_dfs</tt></A>
|
||||
</OL>
|
||||
<LI>Graph Algorithms
|
||||
<OL>
|
||||
<LI>Shortest Paths Algorithms
|
||||
<OL>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A href="./dijkstra_shortest_paths.html"><tt>dijkstra_shortest_paths</tt></A>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A href="./bellman_ford_shortest.html"><tt>bellman_ford_shortest_paths</tt></A>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A href="./dag_shortest_paths.html"><tt>dag_shortest_paths</tt></A>
|
||||
<LI><A href="./dijkstra_shortest_paths.html"><tt>dijkstra_shortest_paths</tt></A>
|
||||
<LI><A href="./bellman_ford_shortest.html"><tt>bellman_ford_shortest_paths</tt></A>
|
||||
<LI><A href="./dag_shortest_paths.html"><tt>dag_shortest_paths</tt></A>
|
||||
<LI><A
|
||||
href="./johnson_all_pairs_shortest.html"><tt>johnson_all_pairs_shortest_paths</tt></A>
|
||||
<li><a href="floyd_warshall_shortest.html"><tt>floyd_warshall_all_pairs_shortest_paths</tt></a></li>
|
||||
</OL>
|
||||
<LI>Minimum Spanning Tree Algorithms
|
||||
<OL>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A
|
||||
<LI><A
|
||||
href="./kruskal_min_spanning_tree.html"><tt>kruskal_minimum_spanning_tree</tt></A>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A
|
||||
<LI><A
|
||||
href="./prim_minimum_spanning_tree.html"><tt>prim_minimum_spanning_tree</tt></A>
|
||||
</OL>
|
||||
<LI>Connected Components Algorithms
|
||||
<OL>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A href="./connected_components.html"><tt>connected_components</tt></A>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A href="./strong_components.html"><tt>strong_components</tt></A>
|
||||
<LI><A href="./connected_components.html"><tt>connected_components</tt></A>
|
||||
<LI><A href="./strong_components.html"><tt>strong_components</tt></A>
|
||||
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><a href="biconnected_components.html"><tt>biconnected_components</tt></a>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><a href="biconnected_components.html#sec:articulation_points"><tt>articulation_points</tt></a>
|
||||
<LI><a href="biconnected_components.html"><tt>biconnected_components</tt></a>
|
||||
<LI><a href="biconnected_components.html#sec:articulation_points"><tt>articulation_points</tt></a>
|
||||
<LI><a href="./incremental_components.html">Incremental Connected Components</a>
|
||||
<OL>
|
||||
<LI><A href="./incremental_components.html#sec:initialize-incremental-components"><tt>initialize_incremental_components</tt></A>
|
||||
@@ -178,35 +178,37 @@
|
||||
|
||||
<li>Sparse Matrix Ordering Algorithms
|
||||
<ol>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A
|
||||
<LI><A
|
||||
href="./cuthill_mckee_ordering.html"><tt>cuthill_mckee_ordering</tt></a>
|
||||
<li><img src="figs/python_ico.gif" alt="(Python)"/><a href="king_ordering.html"><tt>king_ordering</tt></a></li>
|
||||
<li><a href="king_ordering.html"><tt>king_ordering</tt></a></li>
|
||||
<LI><a href="./minimum_degree_ordering.html"><tt>minimum_degree_ordering</tt></a>
|
||||
</ol>
|
||||
</li>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A href="./topological_sort.html"><tt>topological_sort</tt></A>
|
||||
<li><img src="figs/python_ico.gif" alt="(Python)"/><a href="./transitive_closure.html"><tt>transitive_closure</tt></a>
|
||||
<LI><A href="./topological_sort.html"><tt>topological_sort</tt></A>
|
||||
<li><a href="./transitive_closure.html"><tt>transitive_closure</tt></a>
|
||||
<LI><A href="./copy_graph.html"><tt>copy_graph</tt></A>
|
||||
<LI><A href="./transpose_graph.html"><tt>transpose_graph</tt></A>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A href="./isomorphism.html"><tt>isomorphism</tt></A>
|
||||
<LI><A href="./isomorphism.html"><tt>isomorphism</tt></A>
|
||||
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A
|
||||
<LI><A
|
||||
href="sequential_vertex_coloring.html"><tt>sequential_vertex_coloring</tt></A>
|
||||
<li><a href="./sloan_ordering.htm"><tt>sloan_ordering</tt></a></li>
|
||||
<li><a href="sloan_start_end_vertices.htm"><tt>sloan_start_end_vertices</tt></a></li>
|
||||
|
||||
<LI><A href="./wavefront.htm"><tt>ith_wavefront</tt>, <tt>max_wavefront</tt>, <tt>aver_wavefront</tt>, and <tt>rms_wavefront</tt></A></LI>
|
||||
<LI><img src="figs/python_ico.gif" alt="(Python)"/><A href="betweenness_centrality.html"><tt>brandes_betweenness_centrality</tt></A></LI>
|
||||
<LI><A href="betweenness_centrality.html"><tt>brandes_betweenness_centrality</tt></A></LI>
|
||||
<li>Layout algorithms
|
||||
<ol>
|
||||
<li><a href="random_layout.html"><tt>random_graph_layout</tt></a></li>
|
||||
<li><img src="figs/python_ico.gif" alt="(Python)"/><a href="circle_layout.html"><tt>circle_layout</tt></a></li>
|
||||
<li><img src="figs/python_ico.gif" alt="(Python)"/><a href="kamada_kawai_spring_layout.html"><tt>kamada_kawai_spring_layout</tt></a></li>
|
||||
<li><img src="figs/python_ico.gif" alt="(Python)"/><a href="fruchterman_reingold.html"><tt>fruchterman_reingold_force_directed_layout</tt></a></li>
|
||||
<li><a href="circle_layout.html"><tt>circle_layout</tt></a></li>
|
||||
<li><a href="kamada_kawai_spring_layout.html"><tt>kamada_kawai_spring_layout</tt></a></li>
|
||||
<li><a href="fruchterman_reingold.html"><tt>fruchterman_reingold_force_directed_layout</tt></a></li>
|
||||
<li><a href="gursoy_atun_layout.html"><tt>gursoy_atun_layout</tt></a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li>Clustering algorithms
|
||||
<ol>
|
||||
<li><img src="figs/python_ico.gif" alt="(Python)"/><a href="bc_clustering.html"><tt>betweenness_centrality_clustering</tt></a></li>
|
||||
<li><a href="bc_clustering.html"><tt>betweenness_centrality_clustering</tt></a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="astar_search.html"><tt>astar_search</tt></a></li>
|
||||
|
||||
@@ -59,7 +59,7 @@ IN: <tt>VertexListGraph& g</tt>
|
||||
OUT: <tt>OutputIterator result</tt>
|
||||
<blockquote>
|
||||
The vertex descriptors of the graph will be output to the
|
||||
<TT>result</TT> output iterator in their topological order. The
|
||||
<TT>result</TT> output iterator in <b>reverse</b> topological order. The
|
||||
iterator type must model <a
|
||||
href="http://www.sgi.com/tech/stl/OutputIterator.html">Output
|
||||
Iterator</a>.<br>
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<!-- saved from url=(0050)http://www.boost.org/libs/graph/doc/bandwidth.html -->
|
||||
<HTML><HEAD><TITLE>Boost Graph Library: Bandwidth</TITLE>
|
||||
<!-- saved from url=(0050)http://www.boost.org/libs/graph/doc/wavefront.html -->
|
||||
<HTML><HEAD><TITLE>Boost Graph Library: Wavefront</TITLE>
|
||||
<META http-equiv=Content-Type content="text/html; charset=windows-1252"><!--
|
||||
-- Copyright (c) Jeremy Siek 2000
|
||||
--
|
||||
@@ -16,7 +16,7 @@
|
||||
<BODY text=#000000 vLink=#551a8b aLink=#ff0000 link=#0000ee bgColor=#ffffff>
|
||||
<IMG SRC="../../../boost.png"
|
||||
ALT="C++ Boost" width="277" height="86"> <BR>
|
||||
<H1><A name=sec:bandwidth></a><tt>ith_wavefront</tt> </H1>
|
||||
<H1><A name=sec:wavefront></a><tt>ith_wavefront</tt> </H1>
|
||||
<PRE> (1)
|
||||
template <typename Graph><br> typename graph_traits<Graph>::vertices_size_type<br> ith_wavefront(typename graph_traits<Graph>::vertex_descriptor i,<br> const Graph& g)
|
||||
|
||||
@@ -28,10 +28,10 @@
|
||||
</p>
|
||||
<H3>Defined in</H3>
|
||||
<A
|
||||
href="http://www.boost.org/boost/graph/bandwidth.hpp"><TT>boost/graph/wavefront.hpp</TT></A>
|
||||
href="http://www.boost.org/boost/graph/wavefront.hpp"><TT>boost/graph/wavefront.hpp</TT></A>
|
||||
<HR>
|
||||
|
||||
<H1><A name=sec:ith-bandwidth></a><tt>max_wavefront</tt></H1>
|
||||
<H1><A name=sec:ith-wavefront></a><tt>max_wavefront</tt></H1>
|
||||
<PRE> (1)
|
||||
template <typename Graph><br> typename graph_traits<Graph>::vertices_size_type<br> max_wavefront(const Graph& g)
|
||||
|
||||
@@ -41,10 +41,10 @@ Calculates the maximum wavefront a graph.<BR>
|
||||
<BR>
|
||||
<H3>Defined in</H3>
|
||||
<p><A
|
||||
href="http://www.boost.org/boost/graph/bandwidth.hpp"><TT>boost/graph/wavefront.hpp</TT></A>
|
||||
href="http://www.boost.org/boost/graph/wavefront.hpp"><TT>boost/graph/wavefront.hpp</TT></A>
|
||||
</p>
|
||||
<hr>
|
||||
<h1><a name=sec:ith-bandwidth></a><tt>aver_wavefront</tt></h1>
|
||||
<h1><a name=sec:ith-wavefront></a><tt>aver_wavefront</tt></h1>
|
||||
<pre> (1)
|
||||
template <typename Graph><br> typename graph_traits<Graph>::vertices_size_type<br> aver_wavefront(const Graph& g)
|
||||
|
||||
@@ -55,11 +55,11 @@ the number ob vertices).<br>
|
||||
<br>
|
||||
<h3>Defined in</h3>
|
||||
<a
|
||||
href="http://www.boost.org/boost/graph/bandwidth.hpp"><tt>boost/graph/wavefront.hpp</tt></a>
|
||||
href="http://www.boost.org/boost/graph/wavefront.hpp"><tt>boost/graph/wavefront.hpp</tt></a>
|
||||
<p><BR>
|
||||
</p>
|
||||
<hr>
|
||||
<h1><a name=sec:ith-bandwidth></a><tt>rms_wavefront</tt></h1>
|
||||
<h1><a name=sec:ith-wavefront></a><tt>rms_wavefront</tt></h1>
|
||||
<pre> (1)
|
||||
template <typename Graph><br> typename graph_traits<Graph>::vertices_size_type<br> rms_wavefront(const Graph& g)
|
||||
|
||||
@@ -69,7 +69,7 @@ Calculates the root mean square of all wavefronts.<br>
|
||||
<br>
|
||||
<h3>Defined in</h3>
|
||||
<a
|
||||
href="http://www.boost.org/boost/graph/bandwidth.hpp"><tt>boost/graph/wavefront.hpp</tt></a>
|
||||
href="http://www.boost.org/boost/graph/wavefront.hpp"><tt>boost/graph/wavefront.hpp</tt></a>
|
||||
<p> </p>
|
||||
<HR>
|
||||
<TABLE>
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
graph G {
|
||||
A -- B
|
||||
A -- F
|
||||
A -- G
|
||||
B -- C
|
||||
B -- D
|
||||
B -- E
|
||||
C -- D
|
||||
E -- F
|
||||
G -- H
|
||||
G -- I
|
||||
H -- I
|
||||
}
|
||||
@@ -1,21 +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
|
||||
|
||||
import bgl
|
||||
|
||||
g = bgl.Graph("biconnected_components.dot", bgl.file_kind.graphviz)
|
||||
art_points = bgl.biconnected_components(g, g.get_edge_int_map("label"));
|
||||
g.write_graphviz("biconnected_components_out.dot")
|
||||
|
||||
print "Articulation points: ",
|
||||
node_id = g.get_vertex_string_map("node_id")
|
||||
for v in art_points:
|
||||
print node_id[v],
|
||||
print " ",
|
||||
print ""
|
||||
@@ -1,15 +0,0 @@
|
||||
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")), "label")
|
||||
|
||||
|
||||
breadth_first_search(g, s, visitor=bfs_print_discover_visitor())
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
graph G {
|
||||
A -- F
|
||||
B -- C
|
||||
B -- D
|
||||
C -- D
|
||||
E -- F
|
||||
G -- H
|
||||
G -- I
|
||||
H -- I
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
graph G {
|
||||
A -- C [weight="1.0"]
|
||||
B -- D [weight="1.0"]
|
||||
B -- E [weight="2.0"]
|
||||
C -- B [weight="7.0"]
|
||||
C -- D [weight="3.0"]
|
||||
D -- E [weight="1.0"]
|
||||
E -- A [weight="1.0"]
|
||||
E -- B [weight="1.0"]
|
||||
}
|
||||
@@ -1,706 +0,0 @@
|
||||
import bgl
|
||||
import wx
|
||||
import wx.lib.ogl as ogl
|
||||
# import wx.lib.masked
|
||||
import os
|
||||
import random
|
||||
import sys
|
||||
|
||||
wildcard = "GraphViz (*.dot)|*.dot|" \
|
||||
"All files (*.*)|*.*"
|
||||
|
||||
def path_to_title(path):
|
||||
title = path
|
||||
dot_idx = title.rfind('.')
|
||||
if dot_idx != -1: title = title[:dot_idx]
|
||||
slash_idx = title.rfind('/')
|
||||
if slash_idx != -1: title = title[slash_idx+1:]
|
||||
slash_idx = title.rfind('\\')
|
||||
if slash_idx != -1: title = title[slash_idx+1:]
|
||||
return title
|
||||
|
||||
class GraphCanvas(ogl.ShapeCanvas):
|
||||
def __init__(self, parent):
|
||||
ogl.ShapeCanvas.__init__(self, parent)
|
||||
|
||||
maxWidth = 400
|
||||
maxHeight = 400
|
||||
self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20)
|
||||
|
||||
def set_graph(self, graph, position_map, property_maps):
|
||||
self.diagram = ogl.Diagram()
|
||||
self.SetDiagram(self.diagram)
|
||||
self.diagram.SetCanvas(self)
|
||||
|
||||
self.graph = graph
|
||||
self.position_map = position_map
|
||||
self.property_maps = property_maps
|
||||
self.vertex_position_rect = self.compute_rect()
|
||||
self.vertex_to_shape = graph.get_vertex_object_map("__stored_shape")
|
||||
self.edge_to_shape = graph.get_edge_object_map("__stored_shape")
|
||||
self.shape_to_vertex = {}
|
||||
|
||||
for v in graph.vertices:
|
||||
self.add_vertex(v)
|
||||
|
||||
for e in graph.edges:
|
||||
self.add_edge(e)
|
||||
|
||||
self.Refresh()
|
||||
|
||||
def compute_rect(self):
|
||||
pos = self.position_map
|
||||
if self.graph.num_vertices() == 0:
|
||||
return (-50, -50, 50, 50)
|
||||
else:
|
||||
left, top, right, bottom = 0, 0, 0, 0
|
||||
for v in self.graph.vertices:
|
||||
if pos[v].x < left: left = pos[v].x
|
||||
if pos[v].y < top: top = pos[v].y
|
||||
if pos[v].x > right: right = pos[v].x
|
||||
if pos[v].y > bottom: bottom = pos[v].y
|
||||
return (left, top, right, bottom)
|
||||
|
||||
def update_layout(self):
|
||||
self.vertex_position_rect = self.compute_rect()
|
||||
dc = wx.ClientDC(self)
|
||||
self.PrepareDC(dc)
|
||||
for v in self.graph.vertices:
|
||||
shape = self.vertex_to_shape[v]
|
||||
x, y = self.vertex_position_to_shape_position(v)
|
||||
shape.Move(dc, x, y, False)
|
||||
self.Refresh()
|
||||
|
||||
def vertex_position_to_shape_position(self, vertex):
|
||||
(width, height) = self.GetVirtualSize()
|
||||
width = width - 20
|
||||
height = height - 20
|
||||
(pos_width, pos_height) = (self.vertex_position_rect[2]
|
||||
- self.vertex_position_rect[0],
|
||||
self.vertex_position_rect[3]
|
||||
- self.vertex_position_rect[1])
|
||||
return ((self.position_map[vertex].x - self.vertex_position_rect[0])
|
||||
/ pos_width * width + 10,
|
||||
(self.position_map[vertex].y - self.vertex_position_rect[1])
|
||||
/ pos_height * height + 10);
|
||||
|
||||
def translate_color(self, color):
|
||||
if color=="black": return wx.BLACK
|
||||
elif color=="blue": return wx.BLUE
|
||||
elif color=="red": return wx.RED
|
||||
elif color=="green": return wx.GREEN
|
||||
else: return wx.BLACK
|
||||
|
||||
def add_vertex(self, vertex):
|
||||
shape = self.CreateVertex(vertex)
|
||||
shape.SetDraggable(True, True)
|
||||
shape.SetCanvas(self)
|
||||
x, y = self.vertex_position_to_shape_position(vertex)
|
||||
shape.SetX(x)
|
||||
shape.SetY(y)
|
||||
shape.SetPen(self.VertexPen(vertex))
|
||||
shape.SetBrush(self.VertexBrush(vertex))
|
||||
s = self.VertexLabel(vertex)
|
||||
if s != "": shape.AddText(s)
|
||||
self.diagram.AddShape(shape)
|
||||
shape.Show(True)
|
||||
self.vertex_to_shape[vertex] = shape
|
||||
self.shape_to_vertex[shape] = vertex
|
||||
|
||||
evthandler = VertexEventHandler(self)
|
||||
evthandler.SetShape(shape)
|
||||
evthandler.SetPreviousHandler(shape.GetEventHandler())
|
||||
shape.SetEventHandler(evthandler)
|
||||
|
||||
return shape;
|
||||
|
||||
def CreateVertex(self, vertex):
|
||||
return ogl.CircleShape(20)
|
||||
|
||||
def VertexPen(self, vertex):
|
||||
thickness = 1
|
||||
color = wx.BLACK
|
||||
if "vertex.border.thickness" in self.property_maps:
|
||||
thickness = self.property_maps["vertex.border.thickness"][vertex]
|
||||
if "vertex.border.color" in self.property_maps:
|
||||
color_text = self.property_maps["vertex.border.color"][vertex]
|
||||
color = translate_color(color_text)
|
||||
return wx.Pen(color, thickness)
|
||||
|
||||
def VertexBrush(self, vertex):
|
||||
return wx.GREEN_BRUSH
|
||||
|
||||
def VertexLabel(self, vertex):
|
||||
if "vertex.label" in self.property_maps:
|
||||
return self.property_maps["vertex.label"][vertex]
|
||||
else:
|
||||
return ""
|
||||
|
||||
def VertexShape(self, vertex):
|
||||
return self.vertex_to_shape[vertex]
|
||||
|
||||
def add_edge(self, edge):
|
||||
(u, v) = (self.graph.source(edge), self.graph.target(edge))
|
||||
line = ogl.LineShape()
|
||||
line.SetCanvas(self)
|
||||
line.SetPen(wx.BLACK_PEN)
|
||||
line.SetBrush(wx.BLACK_BRUSH)
|
||||
if self.graph.is_directed(): line.AddArrow(ogl.ARROW_ARROW)
|
||||
if "edge.label" in self.property_maps:
|
||||
label = str(self.property_maps["edge.label"][edge])
|
||||
line.AddText(label)
|
||||
line.MakeLineControlPoints(2)
|
||||
self.vertex_to_shape[u].AddLine(line, self.vertex_to_shape[v])
|
||||
self.diagram.AddShape(line)
|
||||
line.Show(True)
|
||||
self.edge_to_shape[edge] = line
|
||||
return line
|
||||
|
||||
def EdgeShape(self, edge):
|
||||
return self.edge_to_shape[edge]
|
||||
|
||||
def set_vertex_colors_from_components(self, component_map):
|
||||
brushes = {}
|
||||
for v in self.graph.vertices:
|
||||
shape = self.vertex_to_shape[v]
|
||||
comp = component_map[v]
|
||||
if not comp in brushes:
|
||||
brushes[comp] = wx.Brush(wx.Color(random.randint(0, 200),
|
||||
random.randint(0, 200),
|
||||
random.randint(0, 200)))
|
||||
shape.SetBrush(brushes[comp])
|
||||
self.Refresh()
|
||||
|
||||
def set_edge_colors_from_components(self, component_map):
|
||||
pens = {}
|
||||
for e in self.graph.edges:
|
||||
shape = self.edge_to_shape[e]
|
||||
comp = component_map[e]
|
||||
if not comp in pens:
|
||||
pens[comp] = wx.Pen(wx.Color(random.randint(0, 200),
|
||||
random.randint(0, 200),
|
||||
random.randint(0, 200)),
|
||||
1)
|
||||
shape.SetPen(pens[comp])
|
||||
self.Refresh()
|
||||
|
||||
def default_property_maps(self, graph, node_id = "node_id"):
|
||||
maps = {}
|
||||
if graph.has_vertex_map("label"):
|
||||
maps["vertex.label"] = graph.get_vertex_string_map("label")
|
||||
elif graph.has_vertex_map(node_id):
|
||||
maps["vertex.label"] = graph.get_vertex_string_map(node_id)
|
||||
if graph.has_edge_map("label"):
|
||||
maps["edge.label"] = graph.get_edge_string_map("label")
|
||||
elif graph.has_edge_map("weight"):
|
||||
maps["edge.label"] = graph.get_edge_double_map("weight")
|
||||
return maps
|
||||
|
||||
class VertexEventHandler(ogl.ShapeEvtHandler):
|
||||
def __init__(self, graphwin):
|
||||
ogl.ShapeEvtHandler.__init__(self)
|
||||
self.graphwin = graphwin
|
||||
|
||||
def OnEndDragLeft(self, x, y, keys=0, attachment=0):
|
||||
shape = self.GetShape()
|
||||
if shape.Selected():
|
||||
vertex = self.graphwin.shape_to_vertex[shape]
|
||||
self.graphwin.position_map[vertex].x = x
|
||||
self.graphwin.position_map[vertex].y = y
|
||||
ogl.ShapeEvtHandler.OnEndDragLeft(self, x, y, keys, attachment)
|
||||
|
||||
class ErdosRenyiDialog(wx.Dialog):
|
||||
def __init__(
|
||||
self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition,
|
||||
style=wx.DEFAULT_DIALOG_STYLE
|
||||
):
|
||||
wx.Dialog.__init__(self, parent, ID, title, pos, size, style,
|
||||
"Erdos-Renyi Generator")
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
box.Add(wx.StaticText(self, -1, "Number of vertices (n)"), 0,
|
||||
wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
num_vertices_spin = wx.SpinCtrl(self, -1, "", (30, 50))
|
||||
num_vertices_spin.SetRange(0,10000000)
|
||||
num_vertices_spin.SetValue(10)
|
||||
box.Add(num_vertices_spin, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
self.num_vertices_spin = num_vertices_spin
|
||||
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
box.Add(wx.StaticText(self, -1, "Edge probability (%)"), 0,
|
||||
wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
# This is better than what we're currently doing with a SpinCtrl, but
|
||||
# it makes the program unstable (?)
|
||||
# probability_ctrl = wx.lib.masked.numctrl.NumCtrl(self, value = 0.2,
|
||||
# integerWidth = 1,
|
||||
# fractionWidth = 3,
|
||||
# allowNegative = False,
|
||||
# min = 0.0, max = 1.0)
|
||||
|
||||
probability_ctrl = wx.SpinCtrl(self, -1, "", (30, 50))
|
||||
probability_ctrl.SetRange(0,100)
|
||||
probability_ctrl.SetValue(20)
|
||||
self.probability_ctrl = probability_ctrl
|
||||
box.Add(probability_ctrl, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box.Add(wx.StaticText(self, -1, "Random seed"), 0,
|
||||
wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
seed_ctrl = wx.SpinCtrl(self, -1, "", (30, 50))
|
||||
seed_ctrl.SetRange(1, sys.maxint)
|
||||
seed_ctrl.SetValue(random.randint(1, sys.maxint))
|
||||
self.seed_ctrl = seed_ctrl
|
||||
box.Add(seed_ctrl, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
|
||||
sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5)
|
||||
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
btn = wx.Button(self, wx.ID_OK, " Generate! ")
|
||||
btn.SetDefault()
|
||||
box.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
btn = wx.Button(self, wx.ID_CANCEL, " Cancel ")
|
||||
box.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
sizer.Add(box, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
self.SetSizer(sizer)
|
||||
self.SetAutoLayout(True)
|
||||
sizer.Fit(self)
|
||||
|
||||
def GetNumVertices(self):
|
||||
return self.num_vertices_spin.GetValue()
|
||||
|
||||
def GetProbability(self):
|
||||
return float(self.probability_ctrl.GetValue())
|
||||
|
||||
def GetRandomSeed(self):
|
||||
return int(self.seed_ctrl.GetValue())
|
||||
|
||||
class PLODDialog(wx.Dialog):
|
||||
def __init__(
|
||||
self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition,
|
||||
style=wx.DEFAULT_DIALOG_STYLE
|
||||
):
|
||||
wx.Dialog.__init__(self, parent, ID, title, pos, size, style)
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
box.Add(wx.StaticText(self, -1, "Number of vertices (n)"), 0,
|
||||
wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
num_vertices_spin = wx.SpinCtrl(self, -1, "", (30, 50))
|
||||
num_vertices_spin.SetRange(0,10000000)
|
||||
num_vertices_spin.SetValue(10)
|
||||
box.Add(num_vertices_spin, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
self.num_vertices_spin = num_vertices_spin
|
||||
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
# Alpha
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box.Add(wx.StaticText(self, -1, "Alpha"), 0,
|
||||
wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
alpha_ctrl = wx.TextCtrl(self, -1, "2.75", (30, 50))
|
||||
self.alpha_ctrl = alpha_ctrl
|
||||
box.Add(alpha_ctrl, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
|
||||
# Beta
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box.Add(wx.StaticText(self, -1, "Beta"), 0,
|
||||
wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
beta_ctrl = wx.SpinCtrl(self, -1, "", (30, 50))
|
||||
beta_ctrl.SetRange(1, sys.maxint)
|
||||
beta_ctrl.SetValue(300)
|
||||
self.beta_ctrl = beta_ctrl
|
||||
box.Add(beta_ctrl, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box.Add(wx.StaticText(self, -1, "Random seed"), 0,
|
||||
wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
seed_ctrl = wx.SpinCtrl(self, -1, "", (30, 50))
|
||||
seed_ctrl.SetRange(1, sys.maxint)
|
||||
seed_ctrl.SetValue(random.randint(1, sys.maxint))
|
||||
self.seed_ctrl = seed_ctrl
|
||||
box.Add(seed_ctrl, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
|
||||
sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5)
|
||||
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
btn = wx.Button(self, wx.ID_OK, " Generate! ")
|
||||
btn.SetDefault()
|
||||
box.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
btn = wx.Button(self, wx.ID_CANCEL, " Cancel ")
|
||||
box.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
sizer.Add(box, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
self.SetSizer(sizer)
|
||||
self.SetAutoLayout(True)
|
||||
sizer.Fit(self)
|
||||
|
||||
def GetNumVertices(self):
|
||||
return self.num_vertices_spin.GetValue()
|
||||
|
||||
def GetAlpha(self):
|
||||
return float(self.alpha_ctrl.GetValue())
|
||||
|
||||
def GetBeta(self):
|
||||
return float(self.beta_ctrl.GetValue())
|
||||
|
||||
def GetRandomSeed(self):
|
||||
return int(self.seed_ctrl.GetValue())
|
||||
|
||||
class SmallWorldDialog(wx.Dialog):
|
||||
def __init__(
|
||||
self, parent, ID, title, size=wx.DefaultSize, pos=wx.DefaultPosition,
|
||||
style=wx.DEFAULT_DIALOG_STYLE
|
||||
):
|
||||
wx.Dialog.__init__(self, parent, ID, title, pos, size, style)
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
box.Add(wx.StaticText(self, -1, "Number of vertices (n)"), 0,
|
||||
wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
num_vertices_spin = wx.SpinCtrl(self, -1, "", (30, 50))
|
||||
num_vertices_spin.SetRange(0,10000000)
|
||||
num_vertices_spin.SetValue(10)
|
||||
box.Add(num_vertices_spin, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
self.num_vertices_spin = num_vertices_spin
|
||||
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
# Number of neighbors
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
box.Add(wx.StaticText(self, -1, "Number of neighbors (k)"), 0,
|
||||
wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
num_neighbors_spin = wx.SpinCtrl(self, -1, "", (30, 50))
|
||||
num_neighbors_spin.SetRange(0,10000000)
|
||||
num_neighbors_spin.SetValue(4)
|
||||
box.Add(num_neighbors_spin, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
self.num_neighbors_spin = num_neighbors_spin
|
||||
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
box.Add(wx.StaticText(self, -1, "Rewiring probability (%)"), 0,
|
||||
wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
# This is better than what we're currently doing with a SpinCtrl, but
|
||||
# it makes the program unstable (?)
|
||||
# probability_ctrl = wx.lib.masked.numctrl.NumCtrl(self, value = 0.2,
|
||||
# integerWidth = 1,
|
||||
# fractionWidth = 3,
|
||||
# allowNegative = False,
|
||||
# min = 0.0, max = 1.0)
|
||||
|
||||
probability_ctrl = wx.SpinCtrl(self, -1, "", (30, 50))
|
||||
probability_ctrl.SetRange(0,100)
|
||||
probability_ctrl.SetValue(20)
|
||||
self.probability_ctrl = probability_ctrl
|
||||
box.Add(probability_ctrl, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
box.Add(wx.StaticText(self, -1, "Random seed"), 0,
|
||||
wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
seed_ctrl = wx.SpinCtrl(self, -1, "", (30, 50))
|
||||
seed_ctrl.SetRange(1, sys.maxint)
|
||||
seed_ctrl.SetValue(random.randint(1, sys.maxint))
|
||||
self.seed_ctrl = seed_ctrl
|
||||
box.Add(seed_ctrl, 1, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
sizer.Add(box, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
|
||||
sizer.Add(line, 0, wx.GROW|wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, 5)
|
||||
|
||||
box = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
btn = wx.Button(self, wx.ID_OK, " Generate! ")
|
||||
btn.SetDefault()
|
||||
box.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
btn = wx.Button(self, wx.ID_CANCEL, " Cancel ")
|
||||
box.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
sizer.Add(box, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALL, 5)
|
||||
|
||||
self.SetSizer(sizer)
|
||||
self.SetAutoLayout(True)
|
||||
sizer.Fit(self)
|
||||
|
||||
def GetNumVertices(self):
|
||||
return self.num_vertices_spin.GetValue()
|
||||
|
||||
def GetNumNeighbors(self):
|
||||
return self.num_neighbors_spin.GetValue()
|
||||
|
||||
def GetProbability(self):
|
||||
return float(self.probability_ctrl.GetValue())
|
||||
|
||||
def GetRandomSeed(self):
|
||||
return int(self.seed_ctrl.GetValue())
|
||||
|
||||
class GraphEditorWindow(wx.Frame):
|
||||
def __init__(self, parent, title='BGL Graph Viewer'):
|
||||
wx.Frame.__init__(self, parent, -1, title);
|
||||
self.canvas = GraphCanvas(self)
|
||||
self.CreateMenuBar()
|
||||
self.erdos_renyi_dlg = None
|
||||
self.plod_dlg = None
|
||||
self.small_world_dlg = None
|
||||
self.NewGraph(None)
|
||||
|
||||
def CreateMenuBar(self):
|
||||
menuBar = wx.MenuBar()
|
||||
|
||||
# File menu
|
||||
fileMenu = wx.Menu()
|
||||
|
||||
# New graph menu
|
||||
newGraphMenu = wx.Menu()
|
||||
newGraphMenu.Append(111, "Empty graph")
|
||||
newGraphMenu.Append(112, "Erdos-Renyi graph...")
|
||||
newGraphMenu.Append(113, "Power Law Out Degree graph...")
|
||||
newGraphMenu.Append(114, "Small-world graph...")
|
||||
fileMenu.AppendMenu(110, "&New graph", newGraphMenu)
|
||||
|
||||
fileMenu.Append(120, "&Open graph")
|
||||
fileMenu.Append(130, "&Save graph")
|
||||
menuBar.Append(fileMenu, "&File")
|
||||
|
||||
# Algorithms menu
|
||||
algorithmsMenu = wx.Menu()
|
||||
# - Connected components menu
|
||||
ccMenu = wx.Menu();
|
||||
ccMenu.Append(201, "Connected Components")
|
||||
ccMenu.Append(202, "Strongly-Connected Components")
|
||||
ccMenu.Append(203, "Biconnected Components")
|
||||
algorithmsMenu.AppendMenu(200, "Connected Components", ccMenu)
|
||||
|
||||
# - Minimum Spanning Tree menu
|
||||
mstMenu = wx.Menu();
|
||||
mstMenu.Append(212, "Kruskal")
|
||||
algorithmsMenu.AppendMenu(210, "Minimum Spanning Tree", mstMenu)
|
||||
|
||||
# Other algorithms...
|
||||
algorithmsMenu.Append(221, "Sequential vertex coloring")
|
||||
|
||||
menuBar.Append(algorithmsMenu, "&Algorithms")
|
||||
|
||||
|
||||
# Layout menu
|
||||
layoutMenu = wx.Menu()
|
||||
layoutMenu.Append(301, "&Circle layout")
|
||||
layoutMenu.Append(302, "&Fruchterman-Reingold layout")
|
||||
layoutMenu.Append(303, "&Kamada-Kawai layout")
|
||||
menuBar.Append(layoutMenu, "&Layout")
|
||||
|
||||
# File menu events
|
||||
self.Bind(wx.EVT_MENU, self.NewGraph, id=111)
|
||||
self.Bind(wx.EVT_MENU, self.ErdosRenyiGraph, id=112)
|
||||
self.Bind(wx.EVT_MENU, self.PLODGraph, id=113)
|
||||
self.Bind(wx.EVT_MENU, self.SmallWorldGraph, id=114)
|
||||
self.Bind(wx.EVT_MENU, self.OpenGraph, id=120)
|
||||
self.Bind(wx.EVT_MENU, self.SaveGraph, id=130)
|
||||
|
||||
# Algorithms menu events
|
||||
self.Bind(wx.EVT_MENU, self.ConnectedComponents, id=201)
|
||||
self.Bind(wx.EVT_MENU, self.StrongComponents, id=202)
|
||||
self.Bind(wx.EVT_MENU, self.BiconnectedComponents, id=203)
|
||||
self.Bind(wx.EVT_MENU, self.KruskalMST, id=212)
|
||||
self.Bind(wx.EVT_MENU, self.SequentialVertexColoring, id=221)
|
||||
|
||||
# Layout menu events
|
||||
self.Bind(wx.EVT_MENU, self.CircleLayout, id=301)
|
||||
self.Bind(wx.EVT_MENU, self.FruchtermanReingoldLayout, id=302)
|
||||
self.Bind(wx.EVT_MENU, self.KamadaKawaiLayout, id=303)
|
||||
|
||||
self.SetMenuBar(menuBar)
|
||||
|
||||
def NewGraph(self, event):
|
||||
graph = bgl.Graph()
|
||||
position_map = graph.get_vertex_point2d_map("position")
|
||||
self.canvas.set_graph(graph, position_map, {})
|
||||
self.SetTitle("Graph")
|
||||
|
||||
def ErdosRenyiGraph(self, event):
|
||||
if not self.erdos_renyi_dlg:
|
||||
self.erdos_renyi_dlg = ErdosRenyiDialog(self, -1,
|
||||
"Erdos-Renyi Generator")
|
||||
dlg = self.erdos_renyi_dlg
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
graph = bgl.Graph(bgl.ErdosRenyi(dlg.GetNumVertices(),
|
||||
dlg.GetProbability() / 100),
|
||||
dlg.GetRandomSeed())
|
||||
position_map = graph.get_vertex_point2d_map("position")
|
||||
bgl.circle_graph_layout(graph, position_map, 50)
|
||||
self.canvas.set_graph(graph, position_map, {})
|
||||
self.SetTitle("Erdos-Renyi Graph ("
|
||||
+ str(dlg.GetNumVertices()) + ", "
|
||||
+ str(dlg.GetProbability() / 100) + ")")
|
||||
def PLODGraph(self, event):
|
||||
if not self.plod_dlg:
|
||||
self.plod_dlg = PLODDialog(self, -1,
|
||||
"Power Law Out Degree Generator")
|
||||
dlg = self.plod_dlg
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
graph = bgl.Graph(bgl.PowerLawOutDegree(dlg.GetNumVertices(),
|
||||
dlg.GetAlpha(),
|
||||
dlg.GetBeta()),
|
||||
dlg.GetRandomSeed())
|
||||
position_map = graph.get_vertex_point2d_map("position")
|
||||
bgl.circle_graph_layout(graph, position_map, 50)
|
||||
self.canvas.set_graph(graph, position_map, {})
|
||||
self.SetTitle("Power Law Out Degree Graph ("
|
||||
+ str(dlg.GetNumVertices()) + ", "
|
||||
+ str(dlg.GetAlpha()) + ", "
|
||||
+ str(dlg.GetBeta()) + ")")
|
||||
|
||||
def SmallWorldGraph(self, event):
|
||||
if not self.small_world_dlg:
|
||||
self.small_world_dlg = SmallWorldDialog(self, -1,
|
||||
"Small-World Generator")
|
||||
dlg = self.small_world_dlg
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
graph = bgl.Graph(bgl.SmallWorld(dlg.GetNumVertices(),
|
||||
dlg.GetNumNeighbors(),
|
||||
dlg.GetProbability() / 100),
|
||||
dlg.GetRandomSeed())
|
||||
position_map = graph.get_vertex_point2d_map("position")
|
||||
bgl.circle_graph_layout(graph, position_map, 50)
|
||||
self.canvas.set_graph(graph, position_map, {})
|
||||
self.SetTitle("Small-World Graph ("
|
||||
+ str(dlg.GetNumVertices()) + ", "
|
||||
+ str(dlg.GetNumNeighbors()) + ", "
|
||||
+ str(dlg.GetProbability() / 100) + ")")
|
||||
|
||||
def OpenGraph(self, event):
|
||||
dlg = wx.FileDialog(
|
||||
self, message="Choose a file", defaultDir=os.getcwd(),
|
||||
defaultFile="", wildcard=wildcard, style=wx.OPEN | wx.CHANGE_DIR)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
path = dlg.GetPath()
|
||||
try:
|
||||
graph = bgl.Graph(path, bgl.file_kind.graphviz)
|
||||
except bgl.directed_graph_error:
|
||||
graph = bgl.Digraph(path, bgl.file_kind.graphviz)
|
||||
needs_layout = not graph.has_vertex_map("position")
|
||||
position_map = graph.get_vertex_point2d_map("position")
|
||||
if needs_layout:
|
||||
bgl.circle_graph_layout(graph, position_map, 50)
|
||||
|
||||
self.canvas.set_graph(graph, position_map,
|
||||
self.canvas.default_property_maps(graph))
|
||||
|
||||
self.SetTitle(path_to_title(path))
|
||||
|
||||
dlg.Destroy()
|
||||
|
||||
def SaveGraph(self, event):
|
||||
dlg = wx.FileDialog(
|
||||
self, message="Choose a file", defaultDir=os.getcwd(),
|
||||
defaultFile="", wildcard=wildcard, style=wx.SAVE | wx.CHANGE_DIR)
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
path = dlg.GetPath()
|
||||
# TBD: This fails because we can't serialize Python
|
||||
# objects. Need to be able to mark some property maps as
|
||||
# internal (i.e., don't serialize them).
|
||||
self.canvas.graph.write_graphviz(path)
|
||||
dlg.Destroy()
|
||||
|
||||
def ConnectedComponents(self, event):
|
||||
graph = self.canvas.graph
|
||||
component_map = graph.get_vertex_int_map("component")
|
||||
bgl.connected_components(graph, component_map)
|
||||
self.canvas.set_vertex_colors_from_components(component_map)
|
||||
|
||||
def StrongComponents(self, event):
|
||||
graph = self.canvas.graph
|
||||
component_map = graph.get_vertex_int_map("component")
|
||||
bgl.strong_components(graph, component_map)
|
||||
self.canvas.set_vertex_colors_from_components(component_map)
|
||||
|
||||
def BiconnectedComponents(self, event):
|
||||
graph = self.canvas.graph
|
||||
component_map = graph.get_edge_int_map("component")
|
||||
art_points = bgl.biconnected_components(graph, component_map)
|
||||
for v in art_points:
|
||||
self.canvas.VertexShape(v).SetBrush(wx.RED_BRUSH)
|
||||
self.canvas.set_edge_colors_from_components(component_map)
|
||||
|
||||
def KruskalMST(self, event):
|
||||
graph = self.canvas.graph
|
||||
weight_map = graph.get_edge_double_map("weight")
|
||||
mst_edges = bgl.kruskal_minimum_spanning_tree(graph, weight_map)
|
||||
for e in mst_edges:
|
||||
shape = self.canvas.EdgeShape(e)
|
||||
shape.SetPen(wx.Pen(shape.GetPen().GetColour(), 3))
|
||||
self.canvas.Refresh()
|
||||
|
||||
def SequentialVertexColoring(self, event):
|
||||
graph = self.canvas.graph
|
||||
color_map = graph.get_vertex_int_map("color")
|
||||
bgl.sequential_vertex_coloring(graph, color_map)
|
||||
self.canvas.set_vertex_colors_from_components(color_map)
|
||||
|
||||
def CircleLayout(self, event):
|
||||
bgl.circle_graph_layout(self.canvas.graph, self.canvas.position_map, 50)
|
||||
self.canvas.update_layout()
|
||||
|
||||
def FruchtermanReingoldLayout(self, event):
|
||||
bgl.fruchterman_reingold_force_directed_layout(self.canvas.graph,
|
||||
self.canvas.position_map,
|
||||
width=100, height=100,
|
||||
progressive=True)
|
||||
self.canvas.update_layout()
|
||||
|
||||
def KamadaKawaiLayout(self, event):
|
||||
bgl.kamada_kawai_spring_layout(self.canvas.graph,
|
||||
self.canvas.position_map, side_length=90)
|
||||
self.canvas.update_layout()
|
||||
|
||||
|
||||
class GraphDrawApp(wx.App):
|
||||
def OnInit(self):
|
||||
# This creates some pens and brushes that the OGL library uses.
|
||||
# It should be called after the app object has been created, but
|
||||
# before OGL is used.
|
||||
ogl.OGLInitialize()
|
||||
|
||||
self.editor = GraphEditorWindow(None)
|
||||
self.editor.Show(True)
|
||||
return True
|
||||
|
||||
app = GraphDrawApp(0)
|
||||
app.MainLoop()
|
||||
@@ -386,7 +386,7 @@ namespace boost {
|
||||
template <class EdgeIterator>
|
||||
inline adjacency_list(EdgeIterator first, EdgeIterator last,
|
||||
vertices_size_type n,
|
||||
edges_size_type m = 0,
|
||||
edges_size_type = 0,
|
||||
const GraphProperty& p = GraphProperty())
|
||||
: Base(n, first, last), m_property(p) { }
|
||||
|
||||
@@ -394,7 +394,7 @@ namespace boost {
|
||||
inline adjacency_list(EdgeIterator first, EdgeIterator last,
|
||||
EdgePropertyIterator ep_iter,
|
||||
vertices_size_type n,
|
||||
edges_size_type m = 0,
|
||||
edges_size_type = 0,
|
||||
const GraphProperty& p = GraphProperty())
|
||||
: Base(n, first, last, ep_iter), m_property(p) { }
|
||||
#endif
|
||||
|
||||
@@ -164,7 +164,7 @@ namespace boost {
|
||||
|
||||
// Find one vertex from each connected component
|
||||
BGL_FORALL_VERTICES_T(v, G, Graph) {
|
||||
if (get(color, v) != Color::white()) {
|
||||
if (get(color, v) == Color::white()) {
|
||||
depth_first_visit(G, v, dfs_visitor<>(), color);
|
||||
vertex_queue.push_back(v);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
|
||||
#include <map> // for vertex_map in copy_impl
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
#include <boost/property_map.hpp>
|
||||
#include <boost/pending/integer_range.hpp>
|
||||
@@ -2669,12 +2670,16 @@ namespace boost {
|
||||
#if !defined(BOOST_NO_HASH) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION)
|
||||
namespace BOOST_STD_EXTENSION_NAMESPACE {
|
||||
|
||||
#if BOOST_WORKAROUND( _STLPORT_VERSION, >= 0x500 )
|
||||
// STLport 5 already defines a hash<void*> specialization.
|
||||
#else
|
||||
template <>
|
||||
struct hash< void* > // Need this when vertex_descriptor=void*
|
||||
{
|
||||
std::size_t
|
||||
operator()(void* v) const { return (std::size_t)v; }
|
||||
};
|
||||
#endif
|
||||
|
||||
template <typename V>
|
||||
struct hash< boost::detail::stored_edge<V> >
|
||||
|
||||
@@ -140,7 +140,7 @@ namespace boost {
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// Initalize distances and call breadth first search
|
||||
// Call breadth first search with default color map.
|
||||
template <class VertexListGraph, class DijkstraVisitor,
|
||||
class PredecessorMap, class DistanceMap,
|
||||
class WeightMap, class IndexMap, class Compare, class Combine,
|
||||
@@ -153,6 +153,27 @@ namespace boost {
|
||||
IndexMap index_map,
|
||||
Compare compare, Combine combine, DistZero zero,
|
||||
DijkstraVisitor vis)
|
||||
{
|
||||
std::vector<default_color_type> color(num_vertices(g));
|
||||
default_color_type c = white_color;
|
||||
dijkstra_shortest_paths_no_init( g, s, predecessor, distance, weight,
|
||||
index_map, compare, combine, zero, vis,
|
||||
make_iterator_property_map(&color[0], index_map, c));
|
||||
}
|
||||
|
||||
// Call breadth first search
|
||||
template <class VertexListGraph, class DijkstraVisitor,
|
||||
class PredecessorMap, class DistanceMap,
|
||||
class WeightMap, class IndexMap, class Compare, class Combine,
|
||||
class DistZero, class ColorMap>
|
||||
inline void
|
||||
dijkstra_shortest_paths_no_init
|
||||
(const VertexListGraph& g,
|
||||
typename graph_traits<VertexListGraph>::vertex_descriptor s,
|
||||
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
|
||||
IndexMap index_map,
|
||||
Compare compare, Combine combine, DistZero zero,
|
||||
DijkstraVisitor vis, ColorMap color)
|
||||
{
|
||||
typedef indirect_cmp<DistanceMap, Compare> IndirectCmp;
|
||||
IndirectCmp icmp(distance, compare);
|
||||
@@ -170,10 +191,7 @@ namespace boost {
|
||||
PredecessorMap, DistanceMap, Combine, Compare>
|
||||
bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero);
|
||||
|
||||
std::vector<default_color_type> color(num_vertices(g));
|
||||
default_color_type c = white_color;
|
||||
breadth_first_visit(g, s, Q, bfs_vis,
|
||||
make_iterator_property_map(&color[0], index_map, c));
|
||||
breadth_first_visit(g, s, Q, bfs_vis, color);
|
||||
return;
|
||||
}
|
||||
#endif // BOOST_GRAPH_DIJKSTRA_TESTING
|
||||
@@ -186,14 +204,10 @@ namespace boost {
|
||||
PredecessorMap, DistanceMap, Combine, Compare>
|
||||
bfs_vis(vis, Q, weight, predecessor, distance, combine, compare, zero);
|
||||
|
||||
std::vector<default_color_type> color(num_vertices(g));
|
||||
default_color_type c = white_color;
|
||||
breadth_first_visit(g, s, Q, bfs_vis,
|
||||
make_iterator_property_map(&color[0], index_map, c));
|
||||
breadth_first_visit(g, s, Q, bfs_vis, color);
|
||||
}
|
||||
|
||||
|
||||
// Initalize distances and call breadth first search
|
||||
// Initialize distances and call breadth first search with default color map
|
||||
template <class VertexListGraph, class DijkstraVisitor,
|
||||
class PredecessorMap, class DistanceMap,
|
||||
class WeightMap, class IndexMap, class Compare, class Combine,
|
||||
@@ -207,15 +221,40 @@ namespace boost {
|
||||
Compare compare, Combine combine, DistInf inf, DistZero zero,
|
||||
DijkstraVisitor vis)
|
||||
{
|
||||
std::vector<default_color_type> color(num_vertices(g));
|
||||
default_color_type c = white_color;
|
||||
dijkstra_shortest_paths(g, s, predecessor, distance, weight, index_map,
|
||||
compare, combine, inf, zero, vis,
|
||||
make_iterator_property_map(&color[0], index_map,
|
||||
c));
|
||||
}
|
||||
|
||||
// Initialize distances and call breadth first search
|
||||
template <class VertexListGraph, class DijkstraVisitor,
|
||||
class PredecessorMap, class DistanceMap,
|
||||
class WeightMap, class IndexMap, class Compare, class Combine,
|
||||
class DistInf, class DistZero, class ColorMap>
|
||||
inline void
|
||||
dijkstra_shortest_paths
|
||||
(const VertexListGraph& g,
|
||||
typename graph_traits<VertexListGraph>::vertex_descriptor s,
|
||||
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
|
||||
IndexMap index_map,
|
||||
Compare compare, Combine combine, DistInf inf, DistZero zero,
|
||||
DijkstraVisitor vis, ColorMap color)
|
||||
{
|
||||
typedef typename property_traits<ColorMap>::value_type ColorValue;
|
||||
typedef color_traits<ColorValue> Color;
|
||||
typename graph_traits<VertexListGraph>::vertex_iterator ui, ui_end;
|
||||
for (tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
|
||||
put(distance, *ui, inf);
|
||||
put(predecessor, *ui, *ui);
|
||||
put(color, *ui, Color::white());
|
||||
}
|
||||
put(distance, s, zero);
|
||||
|
||||
dijkstra_shortest_paths_no_init(g, s, predecessor, distance, weight,
|
||||
index_map, compare, combine, zero, vis);
|
||||
index_map, compare, combine, zero, vis, color);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
@@ -223,13 +262,13 @@ namespace boost {
|
||||
// Handle defaults for PredecessorMap and
|
||||
// Distance Compare, Combine, Inf and Zero
|
||||
template <class VertexListGraph, class DistanceMap, class WeightMap,
|
||||
class IndexMap, class Params>
|
||||
class IndexMap, class Params, class ColorMap>
|
||||
inline void
|
||||
dijkstra_dispatch2
|
||||
(const VertexListGraph& g,
|
||||
typename graph_traits<VertexListGraph>::vertex_descriptor s,
|
||||
DistanceMap distance, WeightMap weight, IndexMap index_map,
|
||||
const Params& params)
|
||||
const Params& params, ColorMap color)
|
||||
{
|
||||
// Default for predecessor map
|
||||
dummy_property_map p_map;
|
||||
@@ -248,17 +287,18 @@ namespace boost {
|
||||
choose_param(get_param(params, distance_zero_t()),
|
||||
D()),
|
||||
choose_param(get_param(params, graph_visitor),
|
||||
make_dijkstra_visitor(null_visitor())));
|
||||
make_dijkstra_visitor(null_visitor())),
|
||||
color);
|
||||
}
|
||||
|
||||
template <class VertexListGraph, class DistanceMap, class WeightMap,
|
||||
class IndexMap, class Params>
|
||||
class IndexMap, class Params, class ColorMap>
|
||||
inline void
|
||||
dijkstra_dispatch1
|
||||
(const VertexListGraph& g,
|
||||
typename graph_traits<VertexListGraph>::vertex_descriptor s,
|
||||
DistanceMap distance, WeightMap weight, IndexMap index_map,
|
||||
const Params& params)
|
||||
const Params& params, ColorMap color)
|
||||
{
|
||||
// Default for distance map
|
||||
typedef typename property_traits<WeightMap>::value_type D;
|
||||
@@ -266,11 +306,19 @@ namespace boost {
|
||||
n = is_default_param(distance) ? num_vertices(g) : 1;
|
||||
std::vector<D> distance_map(n);
|
||||
|
||||
// Default for color map
|
||||
typename std::vector<default_color_type>::size_type
|
||||
m = is_default_param(color) ? num_vertices(g) : 1;
|
||||
std::vector<default_color_type> color_map(m);
|
||||
|
||||
detail::dijkstra_dispatch2
|
||||
(g, s, choose_param(distance, make_iterator_property_map
|
||||
(distance_map.begin(), index_map,
|
||||
distance_map[0])),
|
||||
weight, index_map, params);
|
||||
weight, index_map, params,
|
||||
choose_param(color, make_iterator_property_map
|
||||
(color_map.begin(), index_map,
|
||||
color_map[0])));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
@@ -289,7 +337,8 @@ namespace boost {
|
||||
get_param(params, vertex_distance),
|
||||
choose_const_pmap(get_param(params, edge_weight), g, edge_weight),
|
||||
choose_const_pmap(get_param(params, vertex_index), g, vertex_index),
|
||||
params);
|
||||
params,
|
||||
get_param(params, vertex_color));
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
@@ -201,12 +201,12 @@ namespace boost {
|
||||
template<typename Descriptor>
|
||||
typename graph::detail::bundled_result<Graph, Descriptor>::type&
|
||||
operator[](Descriptor x)
|
||||
{ return this->m_g[local_to_global(x)]; }
|
||||
{ return const_cast<Graph&>(this->m_g)[x]; }
|
||||
|
||||
template<typename Descriptor>
|
||||
typename graph::detail::bundled_result<Graph, Descriptor>::type const&
|
||||
operator[](Descriptor x) const
|
||||
{ return this->m_g[local_to_global(x)]; }
|
||||
{ return this->m_g[x]; }
|
||||
#endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES
|
||||
|
||||
//private:
|
||||
|
||||
@@ -131,41 +131,21 @@ struct grid_force_pairs
|
||||
apply_force(*v, *u);
|
||||
}
|
||||
|
||||
// Repulse vertices in the bucket to the right
|
||||
if (column < columns - 1) {
|
||||
bucket_t& r_bucket = buckets[row * columns + column + 1];
|
||||
for (v = r_bucket.begin(); v != r_bucket.end(); ++v) {
|
||||
apply_force(*u, *v);
|
||||
apply_force(*v, *u);
|
||||
}
|
||||
}
|
||||
|
||||
// Repulse vertices in bucket below
|
||||
if (row < rows - 1) {
|
||||
bucket_t& b_bucket = buckets[(row + 1) * columns + column];
|
||||
for (v = b_bucket.begin(); v != b_bucket.end(); ++v) {
|
||||
apply_force(*u, *v);
|
||||
apply_force(*v, *u);
|
||||
}
|
||||
}
|
||||
|
||||
// Repulse vertices in bucket below and to the right
|
||||
if (column < columns - 1 && row < rows - 1) {
|
||||
bucket_t& br_bucket = buckets[(row + 1) * columns + column + 1];
|
||||
for (v = br_bucket.begin(); v != br_bucket.end(); ++v) {
|
||||
apply_force(*u, *v);
|
||||
apply_force(*v, *u);
|
||||
}
|
||||
}
|
||||
|
||||
// Repulse vertices in bucket above and to the right
|
||||
if (column < columns - 1 && row > 0) {
|
||||
bucket_t& ur_bucket = buckets[(row - 1) * columns + column + 1];
|
||||
for (v = ur_bucket.begin(); v != ur_bucket.end(); ++v) {
|
||||
apply_force(*u, *v);
|
||||
apply_force(*v, *u);
|
||||
}
|
||||
}
|
||||
std::size_t adj_start_row = row == 0? 0 : row - 1;
|
||||
std::size_t adj_end_row = row == rows - 1? row : row + 1;
|
||||
std::size_t adj_start_column = column == 0? 0 : column - 1;
|
||||
std::size_t adj_end_column = column == columns - 1? column : column + 1;
|
||||
for (std::size_t other_row = adj_start_row; other_row <= adj_end_row;
|
||||
++other_row)
|
||||
for (std::size_t other_column = adj_start_column;
|
||||
other_column <= adj_end_column; ++other_column)
|
||||
if (other_row != row || other_column != column) {
|
||||
// Repulse vertices in this bucket
|
||||
bucket_t& other_bucket
|
||||
= buckets[other_row * columns + other_column];
|
||||
for (v = other_bucket.begin(); v != other_bucket.end(); ++v)
|
||||
apply_force(*u, *v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +294,7 @@ namespace boost {
|
||||
|
||||
// Find one vertex from each connected component
|
||||
BGL_FORALL_VERTICES_T(v, G, Graph) {
|
||||
if (get(color, v) != Color::white()) {
|
||||
if (get(color, v) == Color::white()) {
|
||||
depth_first_visit(G, v, dfs_visitor<>(), color);
|
||||
vertex_queue.push_back(v);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
#include <functional>
|
||||
#include <boost/property_map.hpp>
|
||||
#include <cmath>
|
||||
#include <boost/optional.hpp>
|
||||
#include <vector>
|
||||
|
||||
@@ -87,23 +86,38 @@ private:
|
||||
group** children;
|
||||
};
|
||||
|
||||
size_type log2(size_type n)
|
||||
{
|
||||
size_type leading_zeroes = 0;
|
||||
do {
|
||||
size_type next = n << 1;
|
||||
if (n == (next >> 1)) {
|
||||
++leading_zeroes;
|
||||
n = next;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (true);
|
||||
return sizeof(size_type) * CHAR_BIT - leading_zeroes - 1;
|
||||
}
|
||||
|
||||
public:
|
||||
relaxed_heap(size_type n, const Compare& compare = Compare(),
|
||||
const ID& id = ID())
|
||||
: compare(compare), id(id), root(smallest_key), groups(n),
|
||||
smallest_value(0)
|
||||
{
|
||||
#ifndef BOOST_NO_STDC_NAMESPACE
|
||||
using std::log;
|
||||
#endif // BOOST_NO_STDC_NAMESPACE
|
||||
if (n == 0) {
|
||||
root.children = new group*[1];
|
||||
return;
|
||||
}
|
||||
|
||||
if (n == 0) return;
|
||||
log_n = log2(n);
|
||||
|
||||
log_n = static_cast<size_type>(log((double)n) / log(2.0));
|
||||
if (log_n == 0) log_n = 1;
|
||||
size_type g = n / log_n;
|
||||
if (n % log_n > 0) ++g;
|
||||
size_type log_g = static_cast<size_type>(log((double)g) / log(2.0));
|
||||
size_type log_g = log2(g);
|
||||
size_type r = log_g;
|
||||
|
||||
// Reserve an appropriate amount of space for data structures, so
|
||||
@@ -120,7 +134,7 @@ public:
|
||||
root.children[r] = &index_to_group[idx];
|
||||
idx = build_tree(root, idx, r, log_g + 1);
|
||||
if (idx != g)
|
||||
r = static_cast<size_type>(log((double)(g - idx)) / log(2.0));
|
||||
r = static_cast<size_type>(log2(g-idx));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
using std::free;
|
||||
using std::malloc;
|
||||
|
||||
#ifndef GRAPHVIZ_DIRECTED
|
||||
#error Need to define the GRAPHVIZ_DIRECTED macro to either 0 or 1
|
||||
#endif
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
using std::free;
|
||||
using std::malloc;
|
||||
|
||||
#ifndef GRAPHVIZ_DIRECTED
|
||||
#error Need to define the GRAPHVIZ_DIRECTED macro to either 0 or 1
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
#include <sstream>
|
||||
#endif
|
||||
|
||||
using std::free;
|
||||
using std::malloc;
|
||||
|
||||
#ifndef GRAPHVIZ_DIRECTED
|
||||
#error Need to define the GRAPHVIZ_DIRECTED macro to either 0 or 1
|
||||
#endif
|
||||
|
||||
@@ -1,686 +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 "basic_graph.hpp"
|
||||
#include <boost/graph/iteration_macros.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, default_color_type c)
|
||||
{
|
||||
switch (c) {
|
||||
case white_color: return out << "white";
|
||||
case gray_color: return out << "gray";
|
||||
case green_color: return out << "green";
|
||||
case red_color: return out << "red";
|
||||
case black_color: return out << "black";
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
inline std::istream& operator>>(std::istream& in, default_color_type& c)
|
||||
{
|
||||
std::string text;
|
||||
if (in >> text) {
|
||||
if (text == "white") c = white_color;
|
||||
else if (text == "gray") c = gray_color;
|
||||
else if (text == "green") c = green_color;
|
||||
else if (text == "red") c = red_color;
|
||||
else if (text == "black") c = black_color;
|
||||
else {
|
||||
in.setstate(std::ios_base::failbit);
|
||||
return in;
|
||||
}
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
namespace graph { namespace python {
|
||||
|
||||
template<typename DirectedS>
|
||||
struct build_string_property_maps
|
||||
{
|
||||
build_string_property_maps(basic_graph<DirectedS>* g) : g(g) { }
|
||||
|
||||
std::auto_ptr<boost::dynamic_property_map>
|
||||
operator()(const std::string& name, const boost::any& key,
|
||||
const boost::any& value)
|
||||
{
|
||||
typedef typename basic_graph<DirectedS>::VertexIndexMap VertexIndexMap;
|
||||
typedef typename basic_graph<DirectedS>::EdgeIndexMap EdgeIndexMap;
|
||||
|
||||
std::auto_ptr<boost::dynamic_property_map> result(0);
|
||||
|
||||
if (key.type() == typeid(typename basic_graph<DirectedS>::Vertex)) {
|
||||
typedef vector_property_map<std::string, VertexIndexMap>
|
||||
property_map_type;
|
||||
typedef python_dynamic_adaptor<property_map_type> adaptor_type;
|
||||
result.reset
|
||||
(new adaptor_type(property_map_type(g->num_vertices(),
|
||||
g->get_vertex_index_map())));
|
||||
} else if (key.type() == typeid(typename basic_graph<DirectedS>::Edge)) {
|
||||
typedef vector_property_map<std::string, EdgeIndexMap> property_map_type;
|
||||
typedef python_dynamic_adaptor<property_map_type> adaptor_type;
|
||||
result.reset
|
||||
(new adaptor_type(property_map_type(g->num_edges(),
|
||||
g->get_edge_index_map())));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
basic_graph<DirectedS>* g;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Constructors
|
||||
// ----------------------------------------------------------
|
||||
template<typename DirectedS>
|
||||
basic_graph<DirectedS>::basic_graph()
|
||||
: inherited(), dp(build_string_property_maps<DirectedS>(this))
|
||||
{ }
|
||||
|
||||
template<typename DirectedS>
|
||||
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];
|
||||
object vp = l[i][1];
|
||||
|
||||
typename std::map<object, vertex_descriptor>::iterator pos;
|
||||
pos = verts.find(up);
|
||||
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 (!name_map.empty()) name[v] = vp;
|
||||
}
|
||||
else v = pos->second;
|
||||
|
||||
add_edge(u, v);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
basic_graph<DirectedS>::basic_graph(const std::string& filename,
|
||||
graph_file_kind kind)
|
||||
: inherited(), dp(build_string_property_maps<DirectedS>(this))
|
||||
{
|
||||
switch (kind) {
|
||||
case gfk_adjlist:
|
||||
break;
|
||||
case gfk_graphviz:
|
||||
read_graphviz(filename);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
basic_graph<DirectedS>::basic_graph(erdos_renyi er, int seed)
|
||||
: stored_minstd_rand(seed),
|
||||
inherited(er_iterator(this->gen, er.n, er.p), er_iterator(), er.n)
|
||||
{
|
||||
renumber_vertices();
|
||||
renumber_edges();
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
basic_graph<DirectedS>::basic_graph(power_law_out_degree plod, int seed)
|
||||
: stored_minstd_rand(seed),
|
||||
inherited(sf_iterator(this->gen, plod.n, plod.alpha, plod.beta),
|
||||
sf_iterator(),
|
||||
plod.n)
|
||||
{
|
||||
renumber_vertices();
|
||||
renumber_edges();
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
basic_graph<DirectedS>::basic_graph(small_world sw, int seed)
|
||||
: stored_minstd_rand(seed),
|
||||
inherited(sw_iterator(this->gen, sw.n, sw.k, sw.p), sw_iterator(), sw.n)
|
||||
{
|
||||
renumber_vertices();
|
||||
renumber_edges();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Incidence basic_graph<DirectedS> concept
|
||||
// ----------------------------------------------------------
|
||||
template<typename DirectedS>
|
||||
typename basic_graph<DirectedS>::Vertex
|
||||
basic_graph<DirectedS>::source(Edge e) const
|
||||
{ return Vertex(boost::source(e.base, base())); }
|
||||
|
||||
template<typename DirectedS>
|
||||
typename basic_graph<DirectedS>::Vertex
|
||||
basic_graph<DirectedS>::target(Edge e) const
|
||||
{ return Vertex(boost::target(e.base, base())); }
|
||||
|
||||
|
||||
template<typename DirectedS>
|
||||
std::pair<typename basic_graph<DirectedS>::out_edge_iterator,
|
||||
typename basic_graph<DirectedS>::out_edge_iterator>
|
||||
basic_graph<DirectedS>::out_edges(Vertex u) const
|
||||
{
|
||||
std::pair<base_out_edge_iterator, base_out_edge_iterator> rng =
|
||||
boost::out_edges(u.base, base());
|
||||
return std::make_pair(out_edge_iterator(rng.first, typename Edge::create()),
|
||||
out_edge_iterator(rng.second,typename Edge::create()));
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
simple_python_iterator<typename basic_graph<DirectedS>::out_edge_iterator>
|
||||
basic_graph<DirectedS>::py_out_edges(Vertex u) const
|
||||
{
|
||||
return simple_python_iterator<out_edge_iterator>(out_edges(u));
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
std::size_t
|
||||
basic_graph<DirectedS>::out_degree(Vertex u) const
|
||||
{
|
||||
return boost::out_degree(u.base, base());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Bidirectional basic_graph<DirectedS> concept
|
||||
// ----------------------------------------------------------
|
||||
template<typename DirectedS>
|
||||
std::pair<typename basic_graph<DirectedS>::in_edge_iterator,
|
||||
typename basic_graph<DirectedS>::in_edge_iterator>
|
||||
basic_graph<DirectedS>::in_edges(Vertex u) const
|
||||
{
|
||||
std::pair<base_in_edge_iterator, base_in_edge_iterator> rng =
|
||||
boost::in_edges(u.base, base());
|
||||
return std::make_pair(in_edge_iterator(rng.first, typename Edge::create()),
|
||||
in_edge_iterator(rng.second, typename Edge::create()));
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
simple_python_iterator<typename basic_graph<DirectedS>::in_edge_iterator>
|
||||
basic_graph<DirectedS>::py_in_edges(Vertex u) const
|
||||
{
|
||||
return simple_python_iterator<in_edge_iterator>(in_edges(u));
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
std::size_t
|
||||
basic_graph<DirectedS>::in_degree(Vertex u) const
|
||||
{
|
||||
return boost::in_degree(u.base, base());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Adjacency basic_graph<DirectedS> concept
|
||||
// ----------------------------------------------------------
|
||||
template<typename DirectedS>
|
||||
std::pair<typename basic_graph<DirectedS>::adjacency_iterator,
|
||||
typename basic_graph<DirectedS>::adjacency_iterator>
|
||||
basic_graph<DirectedS>::adjacent_vertices(Vertex u) const
|
||||
{
|
||||
std::pair<base_adjacency_iterator, base_adjacency_iterator> rng =
|
||||
boost::adjacent_vertices(u.base, base());
|
||||
return std::make_pair(adjacency_iterator(rng.first, typename Vertex::create()),
|
||||
adjacency_iterator(rng.second, typename Vertex::create()));
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
simple_python_iterator<typename basic_graph<DirectedS>::adjacency_iterator>
|
||||
basic_graph<DirectedS>::py_adjacent_vertices(Vertex u) const
|
||||
{
|
||||
return
|
||||
simple_python_iterator<adjacency_iterator>(adjacent_vertices(u));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Vertex properties
|
||||
// ----------------------------------------------------------
|
||||
template<typename DirectedS>
|
||||
template<typename T>
|
||||
vector_property_map<T, typename basic_graph<DirectedS>::VertexIndexMap>
|
||||
basic_graph<DirectedS>::get_vertex_map(const std::string& name)
|
||||
{
|
||||
typedef vector_property_map<T, VertexIndexMap> result_type;
|
||||
typedef python_dynamic_adaptor<result_type> adaptor_type;
|
||||
|
||||
dynamic_properties::iterator i = dp.lower_bound(name);
|
||||
while (i != dp.end() && i->first == name) {
|
||||
if (i->second->key() == typeid(Vertex)) {
|
||||
if (i->second->value() == typeid(T)) {
|
||||
return dynamic_cast<adaptor_type&>(*i->second).base();
|
||||
} else {
|
||||
// Convert the property map element-by-element to the
|
||||
// requested type.
|
||||
result_type result(num_vertices(), get_vertex_index_map());
|
||||
for(vertex_iterator v = vertices().first; v != vertices().second;
|
||||
++v) {
|
||||
put(result, *v, lexical_cast<T>(i->second->get_string(*v)));
|
||||
}
|
||||
|
||||
// Replace the existing property map with the converted one
|
||||
adaptor_type* adaptor = new adaptor_type(result);
|
||||
delete i->second;
|
||||
i->second = adaptor;
|
||||
|
||||
// Return the new property map.
|
||||
return result;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
typedef vector_property_map<T, VertexIndexMap> property_map_type;
|
||||
typedef python_dynamic_adaptor<property_map_type> adaptor_type;
|
||||
property_map_type result(num_vertices(), get_vertex_index_map());
|
||||
dp.insert(name,
|
||||
std::auto_ptr<dynamic_property_map>(new adaptor_type(result)));
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
bool
|
||||
basic_graph<DirectedS>::has_vertex_map(const std::string& name) const
|
||||
{
|
||||
dynamic_properties::const_iterator i = dp.lower_bound(name);
|
||||
while (i != dp.end() && i->first == name) {
|
||||
if (i->second->key() == typeid(Vertex))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Edge properties
|
||||
// ----------------------------------------------------------
|
||||
template<typename DirectedS>
|
||||
template<typename T>
|
||||
vector_property_map<T, typename basic_graph<DirectedS>::EdgeIndexMap>
|
||||
basic_graph<DirectedS>::get_edge_map(const std::string& name)
|
||||
{
|
||||
typedef vector_property_map<T, EdgeIndexMap> result_type;
|
||||
typedef python_dynamic_adaptor<result_type> adaptor_type;
|
||||
|
||||
dynamic_properties::iterator i = dp.lower_bound(name);
|
||||
while (i != dp.end() && i->first == name) {
|
||||
if (i->second->key() == typeid(Edge)) {
|
||||
if (i->second->value() == typeid(T)) {
|
||||
return dynamic_cast<adaptor_type&>(*i->second).base();
|
||||
} else {
|
||||
// Convert the property map element-by-element to the
|
||||
// requested type.
|
||||
result_type result(num_vertices(), get_edge_index_map());
|
||||
for(edge_iterator e = edges().first; e != edges().second; ++e) {
|
||||
put(result, *e, lexical_cast<T>(i->second->get_string(*e)));
|
||||
}
|
||||
|
||||
// Replace the existing property map with the converted one
|
||||
adaptor_type* adaptor = new adaptor_type(result);
|
||||
delete i->second;
|
||||
i->second = adaptor;
|
||||
|
||||
// Return the new property map.
|
||||
return result;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
|
||||
typedef vector_property_map<T, EdgeIndexMap> property_map_type;
|
||||
typedef python_dynamic_adaptor<property_map_type> adaptor_type;
|
||||
property_map_type result(num_edges(), get_edge_index_map());
|
||||
dp.insert(name,
|
||||
std::auto_ptr<dynamic_property_map>(new adaptor_type(result)));
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
bool
|
||||
basic_graph<DirectedS>::has_edge_map(const std::string& name) const
|
||||
{
|
||||
dynamic_properties::const_iterator i = dp.lower_bound(name);
|
||||
while (i != dp.end() && i->first == name) {
|
||||
if (i->second->key() == typeid(Edge))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Mutable graph
|
||||
// ----------------------------------------------------------
|
||||
template<typename DirectedS>
|
||||
typename basic_graph<DirectedS>::Vertex basic_graph<DirectedS>::add_vertex()
|
||||
{
|
||||
using boost::add_vertex;
|
||||
|
||||
base_vertex_descriptor v = add_vertex(base());
|
||||
put(vertex_index, base(), v, index_to_vertex.size());
|
||||
index_to_vertex.push_back(v);
|
||||
return Vertex(v);
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
void basic_graph<DirectedS>::clear_vertex(Vertex vertex)
|
||||
{
|
||||
// Remove all incoming and outgoing edges
|
||||
while (out_degree(vertex) > 0) remove_edge(*out_edges(vertex).first);
|
||||
while (in_degree(vertex) > 0) remove_edge(*in_edges(vertex).first);
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
void basic_graph<DirectedS>::remove_vertex(Vertex vertex)
|
||||
{
|
||||
using boost::remove_vertex;
|
||||
|
||||
// Update property maps
|
||||
for (dynamic_properties::iterator i = dp.begin(); i != dp.end(); ++i) {
|
||||
if (i->second->key() == typeid(Vertex)) {
|
||||
dynamic_cast<python_dynamic_property_map*>(&*i->second)->
|
||||
copy_value(vertex, Vertex(index_to_vertex.back()));
|
||||
}
|
||||
}
|
||||
|
||||
// Update vertex indices
|
||||
std::size_t index = get(vertex_index, base(), vertex.base);
|
||||
index_to_vertex[index] = index_to_vertex.back();
|
||||
put(vertex_index, base(), index_to_vertex[index], index);
|
||||
index_to_vertex.pop_back();
|
||||
|
||||
// Remove the actual vertex
|
||||
remove_vertex(vertex.base, base());
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
std::size_t basic_graph<DirectedS>::num_vertices() const
|
||||
{
|
||||
using boost::num_vertices;
|
||||
return num_vertices(base());
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
typename basic_graph<DirectedS>::vertex_iterator
|
||||
basic_graph<DirectedS>::vertices_begin() const
|
||||
{
|
||||
return make_transform_iterator(boost::vertices(base()).first,
|
||||
typename Vertex::create());
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
typename basic_graph<DirectedS>::vertex_iterator
|
||||
basic_graph<DirectedS>::vertices_end() const
|
||||
{
|
||||
return make_transform_iterator(boost::vertices(base()).second,
|
||||
typename Vertex::create());
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
std::pair<typename basic_graph<DirectedS>::vertex_iterator,
|
||||
typename basic_graph<DirectedS>::vertex_iterator>
|
||||
basic_graph<DirectedS>::vertices() const
|
||||
{
|
||||
return std::make_pair(vertices_begin(), vertices_end());
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
simple_python_iterator<typename basic_graph<DirectedS>::vertex_iterator>
|
||||
basic_graph<DirectedS>::py_vertices() const
|
||||
{
|
||||
return simple_python_iterator<vertex_iterator>(vertices());
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
typename basic_graph<DirectedS>::Edge
|
||||
basic_graph<DirectedS>::add_edge(Vertex u, Vertex v)
|
||||
{
|
||||
using boost::add_edge;
|
||||
|
||||
base_edge_descriptor e = add_edge(u.base, v.base, base()).first;
|
||||
put(edge_index, base(), e, index_to_edge.size());
|
||||
index_to_edge.push_back(e);
|
||||
return Edge(e);
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
void basic_graph<DirectedS>::remove_edge(Edge edge)
|
||||
{
|
||||
using boost::remove_edge;
|
||||
|
||||
// Update property maps
|
||||
for (dynamic_properties::iterator i = dp.begin(); i != dp.end(); ++i) {
|
||||
if (i->second->key() == typeid(Edge)) {
|
||||
dynamic_cast<python_dynamic_property_map*>(&*i->second)->
|
||||
copy_value(edge, Edge(index_to_edge.back()));
|
||||
}
|
||||
}
|
||||
|
||||
// Update edge indices
|
||||
std::size_t index = get(edge_index, base(), edge.base);
|
||||
index_to_edge[index] = index_to_edge.back();
|
||||
put(edge_index, base(), index_to_edge[index], index);
|
||||
index_to_edge.pop_back();
|
||||
|
||||
// Remove the actual edge
|
||||
remove_edge(edge.base, base());
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
std::size_t basic_graph<DirectedS>::num_edges() const
|
||||
{
|
||||
using boost::num_edges;
|
||||
return num_edges(base());
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
typename basic_graph<DirectedS>::edge_iterator
|
||||
basic_graph<DirectedS>::edges_begin() const
|
||||
{
|
||||
return make_transform_iterator(boost::edges(base()).first,
|
||||
typename Edge::create());
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
typename basic_graph<DirectedS>::edge_iterator
|
||||
basic_graph<DirectedS>::edges_end() const
|
||||
{
|
||||
return make_transform_iterator(boost::edges(base()).second,
|
||||
typename Edge::create());
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
std::pair<typename basic_graph<DirectedS>::edge_iterator,
|
||||
typename basic_graph<DirectedS>::edge_iterator>
|
||||
basic_graph<DirectedS>::edges() const
|
||||
{
|
||||
return std::make_pair(edges_begin(), edges_end());
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
simple_python_iterator<typename basic_graph<DirectedS>::edge_iterator>
|
||||
basic_graph<DirectedS>::py_edges() const
|
||||
{
|
||||
return simple_python_iterator<edge_iterator>(edges());
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
void basic_graph<DirectedS>::renumber_vertices()
|
||||
{
|
||||
using boost::vertices;
|
||||
|
||||
BGL_FORALL_VERTICES_T(v, base(), inherited) {
|
||||
put(vertex_index, base(), v, index_to_vertex.size());
|
||||
index_to_vertex.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
void basic_graph<DirectedS>::renumber_edges()
|
||||
{
|
||||
using boost::edges;
|
||||
|
||||
BGL_FORALL_EDGES_T(e, base(), inherited) {
|
||||
put(edge_index, base(), e, index_to_edge.size());
|
||||
index_to_edge.push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Graph> void export_in_graph();
|
||||
|
||||
template<typename DirectedS>
|
||||
void export_basic_graph(const char* name)
|
||||
{
|
||||
using boost::python::arg;
|
||||
using boost::python::class_;
|
||||
using boost::python::init;
|
||||
using boost::python::object;
|
||||
using boost::python::range;
|
||||
using boost::python::scope;
|
||||
using boost::python::self;
|
||||
using boost::python::tuple;
|
||||
|
||||
typedef basic_graph<DirectedS> Graph;
|
||||
typedef typename Graph::Vertex Vertex;
|
||||
typedef typename Graph::Edge Edge;
|
||||
typedef typename Graph::VertexIndexMap VertexIndexMap;
|
||||
typedef typename Graph::EdgeIndexMap EdgeIndexMap;
|
||||
|
||||
{
|
||||
scope s(
|
||||
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)))
|
||||
.def(init<power_law_out_degree, std::size_t>(
|
||||
(arg("generator"), arg("seed") = 1)))
|
||||
.def(init<small_world, std::size_t>(
|
||||
(arg("generator"), arg("seed") = 1)))
|
||||
.def("is_directed", &Graph::is_directed)
|
||||
// Vertex List Graph concept
|
||||
.def("num_vertices", &Graph::num_vertices)
|
||||
.add_property("vertices", &Graph::py_vertices)
|
||||
// Edge List Graph concept
|
||||
.def("num_edges", &Graph::num_edges)
|
||||
.add_property("edges", &Graph::py_edges)
|
||||
// Mutable Graph concept
|
||||
.def("add_vertex", &Graph::add_vertex)
|
||||
.def("clear_vertex", &Graph::clear_vertex)
|
||||
.def("remove_vertex", &Graph::remove_vertex)
|
||||
.def("add_edge", &Graph::add_edge)
|
||||
.def("remove_edge", &Graph::remove_edge)
|
||||
// Incidence Graph concept
|
||||
.def("source", &Graph::source)
|
||||
.def("target", &Graph::target)
|
||||
.def("out_edges", &Graph::py_out_edges)
|
||||
.def("out_degree", &Graph::out_degree)
|
||||
.def("in_edges", &Graph::py_in_edges)
|
||||
.def("in_degree", &Graph::in_degree)
|
||||
.def("adjacent_vertices", &Graph::py_adjacent_vertices)
|
||||
// Vertex property maps
|
||||
.def("has_vertex_map", &Graph::has_vertex_map)
|
||||
.def("get_vertex_index_map", &Graph::get_vertex_index_map)
|
||||
.def("get_vertex_color_map", &Graph::get_vertex_color_map)
|
||||
.def("get_vertex_double_map", &Graph::get_vertex_double_map)
|
||||
.def("get_vertex_int_map", &Graph::get_vertex_int_map)
|
||||
.def("get_vertex_string_map", &Graph::get_vertex_string_map)
|
||||
.def("get_vertex_object_map", &Graph::get_vertex_object_map)
|
||||
.def("get_vertex_point2d_map", &Graph::get_vertex_point2d_map)
|
||||
// Edge property maps
|
||||
.def("has_edge_map", &Graph::has_edge_map)
|
||||
.def("get_edge_index_map", &Graph::get_edge_index_map)
|
||||
.def("get_edge_color_map", &Graph::get_edge_color_map)
|
||||
.def("get_edge_double_map", &Graph::get_edge_double_map)
|
||||
.def("get_edge_int_map", &Graph::get_edge_int_map)
|
||||
.def("get_edge_string_map", &Graph::get_edge_string_map)
|
||||
.def("get_edge_object_map", &Graph::get_edge_object_map)
|
||||
// Graph I/O
|
||||
.def("read_graphviz", &Graph::read_graphviz)
|
||||
.def("write_graphviz", &Graph::write_graphviz)
|
||||
.def("write_graphviz", &Graph::write_graphviz_def)
|
||||
// Pickling
|
||||
.def_pickle(graph_pickle_suite<DirectedS>())
|
||||
);
|
||||
|
||||
export_in_graph<Graph>();
|
||||
}
|
||||
|
||||
if (!type_already_registered<Vertex>())
|
||||
class_<Vertex>("Vertex")
|
||||
.def(self == self)
|
||||
.def(self != self);
|
||||
|
||||
if (!type_already_registered<Edge>())
|
||||
class_<Edge>("Edge")
|
||||
.def(self == self)
|
||||
.def(self != self);
|
||||
|
||||
// Iterators
|
||||
simple_python_iterator<typename Graph::vertex_iterator>
|
||||
::declare("vertex_iterator");
|
||||
simple_python_iterator<typename Graph::edge_iterator>
|
||||
::declare("edge_iterator");
|
||||
simple_python_iterator<typename Graph::out_edge_iterator>
|
||||
::declare("out_edge_iterator");
|
||||
simple_python_iterator<typename Graph::in_edge_iterator>
|
||||
::declare("in_edge_iterator");
|
||||
simple_python_iterator<typename Graph::adjacency_iterator>
|
||||
::declare("adjacency_iterator");
|
||||
|
||||
// Vertex property maps
|
||||
declare_readable_property_map<VertexIndexMap>
|
||||
::declare("vertex_index_map");
|
||||
declare_property_map<vector_property_map<Vertex, VertexIndexMap> >
|
||||
::declare("vertex_vertex_map");
|
||||
declare_property_map<vector_property_map<double, VertexIndexMap> >
|
||||
::declare("vertex_double_map");
|
||||
declare_property_map<vector_property_map<int, VertexIndexMap> >
|
||||
::declare("vertex_int_map");
|
||||
declare_property_map<vector_property_map<std::string, VertexIndexMap> >
|
||||
::declare("vertex_string_map");
|
||||
declare_property_map<vector_property_map<object, VertexIndexMap> >
|
||||
::declare("vertex_object_map");
|
||||
declare_property_map<vector_property_map<default_color_type,
|
||||
VertexIndexMap> >
|
||||
::declare("vertex_color_map");
|
||||
declare_property_map<vector_property_map<point2d, VertexIndexMap> >
|
||||
::declare("vertex_point2d_map");
|
||||
|
||||
// Edge property maps
|
||||
declare_readable_property_map<EdgeIndexMap>
|
||||
::declare("edge_index_map");
|
||||
declare_property_map<vector_property_map<Edge, EdgeIndexMap> >
|
||||
::declare("edge_edge_map");
|
||||
declare_property_map<vector_property_map<double, EdgeIndexMap> >
|
||||
::declare("edge_double_map");
|
||||
declare_property_map<vector_property_map<int, EdgeIndexMap> >
|
||||
::declare("edge_int_map");
|
||||
declare_property_map<vector_property_map<std::string, EdgeIndexMap> >
|
||||
::declare("edge_string_map");
|
||||
declare_property_map<vector_property_map<object, EdgeIndexMap> >
|
||||
::declare("edge_object_map");
|
||||
declare_property_map<vector_property_map<default_color_type, EdgeIndexMap> >
|
||||
::declare("edge_color_map");
|
||||
}
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,596 +0,0 @@
|
||||
// Copyright 2004-5 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
|
||||
#ifndef BOOST_GRAPH_BASIC_GRAPH_HPP
|
||||
#define BOOST_GRAPH_BASIC_GRAPH_HPP
|
||||
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/vector_property_map.hpp>
|
||||
#include <boost/dynamic_property_map.hpp>
|
||||
#include <boost/random/linear_congruential.hpp>
|
||||
#include <boost/graph/erdos_renyi_generator.hpp>
|
||||
#include <boost/graph/plod_generator.hpp>
|
||||
#include <boost/graph/small_world_generator.hpp>
|
||||
#include <boost/python.hpp>
|
||||
#include "point2d.hpp"
|
||||
#include "generators.hpp"
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
template<typename T> bool type_already_registered()
|
||||
{
|
||||
using boost::python::objects::registered_class_object;
|
||||
using boost::python::type_id;
|
||||
|
||||
return registered_class_object(type_id<T>()).get() != 0;
|
||||
}
|
||||
|
||||
template<typename Iterator>
|
||||
class simple_python_iterator
|
||||
{
|
||||
public:
|
||||
typedef typename std::iterator_traits<Iterator>::difference_type
|
||||
difference_type;
|
||||
|
||||
simple_python_iterator(std::pair<Iterator, Iterator> p)
|
||||
: orig_first(p.first), first(p.first), last(p.second), n(-1) { }
|
||||
|
||||
typename std::iterator_traits<Iterator>::value_type next()
|
||||
{
|
||||
using boost::python::objects::stop_iteration_error;
|
||||
|
||||
if (first == last) stop_iteration_error();
|
||||
return *first++;
|
||||
}
|
||||
|
||||
difference_type len()
|
||||
{
|
||||
if (n == -1) n = std::distance(first, last);
|
||||
return n;
|
||||
}
|
||||
|
||||
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__", identity_function())
|
||||
.def("__len__", &simple_python_iterator<Iterator>::len)
|
||||
.def("next", &simple_python_iterator<Iterator>::next)
|
||||
;
|
||||
}
|
||||
|
||||
private:
|
||||
Iterator orig_first;
|
||||
Iterator first;
|
||||
Iterator last;
|
||||
difference_type n;
|
||||
};
|
||||
|
||||
template<typename PropertyMap>
|
||||
struct declare_readable_property_map
|
||||
{
|
||||
typedef typename property_traits<PropertyMap>::key_type key_type;
|
||||
typedef typename property_traits<PropertyMap>::value_type value_type;
|
||||
|
||||
static value_type getitem(const PropertyMap& pm, const key_type& key)
|
||||
{ return get(pm, key); }
|
||||
|
||||
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)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename PropertyMap>
|
||||
struct declare_property_map
|
||||
{
|
||||
typedef typename property_traits<PropertyMap>::key_type key_type;
|
||||
typedef typename property_traits<PropertyMap>::value_type value_type;
|
||||
|
||||
static value_type getitem(const PropertyMap& pm, const key_type& key)
|
||||
{ return get(pm, key); }
|
||||
|
||||
static void
|
||||
setitem(const PropertyMap& pm, const key_type& key,const value_type& value)
|
||||
{ return put(pm, key, value); }
|
||||
|
||||
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)
|
||||
.def("__setitem__", &setitem)
|
||||
;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T, typename DirectedS>
|
||||
struct basic_descriptor
|
||||
{
|
||||
basic_descriptor() {}
|
||||
basic_descriptor(T base) : base(base) { }
|
||||
|
||||
operator T() const { return base; }
|
||||
|
||||
struct create
|
||||
{
|
||||
typedef basic_descriptor result_type;
|
||||
basic_descriptor operator()(T base) const { return base; }
|
||||
};
|
||||
|
||||
T base;
|
||||
};
|
||||
|
||||
template<typename T, typename DirectedS>
|
||||
inline bool
|
||||
operator==(const basic_descriptor<T, DirectedS>& u,
|
||||
const basic_descriptor<T, DirectedS>& v)
|
||||
{ return u.base == v.base; }
|
||||
|
||||
template<typename T, typename DirectedS>
|
||||
inline bool
|
||||
operator!=(const basic_descriptor<T, DirectedS>& u,
|
||||
const basic_descriptor<T, DirectedS>& v)
|
||||
{ return u.base != v.base; }
|
||||
|
||||
template<typename Key, typename IndexMap>
|
||||
struct basic_index_map
|
||||
{
|
||||
typedef Key key_type;
|
||||
typedef typename property_traits<IndexMap>::value_type value_type;
|
||||
typedef typename property_traits<IndexMap>::reference reference;
|
||||
typedef typename property_traits<IndexMap>::category category;
|
||||
|
||||
basic_index_map(const IndexMap& id = IndexMap())
|
||||
: id(id) { }
|
||||
|
||||
IndexMap id;
|
||||
};
|
||||
|
||||
template<typename Key, typename IndexMap>
|
||||
inline typename basic_index_map<Key, IndexMap>::value_type
|
||||
get(const basic_index_map<Key, IndexMap>& pm,
|
||||
typename basic_index_map<Key, IndexMap>::key_type const& key)
|
||||
{ return get(pm.id, key.base); }
|
||||
|
||||
enum graph_file_kind { gfk_adjlist, gfk_graphviz };
|
||||
|
||||
struct stored_minstd_rand
|
||||
{
|
||||
stored_minstd_rand(int seed = 1) : gen(seed) { }
|
||||
|
||||
minstd_rand gen;
|
||||
};
|
||||
|
||||
template<typename DirectedS>
|
||||
class basic_graph
|
||||
: public stored_minstd_rand,
|
||||
public adjacency_list<listS, listS, DirectedS,
|
||||
property<vertex_index_t, std::size_t>,
|
||||
property<edge_index_t, std::size_t> >
|
||||
{
|
||||
typedef adjacency_list<listS, listS, DirectedS,
|
||||
property<vertex_index_t, std::size_t>,
|
||||
property<edge_index_t, std::size_t> > inherited;
|
||||
typedef graph_traits<inherited> traits;
|
||||
|
||||
typedef typename traits::vertex_iterator base_vertex_iterator;
|
||||
typedef typename traits::edge_iterator base_edge_iterator;
|
||||
typedef typename traits::out_edge_iterator base_out_edge_iterator;
|
||||
typedef typename traits::in_edge_iterator base_in_edge_iterator;
|
||||
typedef typename traits::adjacency_iterator base_adjacency_iterator;
|
||||
typedef typename property_map<inherited, vertex_index_t>::const_type
|
||||
base_vertex_index_map;
|
||||
typedef typename property_map<inherited, edge_index_t>::const_type
|
||||
base_edge_index_map;
|
||||
typedef typename traits::vertex_descriptor base_vertex_descriptor;
|
||||
typedef typename traits::edge_descriptor base_edge_descriptor;
|
||||
|
||||
typedef erdos_renyi_iterator<minstd_rand, basic_graph<DirectedS> >
|
||||
er_iterator;
|
||||
typedef plod_iterator<minstd_rand, basic_graph<DirectedS> >
|
||||
sf_iterator;
|
||||
typedef small_world_iterator<minstd_rand, basic_graph<DirectedS> >
|
||||
sw_iterator;
|
||||
|
||||
public:
|
||||
typedef basic_descriptor<base_vertex_descriptor, DirectedS>
|
||||
Vertex;
|
||||
typedef Vertex vertex_descriptor;
|
||||
typedef basic_descriptor<base_edge_descriptor, DirectedS>
|
||||
Edge;
|
||||
typedef Edge edge_descriptor;
|
||||
typedef basic_index_map<Vertex, base_vertex_index_map>
|
||||
VertexIndexMap;
|
||||
typedef basic_index_map<Edge, base_edge_index_map> EdgeIndexMap;
|
||||
typedef std::size_t vertices_size_type;
|
||||
typedef std::size_t edges_size_type;
|
||||
typedef std::size_t degree_size_type;
|
||||
typedef typename traits::directed_category directed_category;
|
||||
typedef typename traits::edge_parallel_category edge_parallel_category;
|
||||
typedef typename traits::traversal_category traversal_category;
|
||||
typedef transform_iterator<typename Vertex::create, base_vertex_iterator>
|
||||
vertex_iterator;
|
||||
typedef transform_iterator<typename Edge::create, base_edge_iterator>
|
||||
edge_iterator;
|
||||
typedef transform_iterator<typename Edge::create, base_out_edge_iterator>
|
||||
out_edge_iterator;
|
||||
typedef transform_iterator<typename Edge::create, base_in_edge_iterator>
|
||||
in_edge_iterator;
|
||||
typedef transform_iterator<typename Vertex::create, base_adjacency_iterator>
|
||||
adjacency_iterator;
|
||||
|
||||
basic_graph();
|
||||
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);
|
||||
basic_graph(small_world, int seed);
|
||||
|
||||
bool is_directed() const
|
||||
{ return is_convertible<directed_category, directed_tag>::value; }
|
||||
|
||||
Vertex add_vertex();
|
||||
void clear_vertex(Vertex vertex);
|
||||
void remove_vertex(Vertex vertex);
|
||||
std::size_t num_vertices() const;
|
||||
std::pair<vertex_iterator, vertex_iterator> vertices() const;
|
||||
simple_python_iterator<vertex_iterator> py_vertices() const;
|
||||
vertex_iterator vertices_begin() const;
|
||||
vertex_iterator vertices_end() const;
|
||||
|
||||
Edge add_edge(Vertex u, Vertex v);
|
||||
void remove_edge(Edge edge);
|
||||
std::size_t num_edges() const;
|
||||
std::pair<edge_iterator, edge_iterator> edges() const;
|
||||
simple_python_iterator<edge_iterator> py_edges() const;
|
||||
edge_iterator edges_begin() const;
|
||||
edge_iterator edges_end() const;
|
||||
|
||||
// Incidence Graph concept
|
||||
Vertex source(Edge e) const;
|
||||
Vertex target(Edge e) const;
|
||||
std::pair<out_edge_iterator, out_edge_iterator> out_edges(Vertex u) const;
|
||||
simple_python_iterator<out_edge_iterator> py_out_edges(Vertex u) const;
|
||||
std::size_t out_degree(Vertex u) const;
|
||||
|
||||
// Bidirectional Graph concept
|
||||
std::pair<in_edge_iterator, in_edge_iterator> in_edges(Vertex u) const;
|
||||
simple_python_iterator<in_edge_iterator> py_in_edges(Vertex u) const;
|
||||
std::size_t in_degree(Vertex u) const;
|
||||
|
||||
// Adjacency Graph concept
|
||||
std::pair<adjacency_iterator, adjacency_iterator>
|
||||
adjacent_vertices(Vertex u) const;
|
||||
|
||||
simple_python_iterator<adjacency_iterator>
|
||||
py_adjacent_vertices(Vertex u) const;
|
||||
|
||||
// Vertex property maps
|
||||
VertexIndexMap get_vertex_index_map() const
|
||||
{ return get(vertex_index, base()); }
|
||||
|
||||
template<typename T>
|
||||
vector_property_map<T, VertexIndexMap>
|
||||
get_vertex_map(const std::string& name);
|
||||
|
||||
bool has_vertex_map(const std::string& name) const;
|
||||
|
||||
// Edge property maps
|
||||
EdgeIndexMap get_edge_index_map() const
|
||||
{ return get(edge_index, base()); }
|
||||
|
||||
template<typename T>
|
||||
vector_property_map<T, EdgeIndexMap>
|
||||
get_edge_map(const std::string& name);
|
||||
|
||||
bool has_edge_map(const std::string& name) const;
|
||||
|
||||
// Graph I/O
|
||||
void read_graphviz(const std::string& filename,
|
||||
const std::string& node_id = std::string("node_id"));
|
||||
|
||||
void write_graphviz(const std::string& filename,
|
||||
const std::string& node_id = std::string("node_id"));
|
||||
|
||||
void write_graphviz_def(const std::string& filename)
|
||||
{ write_graphviz(filename); }
|
||||
|
||||
// Simple functions for Visual C++ 7.1 :(
|
||||
vector_property_map<default_color_type, VertexIndexMap>
|
||||
get_vertex_color_map(const std::string& name)
|
||||
{ return get_vertex_map<default_color_type>(name); }
|
||||
|
||||
vector_property_map<double, VertexIndexMap>
|
||||
get_vertex_double_map(const std::string& name)
|
||||
{ return get_vertex_map<double>(name); }
|
||||
|
||||
vector_property_map<int, VertexIndexMap>
|
||||
get_vertex_int_map(const std::string& name)
|
||||
{ return get_vertex_map<int>(name); }
|
||||
|
||||
vector_property_map<std::string, VertexIndexMap>
|
||||
get_vertex_string_map(const std::string& name)
|
||||
{ return get_vertex_map<std::string>(name); }
|
||||
|
||||
vector_property_map<boost::python::object, VertexIndexMap>
|
||||
get_vertex_object_map(const std::string& name)
|
||||
{ return get_vertex_map<boost::python::object>(name); }
|
||||
|
||||
vector_property_map<point2d, VertexIndexMap>
|
||||
get_vertex_point2d_map(const std::string& name)
|
||||
{ return get_vertex_map<point2d>(name); }
|
||||
|
||||
vector_property_map<default_color_type, EdgeIndexMap>
|
||||
get_edge_color_map(const std::string& name)
|
||||
{ return get_edge_map<default_color_type>(name); }
|
||||
|
||||
vector_property_map<double, EdgeIndexMap>
|
||||
get_edge_double_map(const std::string& name)
|
||||
{ return get_edge_map<double>(name); }
|
||||
|
||||
vector_property_map<int, EdgeIndexMap>
|
||||
get_edge_int_map(const std::string& name)
|
||||
{ return get_edge_map<int>(name); }
|
||||
|
||||
vector_property_map<std::string, EdgeIndexMap>
|
||||
get_edge_string_map(const std::string& name)
|
||||
{ return get_edge_map<std::string>(name); }
|
||||
|
||||
vector_property_map<boost::python::object, EdgeIndexMap>
|
||||
get_edge_object_map(const std::string& name)
|
||||
{ return get_edge_map<boost::python::object>(name); }
|
||||
|
||||
inherited& base() { return *this; }
|
||||
const inherited& base() const { return *this; }
|
||||
|
||||
dynamic_properties& get_dynamic_properties() { return dp; }
|
||||
const dynamic_properties& get_dynamic_properties() const { return dp; }
|
||||
|
||||
protected:
|
||||
void renumber_vertices();
|
||||
void renumber_edges();
|
||||
|
||||
private:
|
||||
std::vector<vertex_descriptor> index_to_vertex;
|
||||
std::vector<edge_descriptor> index_to_edge;
|
||||
dynamic_properties dp;
|
||||
};
|
||||
|
||||
// Vertex List Graph concept
|
||||
template<typename DirectedS>
|
||||
inline std::pair<typename basic_graph<DirectedS>::vertex_iterator,
|
||||
typename basic_graph<DirectedS>::vertex_iterator>
|
||||
vertices(const basic_graph<DirectedS>& g)
|
||||
{ return g.vertices(); }
|
||||
|
||||
template<typename DirectedS>
|
||||
inline std::size_t num_vertices(const basic_graph<DirectedS>& g)
|
||||
{ return g.num_vertices(); }
|
||||
|
||||
// Edge List Graph concept
|
||||
template<typename DirectedS>
|
||||
inline std::pair<typename basic_graph<DirectedS>::edge_iterator,
|
||||
typename basic_graph<DirectedS>::edge_iterator>
|
||||
edges(const basic_graph<DirectedS>& g)
|
||||
{ return g.edges(); }
|
||||
|
||||
template<typename DirectedS>
|
||||
inline std::size_t num_edges(const basic_graph<DirectedS>& g)
|
||||
{ return g.num_edges(); }
|
||||
|
||||
// Incidence Graph concept
|
||||
template<typename DirectedS>
|
||||
inline typename basic_graph<DirectedS>::vertex_descriptor
|
||||
source(typename basic_graph<DirectedS>::edge_descriptor e,
|
||||
const basic_graph<DirectedS>& g)
|
||||
{ return g.source(e); }
|
||||
|
||||
template<typename DirectedS>
|
||||
inline typename basic_graph<DirectedS>::vertex_descriptor
|
||||
target(typename basic_graph<DirectedS>::edge_descriptor e,
|
||||
const basic_graph<DirectedS>& g)
|
||||
{ return g.target(e); }
|
||||
|
||||
template<typename DirectedS>
|
||||
inline std::pair<typename basic_graph<DirectedS>::out_edge_iterator,
|
||||
typename basic_graph<DirectedS>::out_edge_iterator>
|
||||
out_edges(typename basic_graph<DirectedS>::vertex_descriptor u,
|
||||
const basic_graph<DirectedS>& g)
|
||||
{ return g.out_edges(u); }
|
||||
|
||||
template<typename DirectedS>
|
||||
inline std::size_t
|
||||
out_degree(typename basic_graph<DirectedS>::vertex_descriptor u,
|
||||
const basic_graph<DirectedS>& g)
|
||||
{ return g.out_degree(u); }
|
||||
|
||||
// Bidirectional Graph concept
|
||||
template<typename DirectedS>
|
||||
inline std::pair<typename basic_graph<DirectedS>::in_edge_iterator,
|
||||
typename basic_graph<DirectedS>::in_edge_iterator>
|
||||
in_edges(typename basic_graph<DirectedS>::vertex_descriptor u,
|
||||
const basic_graph<DirectedS>& g)
|
||||
{ return g.in_edges(u); }
|
||||
|
||||
template<typename DirectedS>
|
||||
inline std::size_t
|
||||
in_degree(typename basic_graph<DirectedS>::vertex_descriptor u,
|
||||
const basic_graph<DirectedS>& g)
|
||||
{ return g.in_degree(u); }
|
||||
|
||||
// Adjacency Graph concept
|
||||
template<typename DirectedS>
|
||||
inline std::pair<typename basic_graph<DirectedS>::adjacency_iterator,
|
||||
typename basic_graph<DirectedS>::adjacency_iterator>
|
||||
adjacent_vertices(typename basic_graph<DirectedS>::vertex_descriptor u,
|
||||
const basic_graph<DirectedS>& g)
|
||||
{ return g.adjacent_vertices(u); }
|
||||
|
||||
// Mutable basic_graph<DirectedS> concept
|
||||
template<typename DirectedS>
|
||||
inline typename basic_graph<DirectedS>::vertex_descriptor
|
||||
add_vertex(basic_graph<DirectedS>& g)
|
||||
{ return g.add_vertex(); }
|
||||
|
||||
template<typename DirectedS>
|
||||
inline std::pair<typename basic_graph<DirectedS>::edge_descriptor, bool>
|
||||
add_edge(typename basic_graph<DirectedS>::vertex_descriptor u,
|
||||
typename basic_graph<DirectedS>::vertex_descriptor v,
|
||||
basic_graph<DirectedS>& g)
|
||||
{ return std::make_pair(g.add_edge(u, v), true); }
|
||||
|
||||
template<typename DirectedS>
|
||||
void export_basic_graph(const char* name);
|
||||
|
||||
template<typename DirectedS>
|
||||
typename basic_graph<DirectedS>::VertexIndexMap
|
||||
get(vertex_index_t, const basic_graph<DirectedS>& g)
|
||||
{ return g.get_vertex_index_map(); }
|
||||
|
||||
template<typename DirectedS>
|
||||
typename basic_graph<DirectedS>::EdgeIndexMap
|
||||
get(edge_index_t, const basic_graph<DirectedS>& g)
|
||||
{ return g.get_edge_index_map(); }
|
||||
|
||||
template<typename DirectedS>
|
||||
struct graph_pickle_suite : boost::python::pickle_suite
|
||||
{
|
||||
typedef basic_graph<DirectedS> Graph;
|
||||
typedef typename Graph::vertex_descriptor Vertex;
|
||||
typedef typename Graph::edge_descriptor Edge;
|
||||
|
||||
static
|
||||
boost::python::tuple
|
||||
getstate(boost::python::object g_obj);
|
||||
|
||||
static
|
||||
void
|
||||
setstate(boost::python::object g_obj, boost::python::tuple state);
|
||||
};
|
||||
|
||||
class python_dynamic_property_map
|
||||
{
|
||||
public:
|
||||
virtual ~python_dynamic_property_map() {}
|
||||
|
||||
virtual void copy_value(const any& to, const any& from) = 0;
|
||||
virtual boost::python::object get_python(const any& key) = 0;
|
||||
};
|
||||
|
||||
template<typename PropertyMap,
|
||||
typename ValueType = typename property_traits<PropertyMap>::value_type>
|
||||
class python_dynamic_adaptor
|
||||
: public boost::detail::dynamic_property_map_adaptor<PropertyMap>,
|
||||
public python_dynamic_property_map
|
||||
{
|
||||
typedef boost::detail::dynamic_property_map_adaptor<PropertyMap> inherited;
|
||||
|
||||
public:
|
||||
typedef typename property_traits<PropertyMap>::key_type key_type;
|
||||
|
||||
explicit python_dynamic_adaptor(const PropertyMap& property_map)
|
||||
: inherited(property_map) { }
|
||||
|
||||
virtual void copy_value(const any& to, const any& from)
|
||||
{
|
||||
boost::put(this->base(), any_cast<key_type>(to),
|
||||
boost::get(this->base(), any_cast<key_type>(from)));
|
||||
}
|
||||
|
||||
virtual boost::python::object get_python(const any& key)
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 95)
|
||||
return boost::get(this->base(), any_cast<key_type>(key));
|
||||
#else
|
||||
using boost::get;
|
||||
|
||||
return boost::python::object(get(this->base(), any_cast<key_type>(key)));
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template<typename PropertyMap>
|
||||
class python_dynamic_adaptor<PropertyMap, boost::python::object>
|
||||
: public boost::detail::dynamic_property_map_adaptor<PropertyMap>,
|
||||
public python_dynamic_property_map
|
||||
{
|
||||
typedef boost::detail::dynamic_property_map_adaptor<PropertyMap> inherited;
|
||||
|
||||
public:
|
||||
typedef typename property_traits<PropertyMap>::key_type key_type;
|
||||
|
||||
explicit python_dynamic_adaptor(const PropertyMap& property_map)
|
||||
: inherited(property_map) { }
|
||||
|
||||
virtual void copy_value(const any& to, const any& from)
|
||||
{
|
||||
boost::put(this->base(), any_cast<key_type>(to),
|
||||
boost::get(this->base(), any_cast<key_type>(from)));
|
||||
}
|
||||
|
||||
virtual std::string get_string(const any& key)
|
||||
{
|
||||
using boost::python::extract;
|
||||
using boost::python::str;
|
||||
return std::string(
|
||||
extract<const char*>(str(boost::get(this->base(),
|
||||
any_cast<key_type>(key)))));
|
||||
}
|
||||
|
||||
virtual boost::python::object get_python(const any& key)
|
||||
{
|
||||
#if defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 95)
|
||||
return boost::get(this->base(), any_cast<key_type>(key));
|
||||
#else
|
||||
using boost::get;
|
||||
|
||||
return get(this->base(), any_cast<key_type>(key));
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
} } } // 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>
|
||||
{
|
||||
typedef typename graph::python::basic_graph<DirectedS>::VertexIndexMap
|
||||
type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template<typename DirectedS>
|
||||
struct property_map<graph::python::basic_graph<DirectedS>, edge_index_t>
|
||||
{
|
||||
typedef typename graph::python::basic_graph<DirectedS>::EdgeIndexMap
|
||||
type;
|
||||
typedef type const_type;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // BOOST_GRAPH_BASIC_GRAPH_HPP
|
||||
@@ -1,15 +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
|
||||
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)
|
||||
|
||||
@@ -1,111 +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 <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
|
||||
@@ -1,196 +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 "graph.hpp"
|
||||
#include "digraph.hpp"
|
||||
#include <boost/graph/betweenness_centrality.hpp>
|
||||
#include <boost/graph/bc_clustering.hpp>
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
template<typename Graph>
|
||||
void
|
||||
brandes_betweenness_centrality
|
||||
(Graph& g,
|
||||
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)
|
||||
{
|
||||
typedef vector_property_map<double, typename Graph::VertexIndexMap>
|
||||
VertexCentralityMap;
|
||||
|
||||
typedef vector_property_map<double, typename Graph::EdgeIndexMap>
|
||||
EdgeCentralityMap;
|
||||
|
||||
VertexCentralityMap vertex_centrality =
|
||||
in_vertex_centrality? *in_vertex_centrality
|
||||
: g.template get_vertex_map<double>("centrality");
|
||||
|
||||
EdgeCentralityMap edge_centrality =
|
||||
in_edge_centrality? *in_edge_centrality
|
||||
: g.template get_edge_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>* 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>* 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);
|
||||
}
|
||||
|
||||
struct bc_clustering_done_python
|
||||
{
|
||||
explicit bc_clustering_done_python(boost::python::object done)
|
||||
: done(done) { }
|
||||
|
||||
template<typename Graph>
|
||||
bool
|
||||
operator()(double max_centrality,
|
||||
typename graph_traits<Graph>::edge_descriptor e,
|
||||
const Graph& g)
|
||||
{
|
||||
using boost::python::extract;
|
||||
return extract<bool>(done(max_centrality, e, ref(g)));
|
||||
}
|
||||
|
||||
private:
|
||||
boost::python::object done;
|
||||
};
|
||||
|
||||
template<typename Graph>
|
||||
void
|
||||
betweenness_centrality_clustering
|
||||
(Graph& g, boost::python::object done,
|
||||
const vector_property_map<double, typename Graph::EdgeIndexMap>* in_edge_centrality)
|
||||
// const vector_property_map<double, typename Graph::EdgeIndexMap>* weight)
|
||||
{
|
||||
typedef vector_property_map<double, typename Graph::EdgeIndexMap>
|
||||
EdgeCentralityMap;
|
||||
|
||||
EdgeCentralityMap edge_centrality =
|
||||
in_edge_centrality? *in_edge_centrality
|
||||
: g.template get_edge_map<double>("centrality");
|
||||
|
||||
#if 0
|
||||
if (weight) {
|
||||
boost::betweenness_centrality_clustering
|
||||
(g,
|
||||
weight_map(*weight).
|
||||
centrality_map(vertex_centrality).
|
||||
edge_centrality_map(edge_centrality).
|
||||
vertex_index_map(g.get_vertex_index_map()));
|
||||
} else {
|
||||
#endif
|
||||
boost::betweenness_centrality_clustering(g,
|
||||
bc_clustering_done_python(done),
|
||||
edge_centrality,
|
||||
g.get_vertex_index_map());
|
||||
// }
|
||||
}
|
||||
|
||||
void export_betweenness_centrality()
|
||||
{
|
||||
using boost::python::arg;
|
||||
using boost::python::def;
|
||||
|
||||
// Graph
|
||||
def("brandes_betweenness_centrality",
|
||||
&brandes_betweenness_centrality<Graph>,
|
||||
(arg("graph"),
|
||||
arg("vertex_centrality_map") =
|
||||
(vector_property_map<double, Graph::VertexIndexMap>*)0,
|
||||
arg("edge_centrality_map") =
|
||||
(vector_property_map<double, Graph::EdgeIndexMap>*)0,
|
||||
arg("weight_map") =
|
||||
(vector_property_map<double, Graph::EdgeIndexMap>*)0));
|
||||
def("relative_betweenness_centrality",
|
||||
&relative_betweenness_centrality<Graph>,
|
||||
(arg("graph"),
|
||||
arg("vertex_centrality_map") =
|
||||
(vector_property_map<double, Graph::VertexIndexMap>*)0));
|
||||
def("central_point_dominance",
|
||||
¢ral_point_dominance<Graph>,
|
||||
(arg("graph"),
|
||||
arg("vertex_centrality_map") =
|
||||
(vector_property_map<double, Graph::VertexIndexMap>*)0));
|
||||
def("betweenness_centrality_clustering",
|
||||
&betweenness_centrality_clustering<Graph>,
|
||||
(arg("graph"),
|
||||
arg("done"),
|
||||
arg("edge_centrality_map") =
|
||||
(vector_property_map<double, Graph::EdgeIndexMap>*)0));
|
||||
|
||||
// Digraph
|
||||
def("brandes_betweenness_centrality",
|
||||
&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>,
|
||||
(arg("graph"),
|
||||
arg("vertex_centrality_map") =
|
||||
(vector_property_map<double, Digraph::VertexIndexMap>*)0));
|
||||
def("central_point_dominance",
|
||||
¢ral_point_dominance<Digraph>,
|
||||
(arg("graph"),
|
||||
arg("vertex_centrality_map") =
|
||||
(vector_property_map<double, Digraph::VertexIndexMap>*)0));
|
||||
def("betweenness_centrality_clustering",
|
||||
&betweenness_centrality_clustering<Digraph>,
|
||||
(arg("graph"),
|
||||
arg("done"),
|
||||
arg("edge_centrality_map") =
|
||||
(vector_property_map<double, Digraph::EdgeIndexMap>*)0));
|
||||
}
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,18 +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
|
||||
|
||||
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)
|
||||
@@ -1,70 +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 <boost/graph/biconnected_components.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
|
||||
biconnected_components
|
||||
(Graph& g,
|
||||
const vector_property_map<int, typename Graph::EdgeIndexMap>* in_component)
|
||||
{
|
||||
typedef vector_property_map<int, typename Graph::EdgeIndexMap> ComponentMap;
|
||||
|
||||
ComponentMap component =
|
||||
in_component? *in_component : g.template get_edge_map<int>("bicomponent");
|
||||
|
||||
std::list<typename Graph::Vertex> art_points;
|
||||
boost::biconnected_components(g, component, std::back_inserter(art_points),
|
||||
g.get_vertex_index_map());
|
||||
boost::python::list result;
|
||||
for (typename std::list<typename Graph::Vertex>::iterator i
|
||||
= art_points.begin(); i != art_points.end(); ++i)
|
||||
result.append(*i);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Graph>
|
||||
boost::python::list
|
||||
articulation_points(const Graph& g)
|
||||
{
|
||||
std::list<typename Graph::Vertex> art_points;
|
||||
boost::python::list result;
|
||||
boost::articulation_points(g, std::back_inserter(art_points));
|
||||
for (typename std::list<typename Graph::Vertex>::iterator i
|
||||
= art_points.begin(); i != art_points.end(); ++i)
|
||||
result.append(*i);
|
||||
return result;
|
||||
}
|
||||
|
||||
void export_biconnected_components()
|
||||
{
|
||||
using boost::python::arg;
|
||||
using boost::python::def;
|
||||
|
||||
def("biconnected_components", &biconnected_components<Graph>,
|
||||
(arg("graph"),
|
||||
arg("component_map") =
|
||||
(vector_property_map<int, Graph::EdgeIndexMap>*)0));
|
||||
def("articulation_points", &articulation_points<Graph>, (arg("graph")));
|
||||
|
||||
def("biconnected_components", &biconnected_components<Digraph>,
|
||||
(arg("graph"),
|
||||
arg("component_map") =
|
||||
(vector_property_map<int, Digraph::EdgeIndexMap>*)0));
|
||||
def("articulation_points", &articulation_points<Digraph>, (arg("graph")));
|
||||
}
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,147 +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 <boost/graph/breadth_first_search.hpp>
|
||||
#include "graph.hpp"
|
||||
#include "digraph.hpp"
|
||||
#include "queue.hpp"
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
#define BGL_PYTHON_VISITOR bfs_visitor
|
||||
#define BGL_PYTHON_EVENTS_HEADER "bfs_events.hpp"
|
||||
#include "visitor.hpp"
|
||||
#undef BGL_PYTHON_EVENTS_HEADER
|
||||
#undef BGL_PYTHON_VISITOR
|
||||
|
||||
template<typename Graph>
|
||||
void
|
||||
breadth_first_search
|
||||
(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>* in_color)
|
||||
{
|
||||
typedef vector_property_map<default_color_type,
|
||||
typename Graph::VertexIndexMap> ColorMap;
|
||||
|
||||
ColorMap color =
|
||||
in_color? *in_color : ColorMap(g.num_vertices(), g.get_vertex_index_map());
|
||||
|
||||
typedef typename python_queue<typename Graph::Vertex>::default_queue
|
||||
default_queue_type;
|
||||
|
||||
bool has_default_buffer = dynamic_cast<default_queue_type*>(&Q);
|
||||
bool has_default_visitor =
|
||||
dynamic_cast<typename bfs_visitor<Graph>::default_arg const*>(&visitor);
|
||||
|
||||
if (has_default_buffer) {
|
||||
if (has_default_visitor) {
|
||||
boost::breadth_first_search(g, s, color_map(color));
|
||||
} else {
|
||||
boost::breadth_first_search
|
||||
(g, s,
|
||||
color_map(color).
|
||||
visitor(typename bfs_visitor<Graph>::ref(visitor)));
|
||||
}
|
||||
} else {
|
||||
if (has_default_visitor) {
|
||||
boost::breadth_first_search(g, s,
|
||||
buffer(Q).
|
||||
color_map(color));
|
||||
} else {
|
||||
boost::breadth_first_search
|
||||
(g, s, Q, typename bfs_visitor<Graph>::ref(visitor), color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<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_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>
|
||||
void export_breadth_first_search_in_graph()
|
||||
{
|
||||
bfs_visitor<Graph>::declare("BFSVisitor", "DefaultBFSVisitor");
|
||||
python_queue<typename Graph::Vertex>::declare("VertexQueue",
|
||||
"DefaultVertexQueue");
|
||||
}
|
||||
|
||||
template void export_breadth_first_search_in_graph<Graph>();
|
||||
template void export_breadth_first_search_in_graph<Digraph>();
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,52 +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 <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));
|
||||
|
||||
def("circle_graph_layout",
|
||||
&circle_graph_layout<Digraph>,
|
||||
(arg("graph"),
|
||||
arg("position") =
|
||||
(vector_property_map<point2d, Digraph::VertexIndexMap>*)0,
|
||||
arg("radius") = 250.0));
|
||||
}
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,51 +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 <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
|
||||
@@ -1,39 +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 <boost/graph/cuthill_mckee_ordering.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
|
||||
cuthill_mckee_ordering(const Graph& g)
|
||||
{
|
||||
std::list<typename Graph::Vertex> ordering;
|
||||
boost::python::list result;
|
||||
boost::cuthill_mckee_ordering(g, std::back_inserter(ordering),
|
||||
g.get_vertex_index_map());
|
||||
for (typename std::list<typename Graph::Vertex>::iterator i
|
||||
= ordering.begin(); i != ordering.end(); ++i)
|
||||
result.append(*i);
|
||||
return result;
|
||||
}
|
||||
|
||||
void export_cuthill_mckee_ordering()
|
||||
{
|
||||
using boost::python::arg;
|
||||
using boost::python::def;
|
||||
def("cuthill_mckee_ordering", &cuthill_mckee_ordering<Graph>, arg("graph"));
|
||||
}
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,103 +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 <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
|
||||
@@ -1,163 +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 <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,
|
||||
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 (s == graph_traits<Graph>::null_vertex() && g.num_vertices() > 0)
|
||||
s = *g.vertices().first;
|
||||
|
||||
|
||||
if (has_default_visitor) {
|
||||
boost::depth_first_search(g, boost::dfs_visitor<>(), color, s);
|
||||
} else {
|
||||
boost::depth_first_search(g, typename dfs_visitor<Graph>::ref(visitor),
|
||||
color, s);
|
||||
}
|
||||
}
|
||||
|
||||
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("root_vertex") = graph_traits<Graph>::null_vertex(),
|
||||
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("root_vertex") = graph_traits<Digraph>::null_vertex(),
|
||||
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
|
||||
@@ -1,18 +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
|
||||
|
||||
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)
|
||||
@@ -1,18 +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 "digraph.hpp"
|
||||
#include "basic_graph.cpp"
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
void export_Digraph()
|
||||
{
|
||||
export_basic_graph<bidirectionalS>("Digraph");
|
||||
}
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,18 +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
|
||||
#ifndef BOOST_GRAPH_PYTHON_DIGRAPH_HPP
|
||||
#define BOOST_GRAPH_PYTHON_DIGRAPH_HPP
|
||||
|
||||
#include "basic_graph.hpp"
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
typedef basic_graph<bidirectionalS> Digraph;
|
||||
} } } // end namespace boost::graph::python
|
||||
|
||||
#endif // BOOST_GRAPH_PYTHON_DIGRAPH_HPP
|
||||
@@ -1,15 +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
|
||||
BGL_PYTHON_EVENT(initialize_vertex, vertex_descriptor)
|
||||
BGL_PYTHON_EVENT(examine_vertex, vertex_descriptor)
|
||||
BGL_PYTHON_EVENT(examine_edge, edge_descriptor)
|
||||
BGL_PYTHON_EVENT(discover_vertex, vertex_descriptor)
|
||||
BGL_PYTHON_EVENT(edge_relaxed, edge_descriptor)
|
||||
BGL_PYTHON_EVENT(edge_not_relaxed, edge_descriptor)
|
||||
BGL_PYTHON_EVENT(finish_vertex, vertex_descriptor)
|
||||
@@ -1,103 +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 <boost/graph/dijkstra_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
|
||||
dijkstra_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::dijkstra_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::dijkstra_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_dijkstra_shortest_paths_in_graph()
|
||||
{
|
||||
dijkstra_visitor<Graph>::declare("DijkstraVisitor",
|
||||
"DefaultDijkstraVisitor");
|
||||
}
|
||||
|
||||
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"),
|
||||
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("dijkstra_shortest_paths", &dijkstra_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_dijkstra_shortest_paths_in_graph<Graph>();
|
||||
template void export_dijkstra_shortest_paths_in_graph<Digraph>();
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,20 +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
|
||||
#ifndef BOOST_GRAPH_PYTHON_DIJKSTRA_VISITOR_HPP
|
||||
#define BOOST_GRAPH_PYTHON_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
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
#endif BOOST_GRAPH_PYTHON_DIJKSTRA_VISITOR_HPP
|
||||
@@ -1,136 +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 <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
|
||||
@@ -1,45 +0,0 @@
|
||||
// Copyright 2004-5 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
|
||||
#ifndef BOOST_GRAPH_PYTHON_GENERATORS_HPP
|
||||
#define BOOST_GRAPH_PYTHON_GENERATORS_HPP
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
struct erdos_renyi
|
||||
{
|
||||
erdos_renyi(std::size_t n, double p) : n(n), p(p) { }
|
||||
|
||||
std::size_t n;
|
||||
double p;
|
||||
};
|
||||
|
||||
struct power_law_out_degree
|
||||
{
|
||||
power_law_out_degree(std::size_t n, double alpha, double beta)
|
||||
: n(n), alpha(alpha), beta(beta) { }
|
||||
|
||||
std::size_t n;
|
||||
double alpha;
|
||||
double beta;
|
||||
};
|
||||
|
||||
struct small_world
|
||||
{
|
||||
small_world(std::size_t n, std::size_t k, double p) : n(n), k(k), p(p) { }
|
||||
|
||||
std::size_t n;
|
||||
std::size_t k;
|
||||
double p;
|
||||
};
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
|
||||
#endif // BOOST_GRAPH_PYTHON_GENERATORS_HPP
|
||||
@@ -1,19 +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 "graph.hpp"
|
||||
#include "basic_graph.cpp"
|
||||
#include <iostream>
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
void export_Graph()
|
||||
{
|
||||
export_basic_graph<undirectedS>("Graph");
|
||||
}
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,36 +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
|
||||
#ifndef BOOST_GRAPH_PYTHON_GRAPH_HPP
|
||||
#define BOOST_GRAPH_PYTHON_GRAPH_HPP
|
||||
|
||||
#include "basic_graph.hpp"
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
typedef basic_graph<undirectedS> Graph;
|
||||
|
||||
#if 0
|
||||
class Graph : public basic_graph<undirectedS>
|
||||
{
|
||||
typedef basic_graph<undirectedS> inherited;
|
||||
|
||||
public:
|
||||
Graph() : inherited() { }
|
||||
Graph(const std::string& filename, graph_file_kind kind)
|
||||
: inherited(filename, kind) { }
|
||||
|
||||
vertex_iterator vertices_begin() const;
|
||||
vertex_iterator vertices_end() const;
|
||||
edge_iterator edges_begin() const;
|
||||
edge_iterator edges_end() const;
|
||||
};
|
||||
#endif
|
||||
} } } // end namespace boost::graph::python
|
||||
|
||||
#endif // BOOST_GRAPH_PYTHON_GRAPH_HPP
|
||||
@@ -1,114 +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 "basic_graph.hpp"
|
||||
#include <boost/graph/graphviz.hpp>
|
||||
#include <boost/python.hpp>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
template<typename DirectedS>
|
||||
void
|
||||
basic_graph<DirectedS>::read_graphviz(const std::string& filename,
|
||||
const std::string& node_id)
|
||||
{
|
||||
std::ifstream in(filename.c_str());
|
||||
boost::read_graphviz(in, *this, dp, node_id);
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
void
|
||||
basic_graph<DirectedS>::write_graphviz(const std::string& filename,
|
||||
const std::string& node_id)
|
||||
{
|
||||
std::ofstream out(filename.c_str());
|
||||
|
||||
if (has_vertex_map(node_id))
|
||||
boost::write_graphviz(out, *this, dp, node_id,
|
||||
get_vertex_map<std::string>(node_id));
|
||||
else
|
||||
boost::write_graphviz(out, *this, dp, node_id, get_vertex_index_map());
|
||||
}
|
||||
|
||||
template<typename E>
|
||||
class translate_exception
|
||||
{
|
||||
explicit translate_exception(boost::python::object type) : type(type) { }
|
||||
|
||||
public:
|
||||
template<typename Base>
|
||||
static void declare(const char* name)
|
||||
{
|
||||
using boost::python::class_;
|
||||
using boost::python::bases;
|
||||
|
||||
declare(class_<E, bases<Base> >(name));
|
||||
}
|
||||
|
||||
static void declare(boost::python::object type)
|
||||
{
|
||||
using boost::python::register_exception_translator;
|
||||
register_exception_translator<E>(translate_exception(type));
|
||||
}
|
||||
|
||||
void operator()(const E& e) const
|
||||
{
|
||||
using boost::python::object;
|
||||
PyErr_SetObject(type.ptr(), object(e).ptr());
|
||||
}
|
||||
|
||||
private:
|
||||
boost::python::object type;
|
||||
};
|
||||
|
||||
void export_graphviz()
|
||||
{
|
||||
using boost::python::class_;
|
||||
using boost::python::bases;
|
||||
using boost::python::init;
|
||||
using boost::python::no_init;
|
||||
using boost::python::object;
|
||||
|
||||
object ge_type =
|
||||
class_<graph_exception, noncopyable >("graph_exception", no_init);
|
||||
translate_exception<graph_exception>::declare(ge_type);
|
||||
|
||||
object bpe_type =
|
||||
class_<bad_parallel_edge, bases<graph_exception> >("bad_parallel_edge",
|
||||
no_init)
|
||||
.def(init<std::string, std::string>());
|
||||
translate_exception<bad_parallel_edge>::declare(bpe_type);
|
||||
|
||||
translate_exception<directed_graph_error>
|
||||
::declare<graph_exception>("directed_graph_error");
|
||||
translate_exception<undirected_graph_error>
|
||||
::declare<graph_exception>("undirected_graph_error");
|
||||
}
|
||||
|
||||
// Explicit instantiations
|
||||
template
|
||||
void
|
||||
basic_graph<undirectedS>::read_graphviz(const std::string& filename,
|
||||
const std::string& node_id);
|
||||
template
|
||||
void
|
||||
basic_graph<undirectedS>::write_graphviz(const std::string& filename,
|
||||
const std::string& node_id);
|
||||
|
||||
template
|
||||
void
|
||||
basic_graph<bidirectionalS>::read_graphviz(const std::string& filename,
|
||||
const std::string& node_id);
|
||||
template
|
||||
void
|
||||
basic_graph<bidirectionalS>::write_graphviz(const std::string& filename,
|
||||
const std::string& node_id);
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,68 +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 <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
|
||||
@@ -1,80 +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 <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("g1"), arg("g2"),
|
||||
arg("isomorphism_map") =
|
||||
(vector_property_map<Graph::Vertex, Graph::VertexIndexMap>*)0,
|
||||
arg("vertex_invariant") = object()));
|
||||
|
||||
def("isomorphism", &isomorphism<Digraph>,
|
||||
(arg("g1"), arg("g2"),
|
||||
arg("isomorphism_map") =
|
||||
(vector_property_map<Digraph::Vertex, Digraph::VertexIndexMap>*)0,
|
||||
arg("vertex_invariant") = object()));
|
||||
}
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,80 +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 <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
|
||||
@@ -1,39 +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 <boost/graph/king_ordering.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
|
||||
king_ordering(const Graph& g)
|
||||
{
|
||||
std::list<typename Graph::Vertex> ordering;
|
||||
boost::python::list result;
|
||||
boost::king_ordering(g, std::back_inserter(ordering),
|
||||
g.get_vertex_index_map());
|
||||
for (typename std::list<typename Graph::Vertex>::iterator i
|
||||
= ordering.begin(); i != ordering.end(); ++i)
|
||||
result.append(*i);
|
||||
return result;
|
||||
}
|
||||
|
||||
void export_king_ordering()
|
||||
{
|
||||
using boost::python::arg;
|
||||
using boost::python::def;
|
||||
def("king_ordering", &king_ordering<Graph>, arg("graph"));
|
||||
}
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,53 +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 <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
|
||||
@@ -1,145 +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 "basic_graph.cpp"
|
||||
#include "graph.hpp"
|
||||
#include "digraph.hpp"
|
||||
#include <boost/python.hpp>
|
||||
#include "point2d.hpp"
|
||||
#include "generators.hpp"
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
extern void export_Graph();
|
||||
extern void export_Digraph();
|
||||
extern void export_graphviz();
|
||||
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_cuthill_mckee_ordering();
|
||||
extern void export_king_ordering();
|
||||
//extern void export_minimum_degree_ordering();
|
||||
extern void export_sequential_vertex_coloring();
|
||||
extern void export_betweenness_centrality();
|
||||
extern void export_page_rank();
|
||||
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_;
|
||||
using boost::python::no_init;
|
||||
using boost::python::init;
|
||||
using boost::python::arg;
|
||||
|
||||
enum_<graph_file_kind>("file_kind")
|
||||
.value("adjlist", gfk_adjlist)
|
||||
.value("graphviz", gfk_graphviz)
|
||||
;
|
||||
|
||||
enum_<default_color_type>("Color")
|
||||
.value("white", color_traits<default_color_type>::white())
|
||||
.value("gray", color_traits<default_color_type>::gray())
|
||||
.value("black", color_traits<default_color_type>::black())
|
||||
;
|
||||
|
||||
class_<point2d>("Point2D")
|
||||
.def_readwrite("x", &point2d::x)
|
||||
.def_readwrite("y", &point2d::y)
|
||||
;
|
||||
|
||||
class_<erdos_renyi>("ErdosRenyi", no_init)
|
||||
.def(init<std::size_t, double>(
|
||||
(arg("n"), arg("probability") = 1)))
|
||||
;
|
||||
|
||||
class_<power_law_out_degree>("PowerLawOutDegree", no_init)
|
||||
.def(init<std::size_t, double, double>(
|
||||
(arg("n"), arg("alpha"), arg("beta"))))
|
||||
;
|
||||
|
||||
class_<small_world>("SmallWorld", no_init)
|
||||
.def(init<std::size_t, std::size_t, double>
|
||||
((arg("n"), arg("k"), arg("probability"))))
|
||||
;
|
||||
|
||||
export_Graph();
|
||||
export_Digraph();
|
||||
export_graphviz();
|
||||
// Core Algorithm Patterns
|
||||
export_breadth_first_search();
|
||||
export_depth_first_search();
|
||||
// Shortest Paths Algorithms
|
||||
export_dijkstra_shortest_paths();
|
||||
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();
|
||||
|
||||
// Sparse Matrix Ordering
|
||||
export_cuthill_mckee_ordering();
|
||||
export_king_ordering();
|
||||
// export_minimum_degree_ordering();
|
||||
|
||||
// Other algorithms
|
||||
export_topological_sort();
|
||||
export_transitive_closure();
|
||||
export_sequential_vertex_coloring();
|
||||
export_betweenness_centrality();
|
||||
export_page_rank();
|
||||
|
||||
// Layout Algorithms
|
||||
export_circle_graph_layout();
|
||||
export_fruchterman_reingold_force_directed_layout();
|
||||
export_kamada_kawai_spring_layout();
|
||||
|
||||
// export_transpose_graph();
|
||||
export_isomorphism();
|
||||
}
|
||||
|
||||
template void export_in_graph<Graph>();
|
||||
template void export_in_graph<Digraph>();
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,81 +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 "digraph.hpp"
|
||||
#include <boost/graph/page_rank.hpp>
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
template<typename Graph>
|
||||
void
|
||||
page_rank_iterations
|
||||
(Graph& g,
|
||||
const vector_property_map<double, typename Graph::VertexIndexMap>* in_rank,
|
||||
int iterations)
|
||||
{
|
||||
typedef vector_property_map<double, typename Graph::VertexIndexMap>
|
||||
RankMap;
|
||||
|
||||
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(boost::python::object done) : done(done) { }
|
||||
|
||||
template<typename RankMap, typename Graph>
|
||||
bool
|
||||
operator()(const RankMap& rank, const Graph& g) const
|
||||
{
|
||||
using boost::python::extract;
|
||||
return extract<bool>(done(rank, g));
|
||||
}
|
||||
|
||||
private:
|
||||
boost::python::object done;
|
||||
};
|
||||
|
||||
|
||||
template<typename Graph>
|
||||
void
|
||||
page_rank_done
|
||||
(Graph& g,
|
||||
const vector_property_map<double, typename Graph::VertexIndexMap>* in_rank,
|
||||
boost::python::object done)
|
||||
{
|
||||
typedef vector_property_map<double, typename Graph::VertexIndexMap>
|
||||
RankMap;
|
||||
|
||||
RankMap rank =
|
||||
in_rank? *in_rank : g.template get_vertex_map<double>("pagerank");
|
||||
|
||||
boost::graph::page_rank(g, rank, page_rank_wrap_done(done));
|
||||
}
|
||||
|
||||
void export_page_rank()
|
||||
{
|
||||
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_done<Digraph>,
|
||||
(arg("graph"),
|
||||
arg("rank_map") =
|
||||
(vector_property_map<double, Digraph::VertexIndexMap>*)0,
|
||||
arg("done")));
|
||||
}
|
||||
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,154 +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 "graph.hpp"
|
||||
#include "digraph.hpp"
|
||||
#include <boost/graph/iteration_macros.hpp>
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
template<typename DirectedS>
|
||||
boost::python::tuple
|
||||
graph_pickle_suite<DirectedS>::getstate(boost::python::object g_obj)
|
||||
{
|
||||
using boost::python::tuple;
|
||||
using boost::python::make_tuple;
|
||||
using boost::python::list;
|
||||
using boost::python::extract;
|
||||
using boost::python::dict;
|
||||
using boost::python::object;
|
||||
|
||||
const Graph& g = extract<const Graph&>(g_obj)();
|
||||
typename Graph::VertexIndexMap vertex_index_map = g.get_vertex_index_map();
|
||||
typename Graph::EdgeIndexMap edge_index_map = g.get_edge_index_map();
|
||||
|
||||
dict vertex_properties;
|
||||
dict edge_properties;
|
||||
|
||||
// Collect edges
|
||||
std::vector<tuple> the_edges(g.num_edges());
|
||||
BGL_FORALL_EDGES_T(e, g, Graph)
|
||||
the_edges[get(edge_index_map, e)] =
|
||||
make_tuple(get(vertex_index_map, source(e, g)),
|
||||
get(vertex_index_map, target(e, g)));
|
||||
|
||||
list edges_list;
|
||||
for (std::vector<tuple>::iterator i = the_edges.begin();
|
||||
i != the_edges.end(); ++i)
|
||||
edges_list.append(*i);
|
||||
|
||||
// Collect vertex and edge properties
|
||||
const dynamic_properties& dp = g.get_dynamic_properties();
|
||||
for (dynamic_properties::const_iterator pm = dp.begin();
|
||||
pm != dp.end(); ++pm) {
|
||||
python_dynamic_property_map* pmap =
|
||||
dynamic_cast<python_dynamic_property_map*>(pm->second);
|
||||
if (pm->second->key() == typeid(Vertex)) {
|
||||
std::vector<object> values(g.num_vertices());
|
||||
BGL_FORALL_VERTICES_T(v, g, Graph)
|
||||
values[get(vertex_index_map, v)] = pmap->get_python(v);
|
||||
|
||||
list values_list;
|
||||
for (std::vector<object>::iterator i = values.begin();
|
||||
i != values.end(); ++i)
|
||||
values_list.append(*i);
|
||||
vertex_properties[pm->first] = tuple(values_list);
|
||||
} else if (pm->second->key() == typeid(Edge)) {
|
||||
std::vector<object> values(g.num_edges());
|
||||
BGL_FORALL_EDGES_T(e, g, Graph)
|
||||
values[get(edge_index_map, e)] = pmap->get_python(e);
|
||||
|
||||
list values_list;
|
||||
for (std::vector<object>::iterator i = values.begin();
|
||||
i != values.end(); ++i)
|
||||
values_list.append(*i);
|
||||
edge_properties[pm->first] = tuple(values_list);
|
||||
} else {
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
return make_tuple(g_obj.attr("__dict__"),
|
||||
g.num_vertices(),
|
||||
edges_list,
|
||||
vertex_properties,
|
||||
edge_properties);
|
||||
}
|
||||
|
||||
template<typename DirectedS>
|
||||
void
|
||||
graph_pickle_suite<DirectedS>::setstate(boost::python::object g_obj,
|
||||
boost::python::tuple state)
|
||||
{
|
||||
using boost::python::tuple;
|
||||
using boost::python::make_tuple;
|
||||
using boost::python::list;
|
||||
using boost::python::extract;
|
||||
using boost::python::dict;
|
||||
using boost::python::object;
|
||||
|
||||
Graph& g = extract<Graph&>(g_obj)();
|
||||
|
||||
// restore the graph's __dict__
|
||||
dict d = extract<dict>(g_obj.attr("__dict__"))();
|
||||
d.update(state[0]);
|
||||
|
||||
// Get the number of vertices
|
||||
typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
|
||||
vertices_size_type n = extract<vertices_size_type>(state[1]);
|
||||
std::vector<Vertex> vertices;
|
||||
vertices.reserve(n);
|
||||
while (vertices.size() < n) vertices.push_back(g.add_vertex());
|
||||
|
||||
// Get the edges
|
||||
typedef typename graph_traits<Graph>::edges_size_type edges_size_type;
|
||||
std::vector<Edge> the_edges;
|
||||
list edges_list = extract<list>(state[2]);
|
||||
edges_size_type m = extract<int>(edges_list.attr("__len__")());
|
||||
the_edges.reserve(m);
|
||||
for (unsigned i = 0; i < m; ++i) {
|
||||
tuple e = extract<tuple>(edges_list[i]);
|
||||
the_edges.push_back
|
||||
(g.add_edge(vertices[extract<vertices_size_type>(e[0])],
|
||||
vertices[extract<vertices_size_type>(e[1])]));
|
||||
}
|
||||
|
||||
// Get the vertex properties
|
||||
typedef typename Graph::VertexIndexMap VertexIndexMap;
|
||||
dict vertex_properties = extract<dict>(state[3]);
|
||||
list vertex_map_names = vertex_properties.keys();
|
||||
while (vertex_map_names != list()) {
|
||||
object name_obj = vertex_map_names.pop(0);
|
||||
const char* name = extract<const char*>(name_obj);
|
||||
vector_property_map<object, VertexIndexMap> pmap =
|
||||
g.get_vertex_object_map(name);
|
||||
tuple values = extract<tuple>(vertex_properties[name_obj]);
|
||||
for (vertices_size_type i = 0; i < g.num_vertices(); ++i)
|
||||
put(pmap, vertices[i], values[i]);
|
||||
}
|
||||
|
||||
// Get the edge properties
|
||||
typedef typename Graph::EdgeIndexMap EdgeIndexMap;
|
||||
dict edge_properties = extract<dict>(state[4]);
|
||||
list edge_map_names = edge_properties.keys();
|
||||
while (edge_map_names != list()) {
|
||||
object name_obj = edge_map_names.pop(0);
|
||||
const char* name = extract<const char*>(name_obj);
|
||||
vector_property_map<object, EdgeIndexMap> pmap =
|
||||
g.get_edge_object_map(name);
|
||||
tuple values = extract<tuple>(edge_properties[name_obj]);
|
||||
for (edges_size_type i = 0; i < g.num_edges(); ++i)
|
||||
put(pmap, the_edges[i], values[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template struct graph_pickle_suite<undirectedS>;
|
||||
template struct graph_pickle_suite<bidirectionalS>;
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
|
||||
@@ -1,28 +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
|
||||
#ifndef BOOST_GRAPH_PYTHON_POINT2D_HPP
|
||||
#define BOOST_GRAPH_PYTHON_POINT2D_HPP
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
struct point2d
|
||||
{
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, point2d p)
|
||||
{ return out << p.x << ' ' << p.y; }
|
||||
|
||||
inline std::istream& operator>>(std::istream& in, point2d& p)
|
||||
{ return in >> p.x >> p.y; }
|
||||
} } } // end namespace boost::graph::python
|
||||
|
||||
#endif // BOOST_GRAPH_PYTHON_POINT2D_HPP
|
||||
@@ -1,105 +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 <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
|
||||
@@ -1,71 +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
|
||||
#ifndef BOOST_GRAPH_PYTHON_QUEUE_HPP
|
||||
#define BOOST_GRAPH_PYTHON_QUEUE_HPP
|
||||
|
||||
#include <boost/python.hpp>
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
template<typename T>
|
||||
class python_queue
|
||||
{
|
||||
class wrap
|
||||
: public python_queue<T>, public boost::python::wrapper<python_queue<T> >
|
||||
{
|
||||
public:
|
||||
bool empty() const { return this->get_override("empty")(); }
|
||||
T top() const { return this->get_override("top")(); }
|
||||
void pop() { this->get_override("pop")(); }
|
||||
void push(const T& x) { this->get_override("push")(x); }
|
||||
};
|
||||
|
||||
public:
|
||||
class default_queue : public python_queue<T>
|
||||
{
|
||||
bool empty() const { return true; }
|
||||
T top() const { return T(); }
|
||||
void pop() {}
|
||||
void push(const T&) {}
|
||||
};
|
||||
|
||||
virtual ~python_queue() {}
|
||||
virtual bool empty() const = 0;
|
||||
virtual T top() const = 0;
|
||||
virtual void pop() = 0;
|
||||
virtual void push(const T&) = 0;
|
||||
|
||||
static void declare(const char* name, const char* default_name)
|
||||
{
|
||||
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 (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))
|
||||
.def("pop", pure_virtual(&python_queue<T>::pop))
|
||||
.def("push", pure_virtual(&python_queue<T>::push))
|
||||
;
|
||||
}
|
||||
|
||||
if (registered_class_object(type_id<default_queue>()).get() == 0)
|
||||
{
|
||||
class_<default_queue, bases<python_queue> >(default_name, no_init);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
|
||||
#endif // BOOST_GRAPH_PYTHON_QUEUE_HPP
|
||||
@@ -1,47 +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 "graph.hpp"
|
||||
#include "digraph.hpp"
|
||||
#include <boost/graph/sequential_vertex_coloring.hpp>
|
||||
|
||||
namespace boost { namespace graph { namespace python {
|
||||
|
||||
template<typename Graph>
|
||||
int
|
||||
sequential_vertex_coloring
|
||||
(Graph& g,
|
||||
const vector_property_map<int, typename Graph::VertexIndexMap>* in_color)
|
||||
{
|
||||
typedef vector_property_map<int, typename Graph::VertexIndexMap> ColorMap;
|
||||
|
||||
ColorMap color =
|
||||
in_color? *in_color
|
||||
: ColorMap(num_vertices(g), g.get_vertex_index_map());
|
||||
|
||||
return boost::sequential_vertex_coloring(g, color);
|
||||
}
|
||||
|
||||
void export_sequential_vertex_coloring()
|
||||
{
|
||||
using boost::python::arg;
|
||||
using boost::python::def;
|
||||
|
||||
def("sequential_vertex_coloring",
|
||||
&sequential_vertex_coloring<Graph>,
|
||||
(arg("graph"),
|
||||
arg("color_map") =
|
||||
(vector_property_map<int, Graph::VertexIndexMap>*)0));
|
||||
def("sequential_vertex_coloring",
|
||||
&sequential_vertex_coloring<Digraph>,
|
||||
(arg("graph"),
|
||||
arg("color_map") =
|
||||
(vector_property_map<int, Digraph::VertexIndexMap>*)0));
|
||||
}
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,42 +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 <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
|
||||
@@ -1,55 +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 <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
|
||||
@@ -1,45 +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 <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("orig_to_copy") =
|
||||
(vector_property_map<Digraph::Vertex, Digraph::VertexIndexMap>*)0));
|
||||
}
|
||||
|
||||
} } } // end namespace boost::graph::python
|
||||
@@ -1,85 +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
|
||||
template<typename Graph>
|
||||
class BGL_PYTHON_VISITOR
|
||||
{
|
||||
class wrap
|
||||
: public BGL_PYTHON_VISITOR<Graph>,
|
||||
public boost::python::wrapper<BGL_PYTHON_VISITOR<Graph> >
|
||||
{
|
||||
public:
|
||||
typedef typename BGL_PYTHON_VISITOR<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename BGL_PYTHON_VISITOR<Graph>::edge_descriptor edge_descriptor;
|
||||
|
||||
#define BGL_PYTHON_EVENT(Name,Descriptor) \
|
||||
void Name(Descriptor x, const Graph& g) const \
|
||||
{ \
|
||||
if (boost::python::override f = this->get_override(#Name)) \
|
||||
f(x, boost::cref(g)); \
|
||||
else BGL_PYTHON_VISITOR<Graph>::Name(x, g); \
|
||||
} \
|
||||
\
|
||||
void default_##Name(Descriptor x, const Graph& g) const \
|
||||
{ this->BGL_PYTHON_VISITOR<Graph>::Name(x, g); }
|
||||
# include BGL_PYTHON_EVENTS_HEADER
|
||||
#undef BGL_PYTHON_EVENT
|
||||
};
|
||||
|
||||
public:
|
||||
class default_arg : public BGL_PYTHON_VISITOR<Graph> { };
|
||||
|
||||
struct ref
|
||||
{
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
|
||||
ref(const BGL_PYTHON_VISITOR<Graph>& v) : v(v) { }
|
||||
|
||||
#define BGL_PYTHON_EVENT(Name, Descriptor) \
|
||||
void Name(Descriptor x, const Graph& g) const { v.Name(x, g); }
|
||||
# include BGL_PYTHON_EVENTS_HEADER
|
||||
#undef BGL_PYTHON_EVENT
|
||||
|
||||
private:
|
||||
const BGL_PYTHON_VISITOR<Graph>& v;
|
||||
};
|
||||
|
||||
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
|
||||
virtual ~BGL_PYTHON_VISITOR() {}
|
||||
|
||||
#define BGL_PYTHON_EVENT(Name, Descriptor) \
|
||||
virtual void Name(Descriptor x, const Graph& g) const {}
|
||||
# include BGL_PYTHON_EVENTS_HEADER
|
||||
#undef BGL_PYTHON_EVENT
|
||||
|
||||
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)
|
||||
# include BGL_PYTHON_EVENTS_HEADER
|
||||
#undef BGL_PYTHON_EVENT
|
||||
;
|
||||
|
||||
class_<default_arg, bases<BGL_PYTHON_VISITOR<Graph> > >(default_name,
|
||||
no_init);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
graph G {
|
||||
A -- B
|
||||
A -- F
|
||||
A -- G
|
||||
B -- C
|
||||
B -- D
|
||||
B -- E
|
||||
C -- D
|
||||
E -- F
|
||||
G -- H
|
||||
G -- I
|
||||
H -- I
|
||||
}
|
||||
@@ -1,21 +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
|
||||
|
||||
import bgl
|
||||
|
||||
g = bgl.Graph("biconnected_components.dot", bgl.file_kind.graphviz)
|
||||
art_points = bgl.biconnected_components(g, g.get_edge_int_map("label"));
|
||||
g.write_graphviz("biconnected_components_out.dot")
|
||||
|
||||
print "Articulation points: ",
|
||||
node_id = g.get_vertex_string_map("node_id")
|
||||
for v in art_points:
|
||||
print node_id[v],
|
||||
print " ",
|
||||
print ""
|
||||
@@ -1,14 +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
|
||||
|
||||
import bgl
|
||||
|
||||
g = bgl.Graph("biconnected_components.dot", bgl.file_kind.graphviz)
|
||||
bgl.circle_graph_layout(g, radius=200)
|
||||
g.write_graphviz("circle_graph_layout_out.dot")
|
||||
@@ -1,14 +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
|
||||
|
||||
import bgl
|
||||
|
||||
g = bgl.Graph("biconnected_components.dot", bgl.file_kind.graphviz)
|
||||
bgl.fruchterman_reingold_force_directed_layout(g, width=400, height=400)
|
||||
g.write_graphviz("fruchterman_reingold_out.dot")
|
||||
@@ -1,14 +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
|
||||
|
||||
import bgl
|
||||
|
||||
g = bgl.Graph("biconnected_components.dot", bgl.file_kind.graphviz)
|
||||
bgl.kamada_kawai_spring_layout(g, side_length=400)
|
||||
g.write_graphviz("kamada_kawai_spring_layout_out.dot")
|
||||
@@ -1,110 +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
|
||||
|
||||
# Note: this code requires the Boost Graph Library bindings for Python
|
||||
# and the priodict module. The latter is part of the Python NMS
|
||||
# library (http://pynms.sourceforge.net/).
|
||||
|
||||
import bgl
|
||||
import priodict
|
||||
|
||||
class pqueue(bgl.Digraph.VertexQueue):
|
||||
def __init__(self, distance):
|
||||
bgl.Digraph.VertexQueue.__init__(self)
|
||||
self.Q = priodict.priorityDictionary()
|
||||
self.distance = distance
|
||||
def empty(self):
|
||||
return self.Q == {}
|
||||
def top(self):
|
||||
return self.Q.smallest();
|
||||
def pop(self):
|
||||
del self.Q[self.Q.smallest()]
|
||||
def push(self, x):
|
||||
self.Q[x] = self.distance[x]
|
||||
def update(self, x, v):
|
||||
self.distance[x] = v
|
||||
self.Q[x] = v
|
||||
|
||||
class dijkstra_bfs_visitor(bgl.Digraph.BFSVisitor):
|
||||
def __init__(self, Q, weight, distance, predecessor):
|
||||
bgl.Digraph.BFSVisitor.__init__(self)
|
||||
self.Q = Q
|
||||
self.weight = weight
|
||||
self.distance = distance
|
||||
self.predecessor = predecessor
|
||||
|
||||
def tree_edge(self, e, g):
|
||||
(u, v) = (g.source(e), g.target(e))
|
||||
self.distance[v] = self.distance[u] + self.weight[e]
|
||||
self.predecessor[v] = u
|
||||
|
||||
def gray_target(self, e, g):
|
||||
(u, v) = (g.source(e), g.target(e))
|
||||
if self.distance[u] + self.weight[e] < self.distance[v]:
|
||||
self.Q.update(v, self.distance[u] + self.weight[e])
|
||||
self.predecessor[v] = u;
|
||||
|
||||
|
||||
g = bgl.Digraph()
|
||||
|
||||
# Create vertices in the graph
|
||||
name = g.get_vertex_string_map("node_id")
|
||||
A = g.add_vertex()
|
||||
name[A] = "A"
|
||||
B = g.add_vertex()
|
||||
name[B] = "B"
|
||||
C = g.add_vertex()
|
||||
name[C] = "C"
|
||||
D = g.add_vertex()
|
||||
name[D] = "D"
|
||||
E = g.add_vertex()
|
||||
name[E] = "E"
|
||||
|
||||
# Create (weighted) edges in the graph
|
||||
weight = g.get_edge_double_map("label")
|
||||
weight[g.add_edge(A, C)] = 1
|
||||
weight[g.add_edge(B, B)] = 2
|
||||
weight[g.add_edge(B, D)] = 1
|
||||
weight[g.add_edge(B, E)] = 2.5
|
||||
weight[g.add_edge(C, B)] = 7
|
||||
weight[g.add_edge(C, D)] = 3
|
||||
weight[g.add_edge(D, E)] = 1
|
||||
weight[g.add_edge(E, A)] = 1
|
||||
weight[g.add_edge(E, B)] = 1
|
||||
|
||||
# Initialize property maps
|
||||
predecessor = {}
|
||||
distance = g.get_vertex_double_map("distance_from_A")
|
||||
for v in g.vertices:
|
||||
predecessor[v] = v
|
||||
distance[v] = 1e100
|
||||
|
||||
# Run breadth-first search to compute shortest paths
|
||||
distance[A] = 0
|
||||
buf = pqueue(distance)
|
||||
|
||||
bgl.breadth_first_search(g, A, buf,
|
||||
dijkstra_bfs_visitor(buf,weight,distance,predecessor),
|
||||
color_map = g.get_vertex_color_map("color"))
|
||||
|
||||
class show_relaxed_edges(bgl.Digraph.DijkstraVisitor):
|
||||
def edge_relaxed(self, e, g):
|
||||
text = "Relaxed edge (" + name[g.source(e)] + ", " + name[g.target(e)] + ")"
|
||||
print text
|
||||
|
||||
# Run Dijkstra's algorithm to compute shortest paths
|
||||
distance2 = g.get_vertex_double_map("distance_from_A_also");
|
||||
bgl.dijkstra_shortest_paths(g, A, distance_map = distance2,
|
||||
visitor=show_relaxed_edges(),
|
||||
weight_map = g.get_edge_double_map("label"));
|
||||
|
||||
# Emit graph
|
||||
g.write_graphviz("dijkstra-example.dot")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user