2
0
mirror of https://github.com/boostorg/graph.git synced 2026-01-19 04:12:11 +00:00

Quickbook: Merge from trunk.

Includes blocks in lists fixes, and some documentation changes.


[SVN r77347]
This commit is contained in:
Daniel James
2012-03-16 08:48:10 +00:00
parent 2924624c7b
commit 45a6fa68bf
28 changed files with 823 additions and 150 deletions

View File

@@ -80,7 +80,7 @@ the search.
<TR>
<TD><tt>w</tt></TD>
<TD>An object of type <tt>DistanceMap</tt>.</TD>
<TD>An object of type <tt>WeightMap</tt>.</TD>
</TR>
</table>

191
doc/directed_graph.html Normal file
View File

@@ -0,0 +1,191 @@
<HTML>
<!--
Copyright (c) David Doria 2012
Distributed under 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)
-->
<Head>
<Title>Boost Graph Library: Directed Graph</Title>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="../../../boost.png"
ALT="C++ Boost" width="277" height="86">
<BR Clear>
<H1><A NAME="sec:directed-graph-class"></A>
<pre>
directed_graph&lt;VertexProp, EdgeProp, GraphProp&gt;
</pre>
</H1>
<P>
The <tt>directed_graph</tt> class template is is a simplified version
of the BGL adjacency list. This class is provided for ease of use, but
may not perform as well as custom-defined adjacency list classes. Instances
of this template model the BidirectionalGraph, VertexIndexGraph, and
EdgeIndexGraph concepts.
<H3>Example</H3>
A simple examples of creating a directed_graph is available here <a href="../../../libs/graph/example/directed_graph.cpp"><tt>libs/graph/example/directed_graph.cpp</tt></a>.
<P>
<PRE>
typedef boost::directed_graph<> Graph;
Graph g;
boost::graph_traits<Graph>::vertex_descriptor v0 = g.add_vertex();
boost::graph_traits<Graph>::vertex_descriptor v1 = g.add_vertex();
g.add_edge(v0, v1);
</PRE>
<H3>Template Parameters</H3>
<P>
<TABLE border>
<TR>
<th>Parameter</th><th>Description</th><th>Default</th>
</tr>
<TR><TD><TT>VertexProp</TT></TD>
<TD>A property map for the graph vertices.</TD>
<TD>&nbsp;</TD>
</TR>
<TR>
<TD><TT>EdgeProp</TT></TD>
<TD>A property map for the graph edges.</TD>
<TD>&nbsp;</TD>
</TR>
<TR>
<TD><TT>GraphProp</TT></TD>
<TD>A property map for the graph itself.</TD>
</TR>
</TABLE>
<P>
<H3>Where Defined</H3>
<P>
<a href="../../../boost/graph/directed_graph.hpp"><TT>boost/graph/directed_graph.hpp</TT></a>
<P>
<br>
<HR>
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy; 2000-2001</TD><TD>
<A HREF="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</A>,
Indiana University (<A
HREF="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</A>)<br>
<A HREF="http://www.boost.org/people/liequan_lee.htm">Lie-Quan Lee</A>, Indiana University (<A HREF="mailto:llee@cs.indiana.edu">llee@cs.indiana.edu</A>)<br>
<A HREF="http://www.osl.iu.edu/~lums">Andrew Lumsdaine</A>,
Indiana University (<A
HREF="mailto:lums@osl.iu.edu">lums@osl.iu.edu</A>)
</TD></TR></TABLE>
</BODY>
</HTML>
<HTML>
<!--
Copyright (c) Jeremy Siek 2000
Distributed under 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)
-->
<Head>
<Title>Boost Graph Library: Directed Graph</Title>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="../../../boost.png"
ALT="C++ Boost" width="277" height="86">
<BR Clear>
<H1><A NAME="sec:directed-graph-class"></A>
<pre>
directed_graph&lt;VertexProp, EdgeProp, GraphProp&gt;
</pre>
</H1>
<P>
The <tt>directed_graph</tt> class template is is a simplified version
of the BGL adjacency list. This class is provided for ease of use, but
may not perform as well as custom-defined adjacency list classes. Instances
of this template model the BidirectionalGraph, VertexIndexGraph, and
EdgeIndexGraph concepts.
<H3>Example</H3>
<P>
<PRE>
typedef boost::directed_graph<> Graph;
Graph g;
Graph::vertex_descriptor v0 = g.add_vertex();
Graph::vertex_descriptor v1 = g.add_vertex();
g.add_edge(v0, v1);
</PRE>
<H3>Template Parameters</H3>
<P>
<TABLE border>
<TR>
<th>Parameter</th><th>Description</th><th>Default</th>
</tr>
<TR><TD><TT>VertexProp</TT></TD>
<TD>A property map for the graph vertices.</TD>
<TD>&nbsp;</TD>
</TR>
<TR>
<TD><TT>EdgeProp</TT></TD>
<TD>A property map for the graph edges.</TD>
<TD>&nbsp;</TD>
</TR>
<TR>
<TD><TT>GraphProp</TT></TD>
<TD>A property map for the graph itself.</TD>
</TR>
</TABLE>
<P>
<H3>Where Defined</H3>
<P>
<a href="../../../boost/graph/directed_graph.hpp"><TT>boost/graph/directed_graph.hpp</TT></a>
<P>
<br>
<HR>
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy; 2000-2001</TD><TD>
<A HREF="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</A>,
Indiana University (<A
HREF="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</A>)<br>
<A HREF="http://www.boost.org/people/liequan_lee.htm">Lie-Quan Lee</A>, Indiana University (<A HREF="mailto:llee@cs.indiana.edu">llee@cs.indiana.edu</A>)<br>
<A HREF="http://www.osl.iu.edu/~lums">Andrew Lumsdaine</A>,
Indiana University (<A
HREF="mailto:lums@osl.iu.edu">lums@osl.iu.edu</A>)
</TD></TR></TABLE>
</BODY>
</HTML>

View File

@@ -69,7 +69,7 @@
<p>
Defined in
<a href="../../../boost/graph/grid_graph.hpp"><tt>boost/graph/grid_graph.hpp</tt></a>
with all functions in the <tt>boost</tt> namespace. All examples are available in a single program file in <a href="../../../libs/graph/example/grid_graph_example.cpp"><tt>libs/graph/example/grid_graph_example.cpp</tt></a>
with all functions in the <tt>boost</tt> namespace. A simple examples of creating and iterating over a grid_graph is available here <a href="../../../libs/graph/example/grid_graph_example.cpp"><tt>libs/graph/example/grid_graph_example.cpp</tt></a>. An example of adding properties to a grid_graph is also available <a href="../../../libs/graph/example/grid_graph_example.cpp"><tt>libs/graph/example/grid_graph_properties.cpp</tt></a>
</p>
<h4>Template Parameters</h4>

View File

@@ -97,7 +97,7 @@ and might produce the output
New face: 1 2 5 4
New face: 2 3 4 5
New face: 3 0 1 4
New face: 2 3 0 1
New face: 1 0 3 2
</pre>
<h3>Visitor Event Points</h3>

View File

@@ -101,6 +101,10 @@
<LI>Graph classes
<OL>
<LI><A href="./adjacency_list.html"><tt>adjacency_list</tt></a></li>
<OL>
<LI><A href="./directed_graph.html"><tt>directed_graph</tt></a></li>
<LI><A href="./undirected_graph.html"><tt>undirected_graph</tt></a></li>
</OL>
<LI><A href="./adjacency_matrix.html"><tt>adjacency_matrix</tt></a></li>
<li><a href="compressed_sparse_row.html"><tt>compressed_sparse_row_graph</tt></a></li>
</OL></li>

View File

@@ -124,8 +124,8 @@ class convex_topology
struct point
{
point() { }
double& operator[](std::size_t i) {return values[i];}
const double& operator[](std::size_t i) const {return values[i];}
double&amp; operator[](std::size_t i) {return values[i];}
const double&amp; operator[](std::size_t i) const {return values[i];}
private:
double values[Dims];
@@ -157,7 +157,7 @@ class hypercube_topology : public <a href="#convex_topology">convex_topology</a>
{
public:
explicit hypercube_topology(double scaling = 1.0);
hypercube_topology(RandomNumberGenerator& gen, double scaling = 1.0);
hypercube_topology(RandomNumberGenerator&amp; gen, double scaling = 1.0);
point_type random_point() const;
};
</pre>
@@ -173,13 +173,13 @@ class square_topology : public <a href="#hypercube_topology">hypercube_topology<
{
public:
explicit square_topology(double scaling = 1.0);
square_topology(RandomNumberGenerator& gen, double scaling = 1.0);
square_topology(RandomNumberGenerator&amp; gen, double scaling = 1.0);
};
</pre>
<a name="cube_topology"><h3>Class template <tt>cube_topology</tt></h3></a>
<p>Class template <tt>cube_topology</tt> is a two-dimensional
<p>Class template <tt>cube_topology</tt> is a three-dimensional
hypercube topology.
<pre>
@@ -188,7 +188,7 @@ class cube_topology : public <a href="#hypercube_topology">hypercube_topology</a
{
public:
explicit cube_topology(double scaling = 1.0);
cube_topology(RandomNumberGenerator& gen, double scaling = 1.0);
cube_topology(RandomNumberGenerator&amp; gen, double scaling = 1.0);
};
</pre>
@@ -209,7 +209,7 @@ class ball_topology : public <a href="#convex_topology">convex_topology</a>&lt;D
{
public:
explicit ball_topology(double radius = 1.0);
ball_topology(RandomNumberGenerator& gen, double radius = 1.0);
ball_topology(RandomNumberGenerator&amp; gen, double radius = 1.0);
point_type random_point() const;
};
</pre>
@@ -225,13 +225,13 @@ class circle_topology : public <a href="#ball_topology">ball_topology</a>&lt;2,
{
public:
explicit circle_topology(double radius = 1.0);
circle_topology(RandomNumberGenerator& gen, double radius = 1.0);
circle_topology(RandomNumberGenerator&amp; gen, double radius = 1.0);
};
</pre>
<a name="sphere_topology"><h3>Class template <tt>sphere_topology</tt></h3></a>
<p>Class template <tt>sphere_topology</tt> is a two-dimensional
<p>Class template <tt>sphere_topology</tt> is a three-dimensional
ball topology.
<pre>
@@ -240,7 +240,7 @@ class sphere_topology : public <a href="#ball_topology">ball_topology</a>&lt;3,
{
public:
explicit sphere_topology(double radius = 1.0);
sphere_topology(RandomNumberGenerator& gen, double radius = 1.0);
sphere_topology(RandomNumberGenerator&amp; gen, double radius = 1.0);
};
</pre>
@@ -258,7 +258,7 @@ class heart_topology
typedef <em>unspecified</em> point_type;
heart_topology();
heart_topology(RandomNumberGenerator& gen);
heart_topology(RandomNumberGenerator&amp; gen);
point_type random_point() const;
double distance(point_type a, point_type b) const;
point_type move_position_toward(point_type a, double fraction, point_type b) const;

96
doc/undirected_graph.html Normal file
View File

@@ -0,0 +1,96 @@
<HTML>
<!--
Copyright (c) David Doria 2012
Distributed under 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)
-->
<Head>
<Title>Boost Graph Library: Undirected Graph</Title>
<BODY BGCOLOR="#ffffff" LINK="#0000ee" TEXT="#000000" VLINK="#551a8b"
ALINK="#ff0000">
<IMG SRC="../../../boost.png"
ALT="C++ Boost" width="277" height="86">
<BR Clear>
<H1><A NAME="sec:undirected-graph-class"></A>
<pre>
undirected_graph&lt;VertexProp, EdgeProp, GraphProp&gt;
</pre>
</H1>
<P>
The <tt>undirected_graph</tt> class template is is a simplified version
of the BGL adjacency list. This class is provided for ease of use, but
may not perform as well as custom-defined adjacency list classes. Instances
of this template model the BidirectionalGraph, VertexIndexGraph, and
EdgeIndexGraph concepts.
<H3>Example</H3>
A simple example of creating an undirected_graph is available here <a href="../../../libs/graph/example/undirected_graph.cpp"><tt>libs/graph/example/undirected_graph.cpp</tt></a>
<P>
<PRE>
typedef boost::undirected_graph<> Graph;
Graph g;
boost::graph_traits<Graph>::vertex_descriptor v0 = g.add_vertex();
boost::graph_traits<Graph>::vertex_descriptor v1 = g.add_vertex();
g.add_edge(v0, v1);
</PRE>
<H3>Template Parameters</H3>
<P>
<TABLE border>
<TR>
<th>Parameter</th><th>Description</th><th>Default</th>
</tr>
<TR><TD><TT>VertexProp</TT></TD>
<TD>A property map for the graph vertices.</TD>
<TD>&nbsp;</TD>
</TR>
<TR>
<TD><TT>EdgeProp</TT></TD>
<TD>A property map for the graph edges.</TD>
<TD>&nbsp;</TD>
</TR>
<TR>
<TD><TT>GraphProp</TT></TD>
<TD>A property map for the graph itself.</TD>
</TR>
</TABLE>
<P>
<H3>Where Defined</H3>
<P>
<a href="../../../boost/graph/undirected_graph.hpp"><TT>boost/graph/undirected_graph.hpp</TT></a>
<P>
<br>
<HR>
<TABLE>
<TR valign=top>
<TD nowrap>Copyright &copy; 2000-2001</TD><TD>
<A HREF="http://www.boost.org/people/jeremy_siek.htm">Jeremy Siek</A>,
Indiana University (<A
HREF="mailto:jsiek@osl.iu.edu">jsiek@osl.iu.edu</A>)<br>
<A HREF="http://www.boost.org/people/liequan_lee.htm">Lie-Quan Lee</A>, Indiana University (<A HREF="mailto:llee@cs.indiana.edu">llee@cs.indiana.edu</A>)<br>
<A HREF="http://www.osl.iu.edu/~lums">Andrew Lumsdaine</A>,
Indiana University (<A
HREF="mailto:lums@osl.iu.edu">lums@osl.iu.edu</A>)
</TD></TR></TABLE>
</BODY>
</HTML>

View File

@@ -20,6 +20,7 @@ exe bron_kerbosch_print_cliques : bron_kerbosch_print_cliques.cpp ;
exe bron_kerbosch_clique_number : bron_kerbosch_clique_number.cpp ;
exe mcgregor_subgraphs_example : mcgregor_subgraphs_example.cpp ;
exe grid_graph_example : grid_graph_example.cpp ;
exe grid_graph_properties : grid_graph_properties.cpp ;
exe bipartite_example : bipartite_example.cpp ;
exe fr_layout : fr_layout.cpp ;
exe canonical_ordering : canonical_ordering.cpp ;
@@ -33,3 +34,7 @@ exe stoer_wagner : stoer_wagner.cpp ;
exe bfs-example : bfs-example.cpp ;
exe bfs-example2 : bfs-example2.cpp ;
exe dfs-example : dfs-example.cpp ;
exe adjacency_list_io : adjacency_list_io.cpp ;
exe undirected_adjacency_list : undirected_adjacency_list.cpp ;
exe directed_graph : directed_graph.cpp ;
exe undirected_graph : undirected_graph.cpp ;

View File

@@ -0,0 +1,26 @@
//=======================================================================
// Copyright 2012
// Authors: David Doria
//
// Distributed under 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)
//=======================================================================
#include <boost/graph/directed_graph.hpp> // A subclass to provide reasonable arguments to adjacency_list for a typical directed graph
int main(int,char*[])
{
// directed_graph is a subclass of adjacency_list which gives you object oriented access to functions
// like add_vertex and add_edge, which makes the code easier to understand. However, it hard codes many
// of the template parameters, so it is much less flexible.
typedef boost::directed_graph<> Graph;
Graph g;
boost::graph_traits<Graph>::vertex_descriptor v0 = g.add_vertex();
boost::graph_traits<Graph>::vertex_descriptor v1 = g.add_vertex();
g.add_edge(v0, v1);
return 0;
}

View File

@@ -0,0 +1,40 @@
//=======================================================================
// Copyright 2012 David Doria
// Authors: David Doria
//
// Distributed under 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)
//=======================================================================
#include <iostream>
#include <boost/array.hpp>
#include <boost/graph/grid_graph.hpp>
int main(int argc, char* argv[])
{
// A 2D grid graph
typedef boost::grid_graph<2> GraphType;
// Create a 5x5 graph
const unsigned int dimension = 5;
boost::array<std::size_t, 2> lengths = { { dimension, dimension } };
GraphType graph(lengths);
// Get the index map of the grid graph
typedef boost::property_map<GraphType, boost::vertex_index_t>::const_type indexMapType;
indexMapType indexMap(get(boost::vertex_index, graph));
// Create a float for every node in the graph
boost::vector_property_map<float, indexMapType> dataMap(num_vertices(graph), indexMap);
// Associate the value 2.0 with the node at position (0,1) in the grid
boost::graph_traits<GraphType>::vertex_descriptor v = { { 0, 1 } };
put(dataMap, v, 2.0f);
// Get the data at the node at position (0,1) in the grid
float retrieved = get(dataMap, v);
std::cout << "Retrieved value: " << retrieved << std::endl;
return 0;
}

View File

@@ -0,0 +1,30 @@
//=======================================================================
// Copyright 2012
// Authors: David Doria
//
// Distributed under 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)
//=======================================================================
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/undirected_graph.hpp>
typedef boost::undirected_graph<boost::no_property> Graph;
int main(int,char*[])
{
// Create a graph object
Graph g;
// Add vertices
boost::graph_traits<Graph>::vertex_descriptor v0 = g.add_vertex();
boost::graph_traits<Graph>::vertex_descriptor v1 = g.add_vertex();
boost::graph_traits<Graph>::vertex_descriptor v2 = g.add_vertex();
// Add edges
g.add_edge(v0, v1);
g.add_edge(v1, v2);
return 0;
}

View File

@@ -215,7 +215,7 @@ struct PropertyPrinter
template<class Val>
PropertyPrinter& operator () ( std::ostream& out, const Val& v )
{
typename property_map<Graph,Tag>::type ps = get(Tag(), *graph);
typename property_map<Graph,Tag>::const_type ps = get(Tag(), *graph);
out << ps[ v ] <<" ";
PropertyPrinter<Graph,Next> print(*graph);
print(out, v);

View File

@@ -158,6 +158,7 @@ namespace boost {
template <class Edge, class Graph>
void tree_edge(Edge e, const Graph& g) {
using boost::get;
m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
m_combine, m_compare);
@@ -173,6 +174,7 @@ namespace boost {
template <class Edge, class Graph>
void gray_target(Edge e, const Graph& g) {
using boost::get;
m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
m_combine, m_compare);
@@ -189,6 +191,7 @@ namespace boost {
template <class Edge, class Graph>
void black_target(Edge e, const Graph& g) {
using boost::get;
m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
m_combine, m_compare);

View File

@@ -28,17 +28,23 @@ namespace boost
{
template<typename ComponentMap, typename DiscoverTimeMap,
typename LowPointMap, typename PredecessorMap,
typename OutputIterator, typename Stack,
typename OutputIterator, typename Stack,
typename ArticulationVector, typename IndexMap,
typename DFSVisitor>
struct biconnected_components_visitor : public dfs_visitor<>
{
biconnected_components_visitor
(ComponentMap comp, std::size_t& c, DiscoverTimeMap dtm,
(ComponentMap comp, std::size_t& c,
std::size_t& children_of_root, DiscoverTimeMap dtm,
std::size_t& dfs_time, LowPointMap lowpt, PredecessorMap pred,
OutputIterator out, Stack& S, DFSVisitor vis)
: comp(comp), c(c), children_of_root(0), dtm(dtm),
dfs_time(dfs_time), lowpt(lowpt),
pred(pred), out(out), S(S), vis(vis) { }
OutputIterator out, Stack& S,
ArticulationVector& is_articulation_point, IndexMap index_map,
DFSVisitor vis)
: comp(comp), c(c), children_of_root(children_of_root),
dtm(dtm), dfs_time(dfs_time), lowpt(lowpt),
pred(pred), out(out), S(S),
is_articulation_point(is_articulation_point),
index_map(index_map), vis(vis) { }
template <typename Vertex, typename Graph>
void initialize_vertex(const Vertex& u, Graph& g)
@@ -89,8 +95,7 @@ namespace boost
typename boost::graph_traits<Graph>::vertex_descriptor src = source(e, g);
typename boost::graph_traits<Graph>::vertex_descriptor tgt = target(e, g);
if ( ( tgt != get(pred, src) || get(pred, src) == src ) &&
get(dtm, tgt) < get(dtm, src) ) {
if ( tgt != get(pred, src) ) {
S.push(e);
put(lowpt, src,
min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, src),
@@ -111,40 +116,41 @@ namespace boost
BOOST_USING_STD_MIN();
Vertex parent = get(pred, u);
if (parent == u) { // Root of tree is special
if (children_of_root >= 2) {
*out++ = u;
}
return;
}
put(lowpt, parent,
min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, parent),
is_articulation_point[get(index_map, u)] = (children_of_root > 1);
} else {
put(lowpt, parent,
min BOOST_PREVENT_MACRO_SUBSTITUTION(get(lowpt, parent),
get(lowpt, u)));
if ( get(lowpt, u) >= get(dtm, parent) ) {
if ( get(pred, parent) != parent ) {
*out++ = parent;
}
while ( get(dtm, source(S.top(), g)) >= get(dtm, u) ) {
if ( get(lowpt, u) >= get(dtm, parent) ) {
is_articulation_point[get(index_map, parent)] = true;
while ( get(dtm, source(S.top(), g)) >= get(dtm, u) ) {
put(comp, S.top(), c);
S.pop();
}
assert (source(S.top(), g) == parent);
assert (target(S.top(), g) == u);
put(comp, S.top(), c);
S.pop();
++c;
}
assert (source(S.top(), g) == parent);
assert (target(S.top(), g) == u);
put(comp, S.top(), c);
S.pop();
++c;
}
if ( is_articulation_point[get(index_map, u)] ) {
*out++ = u;
}
vis.finish_vertex(u, g);
}
ComponentMap comp;
std::size_t& c;
std::size_t children_of_root;
std::size_t& children_of_root;
DiscoverTimeMap dtm;
std::size_t& dfs_time;
LowPointMap lowpt;
PredecessorMap pred;
OutputIterator out;
Stack& S;
ArticulationVector& is_articulation_point;
IndexMap index_map;
DFSVisitor vis;
};
@@ -168,14 +174,16 @@ namespace boost
vertex_t> ));
std::size_t num_components = 0;
std::size_t children_of_root;
std::size_t dfs_time = 0;
std::stack<edge_t> S;
std::stack<edge_t> S;
std::vector<char> is_articulation_point(num_vertices(g));
biconnected_components_visitor<ComponentMap, DiscoverTimeMap,
LowPointMap, PredecessorMap, OutputIterator, std::stack<edge_t>,
DFSVisitor>
vis(comp, num_components, dtm, dfs_time, lowpt, pred, out,
S, dfs_vis);
biconnected_components_visitor<ComponentMap, DiscoverTimeMap,
LowPointMap, PredecessorMap, OutputIterator, std::stack<edge_t>,
std::vector<char>, VertexIndexMap, DFSVisitor>
vis(comp, num_components, children_of_root, dtm, dfs_time,
lowpt, pred, out, S, is_articulation_point, index_map, dfs_vis);
depth_first_search(g, visitor(vis).vertex_index_map(index_map));

View File

@@ -1134,7 +1134,6 @@ add_vertices(typename BOOST_DIR_CSR_GRAPH_TYPE::vertices_size_type count, BOOST_
Vertex old_num_verts_plus_one = g.m_forward.m_rowstart.size();
EdgeIndex numedges = g.m_forward.m_rowstart.back();
g.m_forward.m_rowstart.resize(old_num_verts_plus_one + count, numedges);
g.m_backward.m_rowstart.resize(old_num_verts_plus_one + count, numedges);
g.vertex_properties().resize(num_vertices(g));
return old_num_verts_plus_one - 1;
}

View File

@@ -60,6 +60,7 @@ count_starts
// Put the degree of each vertex v into m_rowstart[v + 1]
for (KeyIterator i = begin; i != end; ++i) {
if (key_filter(*i)) {
assert (key_transform(*i) < numkeys);
++starts[key_transform(*i) + 1];
}
}
@@ -99,6 +100,7 @@ histogram_sort(KeyIterator key_begin, KeyIterator key_end,
for (KeyIterator i = key_begin; i != key_end; ++i, ++v1i) {
if (key_filter(*i)) {
vertices_size_type source = key_transform(*i);
assert (source < numkeys);
EdgeIndex insert_pos = current_insert_positions[source];
++current_insert_positions[source];
values1_out[insert_pos] = *v1i;
@@ -137,6 +139,7 @@ histogram_sort(KeyIterator key_begin, KeyIterator key_end,
for (KeyIterator i = key_begin; i != key_end; ++i, ++v1i, ++v2i) {
if (key_filter(*i)) {
vertices_size_type source = key_transform(*i);
assert (source < numkeys);
EdgeIndex insert_pos = current_insert_positions[source];
++current_insert_positions[source];
values1_out[insert_pos] = *v1i;
@@ -163,6 +166,7 @@ histogram_sort_inplace(KeyIterator key_begin,
std::vector<EdgeIndex> insert_positions(rowstart, rowstart + numkeys);
// 2. Swap the sources and targets into place
for (size_t i = 0; i < rowstart[numkeys]; ++i) {
assert (key_transform(key_begin[i]) < numkeys);
// While edge i is not in the right bucket:
while (!(i >= rowstart[key_transform(key_begin[i])] && i < insert_positions[key_transform(key_begin[i])])) {
// Add a slot in the right bucket
@@ -197,6 +201,7 @@ histogram_sort_inplace(KeyIterator key_begin,
std::vector<EdgeIndex> insert_positions(rowstart, rowstart + numkeys);
// 2. Swap the sources and targets into place
for (size_t i = 0; i < rowstart[numkeys]; ++i) {
assert (key_transform(key_begin[i]) < numkeys);
// While edge i is not in the right bucket:
while (!(i >= rowstart[key_transform(key_begin[i])] && i < insert_positions[key_transform(key_begin[i])])) {
// Add a slot in the right bucket

View File

@@ -604,7 +604,9 @@ bool read_graphviz_spirit(MultiPassIterator begin, MultiPassIterator end,
scanner_t scan(begin, end, policies);
return p.parse(scan);
bool ok = p.parse(scan);
m_graph.finish_building_graph();
return ok;
}
} // namespace boost

View File

@@ -52,21 +52,21 @@ namespace boost {
// find minimum residual capacity along the augmenting path
FlowValue delta = (std::numeric_limits<FlowValue>::max)();
e = p[sink];
e = get(p, sink);
do {
BOOST_USING_STD_MIN();
delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, residual_capacity[e]);
delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, get(residual_capacity, e));
u = source(e, g);
e = p[u];
e = get(p, u);
} while (u != src);
// push delta units of flow along the augmenting path
e = p[sink];
e = get(p, sink);
do {
residual_capacity[e] -= delta;
residual_capacity[reverse_edge[e]] += delta;
put(residual_capacity, e, get(residual_capacity, e) - delta);
put(residual_capacity, get(reverse_edge, e), get(residual_capacity, get(reverse_edge, e)) + delta);
u = source(e, g);
e = p[u];
e = get(p, u);
} while (u != src);
}
@@ -94,22 +94,22 @@ namespace boost {
typename graph_traits<Graph>::out_edge_iterator ei, e_end;
for (boost::tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter)
for (boost::tie(ei, e_end) = out_edges(*u_iter, g); ei != e_end; ++ei)
res[*ei] = cap[*ei];
put(res, *ei, get(cap, *ei));
color[sink] = Color::gray();
while (color[sink] != Color::white()) {
put(color, sink, Color::gray());
while (get(color, sink) != Color::white()) {
boost::queue<vertex_t> Q;
breadth_first_search
(detail::residual_graph(g, res), src, Q,
make_bfs_visitor(record_edge_predecessors(pred, on_tree_edge())),
color);
if (color[sink] != Color::white())
if (get(color, sink) != Color::white())
detail::augment(g, src, sink, pred, res, rev);
} // while
typename property_traits<CapacityEdgeMap>::value_type flow = 0;
for (boost::tie(ei, e_end) = out_edges(src, g); ei != e_end; ++ei)
flow += (cap[*ei] - res[*ei]);
flow += (get(cap, *ei) - get(res, *ei));
return flow;
} // edmonds_karp_max_flow()

View File

@@ -262,7 +262,7 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index,
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
{
std::string key_id = "key" + lexical_cast<std::string>(key_count++);
if (i->second->key() == typeid(Graph))
if (i->second->key() == typeid(Graph*))
graph_key_ids[i->first] = key_id;
else if (i->second->key() == typeid(vertex_descriptor))
vertex_key_ids[i->first] = key_id;
@@ -273,7 +273,7 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index,
std::string type_name = "string";
mpl::for_each<value_types>(get_type_name<value_types>(i->second->value(), type_names, type_name));
out << " <key id=\"" << encode_char_entities(key_id) << "\" for=\""
<< (i->second->key() == typeid(Graph) ? "graph" : (i->second->key() == typeid(vertex_descriptor) ? "node" : "edge")) << "\""
<< (i->second->key() == typeid(Graph*) ? "graph" : (i->second->key() == typeid(vertex_descriptor) ? "node" : "edge")) << "\""
<< " attr.name=\"" << i->first << "\""
<< " attr.type=\"" << type_name << "\""
<< " />\n";
@@ -287,10 +287,12 @@ write_graphml(std::ostream& out, const Graph& g, VertexIndexMap vertex_index,
// Output graph data
for (dynamic_properties::const_iterator i = dp.begin(); i != dp.end(); ++i)
{
if (i->second->key() == typeid(Graph))
if (i->second->key() == typeid(Graph*))
{
// The const_cast here is just to get typeid correct for property
// map key; the graph should not be mutated using it.
out << " <data key=\"" << graph_key_ids[i->first] << "\">"
<< encode_char_entities(i->second->get_string(g)) << "</data>\n";
<< encode_char_entities(i->second->get_string(const_cast<Graph*>(&g))) << "</data>\n";
}
}

View File

@@ -25,10 +25,15 @@
#include <boost/property_map/dynamic_property_map.hpp>
#include <boost/graph/overloading.hpp>
#include <boost/graph/dll_import_export.hpp>
#include <boost/graph/compressed_sparse_row_graph.hpp>
#include <boost/graph/iteration_macros.hpp>
#include <boost/spirit/include/classic_multi_pass.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/static_assert.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/xpressive/xpressive_static.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/foreach.hpp>
namespace boost {
@@ -713,6 +718,9 @@ class mutate_graph
virtual void // RG: need new second parameter to support BGL subgraphs
set_graph_property(const id_t& key, const id_t& value) = 0;
virtual void
finish_building_graph() = 0;
};
template<typename MutableGraph>
@@ -781,6 +789,8 @@ class mutate_graph_impl : public mutate_graph
put(key, dp_, &graph_, value);
}
void finish_building_graph() {}
protected:
MutableGraph& graph_;
@@ -790,6 +800,109 @@ class mutate_graph_impl : public mutate_graph
std::map<edge_t, bgl_edge_t> bgl_edges;
};
template<typename Directed,
typename VertexProperty,
typename EdgeProperty,
typename GraphProperty,
typename Vertex,
typename EdgeIndex>
class mutate_graph_impl<compressed_sparse_row_graph<Directed, VertexProperty, EdgeProperty, GraphProperty, Vertex, EdgeIndex> >
: public mutate_graph
{
typedef compressed_sparse_row_graph<Directed, VertexProperty, EdgeProperty, GraphProperty, Vertex, EdgeIndex> CSRGraph;
typedef typename graph_traits<CSRGraph>::vertices_size_type bgl_vertex_t;
typedef typename graph_traits<CSRGraph>::edges_size_type bgl_edge_t;
typedef typename graph_traits<CSRGraph>::edge_descriptor edge_descriptor;
public:
mutate_graph_impl(CSRGraph& graph, dynamic_properties& dp,
std::string node_id_prop)
: graph_(graph), dp_(dp), vertex_count(0), node_id_prop_(node_id_prop) { }
~mutate_graph_impl() {}
void finish_building_graph() {
typedef compressed_sparse_row_graph<directedS, no_property, bgl_edge_t, GraphProperty, Vertex, EdgeIndex> TempCSRGraph;
TempCSRGraph temp(edges_are_unsorted_multi_pass,
edges_to_add.begin(), edges_to_add.end(),
counting_iterator<bgl_edge_t>(0),
vertex_count);
set_property(temp, graph_all, get_property(graph_, graph_all));
graph_.assign(temp); // Copies structure, not properties
std::vector<edge_descriptor> edge_permutation_from_sorting(num_edges(temp));
BGL_FORALL_EDGES_T(e, temp, TempCSRGraph) {
edge_permutation_from_sorting[temp[e]] = e;
}
typedef tuple<id_t, bgl_vertex_t, id_t> v_prop;
BOOST_FOREACH(const v_prop& t, vertex_props) {
put(get<0>(t), dp_, get<1>(t), get<2>(t));
}
typedef tuple<id_t, bgl_edge_t, id_t> e_prop;
BOOST_FOREACH(const e_prop& t, edge_props) {
put(get<0>(t), dp_, edge_permutation_from_sorting[get<1>(t)], get<2>(t));
}
}
bool is_directed() const
{
return
boost::is_convertible<
typename boost::graph_traits<CSRGraph>::directed_category,
boost::directed_tag>::value;
}
virtual void do_add_vertex(const node_t& node)
{
// Add the node to the graph.
bgl_vertex_t v = vertex_count++;
// Set up a mapping from name to BGL vertex.
bgl_nodes.insert(std::make_pair(node, v));
// node_id_prop_ allows the caller to see the real id names for nodes.
vertex_props.push_back(make_tuple(node_id_prop_, v, node));
}
void
do_add_edge(const edge_t& edge, const node_t& source, const node_t& target)
{
bgl_edge_t result = edges_to_add.size();
edges_to_add.push_back(std::make_pair(bgl_nodes[source], bgl_nodes[target]));
bgl_edges.insert(std::make_pair(edge, result));
}
void
set_node_property(const id_t& key, const node_t& node, const id_t& value)
{
vertex_props.push_back(make_tuple(key, bgl_nodes[node], value));
}
void
set_edge_property(const id_t& key, const edge_t& edge, const id_t& value)
{
edge_props.push_back(make_tuple(key, bgl_edges[edge], value));
}
void
set_graph_property(const id_t& key, const id_t& value)
{
/* RG: pointer to graph prevents copying */
put(key, dp_, &graph_, value);
}
protected:
CSRGraph& graph_;
dynamic_properties& dp_;
bgl_vertex_t vertex_count;
std::string node_id_prop_;
std::vector<tuple<id_t, bgl_vertex_t, id_t> > vertex_props;
std::vector<tuple<id_t, bgl_edge_t, id_t> > edge_props;
std::vector<std::pair<bgl_vertex_t, bgl_vertex_t> > edges_to_add;
std::map<node_t, bgl_vertex_t> bgl_nodes;
std::map<edge_t, bgl_edge_t> bgl_edges;
};
} } } // end namespace boost::detail::graph
#ifdef BOOST_GRAPH_USE_SPIRIT_PARSER

View File

@@ -11,6 +11,7 @@
#include <iterator>
#include <algorithm>
#include <boost/config.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/utility.hpp>
#include <boost/detail/algorithm.hpp>
@@ -195,69 +196,123 @@ namespace boost {
}
private:
struct match_continuation {
enum {pos_G2_vertex_loop, pos_fi_adj_loop, pos_dfs_num} position;
typedef typename graph_traits<Graph2>::vertex_iterator vertex_iterator;
std::pair<vertex_iterator, vertex_iterator> G2_verts;
typedef typename graph_traits<Graph2>::adjacency_iterator adjacency_iterator;
std::pair<adjacency_iterator, adjacency_iterator> fi_adj;
edge_iter iter;
int dfs_num_k;
};
bool match(edge_iter iter, int dfs_num_k)
{
std::vector<match_continuation> k;
typedef typename graph_traits<Graph2>::vertex_iterator vertex_iterator;
std::pair<vertex_iterator, vertex_iterator> G2_verts(vertices(G2));
typedef typename graph_traits<Graph2>::adjacency_iterator adjacency_iterator;
std::pair<adjacency_iterator, adjacency_iterator> fi_adj;
vertex1_t i, j;
recur:
if (iter != ordered_edges.end()) {
vertex1_t i = source(*iter, G1), j = target(*iter, G2);
i = source(*iter, G1);
j = target(*iter, G2);
if (dfs_num[i] > dfs_num_k) {
vertex1_t kp1 = dfs_vertices[dfs_num_k + 1];
BGL_FORALL_VERTICES_T(u, G2, Graph2) {
if (invariant1(kp1) == invariant2(u) && in_S[u] == false) {
f[kp1] = u;
in_S[u] = true;
num_edges_on_k = 0;
if (match(iter, dfs_num_k + 1))
#if 0
// dwa 2003/7/11 -- this *HAS* to be a bug!
;
#endif
return true;
G2_verts = vertices(G2);
while (G2_verts.first != G2_verts.second) {
{
vertex2_t u = *G2_verts.first;
vertex1_t kp1 = dfs_vertices[dfs_num_k + 1];
if (invariant1(kp1) == invariant2(u) && in_S[u] == false) {
{
f[kp1] = u;
in_S[u] = true;
num_edges_on_k = 0;
in_S[u] = false;
match_continuation new_k;
new_k.position = match_continuation::pos_G2_vertex_loop;
new_k.G2_verts = G2_verts;
new_k.iter = iter;
new_k.dfs_num_k = dfs_num_k;
k.push_back(new_k);
++dfs_num_k;
goto recur;
}
}
}
G2_loop_k: ++G2_verts.first;
}
}
else if (dfs_num[j] > dfs_num_k) {
vertex1_t k = dfs_vertices[dfs_num_k];
num_edges_on_k -=
count_if(adjacent_vertices(f[k], G2), make_indirect_pmap(in_S));
for (int jj = 0; jj < dfs_num_k; ++jj) {
vertex1_t j = dfs_vertices[jj];
num_edges_on_k -= count(adjacent_vertices(f[j], G2), f[k]);
{
vertex1_t vk = dfs_vertices[dfs_num_k];
num_edges_on_k -=
count_if(adjacent_vertices(f[vk], G2), make_indirect_pmap(in_S));
for (int jj = 0; jj < dfs_num_k; ++jj) {
vertex1_t j = dfs_vertices[jj];
num_edges_on_k -= count(adjacent_vertices(f[j], G2), f[vk]);
}
}
if (num_edges_on_k != 0)
return false;
BGL_FORALL_ADJ_T(f[i], v, G2, Graph2)
if (invariant2(v) == invariant1(j) && in_S[v] == false) {
f[j] = v;
in_S[v] = true;
num_edges_on_k = 1;
BOOST_USING_STD_MAX();
int next_k = max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num_k, max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num[i], dfs_num[j]));
if (match(boost::next(iter), next_k))
return true;
in_S[v] = false;
goto return_point_false;
fi_adj = adjacent_vertices(f[i], G2);
while (fi_adj.first != fi_adj.second) {
{
vertex2_t v = *fi_adj.first;
if (invariant2(v) == invariant1(j) && in_S[v] == false) {
f[j] = v;
in_S[v] = true;
num_edges_on_k = 1;
BOOST_USING_STD_MAX();
int next_k = max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num_k, max BOOST_PREVENT_MACRO_SUBSTITUTION(dfs_num[i], dfs_num[j]));
match_continuation new_k;
new_k.position = match_continuation::pos_fi_adj_loop;
new_k.fi_adj = fi_adj;
new_k.iter = iter;
new_k.dfs_num_k = dfs_num_k;
++iter;
dfs_num_k = next_k;
k.push_back(new_k);
goto recur;
}
}
fi_adj_loop_k:++fi_adj.first;
}
}
else {
if (container_contains(adjacent_vertices(f[i], G2), f[j])) {
++num_edges_on_k;
if (match(boost::next(iter), dfs_num_k))
return true;
match_continuation new_k;
new_k.position = match_continuation::pos_dfs_num;
k.push_back(new_k);
++iter;
goto recur;
}
}
} else
return true;
return false;
}
goto return_point_true;
goto return_point_false;
{
return_point_true: return true;
return_point_false:
if (k.empty()) return false;
const match_continuation& this_k = k.back();
switch (this_k.position) {
case match_continuation::pos_G2_vertex_loop: {G2_verts = this_k.G2_verts; iter = this_k.iter; dfs_num_k = this_k.dfs_num_k; k.pop_back(); in_S[*G2_verts.first] = false; i = source(*iter, G1); j = target(*iter, G2); goto G2_loop_k;}
case match_continuation::pos_fi_adj_loop: {fi_adj = this_k.fi_adj; iter = this_k.iter; dfs_num_k = this_k.dfs_num_k; k.pop_back(); in_S[*fi_adj.first] = false; i = source(*iter, G1); j = target(*iter, G2); goto fi_adj_loop_k;}
case match_continuation::pos_dfs_num: {k.pop_back(); goto return_point_false;}
default: assert (!"Bad position"); abort();
}
}
}
};

View File

@@ -29,7 +29,7 @@ namespace boost
// The null_property_map<K,V> only has a put() function.
template <typename K, typename V>
void put(null_property_map<K,V>& pm, const K& key, const V& value)
void put(null_property_map<K,V>& /*pm*/, const K& /*key*/, const V& /*value*/)
{ }
// A helper function for intantiating null property maps.

View File

@@ -131,15 +131,29 @@ public:
// copy constructor
subgraph(const subgraph& x)
: m_graph(x.m_graph), m_parent(x.m_parent), m_edge_counter(x.m_edge_counter)
: m_parent(x.m_parent), m_edge_counter(x.m_edge_counter)
, m_global_vertex(x.m_global_vertex), m_global_edge(x.m_global_edge)
{
// Do a deep copy (recursive).
for(typename ChildrenList::const_iterator i = x.m_children.begin();
i != x.m_children.end(); ++i)
if(x.is_root())
{
m_children.push_back(new subgraph<Graph>( **i ));
m_graph = x.m_graph;
}
// Do a deep copy (recursive).
// Only the root graph is copied, the subgraphs contain
// only references to the global vertices they own.
typename subgraph<Graph>::children_iterator i,i_end;
boost::tie(i,i_end) = x.children();
for(; i != i_end; ++i)
{
subgraph<Graph> child = this->create_subgraph();
child = *i;
vertex_iterator vi,vi_end;
boost::tie(vi,vi_end) = vertices(*i);
for (;vi!=vi_end;++vi)
{
add_vertex(*vi,child);
}
}
}

View File

@@ -19,6 +19,7 @@
#include <vector>
#include <cstddef>
#include <boost/iterator.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/range/irange.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/property_map/property_map.hpp>
@@ -71,7 +72,7 @@ namespace boost {
out_edge_iterator;
typedef void in_edge_iterator;
typedef void edge_iterator;
typedef typename integer_range<V>::iterator vertex_iterator;
typedef counting_iterator<V> vertex_iterator;
typedef directed_tag directed_category;
typedef allow_parallel_edge_tag edge_parallel_category;
typedef vector_as_graph_traversal_tag traversal_category;
@@ -178,14 +179,11 @@ namespace boost {
// source() and target() already provided for pairs in graph_traits.hpp
template <class EdgeList, class Alloc>
std::pair<typename boost::integer_range<typename EdgeList::value_type>
::iterator,
typename boost::integer_range<typename EdgeList::value_type>
::iterator >
std::pair<boost::counting_iterator<typename EdgeList::value_type>,
boost::counting_iterator<typename EdgeList::value_type> >
vertices(const std::vector<EdgeList, Alloc>& v)
{
typedef typename boost::integer_range<typename EdgeList::value_type>
::iterator Iter;
typedef boost::counting_iterator<typename EdgeList::value_type> Iter;
return std::make_pair(Iter(0), Iter(v.size()));
}

View File

@@ -787,6 +787,7 @@ namespace read_graphviz_detail {
for (properties::const_iterator i = root_graph_props.begin(); i != root_graph_props.end(); ++i) {
mg->set_graph_property(i->first, i->second);
}
mg->finish_building_graph();
}
} // end namespace read_graphviz_detail

View File

@@ -17,6 +17,7 @@
#include <boost/graph/graphviz.hpp>
#include <boost/assign/std/map.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/compressed_sparse_row_graph.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
@@ -41,33 +42,46 @@ typedef std::pair<node_t,node_t> edge_t;
typedef std::map<node_t,float> mass_map_t;
typedef std::map<edge_t,double> weight_map_t;
template <typename Directedness, typename OutEdgeList>
template <typename graph_t, typename NameMap, typename MassMap, typename WeightMap>
bool test_graph(std::istream& dotfile, graph_t& graph,
std::size_t correct_num_vertices,
mass_map_t const& masses,
weight_map_t const& weights,
std::string const& node_id,
std::string const& g_name,
NameMap name,
MassMap mass,
WeightMap weight);
template <typename graph_t>
bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
mass_map_t const& masses,
weight_map_t const& weights,
std::string const& node_id = "node_id",
std::string const& g_name = std::string()) {
graph_t g;
return test_graph(dotfile, g, correct_num_vertices, masses, weights, node_id, g_name,
get(vertex_name, g), get(vertex_color, g), get(edge_weight, g));
}
template <typename graph_t, typename NameMap, typename MassMap, typename WeightMap>
bool test_graph(std::istream& dotfile, graph_t& graph,
std::size_t correct_num_vertices,
mass_map_t const& masses,
weight_map_t const& weights,
std::string const& node_id,
std::string const& g_name,
NameMap name,
MassMap mass,
WeightMap weight) {
typedef property < vertex_name_t, std::string,
property < vertex_color_t, float > > vertex_p;
typedef property < edge_weight_t, double > edge_p;
typedef property < graph_name_t, std::string > graph_p;
typedef adjacency_list < OutEdgeList, vecS, Directedness,
vertex_p, edge_p, graph_p > graph_t;
typedef typename graph_traits < graph_t >::edge_descriptor edge_t;
typedef typename graph_traits < graph_t >::vertex_descriptor vertex_t;
// Construct a graph and set up the dynamic_property_maps.
graph_t graph(0);
dynamic_properties dp(ignore_other_properties);
typename property_map<graph_t, vertex_name_t>::type name =
get(vertex_name, graph);
dp.property(node_id,name);
typename property_map<graph_t, vertex_color_t>::type mass =
get(vertex_color, graph);
dp.property("mass",mass);
typename property_map<graph_t, edge_weight_t>::type weight =
get(edge_weight, graph);
dp.property("weight",weight);
boost::ref_property_map<graph_t*,std::string> gname(
@@ -139,19 +153,31 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
typedef istringstream gs_t;
typedef property < vertex_name_t, std::string,
property < vertex_color_t, float > > vertex_p;
typedef property < edge_weight_t, double > edge_p;
typedef property < graph_name_t, std::string > graph_p;
struct vertex_p_bundled {std::string name; float color;};
struct edge_p_bundled {double weight;};
// Basic directed graph tests
BOOST_AUTO_TEST_CASE (basic_directed_graph_1) {
mass_map_t masses;
insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f);
gs_t gs("digraph { a node [mass = 7.7] c e [mass = 6.66] }");
BOOST_CHECK((test_graph<directedS,vecS>(gs,3,masses,weight_map_t())));
typedef adjacency_list < vecS, vecS, directedS,
vertex_p, edge_p, graph_p > graph_t;
BOOST_CHECK((test_graph<graph_t>(gs,3,masses,weight_map_t())));
}
BOOST_AUTO_TEST_CASE (basic_directed_graph_2) {
mass_map_t masses;
insert ( masses ) ("a",0.0f) ("e", 6.66f);
gs_t gs("digraph { a node [mass = 7.7] \"a\" e [mass = 6.66] }");
BOOST_CHECK((test_graph<directedS,vecS>(gs,2,masses,weight_map_t())));
typedef adjacency_list < vecS, vecS, directedS,
vertex_p, edge_p, graph_p > graph_t;
BOOST_CHECK((test_graph<graph_t>(gs,2,masses,weight_map_t())));
}
BOOST_AUTO_TEST_CASE (basic_directed_graph_3) {
@@ -162,7 +188,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
gs_t gs("digraph { a -> b eDge [weight = 7.7] "
"c -> d e-> f [weight = 6.66] "
"d ->e->a [weight=.5]}");
BOOST_CHECK((test_graph<directedS,vecS>(gs,6,mass_map_t(),weights)));
typedef adjacency_list < vecS, vecS, directedS,
vertex_p, edge_p, graph_p > graph_t;
BOOST_CHECK((test_graph<graph_t>(gs,6,mass_map_t(),weights)));
}
// undirected graph with alternate node_id property name
@@ -170,8 +198,10 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
mass_map_t masses;
insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f);
gs_t gs("graph { a node [mass = 7.7] c e [mass = 6.66] }");
BOOST_CHECK((test_graph<undirectedS,vecS>(gs,3,masses,weight_map_t(),
"nodenames")));
typedef adjacency_list < vecS, vecS, undirectedS,
vertex_p, edge_p, graph_p > graph_t;
BOOST_CHECK((test_graph<graph_t>(gs,3,masses,weight_map_t(),
"nodenames")));
}
// Basic undirected graph tests
@@ -179,7 +209,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
mass_map_t masses;
insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f);
gs_t gs("graph { a node [mass = 7.7] c e [mass =\\\n6.66] }");
BOOST_CHECK((test_graph<undirectedS,vecS>(gs,3,masses,weight_map_t())));
typedef adjacency_list < vecS, vecS, undirectedS,
vertex_p, edge_p, graph_p > graph_t;
BOOST_CHECK((test_graph<graph_t>(gs,3,masses,weight_map_t())));
}
BOOST_AUTO_TEST_CASE (basic_undirected_graph_2) {
@@ -188,7 +220,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
(make_pair("c","d"),7.7)(make_pair("e","f"),6.66);
gs_t gs("graph { a -- b eDge [weight = 7.7] "
"c -- d e -- f [weight = 6.66] }");
BOOST_CHECK((test_graph<undirectedS,vecS>(gs,6,mass_map_t(),weights)));
typedef adjacency_list < vecS, vecS, undirectedS,
vertex_p, edge_p, graph_p > graph_t;
BOOST_CHECK((test_graph<graph_t>(gs,6,mass_map_t(),weights)));
}
// Mismatch directed graph test
@@ -197,7 +231,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f);
gs_t gs("graph { a nodE [mass = 7.7] c e [mass = 6.66] }");
try {
test_graph<directedS,vecS>(gs,3,masses,weight_map_t());
typedef adjacency_list < vecS, vecS, directedS,
vertex_p, edge_p, graph_p > graph_t;
test_graph<graph_t>(gs,3,masses,weight_map_t());
BOOST_ERROR("Failed to throw boost::undirected_graph_error.");
} catch (boost::undirected_graph_error&) {
} catch (boost::directed_graph_error&) {
@@ -211,7 +247,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
insert ( masses ) ("a",0.0f) ("c",7.7f) ("e", 6.66f);
gs_t gs("digraph { a node [mass = 7.7] c e [mass = 6.66] }");
try {
test_graph<undirectedS,vecS>(gs,3,masses,weight_map_t());
typedef adjacency_list < vecS, vecS, undirectedS,
vertex_p, edge_p, graph_p > graph_t;
test_graph<graph_t>(gs,3,masses,weight_map_t());
BOOST_ERROR("Failed to throw boost::directed_graph_error.");
} catch (boost::directed_graph_error&) {}
}
@@ -223,7 +261,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
insert( weights )(make_pair("a","b"),7.7);
gs_t gs("diGraph { a -> b [weight = 7.7] a -> b [weight = 7.7] }");
try {
test_graph<directedS,setS>(gs,2,mass_map_t(),weights);
typedef adjacency_list < setS, vecS, directedS,
vertex_p, edge_p, graph_p > graph_t;
test_graph<graph_t>(gs,2,mass_map_t(),weights);
BOOST_ERROR("Failed to throw boost::bad_parallel_edge.");
} catch (boost::bad_parallel_edge&) {}
}
@@ -233,7 +273,9 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
weight_map_t weights;
insert( weights )(make_pair("a","b"),7.7);
gs_t gs("digraph { a -> b [weight = 7.7] a -> b [weight = 7.7] }");
BOOST_CHECK((test_graph<directedS,vecS>(gs,2,mass_map_t(),weights)));
typedef adjacency_list < vecS, vecS, directedS,
vertex_p, edge_p, graph_p > graph_t;
BOOST_CHECK((test_graph<graph_t>(gs,2,mass_map_t(),weights)));
}
// Graph Property Test 1
@@ -242,8 +284,10 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
insert ( masses ) ("a",0.0f) ("c",0.0f) ("e", 6.66f);
gs_t gs("digraph { graph [name=\"foo \\\"escaped\\\"\"] a c e [mass = 6.66] }");
std::string graph_name("foo \"escaped\"");
BOOST_CHECK((test_graph<directedS,vecS>(gs,3,masses,weight_map_t(),"",
graph_name)));
typedef adjacency_list < vecS, vecS, directedS,
vertex_p, edge_p, graph_p > graph_t;
BOOST_CHECK((test_graph<graph_t>(gs,3,masses,weight_map_t(),"",
graph_name)));
}
// Graph Property Test 2
@@ -252,8 +296,10 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
insert ( masses ) ("a",0.0f) ("c",0.0f) ("e", 6.66f);
gs_t gs("digraph { name=\"fo\"+ \"\\\no\" a c e [mass = 6.66] }");
std::string graph_name("foo");
BOOST_CHECK((test_graph<directedS,vecS>(gs,3,masses,weight_map_t(),"",
graph_name)));
typedef adjacency_list < vecS, vecS, directedS,
vertex_p, edge_p, graph_p > graph_t;
BOOST_CHECK((test_graph<graph_t>(gs,3,masses,weight_map_t(),"",
graph_name)));
}
// Graph Property Test 3 (HTML)
@@ -262,8 +308,10 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
insert ( masses ) ("a",0.0f) ("c",0.0f) ("e", 6.66f);
std::string graph_name = "<html title=\"x'\" title2='y\"'>foo<b><![CDATA[><bad tag&>]]>bar</b>\n<br/>\nbaz</html>";
gs_t gs("digraph { name=" + graph_name + " a c e [mass = 6.66] }");
BOOST_CHECK((test_graph<directedS,vecS>(gs,3,masses,weight_map_t(),"",
graph_name)));
typedef adjacency_list < vecS, vecS, directedS,
vertex_p, edge_p, graph_p > graph_t;
BOOST_CHECK((test_graph<graph_t>(gs,3,masses,weight_map_t(),"",
graph_name)));
}
// Comments embedded in strings
@@ -274,7 +322,40 @@ bool test_graph(std::istream& dotfile, std::size_t correct_num_vertices,
"a1 [ label = \"//depot/path/to/file_29#9\" ];"
"a0 -> a1 [ color=gray ];"
"}");
BOOST_CHECK((test_graph<directedS,vecS>(gs,2,mass_map_t(),weight_map_t())));
typedef adjacency_list < vecS, vecS, directedS,
vertex_p, edge_p, graph_p > graph_t;
BOOST_CHECK((test_graph<graph_t>(gs,2,mass_map_t(),weight_map_t())));
}
#if 0 // Currently broken
BOOST_AUTO_TEST_CASE (basic_csr_directed_graph) {
weight_map_t weights;
insert( weights )(make_pair("a","b"),0.0)
(make_pair("c","d"),7.7)(make_pair("e","f"),6.66)
(make_pair("d","e"),0.5)(make_pair("e","a"),0.5);
gs_t gs("digraph { a -> b eDge [weight = 7.7] "
"c -> d e-> f [weight = 6.66] "
"d ->e->a [weight=.5]}");
typedef compressed_sparse_row_graph<directedS, vertex_p_bundled, edge_p_bundled, graph_p > graph_t;
BOOST_CHECK((test_graph<graph_t>(gs,6,mass_map_t(),weights,"node_id","",&vertex_p_bundled::name,&vertex_p_bundled::color,&edge_p_bundled::weight)));
}
#endif
BOOST_AUTO_TEST_CASE (basic_csr_directed_graph_ext_props) {
weight_map_t weights;
insert( weights )(make_pair("a","b"),0.0)
(make_pair("c","d"),7.7)(make_pair("e","f"),6.66)
(make_pair("d","e"),0.5)(make_pair("e","a"),0.5);
gs_t gs("digraph { a -> b eDge [weight = 7.7] "
"c -> d e-> f [weight = 6.66] "
"d ->e->a [weight=.5]}");
typedef compressed_sparse_row_graph<directedS, no_property, no_property, graph_p > graph_t;
graph_t g;
vector_property_map<std::string, property_map<graph_t, vertex_index_t>::const_type> vertex_name(get(vertex_index, g));
vector_property_map<float, property_map<graph_t, vertex_index_t>::const_type> vertex_color(get(vertex_index, g));
vector_property_map<double, property_map<graph_t, edge_index_t>::const_type> edge_weight(get(edge_index, g));
BOOST_CHECK((test_graph(gs,g,6,mass_map_t(),weights,"node_id","",vertex_name,vertex_color,edge_weight)));
}
// return 0;
// }