mirror of
https://github.com/boostorg/graph.git
synced 2026-07-21 13:23:42 +00:00
adaptors ok
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/filtered_graph.hpp>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
|
||||
struct Road {
|
||||
int weight;
|
||||
};
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, no_property, Road>;
|
||||
using Edge = graph_traits<Graph>::edge_descriptor;
|
||||
|
||||
Graph g(4);
|
||||
add_edge(0, 1, Road{5}, g);
|
||||
add_edge(0, 2, Road{0}, g);
|
||||
add_edge(1, 3, Road{3}, g);
|
||||
add_edge(2, 3, Road{0}, g);
|
||||
|
||||
// Keep only edges with positive weight
|
||||
auto filter = [&g](Edge e) { return g[e].weight > 0; };
|
||||
filtered_graph<Graph, std::function<bool(Edge)>> fg(g, filter);
|
||||
|
||||
std::cout << "Original: " << num_edges(g) << " edges\n";
|
||||
for (auto ei = edges(g).first; ei != edges(g).second; ++ei) {
|
||||
std::cout << " " << source(*ei, g) << " -> " << target(*ei, g)
|
||||
<< " (weight=" << g[*ei].weight << ")\n";
|
||||
}
|
||||
|
||||
std::cout << "Filtered (weight > 0):\n";
|
||||
for (auto ei = edges(fg).first; ei != edges(fg).second; ++ei) {
|
||||
std::cout << " " << source(*ei, fg) << " -> " << target(*ei, fg)
|
||||
<< " (weight=" << fg[*ei].weight << ")\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#include <boost/graph/grid_graph.hpp>
|
||||
#include <boost/array.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = grid_graph<3>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
// 3x3x3 cube (no wrapping)
|
||||
boost::array<std::size_t, 3> lengths = {{ 3, 3, 3 }};
|
||||
Graph g(lengths);
|
||||
|
||||
std::cout << num_vertices(g) << " vertices, "
|
||||
<< num_edges(g) << " edges\n";
|
||||
|
||||
// Corner vertex: 3 neighbors. Center vertex: 6 neighbors.
|
||||
Vertex corner = vertex(0, g);
|
||||
Vertex center = {{ 1, 1, 1 }};
|
||||
std::cout << "corner (" << corner[0] << "," << corner[1] << ","
|
||||
<< corner[2] << ") degree=" << out_degree(corner, g) << "\n";
|
||||
std::cout << "center (" << center[0] << "," << center[1] << ","
|
||||
<< center[2] << ") degree=" << out_degree(center, g) << "\n";
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#include <boost/graph/grid_graph.hpp>
|
||||
#include <boost/array.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = grid_graph<2>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
// 4x3 cylinder: dimension 0 wraps, dimension 1 does not
|
||||
boost::array<std::size_t, 2> lengths = {{ 4, 3 }};
|
||||
boost::array<bool, 2> wrap = {{ true, false }};
|
||||
Graph g(lengths, wrap);
|
||||
|
||||
std::cout << num_vertices(g) << " vertices, "
|
||||
<< num_edges(g) << " edges\n";
|
||||
|
||||
// Navigate: wrapping in dimension 0
|
||||
Vertex corner = vertex(0, g);
|
||||
Vertex wrapped = g.previous(corner, 0); // wraps to (3,0)
|
||||
std::cout << "\nFrom (" << corner[0] << "," << corner[1] << "):\n";
|
||||
std::cout << " previous in dim 0 (wraps) = ("
|
||||
<< wrapped[0] << "," << wrapped[1] << ")\n";
|
||||
|
||||
// Navigate: no wrapping in dimension 1
|
||||
Vertex same = g.previous(corner, 1); // stays at (0,0)
|
||||
std::cout << " previous in dim 1 (stops) = ("
|
||||
<< same[0] << "," << same[1] << ")\n";
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <boost/graph/grid_graph.hpp>
|
||||
#include <boost/array.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = grid_graph<2>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
// 3x3 torus (all dimensions wrap)
|
||||
boost::array<std::size_t, 2> lengths = {{ 3, 3 }};
|
||||
Graph g(lengths, true);
|
||||
|
||||
std::cout << num_vertices(g) << " vertices, "
|
||||
<< num_edges(g) << " edges\n";
|
||||
|
||||
// Every vertex has exactly 4 neighbors on a torus
|
||||
for (auto vi = vertices(g).first; vi != vertices(g).second; ++vi) {
|
||||
Vertex v = *vi;
|
||||
std::cout << "(" << v[0] << "," << v[1] << ") degree="
|
||||
<< out_degree(v, g) << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#include <boost/graph/grid_graph.hpp>
|
||||
#include <boost/array.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = grid_graph<2>;
|
||||
using Vertex = graph_traits<Graph>::vertex_descriptor;
|
||||
|
||||
// 3x3 flat grid (no wrapping)
|
||||
boost::array<std::size_t, 2> lengths = {{ 3, 3 }};
|
||||
Graph g(lengths);
|
||||
|
||||
std::cout << num_vertices(g) << " vertices, "
|
||||
<< num_edges(g) << " edges\n";
|
||||
|
||||
// Corner vertex has 2 neighbors, edge vertex has 3, center has 4
|
||||
for (auto vi = vertices(g).first; vi != vertices(g).second; ++vi) {
|
||||
Vertex v = *vi;
|
||||
std::cout << "(" << v[0] << "," << v[1] << ") degree="
|
||||
<< out_degree(v, g) << "\n";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/reverse_graph.hpp>
|
||||
#include <boost/graph/graph_utility.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, bidirectionalS>;
|
||||
|
||||
Graph g(4);
|
||||
add_edge(0, 1, g);
|
||||
add_edge(1, 2, g);
|
||||
add_edge(2, 3, g);
|
||||
add_edge(3, 0, g);
|
||||
|
||||
std::cout << "Original:\n";
|
||||
print_graph(g);
|
||||
|
||||
std::cout << "\nReversed:\n";
|
||||
print_graph(make_reverse_graph(g));
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#include <boost/graph/adjacency_list.hpp>
|
||||
#include <boost/graph/subgraph.hpp>
|
||||
#include <iostream>
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
// subgraph requires edge_index_t as an internal property tag
|
||||
using Graph = subgraph<adjacency_list<vecS, vecS, directedS,
|
||||
no_property, property<edge_index_t, int>>>;
|
||||
|
||||
// Root graph: 5 vertices, 6 edges
|
||||
Graph root(5);
|
||||
add_edge(0, 1, root);
|
||||
add_edge(1, 2, root);
|
||||
add_edge(2, 3, root);
|
||||
add_edge(3, 4, root);
|
||||
add_edge(4, 0, root);
|
||||
add_edge(1, 3, root);
|
||||
|
||||
// Create a subgraph containing vertices {1, 2, 3}
|
||||
Graph& sub = root.create_subgraph();
|
||||
add_vertex(1, sub); // global vertex 1
|
||||
add_vertex(2, sub); // global vertex 2
|
||||
add_vertex(3, sub); // global vertex 3
|
||||
|
||||
std::cout << "Root: " << num_vertices(root) << " vertices, "
|
||||
<< num_edges(root) << " edges\n";
|
||||
std::cout << "Subgraph: " << num_vertices(sub) << " vertices, "
|
||||
<< num_edges(sub) << " edges\n\n";
|
||||
|
||||
std::cout << "Subgraph edges (local descriptors):\n";
|
||||
for (auto ei = edges(sub).first; ei != edges(sub).second; ++ei) {
|
||||
auto s = sub.local_to_global(source(*ei, sub));
|
||||
auto t = sub.local_to_global(target(*ei, sub));
|
||||
std::cout << " " << s << " -> " << t << "\n";
|
||||
}
|
||||
}
|
||||
@@ -3,24 +3,25 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
struct City { std::string name; };
|
||||
struct Road { int weight; };
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS,
|
||||
property<vertex_name_t, std::string>,
|
||||
property<edge_weight_t, int>>;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, City, Road>;
|
||||
|
||||
// --- Write ---
|
||||
Graph g(3);
|
||||
add_edge(0, 1, {10}, g);
|
||||
add_edge(1, 2, {20}, g);
|
||||
add_edge(0, 2, {30}, g);
|
||||
put(vertex_name, g, 0, "Paris");
|
||||
put(vertex_name, g, 1, "Lyon");
|
||||
put(vertex_name, g, 2, "Marseille");
|
||||
g[0].name = "Paris";
|
||||
g[1].name = "Lyon";
|
||||
g[2].name = "Marseille";
|
||||
add_edge(0, 1, Road{10}, g);
|
||||
add_edge(1, 2, Road{20}, g);
|
||||
add_edge(0, 2, Road{30}, g);
|
||||
|
||||
dynamic_properties dp;
|
||||
dp.property("name", get(vertex_name, g));
|
||||
dp.property("weight", get(edge_weight, g));
|
||||
dp.property("name", get(&City::name, g));
|
||||
dp.property("weight", get(&Road::weight, g));
|
||||
|
||||
std::ostringstream xml;
|
||||
write_graphml(xml, g, dp, true);
|
||||
@@ -29,8 +30,8 @@ int main() {
|
||||
// --- Read back ---
|
||||
Graph g2;
|
||||
dynamic_properties dp2;
|
||||
dp2.property("name", get(vertex_name, g2));
|
||||
dp2.property("weight", get(edge_weight, g2));
|
||||
dp2.property("name", get(&City::name, g2));
|
||||
dp2.property("weight", get(&Road::weight, g2));
|
||||
|
||||
std::istringstream in(xml.str());
|
||||
read_graphml(in, g2, dp2);
|
||||
@@ -39,6 +40,6 @@ int main() {
|
||||
std::cout << num_vertices(g2) << " vertices, "
|
||||
<< num_edges(g2) << " edges\n";
|
||||
for (auto v : make_iterator_range(vertices(g2))) {
|
||||
std::cout << " " << get(vertex_name, g2, v) << "\n";
|
||||
std::cout << " " << g2[v].name << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,24 +3,25 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
struct City { std::string name; };
|
||||
struct Road { double weight; };
|
||||
|
||||
int main() {
|
||||
using namespace boost;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS,
|
||||
property<vertex_name_t, std::string>,
|
||||
property<edge_weight_t, double>>;
|
||||
using Graph = adjacency_list<vecS, vecS, directedS, City, Road>;
|
||||
|
||||
// --- Write ---
|
||||
Graph g(3);
|
||||
add_edge(0, 1, {1.5}, g);
|
||||
add_edge(1, 2, {2.5}, g);
|
||||
add_edge(0, 2, {4.0}, g);
|
||||
put(vertex_name, g, 0, "A");
|
||||
put(vertex_name, g, 1, "B");
|
||||
put(vertex_name, g, 2, "C");
|
||||
g[0].name = "A";
|
||||
g[1].name = "B";
|
||||
g[2].name = "C";
|
||||
add_edge(0, 1, Road{1.5}, g);
|
||||
add_edge(1, 2, Road{2.5}, g);
|
||||
add_edge(0, 2, Road{4.0}, g);
|
||||
|
||||
dynamic_properties dp;
|
||||
dp.property("node_id", get(vertex_name, g));
|
||||
dp.property("weight", get(edge_weight, g));
|
||||
dp.property("node_id", get(&City::name, g));
|
||||
dp.property("weight", get(&Road::weight, g));
|
||||
|
||||
std::ostringstream dot;
|
||||
write_graphviz_dp(dot, g, dp, "node_id");
|
||||
@@ -29,8 +30,8 @@ int main() {
|
||||
// --- Read back ---
|
||||
Graph g2;
|
||||
dynamic_properties dp2;
|
||||
dp2.property("node_id", get(vertex_name, g2));
|
||||
dp2.property("weight", get(edge_weight, g2));
|
||||
dp2.property("node_id", get(&City::name, g2));
|
||||
dp2.property("weight", get(&Road::weight, g2));
|
||||
|
||||
std::istringstream in(dot.str());
|
||||
read_graphviz(in, g2, dp2, "node_id");
|
||||
|
||||
@@ -170,11 +170,11 @@
|
||||
** xref:io/graphml.adoc[GraphML]
|
||||
** xref:io/dimacs.adoc[DIMACS]
|
||||
* Graph Adaptors
|
||||
** xref:adaptors/subgraph.adoc[subgraph]
|
||||
** xref:adaptors/edge_list.adoc[Edge List]
|
||||
** xref:adaptors/reverse_graph.adoc[Reverse Graph]
|
||||
** xref:adaptors/overview.adoc[Overview]
|
||||
** xref:adaptors/filtered_graph.adoc[Filtered Graph]
|
||||
** xref:adaptors/stanford_graph.adoc[Stanford GraphBase]
|
||||
** xref:adaptors/reverse_graph.adoc[Reverse Graph]
|
||||
** xref:adaptors/subgraph.adoc[Subgraph]
|
||||
** xref:adaptors/edge_list.adoc[Edge List]
|
||||
** xref:adaptors/grid_graph.adoc[Grid Graph]
|
||||
* Traits and Iterators
|
||||
** xref:traits/graph_traits.adoc[Graph Traits]
|
||||
|
||||
@@ -1,157 +1,108 @@
|
||||
[#sec:edge-list-class]
|
||||
= Edge List Class
|
||||
= Edge List
|
||||
|
||||
....
|
||||
Turns a pair of edge iterators into an EdgeListGraph. Minimal adaptor providing
|
||||
only `edges()`, `source()`, and `target()`.
|
||||
|
||||
edge_list<EdgeIterator, ValueType, DiffType>
|
||||
....
|
||||
*Defined in:* `<boost/graph/edge_list.hpp>` +
|
||||
*Models:* EdgeListGraph only
|
||||
|
||||
The `edge_list` class is an adaptor that turns a pair of edge
|
||||
iterators into a class that models `EdgeListGraph`. The `value_type`
|
||||
of the edge iterator must be a `std::pair` (or at least have `first` and
|
||||
`second` members). The `first_type` and `second_type` of the
|
||||
pair must be the same and they will be used for the graph's
|
||||
`vertex_descriptor`. The `ValueType` and `DiffType` template
|
||||
parameters are only needed if your compiler does not support partial
|
||||
specialization. Otherwise they default to the correct types.
|
||||
WARNING: `edge_list` does not model VertexListGraph, IncidenceGraph, or
|
||||
AdjacencyGraph. Most BGL algorithms (BFS, DFS, Dijkstra, etc.) cannot be used
|
||||
with it. It works with algorithms that only need edge iteration, such as
|
||||
`bellman_ford_shortest_paths` and `kruskal_minimum_spanning_tree`.
|
||||
|
||||
==== Example
|
||||
|
||||
Applying the Bellman-Ford shortest paths algorithm to an
|
||||
`edge_list`.
|
||||
== Example
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
enum { u, v, x, y, z, N };
|
||||
char name[] = { 'u', 'v', 'x', 'y', 'z' };
|
||||
|
||||
enum { u, v, x, y, z, N };
|
||||
char name[] = { 'u', 'v', 'x', 'y', 'z' };
|
||||
using E = std::pair<int, int>;
|
||||
E edges[] = { E(u,y), E(u,x), E(u,v),
|
||||
E(v,u),
|
||||
E(x,y), E(x,v),
|
||||
E(y,v), E(y,z),
|
||||
E(z,u), E(z,x) };
|
||||
|
||||
typedef std::pair<int,int> E;
|
||||
E edges[] = { E(u,y), E(u,x), E(u,v),
|
||||
E(v,u),
|
||||
E(x,y), E(x,v),
|
||||
E(y,v), E(y,z),
|
||||
E(z,u), E(z,x) };
|
||||
|
||||
int weight[] = { -4, 8, 5,
|
||||
-2,
|
||||
9, -3,
|
||||
7, 2,
|
||||
6, 7 };
|
||||
|
||||
typedef boost::edge_list<E*> Graph;
|
||||
Graph g(edges, edges + sizeof(edges) / sizeof(E));
|
||||
|
||||
std::vector<int> distance(N, std::numeric_limits<short>::max());
|
||||
std::vector<int> parent(N,-1);
|
||||
|
||||
distance[z] = 0;
|
||||
parent[z] = z;
|
||||
bool r = boost::bellman_ford_shortest_paths(g, int(N), weight,
|
||||
distance.begin(),
|
||||
parent.begin());
|
||||
if (r)
|
||||
for (int i = 0; i < N; ++i)
|
||||
std::cout << name[i] << ": " << distance[i]
|
||||
<< " " << name[parent[i]] << std::endl;
|
||||
else
|
||||
std::cout << "negative cycle" << std::endl;
|
||||
boost::edge_list<E*> g(edges, edges + 10);
|
||||
----
|
||||
|
||||
The output is the distance from the root and the parent of each vertex
|
||||
in the shortest paths tree.
|
||||
== Synopsis
|
||||
|
||||
....
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename EdgeIterator,
|
||||
typename ValueType = std::iterator_traits<EdgeIterator>::value_type,
|
||||
typename DiffType = std::iterator_traits<EdgeIterator>::difference_type>
|
||||
class edge_list;
|
||||
----
|
||||
|
||||
u: 2 v
|
||||
v: 4 x
|
||||
x: 7 z
|
||||
y: -2 u
|
||||
z: 0 z
|
||||
....
|
||||
The `value_type` of the edge iterator must be a `std::pair` (or have `first`
|
||||
and `second` members). Both members must be the same type, used as vertex
|
||||
descriptors. The `ValueType` and `DiffType` parameters are only needed for
|
||||
compilers without partial specialization support.
|
||||
|
||||
==== Where Defined
|
||||
== Template Parameters
|
||||
|
||||
link:../../../boost/graph/edge_list.hpp[`boost/graph/edge_list.hpp`]
|
||||
|
||||
==== Template Parameters
|
||||
|
||||
[width="100%",cols="50%,50%",options="header",]
|
||||
[cols="1,3,1",options="header"]
|
||||
|===
|
||||
|Parameter |Description
|
||||
|`EdgeIterator` |Must be model of
|
||||
http://www.boost.org/sgi/stl/InputIterator.html[InputIterator] who's
|
||||
`value_type` must be a pair of vertex descriptors.
|
||||
| Parameter | Description | Default
|
||||
|
||||
|`ValueType` |The `value_type` of the `EdgeIterator`. +
|
||||
Default:
|
||||
`std::iterator_traits<EdgeIterator>::value_type`
|
||||
| `EdgeIterator`
|
||||
| Must model InputIterator. `value_type` must be a pair of vertex descriptors.
|
||||
|
|
||||
|
||||
|`DiffType` |The `difference_type` of the `EdgeIterator`. +
|
||||
Default:
|
||||
`std::iterator_traits<EdgeIterator>::difference_type`
|
||||
| `ValueType`
|
||||
| The `value_type` of `EdgeIterator`.
|
||||
| `std::iterator_traits<EdgeIterator>::value_type`
|
||||
|
||||
| `DiffType`
|
||||
| The `difference_type` of `EdgeIterator`.
|
||||
| `std::iterator_traits<EdgeIterator>::difference_type`
|
||||
|===
|
||||
|
||||
==== Model of
|
||||
== Member Functions
|
||||
|
||||
xref:concepts/EdgeListGraph.adoc[EdgeListGraph]
|
||||
[source,cpp]
|
||||
----
|
||||
edge_list(EdgeIterator first, EdgeIterator last);
|
||||
----
|
||||
|
||||
==== Associated Types
|
||||
Create a graph from the edge range `[first, last)`.
|
||||
|
||||
'''''
|
||||
== Non-Member Functions
|
||||
|
||||
`boost::graph_traits<edge_list>::vertex_descriptor` +
|
||||
+
|
||||
The type for the vertex descriptors associated with the `edge_list`.
|
||||
This will be the same type as
|
||||
`std::iterator_traits<EdgeIterator>::value_type::first_type`.
|
||||
[source,cpp]
|
||||
----
|
||||
std::pair<edge_iterator, edge_iterator>
|
||||
edges(const edge_list& g);
|
||||
----
|
||||
|
||||
'''''
|
||||
Returns an iterator-range for the edge set.
|
||||
|
||||
` boost::graph_traits<edge_list>::edge_descriptor ` +
|
||||
+
|
||||
The type for the edge descriptors associated with the `edge_list`.
|
||||
'''
|
||||
|
||||
'''''
|
||||
[source,cpp]
|
||||
----
|
||||
vertex_descriptor source(edge_descriptor e, const edge_list& g);
|
||||
vertex_descriptor target(edge_descriptor e, const edge_list& g);
|
||||
----
|
||||
|
||||
` boost::graph_traits<edge_list>::edge_iterator ` +
|
||||
+
|
||||
The type for the iterators returned by `edges()`. The iterator category
|
||||
of the `edge_iterator` will be the same as that of the
|
||||
`EdgeIterator`.
|
||||
Returns the source/target vertex of edge `e`.
|
||||
|
||||
'''''
|
||||
== Associated Types
|
||||
|
||||
==== Member Functions
|
||||
[cols="1,3",options="header"]
|
||||
|===
|
||||
| Type | Description
|
||||
|
||||
'''''
|
||||
| `vertex_descriptor`
|
||||
| Same as `std::iterator_traits<EdgeIterator>::value_type::first_type`.
|
||||
|
||||
` edge_list(EdgeIterator first, EdgeIterator last) ` +
|
||||
+
|
||||
Creates a graph object with `n` vertices and with the edges specified in
|
||||
the edge list given by the range `[first,last)`.
|
||||
| `edge_descriptor`
|
||||
| Internal edge descriptor type.
|
||||
|
||||
'''''
|
||||
|
||||
==== Non-Member Functions
|
||||
|
||||
'''''
|
||||
|
||||
` std::pair<edge_iterator, edge_iterator>` +
|
||||
`edges(const edge_list& g) ` +
|
||||
+
|
||||
Returns an iterator-range providing access to the edge set of graph `g`.
|
||||
|
||||
'''''
|
||||
|
||||
` vertex_descriptor` +
|
||||
`source(edge_descriptor e, const edge_list& g) ` +
|
||||
+
|
||||
Returns the source vertex of edge `e`.
|
||||
|
||||
'''''
|
||||
|
||||
` vertex_descriptor` +
|
||||
`target(edge_descriptor e, const edge_list& g) ` +
|
||||
+
|
||||
Returns the target vertex of edge `e`.
|
||||
| `edge_iterator`
|
||||
| Same iterator category as `EdgeIterator`.
|
||||
|===
|
||||
|
||||
@@ -1,522 +1,299 @@
|
||||
[#sec:filtered-graph-class]
|
||||
= Filtered Graph
|
||||
|
||||
....
|
||||
A view of a graph that hides vertices and/or edges based on predicate functions.
|
||||
|
||||
filtered_graph<Graph, EdgePredicate, VertexPredicate>
|
||||
....
|
||||
*Defined in:* `<boost/graph/filtered_graph.hpp>` +
|
||||
*Models:* same concepts as the underlying graph (VertexListGraph, EdgeListGraph,
|
||||
IncidenceGraph, BidirectionalGraph, PropertyGraph, etc.)
|
||||
|
||||
The `filtered_graph` class template is an adaptor that creates a
|
||||
filtered view of a graph. The predicate function objects determine which
|
||||
edges and vertices of the original graph will show up in the filtered
|
||||
graph. If the edge predicate returns `true` for an edge then it shows up
|
||||
in the filtered graph, and if the predicate returns `false` then the
|
||||
edge does not appear in the filtered graph. Likewise for vertices. The
|
||||
`filtered_graph` class does not create a copy of the original graph,
|
||||
but uses a reference to the original graph. The lifetime of the original
|
||||
graph must extend past any use of the filtered graph. The filtered graph
|
||||
does not change the structure of the original graph, though vertex and
|
||||
edge properties of the original graph can be changed through property
|
||||
maps of the filtered graph. Vertex and edge descriptors of the filtered
|
||||
graph are the same as, and interchangeable with, the vertex and edge
|
||||
descriptors of the original graph.
|
||||
WARNING: `num_vertices()` and `num_edges()` return counts from the _underlying_
|
||||
graph, not the filtered view. This means
|
||||
`std::distance(vertices(fg).first, vertices(fg).second) != num_vertices(fg)`.
|
||||
This is by design: computing filtered counts would be O(V) instead of O(1), and
|
||||
the vertex/edge indices would no longer fall in the range `[0, num_vertices(g))`
|
||||
which many algorithms assume. Some algorithms (e.g. `vf2_sub_graph_iso`) have
|
||||
been specifically patched to use `std::distance` instead of `num_vertices`.
|
||||
|
||||
The <<num_vertices,`num_vertices`>> and
|
||||
<<num_edges,`num_edges`>> functions do not filter before
|
||||
returning results, so they return the number of vertices or edges in the
|
||||
underlying graph, unfiltered <<2,[2>>].
|
||||
|
||||
==== Example
|
||||
|
||||
In this example we will filter a graph's edges based on edge weight. We
|
||||
will keep all edges with positive edge weight. First, we create a
|
||||
predicate function object.
|
||||
== Example
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
template <typename EdgeWeightMap>
|
||||
struct positive_edge_weight {
|
||||
positive_edge_weight() { }
|
||||
positive_edge_weight(EdgeWeightMap weight) : m_weight(weight) { }
|
||||
template <typename Edge>
|
||||
bool operator()(const Edge& e) const {
|
||||
return 0 < get(m_weight, e);
|
||||
}
|
||||
EdgeWeightMap m_weight;
|
||||
};
|
||||
include::example$adaptors/filtered_graph.cpp[]
|
||||
----
|
||||
|
||||
Now we create a graph and print out the filtered graph.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
int main()
|
||||
{
|
||||
using namespace boost;
|
||||
|
||||
typedef adjacency_list<vecS, vecS, directedS,
|
||||
no_property, property<edge_weight_t, int> > Graph;
|
||||
typedef property_map<Graph, edge_weight_t>::type EdgeWeightMap;
|
||||
|
||||
enum { A, B, C, D, E, N };
|
||||
const char* name = "ABCDE";
|
||||
Graph g(N);
|
||||
add_edge(A, B, 2, g);
|
||||
add_edge(A, C, 0, g);
|
||||
add_edge(C, D, 1, g);
|
||||
add_edge(C, E, 0, g);
|
||||
add_edge(D, B, 3, g);
|
||||
add_edge(E, C, 0, g);
|
||||
|
||||
positive_edge_weight<EdgeWeightMap> filter(get(edge_weight, g));
|
||||
filtered_graph<Graph, positive_edge_weight<EdgeWeightMap> >
|
||||
fg(g, filter);
|
||||
|
||||
std::cout << "filtered edge set: ";
|
||||
print_edges(fg, name);
|
||||
|
||||
std::cout << "filtered out-edges:" << std::endl;
|
||||
print_graph(fg, name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
----
|
||||
|
||||
The output is:
|
||||
Expected output:
|
||||
|
||||
....
|
||||
|
||||
filtered edge set: (A,B) (C,D) (D,B)
|
||||
filtered out-edges:
|
||||
A --> B
|
||||
B -->
|
||||
C --> D
|
||||
D --> B
|
||||
E -->
|
||||
Original: 4 edges
|
||||
0 -> 1 (weight=5)
|
||||
0 -> 2 (weight=0)
|
||||
1 -> 3 (weight=3)
|
||||
2 -> 3 (weight=0)
|
||||
Filtered (weight > 0):
|
||||
0 -> 1 (weight=5)
|
||||
1 -> 3 (weight=3)
|
||||
....
|
||||
|
||||
==== Template Parameters
|
||||
|
||||
[cols=",,",options="header",]
|
||||
|===
|
||||
|Parameter |Description |Default
|
||||
|`Graph` |The underlying graph type. |
|
||||
|
||||
|`EdgePredicate` |A function object that selects which edges from the
|
||||
original graph will appear in the filtered graph. The function object
|
||||
must model http://www.boost.org/sgi/stl/Predicate.html[Predicate]. The
|
||||
argument type for the function object must be the edge descriptor type
|
||||
of the graph. Also, the predicate must be
|
||||
http://www.boost.org/sgi/stl/DefaultConstructible.html[Default
|
||||
Constructible] <<1,[1>>]. |
|
||||
|
||||
|`VertexPredicate` |A function object that selects which vertices from
|
||||
the original graph will appear in the filtered graph. The function
|
||||
object must model
|
||||
http://www.boost.org/sgi/stl/Predicate.html[Predicate]. The argument
|
||||
type for the function object must be the vertex descriptor type of the
|
||||
graph. Also, the predicate must be
|
||||
http://www.boost.org/sgi/stl/DefaultConstructible.html[Default
|
||||
Constructible] <<1,[1>>]. |`keep_all`
|
||||
|===
|
||||
|
||||
==== Model of
|
||||
|
||||
This depends on the underlying graph type. If the underlying `Graph`
|
||||
type models xref:concepts/VertexAndEdgeListGraph.adoc[VertexAndEdgeListGraph]
|
||||
and xref:concepts/PropertyGraph.adoc[PropertyGraph] then so does the filtered
|
||||
graph. If the underlying `Graph` type models fewer or smaller concepts
|
||||
than these, then so does the filtered graph.
|
||||
|
||||
==== Where Defined
|
||||
|
||||
link:../../../boost/graph/filtered_graph.hpp[`boost/graph/filtered_graph.hpp`]
|
||||
|
||||
=== Associated Types
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<filtered_graph>::vertex_descriptor` +
|
||||
+
|
||||
The type for the vertex descriptors associated with the
|
||||
`filtered_graph`, which is the same type as the
|
||||
`vertex_descriptor` for the original `Graph`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<filtered_graph>::edge_descriptor` +
|
||||
+
|
||||
+
|
||||
The type for the edge descriptors associated with the
|
||||
`filtered_graph`, which is the same type as the
|
||||
`edge_descriptor` for the original `Graph`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<filtered_graph>::vertex_iterator` +
|
||||
+
|
||||
+
|
||||
The type for the iterators returned by `vertices()`, which is:
|
||||
== Synopsis
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
filter_iterator<VertexPredicate, graph_traits<Graph>::vertex_iterator>
|
||||
template <typename Graph,
|
||||
typename EdgePredicate,
|
||||
typename VertexPredicate = keep_all>
|
||||
class filtered_graph;
|
||||
----
|
||||
|
||||
The iterator is a model of
|
||||
link:../../utility/MultiPassInputIterator.html[MultiPassInputIterator].
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<filtered_graph>::edge_iterator` +
|
||||
+
|
||||
The type for the iterators returned by `edges()`, which is:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
filter_iterator<EdgePredicate, graph_traits<Graph>::edge_iterator>
|
||||
----
|
||||
|
||||
The iterator is a model of
|
||||
link:../../utility/MultiPassInputIterator.html[MultiPassInputIterator].
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<filtered_graph>::out_edge_iterator` +
|
||||
+
|
||||
The type for the iterators returned by `out_edges()`, which is:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
filter_iterator<EdgePredicate, graph_traits<Graph>::out_edge_iterator>
|
||||
----
|
||||
|
||||
The iterator is a model of
|
||||
link:../../utility/MultiPassInputIterator.html[MultiPassInputIterator].
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<filtered_graph>::adjacency_iterator` +
|
||||
+
|
||||
The type for the iterators returned by `adjacent_vertices()`. The
|
||||
`adjacency_iterator` models the same iterator concept as
|
||||
`out_edge_iterator`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<filtered_graph>::directed_category` +
|
||||
+
|
||||
+
|
||||
Provides information about whether the graph is directed
|
||||
(`directed_tag`) or undirected (`undirected_tag`).
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<filtered_graph>::edge_parallel_category` +
|
||||
+
|
||||
+
|
||||
This describes whether the graph class allows the insertion of parallel
|
||||
edges (edges with the same source and target). The two tags are
|
||||
`allow_parallel_edge_tag` and
|
||||
`disallow_parallel_edge_tag`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<filtered_graph>::vertices_size_type` +
|
||||
+
|
||||
The type used for dealing with the number of vertices in the graph.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<filtered_graph>::edges_size_type` +
|
||||
+
|
||||
The type used for dealing with the number of edges in the graph.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<filtered_graph>::degree_size_type` +
|
||||
+
|
||||
The type used for dealing with the number of edges incident to a vertex
|
||||
in the graph.
|
||||
|
||||
'''''
|
||||
|
||||
`property_map<filtered_graph, Property>::type` +
|
||||
and +
|
||||
`property_map<filtered_graph, Property>::const_type` +
|
||||
+
|
||||
The property map type for vertex or edge properties in the graph. The
|
||||
same property maps from the adapted graph are available in the filtered
|
||||
The `filtered_graph` does not copy the original graph. It holds a reference to
|
||||
it. The lifetime of the original graph must extend past any use of the filtered
|
||||
graph.
|
||||
|
||||
'''''
|
||||
Vertex and edge descriptors of the filtered graph are the same as, and
|
||||
interchangeable with, the descriptors of the original graph. Property maps from
|
||||
the original graph are available through the filtered graph.
|
||||
|
||||
=== Member Functions
|
||||
== Template Parameters
|
||||
|
||||
'''''
|
||||
[cols="1,3,1",options="header"]
|
||||
|===
|
||||
| Parameter | Description | Default
|
||||
|
||||
....
|
||||
| `Graph`
|
||||
| The underlying graph type.
|
||||
|
|
||||
|
||||
filtered_graph(Graph& g, EdgePredicate ep, VertexPredicate vp)
|
||||
....
|
||||
| `EdgePredicate`
|
||||
| Function object selecting which edges appear. Must model Predicate (argument
|
||||
type: edge descriptor). Must be Default Constructible.
|
||||
|
|
||||
|
||||
Create a filtered graph based on the graph _g_ and the edge filter _ep_
|
||||
and vertex filter _vp_.
|
||||
| `VertexPredicate`
|
||||
| Function object selecting which vertices appear. Must model Predicate
|
||||
(argument type: vertex descriptor). Must be Default Constructible.
|
||||
| `keep_all`
|
||||
|===
|
||||
|
||||
'''''
|
||||
NOTE: Predicates must be Default Constructible because they are stored by-value
|
||||
in filter iterators, and the C++ Standard requires iterators to be Default
|
||||
Constructible.
|
||||
|
||||
....
|
||||
== Member Functions
|
||||
|
||||
filtered_graph(Graph& g, EdgePredicate ep)
|
||||
....
|
||||
=== Constructors
|
||||
|
||||
Create a filtered graph based on the graph _g_ and the edge filter _ep_.
|
||||
All vertices from the original graph are retained.
|
||||
[source,cpp]
|
||||
----
|
||||
filtered_graph(Graph& g, EdgePredicate ep, VertexPredicate vp);
|
||||
----
|
||||
|
||||
'''''
|
||||
Create a filtered view of `g` with both edge and vertex filters.
|
||||
|
||||
filtered_graph(const filtered_graph& x)
|
||||
'''
|
||||
|
||||
This creates a filtered graph for the same underlying graph as _x_.
|
||||
Anotherwords, this is a shallow copy.
|
||||
[source,cpp]
|
||||
----
|
||||
filtered_graph(Graph& g, EdgePredicate ep);
|
||||
----
|
||||
|
||||
'''''
|
||||
Create a filtered view of `g` with an edge filter only. All vertices are
|
||||
retained.
|
||||
|
||||
....
|
||||
== Non-Member Functions
|
||||
|
||||
filtered_graph& operator=(const filtered_graph& x)
|
||||
....
|
||||
|
||||
This creates a filtered graph for the same underlying graph as _x_.
|
||||
Anotherwords, this is a shallow copy.
|
||||
|
||||
'''''
|
||||
|
||||
=== Non-Member Functions
|
||||
|
||||
===== Structure Access
|
||||
|
||||
'''''
|
||||
=== Structure Access
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
std::pair<vertex_iterator, vertex_iterator>
|
||||
vertices(const filtered_graph& g)
|
||||
vertices(const filtered_graph& g);
|
||||
----
|
||||
|
||||
Returns an iterator-range providing access to the vertex set of graph
|
||||
`g`.
|
||||
Returns an iterator-range for the filtered vertex set.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
std::pair<edge_iterator, edge_iterator>
|
||||
edges(const filtered_graph& g)
|
||||
edges(const filtered_graph& g);
|
||||
----
|
||||
|
||||
Returns an iterator-range providing access to the edge set of graph
|
||||
`g`.
|
||||
Returns an iterator-range for the filtered edge set.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
std::pair<adjacency_iterator, adjacency_iterator>
|
||||
adjacent_vertices(vertex_descriptor u, const filtered_graph& g)
|
||||
----
|
||||
|
||||
Returns an iterator-range providing access to the vertices adjacent to
|
||||
vertex `u` in graph `g`.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
std::pair<out_edge_iterator, out_edge_iterator>
|
||||
out_edges(vertex_descriptor u, const filtered_graph& g)
|
||||
out_edges(vertex_descriptor u, const filtered_graph& g);
|
||||
----
|
||||
|
||||
Returns an iterator-range providing access to the out-edges of vertex
|
||||
`u` in graph `g`. If the graph is undirected, this iterator-range
|
||||
provides access to all edges incident on vertex `u`. For both directed
|
||||
and undirected graphs, for an out-edge `e`, `source(e, g) == u` and
|
||||
`target(e, g) == v` where `v` is a vertex adjacent to `u`.
|
||||
Returns an iterator-range for the filtered out-edges of vertex `u`.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
std::pair<in_edge_iterator, in_edge_iterator>
|
||||
in_edges(vertex_descriptor v, const filtered_graph& g)
|
||||
in_edges(vertex_descriptor v, const filtered_graph& g);
|
||||
----
|
||||
|
||||
Returns an iterator-range providing access to the in-edges of vertex
|
||||
`v` in graph `g`. For an in-edge `e`, `target(e, g) == v` and
|
||||
`source(e, g) == u` for some vertex `u` that is adjacent to `v`,
|
||||
whether the graph is directed or undirected.
|
||||
Returns an iterator-range for the filtered in-edges of vertex `v`.
|
||||
Requires the underlying graph to model BidirectionalGraph.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
vertex_descriptor
|
||||
source(edge_descriptor e, const filtered_graph& g)
|
||||
std::pair<adjacency_iterator, adjacency_iterator>
|
||||
adjacent_vertices(vertex_descriptor u, const filtered_graph& g);
|
||||
----
|
||||
|
||||
Returns the source vertex of edge `e`.
|
||||
Returns an iterator-range for the vertices adjacent to `u` through filtered
|
||||
edges.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
vertex_descriptor
|
||||
target(edge_descriptor e, const filtered_graph& g)
|
||||
vertex_descriptor source(edge_descriptor e, const filtered_graph& g);
|
||||
vertex_descriptor target(edge_descriptor e, const filtered_graph& g);
|
||||
----
|
||||
|
||||
Returns the target vertex of edge `e`.
|
||||
Returns the source/target vertex of edge `e`.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
degree_size_type
|
||||
out_degree(vertex_descriptor u, const filtered_graph& g)
|
||||
degree_size_type out_degree(vertex_descriptor u, const filtered_graph& g);
|
||||
degree_size_type in_degree(vertex_descriptor u, const filtered_graph& g);
|
||||
----
|
||||
|
||||
Returns the number of edges leaving vertex `u`.
|
||||
Returns the filtered out-degree/in-degree of vertex `u`.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
degree_size_type
|
||||
in_degree(vertex_descriptor u, const filtered_graph& g)
|
||||
vertices_size_type num_vertices(const filtered_graph& g);
|
||||
edges_size_type num_edges(const filtered_graph& g);
|
||||
----
|
||||
|
||||
Returns the number of edges entering vertex `u`.
|
||||
Returns the number of vertices/edges in the _underlying_ graph (not the
|
||||
filtered count).
|
||||
|
||||
'''''
|
||||
|
||||
[[num_vertices]]
|
||||
[source,cpp]
|
||||
----
|
||||
vertices_size_type
|
||||
num_vertices(const filtered_graph& g)
|
||||
----
|
||||
|
||||
Returns the number of vertices in the underlying graph <<2,[2]>>.
|
||||
|
||||
'''''
|
||||
|
||||
[[num_edges]]
|
||||
[source,cpp]
|
||||
----
|
||||
edges_size_type
|
||||
num_edges(const filtered_graph& g)
|
||||
----
|
||||
|
||||
Returns the number of edges in the underlying graph <<2,[2]>>.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
std::pair<edge_descriptor, bool>
|
||||
edge(vertex_descriptor u, vertex_descriptor v,
|
||||
const filtered_graph& g)
|
||||
edge(vertex_descriptor u, vertex_descriptor v, const filtered_graph& g);
|
||||
----
|
||||
|
||||
Returns the edge connecting vertex `u` to vertex `v` in graph `g`.
|
||||
Returns the edge connecting `u` to `v`, if it exists and passes the filter.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename G, typename EP, typename VP>
|
||||
std::pair<out_edge_iterator, out_edge_iterator>
|
||||
edge_range(vertex_descriptor u, vertex_descriptor v,
|
||||
const filtered_graph& g)
|
||||
const filtered_graph& g);
|
||||
----
|
||||
|
||||
Returns a pair of out-edge iterators that give the range for all the
|
||||
parallel edges from `u` to `v`. This function only works when the
|
||||
underlying graph supports `edge_range`, which requires that it sorts
|
||||
its out edges according to target vertex and allows parallel edges. The
|
||||
`adjacency_list` class with `OutEdgeList=multisetS` is an example of
|
||||
such a graph.
|
||||
Returns all parallel edges from `u` to `v`. Only works when the underlying
|
||||
graph sorts out-edges by target (e.g. `adjacency_list` with
|
||||
`OutEdgeList=multisetS`).
|
||||
|
||||
'''''
|
||||
|
||||
===== Property Map Access
|
||||
|
||||
'''''
|
||||
=== Property Map Access
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename PropertyTag>
|
||||
property_map<filtered_graph, PropertyTag>::type
|
||||
get(PropertyTag, filtered_graph& g)
|
||||
get(PropertyTag, filtered_graph& g);
|
||||
|
||||
template <typename PropertyTag>
|
||||
property_map<filtered_graph, PropertyTag>::const_type
|
||||
get(PropertyTag, const filtered_graph& g)
|
||||
get(PropertyTag, const filtered_graph& g);
|
||||
----
|
||||
|
||||
Returns the property map object for the vertex property specified by
|
||||
`PropertyTag`. The `PropertyTag` must match one of the properties
|
||||
specified in the graph's `VertexProperty` template argument.
|
||||
Returns the property map for the given tag. The same property maps from the
|
||||
underlying graph are accessible through the filtered graph.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename PropertyTag, typename X>
|
||||
typename property_traits<property_map<filtered_graph, PropertyTag>::const_type>::value_type
|
||||
get(PropertyTag, const filtered_graph& g, X x)
|
||||
auto get(PropertyTag, const filtered_graph& g, X x);
|
||||
----
|
||||
|
||||
This returns the property value for `x`, where `x` is either a vertex
|
||||
or edge descriptor.
|
||||
Returns the property value for vertex or edge `x`.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename PropertyTag, typename X, typename Value>
|
||||
void
|
||||
put(PropertyTag, const filtered_graph& g, X x, const Value& value)
|
||||
void put(PropertyTag, const filtered_graph& g, X x, const Value& value);
|
||||
----
|
||||
|
||||
This sets the property value for `x` to `value`. `x` is either a
|
||||
vertex or edge descriptor. `Value` must be convertible to
|
||||
`typename property_traits<property_map<filtered_graph, PropertyTag>::type>::value_type`
|
||||
Sets the property value for vertex or edge `x`. This modifies the property in
|
||||
the underlying graph.
|
||||
|
||||
'''''
|
||||
== Associated Types
|
||||
|
||||
==== See Also
|
||||
[cols="1,3",options="header"]
|
||||
|===
|
||||
| Type | Description
|
||||
|
||||
xref:helpers/property_map.adoc[`property_map`],
|
||||
xref:traits/graph_traits.adoc[`graph_traits`]
|
||||
| `vertex_descriptor`
|
||||
| Same as the underlying graph.
|
||||
|
||||
==== Notes
|
||||
| `edge_descriptor`
|
||||
| Same as the underlying graph.
|
||||
|
||||
[[1]][1] The reason for requiring
|
||||
http://www.boost.org/sgi/stl/DefaultConstructible.html[Default
|
||||
Constructible] in the `EdgePredicate` and `VertexPredicate` types is
|
||||
that these predicates are stored by-value (for performance reasons) in
|
||||
the filter iterator adaptor, and iterators are required to be Default
|
||||
Constructible by the C++ Standard.
|
||||
| `vertex_iterator`
|
||||
| `filter_iterator<VertexPredicate, graph_traits<Graph>::vertex_iterator>`
|
||||
|
||||
[[2]][2] It would be nicer to return the number of vertices (or edges)
|
||||
remaining after the filter has been applied, but this has two problems.
|
||||
The first is that it would take longer to calculate, and the second is
|
||||
that it would interact badly with the underlying vertex/edge index
|
||||
mappings. The index mapping would no longer fall in the range
|
||||
`[0,num_vertices(g))` (resp. `[0, num_edges(g))`) which is assumed in
|
||||
many of the algorithms.
|
||||
| `edge_iterator`
|
||||
| `filter_iterator<EdgePredicate, graph_traits<Graph>::edge_iterator>`
|
||||
|
||||
| `out_edge_iterator`
|
||||
| `filter_iterator<EdgePredicate, graph_traits<Graph>::out_edge_iterator>`
|
||||
|
||||
| `adjacency_iterator`
|
||||
| Models the same iterator concept as `out_edge_iterator`.
|
||||
|
||||
| `directed_category`
|
||||
| `directed_tag` or `undirected_tag` (from underlying graph).
|
||||
|
||||
| `edge_parallel_category`
|
||||
| `allow_parallel_edge_tag` or `disallow_parallel_edge_tag` (from underlying graph).
|
||||
|
||||
| `vertices_size_type`, `edges_size_type`, `degree_size_type`
|
||||
| Size types from the underlying graph.
|
||||
|===
|
||||
|
||||
== Helper Predicates
|
||||
|
||||
The header provides several ready-made predicates:
|
||||
|
||||
[cols="1,3"]
|
||||
|===
|
||||
| Predicate | Description
|
||||
|
||||
| `keep_all`
|
||||
| Keeps all elements (the default vertex predicate).
|
||||
|
||||
| `is_residual_edge<ResCapMap>`
|
||||
| Keeps edges with positive residual capacity. Useful for max-flow.
|
||||
|
||||
| `is_in_subset<Set>`
|
||||
| Keeps vertices that are in the given set.
|
||||
|
||||
| `is_not_in_subset<Set>`
|
||||
| Keeps vertices that are not in the given set.
|
||||
|===
|
||||
|
||||
@@ -1,276 +1,220 @@
|
||||
= `grid_graph`
|
||||
= Grid Graph
|
||||
|
||||
* <<overview,Overview>>
|
||||
* <<creating,Creating a Grid Graph>>
|
||||
* <<indexing,Indexing>>
|
||||
* <<member,Grid Graph Member Functions>>
|
||||
A multi-dimensional, rectangular grid of vertices with user-defined dimension
|
||||
lengths and optional wrapping per dimension.
|
||||
|
||||
==== Overview
|
||||
*Defined in:* `<boost/graph/grid_graph.hpp>` +
|
||||
*Models:* IncidenceGraph, AdjacencyGraph, VertexListGraph, EdgeListGraph,
|
||||
BidirectionalGraph, AdjacencyMatrix
|
||||
|
||||
A `grid_graph` represents a multi-dimensional, rectangular grid of
|
||||
vertices with user-defined dimension lengths and wrapping.
|
||||
NOTE: `grid_graph` does not support bundled properties. To associate data with
|
||||
grid cells (e.g. terrain costs), maintain an external container indexed by the
|
||||
grid's vertex index: `std::vector<double> cost(num_vertices(g));`
|
||||
|
||||
`grid_graph` models:
|
||||
== Flat grid
|
||||
|
||||
* xref:concepts/IncidenceGraph.adoc[Incidence Graph]
|
||||
* xref:concepts/AdjacencyGraph.adoc[Adjacency Graph]
|
||||
* xref:concepts/VertexListGraph.adoc[Vertex List Graph]
|
||||
* xref:concepts/EdgeListGraph.adoc[Edge List Graph]
|
||||
* xref:concepts/BidirectionalGraph.adoc[Bidirectional Graph]
|
||||
* xref:concepts/AdjacencyMatrix.adoc[Adjacency Matrix]
|
||||
The simplest case: a rectangular grid with no wrapping. Corner vertices have
|
||||
fewer neighbors than interior vertices.
|
||||
|
||||
Defined in
|
||||
link:../../../boost/graph/grid_graph.hpp[`boost/graph/grid_graph.hpp`]
|
||||
with all functions in the `boost` namespace. A simple examples of
|
||||
creating and iterating over a grid_graph is available here
|
||||
link:../../../libs/graph/example/grid_graph_example.cpp[`libs/graph/example/grid_graph_example.cpp`].
|
||||
An example of adding properties to a grid_graph is also available
|
||||
link:../../../libs/graph/example/grid_graph_properties.cpp[`libs/graph/example/grid_graph_properties.cpp`]
|
||||
image::figs/grid_graph_unwrapped.png[3x3 unwrapped grid]
|
||||
|
||||
===== Template Parameters
|
||||
|
||||
[source,code]
|
||||
[source,cpp]
|
||||
----
|
||||
include::example$adaptors/grid_graph_unwrapped.cpp[]
|
||||
----
|
||||
|
||||
Expected output:
|
||||
|
||||
....
|
||||
9 vertices, 24 edges
|
||||
(0,0) degree=2
|
||||
(1,0) degree=3
|
||||
(2,0) degree=2
|
||||
(0,1) degree=3
|
||||
(1,1) degree=4
|
||||
(2,1) degree=3
|
||||
(0,2) degree=2
|
||||
(1,2) degree=3
|
||||
(2,2) degree=2
|
||||
....
|
||||
|
||||
== Torus (all dimensions wrap)
|
||||
|
||||
Pass `true` as the second constructor argument to wrap all dimensions. Every
|
||||
vertex now has the same degree.
|
||||
|
||||
image::figs/grid_graph_wrapped.png[3x3 wrapped grid (torus)]
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
include::example$adaptors/grid_graph_torus.cpp[]
|
||||
----
|
||||
|
||||
Expected output:
|
||||
|
||||
....
|
||||
9 vertices, 36 edges
|
||||
(0,0) degree=4
|
||||
(1,0) degree=4
|
||||
(2,0) degree=4
|
||||
(0,1) degree=4
|
||||
(1,1) degree=4
|
||||
(2,1) degree=4
|
||||
(0,2) degree=4
|
||||
(1,2) degree=4
|
||||
(2,2) degree=4
|
||||
....
|
||||
|
||||
== Cylinder (mixed wrapping)
|
||||
|
||||
Pass a `boost::array<bool, Dimensions>` to control wrapping per dimension.
|
||||
Here dimension 0 wraps (cylinder) but dimension 1 does not.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
include::example$adaptors/grid_graph_cylinder.cpp[]
|
||||
----
|
||||
|
||||
Expected output:
|
||||
|
||||
....
|
||||
12 vertices, 40 edges
|
||||
|
||||
From (0,0):
|
||||
previous in dim 0 (wraps) = (3,0)
|
||||
previous in dim 1 (stops) = (0,0)
|
||||
....
|
||||
|
||||
== Higher dimensions
|
||||
|
||||
The `Dimensions` template parameter is a compile-time constant. A 3D grid
|
||||
works the same way.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
include::example$adaptors/grid_graph_3d.cpp[]
|
||||
----
|
||||
|
||||
Expected output:
|
||||
|
||||
....
|
||||
27 vertices, 108 edges
|
||||
corner (0,0,0) degree=3
|
||||
center (1,1,1) degree=6
|
||||
....
|
||||
|
||||
'''
|
||||
|
||||
== Synopsis
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <std::size_t Dimensions,
|
||||
typename VertexIndex = std::size_t,
|
||||
typename EdgeIndex = VertexIndex>
|
||||
class grid_graph;
|
||||
|
||||
class grid_graph;
|
||||
----
|
||||
|
||||
* `Dimensions` - Number of dimensions in the graph
|
||||
* `VertexIndex` - Type used for vertex indices, defaults to
|
||||
`std::size_t`
|
||||
* `EdgeIndex` - Type used for edge indices, defaults to the same type as
|
||||
`VertexIndex`
|
||||
== Template Parameters
|
||||
|
||||
[[creating]]
|
||||
==== Creating a Grid Graph
|
||||
[cols="1,3,1",options="header"]
|
||||
|===
|
||||
| Parameter | Description | Default
|
||||
|
||||
The constructor to `grid_graph` has several overloads to aid in
|
||||
configuring each dimension:
|
||||
| `Dimensions`
|
||||
| Number of dimensions (compile-time constant).
|
||||
|
|
||||
|
||||
[source,code]
|
||||
| `VertexIndex`
|
||||
| Integer type for vertex indices.
|
||||
| `std::size_t`
|
||||
|
||||
| `EdgeIndex`
|
||||
| Integer type for edge indices.
|
||||
| same as `VertexIndex`
|
||||
|===
|
||||
|
||||
== Constructors
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
grid_graph(boost::array<VertexIndex, Dimensions> lengths);
|
||||
----
|
||||
|
||||
// Defines a grid_graph that does not wrap.
|
||||
grid_graph<...>(boost:array<VertexIndex, Dimensions> dimension_lengths);
|
||||
Create an unwrapped grid with the given dimension lengths.
|
||||
|
||||
// Defines a grid_graph where all dimensions are either wrapped or unwrapped.
|
||||
grid_graph<...>(boost:array<VertexIndex, Dimensions> dimension_lengths,
|
||||
bool wrap_all_dimensions);
|
||||
'''
|
||||
|
||||
// Defines a grid_graph where the wrapping for each dimension is specified individually.
|
||||
grid_graph<...>(boost:array<VertexIndex, Dimensions> dimension_lengths,
|
||||
boost:array<bool, Dimensions> wrap_dimension);
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
grid_graph(boost::array<VertexIndex, Dimensions> lengths,
|
||||
bool wrap_all);
|
||||
----
|
||||
|
||||
===== Example
|
||||
Create a grid where all dimensions wrap (`true`) or none wrap (`false`).
|
||||
|
||||
[source,code]
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
grid_graph(boost::array<VertexIndex, Dimensions> lengths,
|
||||
boost::array<bool, Dimensions> wrap_per_dim);
|
||||
----
|
||||
|
||||
// Define dimension lengths, a 3x3 in this case
|
||||
boost::array<std::size_t, 2> lengths = { { 3, 3 } };
|
||||
Create a grid with per-dimension wrapping control.
|
||||
|
||||
// Create a 3x3 two-dimensional, unwrapped grid graph (Figure 1)
|
||||
grid_graph<2> graph(lengths);
|
||||
== Member Functions
|
||||
|
||||
// Create a 3x3 two-dimensional, wrapped grid graph (Figure 2)
|
||||
grid_graph<2> graph(lengths, true);
|
||||
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
image:figs/grid_graph_unwrapped.png[figs/grid_graph_unwrapped] +
|
||||
_*Figure 1:* A 3x3 two-dimensional, unwrapped grid graph_
|
||||
|
||||
|
||||
|
||||
image:figs/grid_graph_wrapped.png[figs/grid_graph_wrapped] +
|
||||
_*Figure 2:* A 3x3 two-dimensional, wrapped grid graph_
|
||||
|
||||
|
||||
|
||||
==== Indexing
|
||||
|
||||
The `grid_graph` supports addressing vertices and edges by index.
|
||||
The following functions allow you to convert between vertices, edges,
|
||||
and their associated indices:
|
||||
|
||||
[source,code]
|
||||
----
|
||||
|
||||
typedef grid_graph<...> Graph;
|
||||
typedef graph_traits<Graph> Traits;
|
||||
|
||||
// Get the vertex associated with vertex_index
|
||||
Traits::vertex_descriptor
|
||||
vertex(Traits::vertices_size_type vertex_index,
|
||||
const Graph& graph);
|
||||
|
||||
// Get the index associated with vertex
|
||||
Traits::vertices_size_type
|
||||
get(boost::vertex_index_t,
|
||||
const Graph& graph,
|
||||
Traits::vertex_descriptor vertex);
|
||||
|
||||
// Get the edge associated with edge_index
|
||||
Traits::edge_descriptor
|
||||
edge_at(Traits::edges_size_type edge_index,
|
||||
const Graph& graph);
|
||||
|
||||
// Get the index associated with edge
|
||||
Traits::edges_size_type
|
||||
get(boost::edge_index_t,
|
||||
const Graph& graph,
|
||||
Traits::edge_descriptor edge);
|
||||
|
||||
// Get the out-edge associated with vertex and out_edge_index
|
||||
Traits::edge_descriptor
|
||||
out_edge_at(Traits::vertex_descriptor vertex,
|
||||
Traits::degree_size_type out_edge_index,
|
||||
const Graph& graph);
|
||||
|
||||
// Get the out-edge associated with vertex and in_edge_index
|
||||
Traits::edge_descriptor
|
||||
in_edge_at(Traits::vertex_descriptor vertex,
|
||||
Traits::degree_size_type in_edge_index,
|
||||
const Graph& graph);
|
||||
|
||||
----
|
||||
|
||||
===== Example
|
||||
|
||||
[source,code]
|
||||
----
|
||||
|
||||
typedef grid_graph<2> Graph;
|
||||
typedef graph_traits<Graph> Traits;
|
||||
|
||||
// Create a 3x3, unwrapped grid_graph (Figure 3)
|
||||
boost::array<std::size_t, 2> lengths = { { 3, 3 } };
|
||||
Graph graph(lengths);
|
||||
|
||||
// Do a round-trip test of the vertex index functions
|
||||
for (Traits::vertices_size_type v_index = 0;
|
||||
v_index < num_vertices(graph); ++v_index) {
|
||||
|
||||
// The two indices should always be equal
|
||||
std::cout << "Index of vertex " << v_index << " is " <<
|
||||
get(boost::vertex_index, graph, vertex(v_index, graph)) << std::endl;
|
||||
|
||||
}
|
||||
|
||||
// Do a round-trip test of the edge index functions
|
||||
for (Traits::edges_size_type e_index = 0;
|
||||
e_index < num_edges(graph); ++e_index) {
|
||||
|
||||
// The two indices should always be equal
|
||||
std::cout << "Index of edge " << e_index << " is " <<
|
||||
get(boost::edge_index, graph, edge_at(e_index, graph)) << std::endl;
|
||||
|
||||
}
|
||||
|
||||
----
|
||||
|
||||
image:figs/grid_graph_indexed.png[figs/grid_graph_indexed] +
|
||||
_*Figure 3:* 3x3 unwrapped grid_graph with vertex and edge indices
|
||||
shown._
|
||||
|
||||
|
||||
|
||||
[[member]]
|
||||
==== Member Functions
|
||||
|
||||
There are several `grid_graph` specific member functions available:
|
||||
|
||||
[source,code]
|
||||
----
|
||||
|
||||
typedef grid_graph<...> Graph;
|
||||
typedef graph_traits<Graph> Traits;
|
||||
|
||||
// Returns the number of dimensions
|
||||
std::size_t dimensions();
|
||||
|
||||
// Returns the length of a dimension
|
||||
Traits::vertices_size_type length(std::size_t dimension);
|
||||
|
||||
// Returns true if the dimension wraps, false if not
|
||||
bool wrapped(std::size_t dimension);
|
||||
|
||||
// Returns the "next" vertex in a dimension at a given distance. If the dimension
|
||||
// is unwrapped, next will stop at the last vertex in the dimension.
|
||||
Traits::vertex_descriptor next(Traits::vertex_descriptor vertex,
|
||||
std::size_t dimension,
|
||||
Traits::vertices_size_type distance = 1);
|
||||
|
||||
// Returns the "previous" vertex in a dimension at a given distance. If the
|
||||
// dimension is unwrapped, previous will stop at the beginning vertex in the dimension.
|
||||
Traits::vertex_descriptor previous(Traits::vertex_descriptor vertex,
|
||||
std::size_t dimension,
|
||||
Traits::vertices_size_type distance = 1);
|
||||
|
||||
----
|
||||
|
||||
===== Example
|
||||
Returns the number of dimensions.
|
||||
|
||||
[source,code]
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
VertexIndex length(std::size_t dim);
|
||||
----
|
||||
|
||||
typedef grid_graph<3> Graph;
|
||||
typedef graph_traits<Graph> Traits;
|
||||
Returns the length of dimension `dim`.
|
||||
|
||||
// Define a 3x5x7 grid_graph where the second dimension doesn't wrap
|
||||
boost::array<std::size_t, 3> lengths = { { 3, 5, 7 } };
|
||||
boost::array<bool, 3> wrapped = { { true, false, true } };
|
||||
Graph graph(lengths, wrapped);
|
||||
'''
|
||||
|
||||
// Print number of dimensions
|
||||
std::cout << graph.dimensions() << std::endl; // prints "3"
|
||||
|
||||
// Print dimension lengths (same order as in the lengths array)
|
||||
std::cout << graph.length(0) << "x" << graph.length(1) <<
|
||||
"x" << graph.length(2) << std::endl; // prints "3x5x7"
|
||||
|
||||
// Print dimension wrapping (W = wrapped, U = unwrapped)
|
||||
std::cout << graph.wrapped(0) ? "W" : "U" << ", " <<
|
||||
graph.wrapped(1) ? "W" : "U" << ", " <<
|
||||
graph.wrapped(2) ? "W" : "U" << std::endl; // prints "W, U, W"
|
||||
|
||||
// Define a simple function to print vertices
|
||||
void print_vertex(Traits::vertex_descriptor vertex_to_print) {
|
||||
std::cout << "(" << vertex_to_print[0] << ", " << vertex_to_print[1] <<
|
||||
", " << vertex_to_print[2] << ")" << std::endl;
|
||||
}
|
||||
|
||||
// Start with the first vertex in the graph
|
||||
Traits::vertex_descriptor first_vertex = vertex(0, graph);
|
||||
print_vertex(first_vertex); // prints "(0, 0, 0)"
|
||||
|
||||
// Print the next vertex in dimension 0
|
||||
print_vertex(graph.next(first_vertex, 0)); // prints "(1, 0, 0)"
|
||||
|
||||
// Print the next vertex in dimension 1
|
||||
print_vertex(graph.next(first_vertex, 1)); // prints "(0, 1, 0)"
|
||||
|
||||
// Print the 5th next vertex in dimension 2
|
||||
print_vertex(graph.next(first_vertex, 2, 5)); // prints "(0, 0, 5)"
|
||||
|
||||
// Print the previous vertex in dimension 0 (wraps)
|
||||
print_vertex(graph.previous(first_vertex, 0)); // prints "(2, 0, 0)"
|
||||
|
||||
// Print the previous vertex in dimension 1 (doesn't wrap, so it's the same)
|
||||
print_vertex(graph.previous(first_vertex, 1)); // prints "(0, 0, 0)"
|
||||
|
||||
// Print the 20th previous vertex in dimension 2 (wraps around twice)
|
||||
print_vertex(graph.previous(first_vertex, 2, 20)); // prints "(0, 0, 1)"
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
bool wrapped(std::size_t dim);
|
||||
----
|
||||
|
||||
'''''
|
||||
Returns whether dimension `dim` wraps.
|
||||
|
||||
Copyright © 2009 Trustees of Indiana University
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
vertex_descriptor next(vertex_descriptor v, std::size_t dim,
|
||||
vertices_size_type distance = 1);
|
||||
vertex_descriptor previous(vertex_descriptor v, std::size_t dim,
|
||||
vertices_size_type distance = 1);
|
||||
----
|
||||
|
||||
Move along a dimension. In an unwrapped dimension, `next` stops at the last
|
||||
vertex and `previous` stops at the first. In a wrapped dimension, movement
|
||||
wraps around.
|
||||
|
||||
== Indexing
|
||||
|
||||
Vertices and edges can be addressed by integer index:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
vertex_descriptor vertex(vertices_size_type idx, const grid_graph& g);
|
||||
edges_size_type get(edge_index_t, const grid_graph& g, edge_descriptor e);
|
||||
edge_descriptor edge_at(edges_size_type idx, const grid_graph& g);
|
||||
----
|
||||
|
||||
The vertex descriptor is a `boost::array<VertexIndex, Dimensions>` that can
|
||||
be indexed by dimension: `v[0]` is the position in dimension 0, `v[1]` in
|
||||
dimension 1, etc.
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
= Graph Adaptors
|
||||
|
||||
A graph adaptor wraps an existing graph and presents a different view of it
|
||||
without copying. The original graph's data and structure are reused. Adaptors
|
||||
are lightweight (typically O(1) to construct) and composable.
|
||||
|
||||
[cols="1,3"]
|
||||
|===
|
||||
| Adaptor | What it does
|
||||
|
||||
| xref:adaptors/filtered_graph.adoc[filtered_graph]
|
||||
| Hides vertices and/or edges based on predicate functions.
|
||||
|
||||
| xref:adaptors/reverse_graph.adoc[reverse_graph]
|
||||
| Reverses all edge directions (graph transposition). O(1).
|
||||
|
||||
| xref:adaptors/subgraph.adoc[subgraph]
|
||||
| Selects a subset of vertices; all edges between them are included
|
||||
automatically. Supports parent/child nesting.
|
||||
|
||||
| xref:adaptors/edge_list.adoc[edge_list]
|
||||
| Turns raw data (an array of `std::pair`, a CSV file parsed into pairs, etc.)
|
||||
into a graph that algorithms like `bellman_ford_shortest_paths` can consume
|
||||
directly. Useful when you have edge data but do not want to build a full
|
||||
`adjacency_list`.
|
||||
|
||||
| xref:adaptors/grid_graph.adoc[grid_graph]
|
||||
| N-dimensional rectangular grid with optional wrapping per dimension.
|
||||
Not an adaptor in the strict sense (it generates its own structure), but
|
||||
it follows the same zero-copy philosophy.
|
||||
|===
|
||||
|
||||
Adaptors model the same graph concepts as their underlying graph. A
|
||||
`filtered_graph` over a BidirectionalGraph is itself a BidirectionalGraph.
|
||||
A `reverse_graph` over a BidirectionalGraph is a BidirectionalGraph.
|
||||
|
||||
Vertex and edge descriptors from an adaptor are typically the same type as
|
||||
descriptors from the underlying graph, so they can be used interchangeably.
|
||||
The exception is `subgraph`, which uses local descriptors that must be
|
||||
converted with `local_to_global()` and `global_to_local()`.
|
||||
|
||||
@@ -1,432 +1,188 @@
|
||||
= Reverse Graph Adaptor
|
||||
= Reverse Graph
|
||||
|
||||
....
|
||||
A view of a graph with all edges reversed (transposed). Construction is O(1).
|
||||
|
||||
reverse_graph<BidirectionalGraph, GraphReference>
|
||||
....
|
||||
*Defined in:* `<boost/graph/reverse_graph.hpp>` +
|
||||
*Models:* BidirectionalGraph, VertexListGraph, PropertyGraph (depending on
|
||||
underlying graph)
|
||||
|
||||
The `reverse_graph` adaptor flips the in-edges and out-edges of a
|
||||
xref:concepts/BidirectionalGraph.adoc[BidirectionalGraph], effectively
|
||||
transposing the graph. The construction of the `reverse_graph` is
|
||||
constant time, providing a highly efficient way to obtain a transposed
|
||||
view of a graph.
|
||||
|
||||
==== Example
|
||||
|
||||
The example from
|
||||
link:../example/reverse_graph.cpp[`example/reverse_graph.cpp`].
|
||||
== Example
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
typedef boost::adjacency_list<
|
||||
boost::vecS, boost::vecS, boost::bidirectionalS,
|
||||
> Graph;
|
||||
|
||||
Graph G(5);
|
||||
boost::add_edge(0, 2, G);
|
||||
boost::add_edge(1, 1, G);
|
||||
boost::add_edge(1, 3, G);
|
||||
boost::add_edge(1, 4, G);
|
||||
boost::add_edge(2, 1, G);
|
||||
boost::add_edge(2, 3, G);
|
||||
boost::add_edge(2, 4, G);
|
||||
boost::add_edge(3, 1, G);
|
||||
boost::add_edge(3, 4, G);
|
||||
boost::add_edge(4, 0, G);
|
||||
boost::add_edge(4, 1, G);
|
||||
|
||||
std::cout << "original graph:" << std::endl;
|
||||
boost::print_graph(G, boost::get(boost::vertex_index, G));
|
||||
|
||||
std::cout << std::endl << "reversed graph:" << std::endl;
|
||||
boost::print_graph(boost::make_reverse_graph(G),
|
||||
boost::get(boost::vertex_index, G));
|
||||
|
||||
return 0;
|
||||
}
|
||||
include::example$adaptors/reverse_graph.cpp[]
|
||||
----
|
||||
|
||||
The output is:
|
||||
Expected output:
|
||||
|
||||
....
|
||||
Original:
|
||||
0 --> 1
|
||||
1 --> 2
|
||||
2 --> 3
|
||||
3 --> 0
|
||||
|
||||
original graph:
|
||||
0 --> 2
|
||||
1 --> 1 3 4
|
||||
2 --> 1 3 4
|
||||
3 --> 1 4
|
||||
4 --> 0 1
|
||||
|
||||
reversed graph:
|
||||
0 --> 4
|
||||
1 --> 1 2 3 4
|
||||
2 --> 0
|
||||
3 --> 1 2
|
||||
4 --> 1 2 3
|
||||
Reversed:
|
||||
0 --> 3
|
||||
1 --> 0
|
||||
2 --> 1
|
||||
3 --> 2
|
||||
....
|
||||
|
||||
==== Template Parameters
|
||||
|
||||
[cols=",,",options="header",]
|
||||
|===
|
||||
|Parameter |Description |Default
|
||||
|`BidirectionalGraph` |The graph type to be adapted. |
|
||||
|
||||
|`GraphReference` |This type should be `const BidirectionalGraph&` if
|
||||
you want to create a const reverse graph, or `BidirectionalGraph&` if
|
||||
you want to create a non-const reverse graph.
|
||||
|`const BidirectionalGraph&`
|
||||
|===
|
||||
|
||||
==== Model of
|
||||
|
||||
xref:concepts/BidirectionalGraph.adoc[BidirectionalGraph] and optionally
|
||||
xref:concepts/VertexListGraph.adoc[VertexListGraph] and
|
||||
xref:concepts/PropertyGraph.adoc[PropertyGraph]
|
||||
|
||||
==== Where Defined
|
||||
|
||||
link:../../../boost/graph/reverse_graph.hpp[`boost/graph/reverse_graph.hpp`]
|
||||
|
||||
=== Associated Types
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<reverse_graph>::vertex_descriptor` +
|
||||
+
|
||||
The type for the vertex descriptors associated with the
|
||||
`reverse_graph`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<reverse_graph>::edge_descriptor` +
|
||||
+
|
||||
The type for the edge descriptors associated with the
|
||||
`reverse_graph`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<reverse_graph>::vertex_iterator` +
|
||||
+
|
||||
The type for the iterators returned by `vertices()`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<reverse_graph>::edge_iterator` +
|
||||
+
|
||||
The type for the iterators returned by `edges()`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<reverse_graph>::out_edge_iterator` +
|
||||
+
|
||||
The type for the iterators returned by `out_edges()`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<reverse_graph>::adjacency_iterator` +
|
||||
+
|
||||
The type for the iterators returned by `adjacent_vertices()`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<reverse_graph>::directed_category` +
|
||||
+
|
||||
Provides information about whether the graph is directed
|
||||
(`directed_tag`) or undirected (`undirected_tag`).
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<reverse_graph>::edge_parallel_category` +
|
||||
+
|
||||
This describes whether the graph class allows the insertion of parallel
|
||||
edges (edges with the same source and target). The two tags are
|
||||
`allow_parallel_edge-_tag` and
|
||||
`disallow_parallel_edge_tag`. The `setS` and `hash_setS`
|
||||
variants disallow parallel edges while the others allow parallel edges.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<reverse_graph>::vertices_size_type` +
|
||||
+
|
||||
The type used for dealing with the number of vertices in the graph.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<reverse_graph>::edges_size_type` +
|
||||
+
|
||||
The type used for dealing with the number of edges in the graph.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<reverse_graph>::degree_size_type` +
|
||||
+
|
||||
The type used for dealing with the number of edges incident to a vertex
|
||||
in the graph.
|
||||
|
||||
'''''
|
||||
|
||||
`property_map<reverse_graph, PropertyTag>::type` +
|
||||
and +
|
||||
`property_map<reverse_graph, PropertyTag>::const_type` +
|
||||
+
|
||||
The property map type for vertex or edge properties in the graph. The
|
||||
specific property is specified by the `PropertyTag` template argument,
|
||||
and must match one of the properties specified in the `VertexProperty`
|
||||
or `EdgeProperty` for the graph.
|
||||
|
||||
'''''
|
||||
|
||||
`property_map<reverse_graph, edge_underlying_t>::type` +
|
||||
and +
|
||||
`property_map<reverse_graph, edge_underlying_t>::const_type` +
|
||||
+
|
||||
An edge property type mapping from edge descriptors in the
|
||||
`reverse_graph` to edge descriptors in the underlying
|
||||
`BidirectionalGraph` object.
|
||||
|
||||
'''''
|
||||
|
||||
=== Member Functions
|
||||
|
||||
'''''
|
||||
|
||||
....
|
||||
|
||||
reverse_graph(BidirectionalGraph& g)
|
||||
....
|
||||
|
||||
Constructor. Create a reversed (transposed) view of the graph `g`.
|
||||
|
||||
'''''
|
||||
|
||||
=== Non-Member Functions
|
||||
|
||||
'''''
|
||||
== Synopsis
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename BidirectionalGraph>
|
||||
reverse_graph<BidirectionalGraph, BidirectionalGraph&>
|
||||
make_reverse_graph(BidirectionalGraph& g);
|
||||
template <typename BidirectionalGraph,
|
||||
typename GraphRef = const BidirectionalGraph&>
|
||||
class reverse_graph;
|
||||
|
||||
template <typename BidirectionalGraph>
|
||||
reverse_graph<BidirectionalGraph, const BidirectionalGraph&>
|
||||
make_reverse_graph(const BidirectionalGraph& g)
|
||||
make_reverse_graph(const BidirectionalGraph& g);
|
||||
|
||||
template <typename BidirectionalGraph>
|
||||
reverse_graph<BidirectionalGraph, BidirectionalGraph&>
|
||||
make_reverse_graph(BidirectionalGraph& g);
|
||||
----
|
||||
|
||||
Helper function for creating a `reverse_graph`.
|
||||
The `reverse_graph` does not copy the original graph. It holds a reference and
|
||||
swaps the meaning of `out_edges` and `in_edges`. This makes `source()` and
|
||||
`target()` return the opposite of what they return on the original graph.
|
||||
|
||||
'''''
|
||||
The `GraphRef` parameter controls const-ness: `const BidirectionalGraph&`
|
||||
(default) gives a read-only view, `BidirectionalGraph&` gives a mutable view.
|
||||
|
||||
== Template Parameters
|
||||
|
||||
[cols="1,3,1",options="header"]
|
||||
|===
|
||||
| Parameter | Description | Default
|
||||
|
||||
| `BidirectionalGraph`
|
||||
| The underlying graph type. Must model BidirectionalGraph.
|
||||
|
|
||||
|
||||
| `GraphRef`
|
||||
| Reference type to the underlying graph. Use `const BidirectionalGraph&` for a
|
||||
read-only view, `BidirectionalGraph&` for a mutable view.
|
||||
| `const BidirectionalGraph&`
|
||||
|===
|
||||
|
||||
== Non-Member Functions
|
||||
|
||||
=== Structure Access
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
std::pair<vertex_iterator, vertex_iterator>
|
||||
vertices(const reverse_graph& g)
|
||||
vertices(const reverse_graph& g);
|
||||
----
|
||||
|
||||
Returns an iterator-range providing access to the vertex set of graph
|
||||
`g`.
|
||||
Same vertices as the underlying graph.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
std::pair<out_edge_iterator, out_edge_iterator>
|
||||
out_edges(vertex_descriptor v, const reverse_graph& g)
|
||||
vertex_descriptor vertex(vertices_size_type n, const reverse_graph& g);
|
||||
----
|
||||
|
||||
Returns an iterator-range providing access to the out-edges of vertex
|
||||
`v` in graph `g`. These out-edges correspond to the in-edges of the
|
||||
adapted graph.
|
||||
Returns the nth vertex.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
std::pair<in_edge_iterator, in_edge_iterator>
|
||||
in_edges(vertex_descriptor v, const reverse_graph& g)
|
||||
----
|
||||
|
||||
Returns an iterator-range providing access to the in-edges of vertex
|
||||
`v` in graph `g`. These in-edges correspond to the out edges of the
|
||||
adapted graph.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
std::pair<adjacency_iterator, adjacency_iterator>
|
||||
adjacent_vertices(vertex_descriptor v, const reverse_graph& g)
|
||||
adjacent_vertices(vertex_descriptor v, const reverse_graph& g);
|
||||
----
|
||||
|
||||
Returns an iterator-range providing access to the adjacent vertices of
|
||||
vertex `v` in graph `g`.
|
||||
Returns the vertices adjacent to `v` through reversed edges.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
vertex_descriptor
|
||||
source(edge_descriptor e, const reverse_graph& g)
|
||||
std::pair<out_edge_iterator, out_edge_iterator>
|
||||
out_edges(vertex_descriptor v, const reverse_graph& g);
|
||||
----
|
||||
|
||||
Returns the source vertex of edge `e`.
|
||||
Returns the in-edges of `v` in the underlying graph (as out-edges of the
|
||||
reversed view).
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
vertex_descriptor
|
||||
target(edge_descriptor e, const reverse_graph& g)
|
||||
std::pair<in_edge_iterator, in_edge_iterator>
|
||||
in_edges(vertex_descriptor v, const reverse_graph& g);
|
||||
----
|
||||
|
||||
Returns the target vertex of edge `e`.
|
||||
Returns the out-edges of `v` in the underlying graph (as in-edges of the
|
||||
reversed view).
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
degree_size_type
|
||||
out_degree(vertex_descriptor u, const reverse_graph& g)
|
||||
vertex_descriptor source(edge_descriptor e, const reverse_graph& g);
|
||||
vertex_descriptor target(edge_descriptor e, const reverse_graph& g);
|
||||
----
|
||||
|
||||
Returns the number of edges leaving vertex `u`.
|
||||
Reversed: `source()` returns the target of the underlying edge, and vice versa.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
degree_size_type
|
||||
in_degree(vertex_descriptor u, const reverse_graph& g)
|
||||
degree_size_type out_degree(vertex_descriptor u, const reverse_graph& g);
|
||||
degree_size_type in_degree(vertex_descriptor u, const reverse_graph& g);
|
||||
vertices_size_type num_vertices(const reverse_graph& g);
|
||||
edges_size_type num_edges(const reverse_graph& g);
|
||||
----
|
||||
|
||||
Returns the number of edges entering vertex `u`. This operation is only
|
||||
available if `bidirectionalS` was specified for the `Directed` template
|
||||
parameter.
|
||||
Degree and count functions. `out_degree` returns the in-degree of the
|
||||
underlying graph, and vice versa.
|
||||
|
||||
'''''
|
||||
=== Property Map Access
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
vertices_size_type
|
||||
num_vertices(const reverse_graph& g)
|
||||
----
|
||||
|
||||
Returns the number of vertices in the graph `g`.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
vertex_descriptor
|
||||
vertex(vertices_size_type n, const reverse_graph& g)
|
||||
----
|
||||
|
||||
Returns the nth vertex in the graph's vertex list.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
std::pair<edge_descriptor, bool>
|
||||
edge(vertex_descriptor u, vertex_descriptor v,
|
||||
const reverse_graph& g)
|
||||
----
|
||||
|
||||
Returns the edge connecting vertex `u` to vertex `v` in graph `g`.
|
||||
|
||||
'''''
|
||||
Property maps from the underlying graph are accessible through the reversed
|
||||
view. Additionally, the `edge_underlying_t` property maps reversed edge
|
||||
descriptors back to the underlying edge descriptors.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename PropertyTag>
|
||||
property_map<reverse_graph, PropertyTag>::type
|
||||
get(PropertyTag, reverse_graph& g)
|
||||
get(PropertyTag, reverse_graph& g);
|
||||
|
||||
template <typename PropertyTag>
|
||||
property_map<reverse_graph, PropertyTag>::const_type
|
||||
get(PropertyTag, const reverse_graph& g)
|
||||
get(PropertyTag, const reverse_graph& g);
|
||||
----
|
||||
|
||||
Returns the property map object for the vertex property specified by
|
||||
`PropertyTag`. The `PropertyTag` must match one of the properties
|
||||
specified in the graph's `VertexProperty` template argument.
|
||||
== Associated Types
|
||||
|
||||
'''''
|
||||
[cols="1,3",options="header"]
|
||||
|===
|
||||
| Type | Description
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
property_map<reverse_graph, edge_underlying_t>::const_type
|
||||
get(edge_underlying_t, const reverse_graph& g)
|
||||
----
|
||||
| `vertex_descriptor`
|
||||
| Same as the underlying graph.
|
||||
|
||||
Returns a property map object that converts from edge descriptors in the
|
||||
`reverse_graph` to edge descriptors in the underlying
|
||||
`BidirectionalGraph` object.
|
||||
| `edge_descriptor`
|
||||
| Same as the underlying graph.
|
||||
|
||||
'''''
|
||||
| `out_edge_iterator`
|
||||
| Corresponds to `in_edge_iterator` of the underlying graph.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename PropertyTag, typename X>
|
||||
typename property_traits<property_map<reverse_graph, PropertyTag>::const_type>::value_type
|
||||
get(PropertyTag, const reverse_graph& g, X x)
|
||||
----
|
||||
| `in_edge_iterator`
|
||||
| Corresponds to `out_edge_iterator` of the underlying graph.
|
||||
|
||||
This returns the property value for `x`, which is either a vertex or
|
||||
edge descriptor.
|
||||
| `directed_category`
|
||||
| From the underlying graph.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
typename graph_traits<BidirectionalGraph>::edge_descriptor
|
||||
get(edge_underlying_t, const reverse_graph& g, edge_descriptor e)
|
||||
----
|
||||
|
||||
This returns the underlying edge descriptor for the edge `e` in the
|
||||
`reverse_graph`.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename PropertyTag, typename X, typename Value>
|
||||
void
|
||||
put(PropertyTag, const reverse_graph& g, X x, const Value& value)
|
||||
----
|
||||
|
||||
This sets the property value for `x` to `value`. `x` is either a
|
||||
vertex or edge descriptor. `Value` must be convertible to
|
||||
`typename property_traits<property_map<reverse_graph, PropertyTag>::type>::value_type`
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename GraphProperties, typename GraphPropertyTag>
|
||||
typename property_value<GraphProperties, GraphPropertyTag>::type&
|
||||
get_property(reverse_graph& g, GraphPropertyTag)
|
||||
----
|
||||
|
||||
Return the property specified by `GraphPropertyTag` that is attached to
|
||||
the graph object `g`. The `property_value` traits class is defined in
|
||||
link:../../../boost/pending/property.hpp[`boost/pending/property.hpp`].
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename GraphProperties, typename GraphPropertyTag>
|
||||
const typename property_value<GraphProperties, GraphPropertyTag>::type&
|
||||
get_property(const reverse_graph& g, GraphPropertyTag)
|
||||
----
|
||||
|
||||
Return the property specified by `GraphPropertyTag` that is attached to
|
||||
the graph object `g`. The `property_value` traits class is defined in
|
||||
link:../../../boost/pending/property.hpp[`boost/pending/property.hpp`].
|
||||
| `edge_parallel_category`
|
||||
| From the underlying graph.
|
||||
|===
|
||||
|
||||
@@ -1,248 +0,0 @@
|
||||
= Using SGB Graphs in BGL
|
||||
|
||||
The Boost Graph Library (BGL) header,
|
||||
link:../../../boost/graph/stanford_graph.hpp[`<boost/graph/stanford_graph.hpp>`],
|
||||
adapts a Stanford GraphBase (SGB) `Graph` pointer into a BGL-compatible
|
||||
xref:concepts/VertexListGraph.adoc[VertexListGraph]. Note that a graph adaptor
|
||||
*class* is _not_ used; SGB's `Graph*` itself becomes a model of
|
||||
VertexListGraph. The VertexListGraph concept is fulfilled by defining
|
||||
the appropriate non-member functions for `Graph*`.
|
||||
|
||||
[#sec:SGB]
|
||||
=== The Stanford GraphBase
|
||||
|
||||
"The http://www-cs-staff.stanford.edu/~knuth/sgb.html[Stanford
|
||||
GraphBase] (SGB) is a collection of datasets and computer programs that
|
||||
generate and examine a wide variety of graphs and networks." The SGB
|
||||
was developed and published by
|
||||
http://www-cs-staff.stanford.edu/~knuth[Donald E. Knuth] in 1993. The
|
||||
fully documented source code is available for anonymous ftp from
|
||||
ftp://labrea.stanford.edu/pub/sgb/sgb.tar.gz[Stanford University] and in
|
||||
the book "The Stanford GraphBase, A Platform for Combinatorial
|
||||
Computing," published jointly by ACM Press and Addison-Wesley Publishing
|
||||
Company in 1993. (This book contains several chapters with additional
|
||||
information not available in the electronic distribution.)
|
||||
|
||||
[#sec:CWEB]
|
||||
==== Prerequisites
|
||||
|
||||
The source code of SGB is written in accordance with the rules of the
|
||||
http://www-cs-staff.stanford.edu/~knuth/lp.html[Literate Programming]
|
||||
paradigm, so you need to make sure that your computer supports the
|
||||
http://www-cs-staff.stanford.edu/~knuth/cweb.html[CWEB] system. The
|
||||
CWEB sources are available for anonymous ftp from
|
||||
ftp://labrea.stanford.edu/pub/cweb/cweb.tar.gz[Stanford University].
|
||||
Bootstrapping CWEB on Unix systems is elementary and documented in the
|
||||
CWEB distribution; pre-compiled binary executables of the CWEB tools for
|
||||
Win32 systems are available from
|
||||
http://www.literateprogramming.com[www.literateprogramming.com].
|
||||
|
||||
[#sec:SGB:Installation]
|
||||
==== Installing the SGB
|
||||
|
||||
After you have acquired the <<sec:SGB,SGB sources>> and have
|
||||
installed a working <<sec:CWEB,CWEB system>> (at least the "ctangle"
|
||||
processor is required), you're almost set for compiling the SGB
|
||||
sources. SGB is written in "old-style C," but the Boost Graph Library
|
||||
expects to handle "modern C" and C++. Fortunately, the SGB
|
||||
distribution comes with an appropriate set of patches that convert all
|
||||
the sources from "KR-C" to "ANSI-C," thus allowing for smooth
|
||||
integration of the Stanford GraphBase in the Boost Graph Library.
|
||||
|
||||
* *Unix*: After extracting the SGB archive, but prior to invoking
|
||||
"`make tests`" and "`make install`," you should say
|
||||
"`ln -s PROTOTYPES/*.ch .`" in the root directory where you
|
||||
extracted the SGB files (or you can simply copy the change files next to
|
||||
the proper source files). The Unix `Makefile` coming with SGB
|
||||
conveniently looks for "change files" matching the SGB source files and
|
||||
automatically applies them with the "ctangle" processor. The resulting
|
||||
C files will smoothly run through the compiler.
|
||||
* *Win32*: The "MSVC" subdirectory of the SGB distribution contains a
|
||||
complete set of "Developer Studio Projects" (and a single "Workspace"),
|
||||
applicable with Microsoft Developer Studio 6. The installation process
|
||||
is documented in the accompanying file `README.MSVC`. The "MSVC"
|
||||
contribution has been updated to make use of the "PROTOTYPES" as well,
|
||||
so you don't need to worry about that.
|
||||
|
||||
[#sec:UsingSGB]
|
||||
==== Using the SGB
|
||||
|
||||
After you have run <<sec:SGB:Installation,the installation process>>
|
||||
of the SGB, you can use the BGL graph interface with the SGB
|
||||
`Graph*`,
|
||||
link:../../../boost/graph/stanford_graph.hpp[`<boost/graph/stanford_graph.hpp>`],
|
||||
which will be described <<sec:BGL:Interface,next>>. All you have to
|
||||
do is tell the C++ compiler where to look for the SGB
|
||||
headerfiles (by default, `/usr/local/sgb/include` on Unix and the "MSVC"
|
||||
subdirectory of the SGB installation on Win32) and the linker where to
|
||||
find the SGB static library file (`libgb.a` on Unix and `libgb.lib` on
|
||||
Win32); consult the documentation of your particular compiler about how
|
||||
to do that.
|
||||
|
||||
[#sec:SGB:Problems]
|
||||
==== Technicalities
|
||||
|
||||
* *Headerfile selection*: The two SGB modules `gb_graph` and
|
||||
`gb_io` use the preprocessor switch `SYSV` to select either the
|
||||
headerfile `<string.h>` (if `SYSV` is `++#++define`d) or the
|
||||
headerfile `<strings.h>` (if `SYSV` is _not_ `++#++define`d).
|
||||
Some compilers, like `gcc`/`g++`, don't care much (`gcc`
|
||||
"knows" about the "string" functions without referring to
|
||||
`<string.h>`), but others, like MSVC on Win32, do (so all
|
||||
"Developer Studio Projects" in the "MSVC" subdirectory of the
|
||||
<<sec:SGB,SGB distribution>> appropriately define `SYSV`). You should
|
||||
be careful to set (or not) `SYSV` according to the needs of your
|
||||
compiler.
|
||||
* *Missing include guards*: None of the SGB headerfiles uses "internal
|
||||
include guards" to protect itself from multiple inclusion. To avoid
|
||||
trouble, you must _not_ `++#++include` any of the SGB headerfiles before
|
||||
or after <<sec:Wrapper,the BGL wrapper>> in a compilation unit; it
|
||||
will fully suffice to use the BGL interface.
|
||||
* *Preprocessor macros*: The SGB headerfiles make liberal use of the
|
||||
preprocessor _without_ sticking to a particular convention (like
|
||||
all-uppercase names or a particular prefix). At the time of writing,
|
||||
already three of these preprocessor macros collide with the conventions
|
||||
of either C++, g++, or BGL, and are fixed in
|
||||
<<sec:Wrapper,the BGL wrapper>>. We can not guarantee that no other
|
||||
preprocessor-induced problems may arise (but we are willing to learn
|
||||
about any such collisions).
|
||||
|
||||
[#sec:BGL:Interface]
|
||||
=== The BGL Interface for the SGB
|
||||
|
||||
[#sec:Wrapper]
|
||||
==== Where Defined
|
||||
|
||||
link:../../../boost/graph/stanford_graph.hpp[`<boost/graph/stanford_graph.hpp>`]
|
||||
|
||||
The main purpose of this Boost Graph Library (BGL) headerfile is to
|
||||
`++#++include` all global definitions for the general stuff of the
|
||||
<<sec:SGB,Stanford GraphBase>> (SGB) and its various graph generator
|
||||
functions by reading all <<sec:SGB:Problems,SGB headerfiles>> as in
|
||||
section 2 of the "`test_sample`" program.
|
||||
|
||||
On top of the SGB stuff, the BGL `stanford_graph.hpp` header adds
|
||||
and defines appropriate types and functions for using the SGB graphs in
|
||||
the BGL framework. Apart from the improved interface, the
|
||||
<<sec:UsingSGB,SGB (static) library>> is used "as is" in the context
|
||||
of BGL.
|
||||
|
||||
==== Model Of
|
||||
|
||||
xref:concepts/VertexListGraph.adoc[Vertex List Graph] and
|
||||
xref:concepts/PropertyGraph.adoc[Property Graph]. The set of property tags that
|
||||
can be used with the SGB graph is described in the
|
||||
<<properties,Vertex and Edge Properties>> section below.
|
||||
|
||||
[#sec:Example]
|
||||
==== Example
|
||||
|
||||
The example program
|
||||
link:../example/miles_span.cpp[`<example/miles_span.cpp>`]
|
||||
represents the first application of the generic framework of BGL to an
|
||||
SGB graph. It uses Prim's algorithm to solve the "minimum spanning
|
||||
tree" problem. In addition, the programs
|
||||
link:../../../libs/graph/example/girth.cpp[`<example/girth.cpp>`]
|
||||
and
|
||||
link:../example/roget_components.cpp[`<example/roget_components.cpp>`]
|
||||
have been ported from the SGB. We intend to implement more algorithms
|
||||
from SGB in a generic fashion and to provide the remaining example
|
||||
programs of SGB for the BGL framework. If you would like to help, feel
|
||||
free to submit your contributions!
|
||||
|
||||
==== Associated Types
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<Graph++*>++::vertex_descriptor` +
|
||||
+
|
||||
The type for the vertex descriptors associated with the `Graph*`. We
|
||||
use the type `Vertex*` as the vertex descriptor.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<Graph++*>++::edge_descriptor` +
|
||||
+
|
||||
The type for the edge descriptors associated with the `Graph*`. This
|
||||
is the type `boost::sgb_edge`. In addition to supporting all the
|
||||
required operations of a BGL edge descriptor, the `boost::sgb_edge`
|
||||
class has the following constructor.
|
||||
|
||||
....
|
||||
|
||||
sgb_edge::sgb_edge(Arc* arc, Vertex* source)
|
||||
....
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<Graph++*>++::vertex_iterator` +
|
||||
+
|
||||
The type for the iterators returned by `vertices()`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<Graph++*>++::out_edge_iterator` +
|
||||
+
|
||||
The type for the iterators returned by `out_edges()`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<Graph++*>++::adjacency_iterator` +
|
||||
+
|
||||
The type for the iterators returned by `adjacent_vertices()`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<Graph++*>++::vertices_size_type` +
|
||||
+
|
||||
The type used for dealing with the number of vertices in the graph.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<Graph++*>++::edge_size_type` +
|
||||
+
|
||||
The type used for dealing with the number of edges in the graph.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<Graph++*>++::degree_size_type` +
|
||||
+
|
||||
The type used for dealing with the number of edges incident to a vertex
|
||||
in the graph.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<Graph++*>++::directed_category` +
|
||||
+
|
||||
Provides information about whether the graph is directed or undirected.
|
||||
An SGB `Graph*` is directed so this type is `directed_tag`.
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<Graph++*>++::traversal_category` +
|
||||
+
|
||||
An SGB `Graph*` provides traversal of the vertex set, out edges, and
|
||||
adjacent vertices. Therefore the traversal category tag is defined as
|
||||
follows:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
struct sgb_traversal_tag :
|
||||
public virtual vertex_list_graph_tag,
|
||||
public virtual incidence_graph_tag,
|
||||
public virtual adjacency_graph_tag { };
|
||||
----
|
||||
|
||||
'''''
|
||||
|
||||
`graph_traits<Graph++*>++::edge_parallel_category` +
|
||||
+
|
||||
This describes whether the graph class allows the insertion of parallel
|
||||
edges (edges with the same source and target). The SGB `Graph*`
|
||||
does not prevent addition of parallel edges, so this type is
|
||||
`allow_parallel_edge_tag`.
|
||||
|
||||
'''''
|
||||
|
||||
==== Non-Member Functions
|
||||
@@ -1,806 +1,227 @@
|
||||
[#sec:subgraph-class]
|
||||
= Subgraph
|
||||
|
||||
....
|
||||
An induced subgraph with a hierarchical parent/child structure.
|
||||
|
||||
subgraph<Graph>
|
||||
....
|
||||
*Defined in:* `<boost/graph/subgraph.hpp>` +
|
||||
*Models:* VertexMutableGraph, EdgeMutableGraph (plus whatever the underlying
|
||||
graph models: VertexListGraph, EdgeListGraph, BidirectionalGraph, etc.)
|
||||
|
||||
The subgraph class provides a mechanism for keeping track of a graph and
|
||||
its subgraphs. A graph _G'_ is a _subgraph_ of a graph _G_ if the vertex
|
||||
set of _G'_ is a subset of the vertex set of _G_ and if the edge set of
|
||||
_G'_ is a subset of the edge set of _G_. That is, if _G'=(V',E')_ and
|
||||
_G=(V,E)_, then _G'_ is a subgraph of _G_ if _V'_ is a subset of _V_ and
|
||||
_E_ is a subset of _E'_. An _induced subgraph_ is a subgraph formed by
|
||||
specifying a set of vertices _V'_ and then selecting all of the edges
|
||||
from the original graph that connect two vertices in _V'_. So in this
|
||||
case _E' = {(u,v) in E: u,v in V'}_. Figure 1 shows a graph _G~0~_
|
||||
and two subgraphs _G~1~_ and _G~2~_. The edge set for _G~1~_ is _E~1~ =
|
||||
{ (E,F), (C,F) }_ and the edge set for _G~2~_ is _E~2~ = { (A,B)
|
||||
}_. Edges such as _(E,B)_ and _(F,D)_ that cross out of a subgraph are
|
||||
not in the edge set of the subgraph.
|
||||
WARNING: The underlying graph type must have both `vertex_index` and
|
||||
`edge_index` internal properties. Edge indices are assigned by the subgraph
|
||||
class.
|
||||
|
||||
[#fig:subgraph-tree]
|
||||
.*Figure 1:* A graph with nested subgraphs, maintained in a tree
|
||||
structure.
|
||||
[cols=",",]
|
||||
|===
|
||||
|image:figs/subgraph.gif[figs/subgraph]
|
||||
|image:figs/subgraph-tree.gif[figs/subgraph-tree]
|
||||
|===
|
||||
|
||||
The `subgraph` class implements induced subgraphs. The main graph and
|
||||
its subgraphs are maintained in a tree data structure. The main graph is
|
||||
the root, and subgraphs are either children of the root or of other
|
||||
subgraphs. All of the nodes in this tree, including the root graph, are
|
||||
instances of the `subgraph` class. The `subgraph` implementation ensures
|
||||
that each node in the tree is an induced subgraph of its parent. The
|
||||
`subgraph` class implements the BGL graph interface, so each subgraph
|
||||
object can be treated as a graph.
|
||||
|
||||
==== Example
|
||||
|
||||
The full source code for this example is in `example/subgraph.cpp`. To
|
||||
create a graph and subgraphs, first create the root graph object. Here
|
||||
we use `adjacency_list` as the underlying graph implementation. The
|
||||
underlying graph type is required to have `vertex_index` and
|
||||
`edge_index` internal properties, so we add an edge index property
|
||||
to the adjacency list. We do not need to add a vertex index property
|
||||
because that is built in to the `adjacency_list`. We will be
|
||||
building the graph and subgraphs in Figure 1, so we will need a total of
|
||||
six vertices.
|
||||
== Example
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
typedef adjacency_list_traits< vecS, vecS, directedS > Traits;
|
||||
typedef subgraph< adjacency_list< vecS, vecS, directedS,
|
||||
no_property, property< edge_index_t, int > > > Graph;
|
||||
|
||||
const int N = 6;
|
||||
Graph G0(N);
|
||||
|
||||
enum { A, B, C, D, E, F}; // for conveniently referring to vertices in G0
|
||||
include::example$adaptors/subgraph.cpp[]
|
||||
----
|
||||
|
||||
Next we create two empty subgraph objects, specifying `G0` as their
|
||||
Expected output:
|
||||
|
||||
....
|
||||
Root: 5 vertices, 6 edges
|
||||
Subgraph: 3 vertices, 3 edges
|
||||
|
||||
Subgraph edges (local descriptors):
|
||||
1 -> 2
|
||||
1 -> 3
|
||||
2 -> 3
|
||||
....
|
||||
|
||||
== Synopsis
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename Graph>
|
||||
class subgraph;
|
||||
----
|
||||
|
||||
The `subgraph` class wraps an `adjacency_list` and maintains a tree of
|
||||
subgraphs. The root graph owns all vertices and edges. Child subgraphs hold
|
||||
subsets of the root's vertices, and their edge sets are _induced_: any edge in
|
||||
the root whose both endpoints are in the child automatically appears in the
|
||||
child.
|
||||
|
||||
Each subgraph uses _local_ descriptors (0-based within that subgraph). Use
|
||||
`local_to_global()` and `global_to_local()` to convert between local and root
|
||||
descriptors.
|
||||
|
||||
Adding an edge to a child subgraph also adds it to all ancestor subgraphs.
|
||||
Adding a vertex to a child subgraph also adds it to all ancestors.
|
||||
|
||||
== Template Parameters
|
||||
|
||||
[cols="1,3",options="header"]
|
||||
|===
|
||||
| Parameter | Description
|
||||
|
||||
| `Graph`
|
||||
| Must model VertexMutableGraph and EdgeMutableGraph. Must have internal
|
||||
`vertex_index` and `edge_index` properties. With `vecS` for the vertex
|
||||
container, `vertex_index` is automatic. `edge_index` must always be declared
|
||||
explicitly:
|
||||
|
||||
`adjacency_list<vecS, vecS, directedS, no_property, property<edge_index_t, int>>`
|
||||
|===
|
||||
|
||||
== Member Functions
|
||||
|
||||
=== Constructors
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
subgraph(vertices_size_type n,
|
||||
const GraphProperty& p = GraphProperty());
|
||||
----
|
||||
|
||||
Create a root graph with `n` vertices and no edges.
|
||||
|
||||
=== Subgraph Creation
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
subgraph& create_subgraph();
|
||||
----
|
||||
|
||||
Create an empty child subgraph.
|
||||
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
template <typename VertexIterator>
|
||||
subgraph& create_subgraph(VertexIterator first, VertexIterator last);
|
||||
----
|
||||
|
||||
Create a child subgraph with the given vertices. Edges are induced from the
|
||||
parent.
|
||||
|
||||
....
|
||||
|
||||
Graph& G1 = G0.create_subgraph(), G2 = G0.create_subgraph();
|
||||
enum { A1, B1, C1 }; // for conveniently referring to vertices in G1
|
||||
enum { A2, B2 }; // for conveniently referring to vertices in G2
|
||||
....
|
||||
|
||||
We can add vertices from the root graph to the subgraphs using the
|
||||
`add_vertex` function. Since the graph implementation is
|
||||
`adjacency_list` with `VertexList=vecS`, we can use the integers (or
|
||||
in this case enums) in the range _[0,6)_ as vertex descriptors.
|
||||
|
||||
....
|
||||
|
||||
add_vertex(C, G1); // global vertex C becomes local A1 for G1
|
||||
add_vertex(E, G1); // global vertex E becomes local B1 for G1
|
||||
add_vertex(F, G1); // global vertex F becomes local C1 for G1
|
||||
|
||||
add_vertex(A, G2); // global vertex A becomes local A2 for G2
|
||||
add_vertex(B, G2); // global vertex B becomes local B2 for G2
|
||||
....
|
||||
|
||||
Next we can add edges to the main graph using the usual `add_edge`
|
||||
function.
|
||||
|
||||
....
|
||||
|
||||
add_edge(A, B, G0);
|
||||
add_edge(B, C, G0);
|
||||
add_edge(B, D, G0);
|
||||
add_edge(E, B, G0);
|
||||
add_edge(E, F, G0);
|
||||
add_edge(F, D, G0);
|
||||
....
|
||||
|
||||
We can also add edges to subgraphs such as `G1` using the `add_edge`
|
||||
function. Each subgraph has its own vertex and edge descriptors, which
|
||||
we call _local_ descriptors. We refer to root graph's vertex and edge
|
||||
descriptors as the _global_ descriptors. Above, we used global vertex
|
||||
descriptors to add vertices to the graph. However, most `subgraph`
|
||||
functions work with local descriptors. So in the following call to
|
||||
`add_edge` we add the edge `(A1,C1)` (or numerically `(0,2)`) which
|
||||
is the local version (for subgraph `G1`) of the global edge `(C,F)` (or
|
||||
numerically `(2,5)`). Adding an edge to a subgraph causes the edge to
|
||||
also be added to all of its ancestors in the subgraph tree to ensure
|
||||
that the subgraph property is maintained.
|
||||
|
||||
....
|
||||
|
||||
add_edge(A1, C1, G1); // (A1,C1) is subgraph G1 local indices
|
||||
// for the global edge (C,F).
|
||||
....
|
||||
|
||||
==== Where Defined
|
||||
|
||||
`boost/graph/subgraph.hpp`
|
||||
|
||||
==== Template Parameters
|
||||
|
||||
[cols=",",options="header",]
|
||||
|===
|
||||
|Parameter |Description
|
||||
|`Graph` |A graph type modeling
|
||||
xref:concepts/VertexMutableGraph.adoc[VertexMutableGraph] and
|
||||
xref:concepts/EdgeMutableGraph.adoc[EdgeMutableGraph]. Also the graph must have
|
||||
internal `vertex_index` and `edge_index` properties. The vertex
|
||||
indices must be maintained automatically by the graph, whereas the edge
|
||||
indices will be assigned by the `subgraph` class implementation.
|
||||
|===
|
||||
|
||||
==== Model Of
|
||||
|
||||
`subgraph` is a model of
|
||||
xref:concepts/VertexMutableGraph.adoc[VertexMutableGraph]. Also, if the `Graph`
|
||||
type models xref:concepts/VertexListGraph.adoc[VertexListGraph],
|
||||
xref:concepts/EdgeListGraph.adoc[EdgeListGraph] and/or
|
||||
xref:concepts/BidirectionalGraph.adoc[BidirectionalGraph], then
|
||||
`subgraph<Graph>` will also models these concepts.
|
||||
|
||||
==== Associated Types
|
||||
|
||||
If the graph is the root of the subgraph tree, then the vertex and edge
|
||||
descriptors are both the local descriptors for the root graph, and they
|
||||
are the global descriptors. If the graph is not the root, then the
|
||||
descriptors are local descriptors for the subgraph. The subgraph
|
||||
iterators are the same iterator types as the iterators of the underlying
|
||||
`Graph` type.
|
||||
|
||||
'''''
|
||||
=== Descriptor Conversion
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
graph_traits<subgraph>::vertex_descriptor
|
||||
vertex_descriptor local_to_global(vertex_descriptor u_local) const;
|
||||
vertex_descriptor global_to_local(vertex_descriptor u_global) const;
|
||||
edge_descriptor local_to_global(edge_descriptor e_local) const;
|
||||
edge_descriptor global_to_local(edge_descriptor e_global) const;
|
||||
----
|
||||
|
||||
The type for the vertex descriptors. (Required by
|
||||
xref:concepts/Graph.adoc[Graph].)
|
||||
Convert between local (subgraph-relative) and global (root) descriptors.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
graph_traits<subgraph>::edge_descriptor
|
||||
std::pair<vertex_descriptor, bool>
|
||||
find_vertex(vertex_descriptor u_global) const;
|
||||
----
|
||||
|
||||
The type for the edge descriptors. (Required by xref:concepts/Graph.adoc[Graph].)
|
||||
Returns `(local_descriptor, true)` if the global vertex is in this subgraph,
|
||||
`(_, false)` otherwise.
|
||||
|
||||
'''''
|
||||
=== Hierarchy Navigation
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
graph_traits<subgraph>::vertex_iterator
|
||||
subgraph& root();
|
||||
bool is_root() const;
|
||||
subgraph& parent();
|
||||
std::pair<children_iterator, children_iterator> children() const;
|
||||
----
|
||||
|
||||
The type for the iterators returned by `vertices`. (Required by
|
||||
xref:concepts/VertexListGraph.adoc[VertexListGraph].)
|
||||
Navigate the subgraph tree. `root()` returns the top-level graph. `parent()`
|
||||
returns the direct parent. `children()` iterates over child subgraphs.
|
||||
|
||||
'''''
|
||||
== Non-Member Functions
|
||||
|
||||
=== Structure Access
|
||||
|
||||
Standard graph functions: `vertices()`, `edges()`, `out_edges()`, `in_edges()`,
|
||||
`adjacent_vertices()`, `source()`, `target()`, `out_degree()`, `in_degree()`,
|
||||
`num_vertices()`, `num_edges()`, `edge()`. All operate on local descriptors.
|
||||
|
||||
=== Structure Modification
|
||||
|
||||
WARNING: `remove_vertex()` is not implemented. Calling it triggers an assertion
|
||||
failure at runtime. If you need to hide vertices, use `filtered_graph` on top
|
||||
of the subgraph.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
graph_traits<subgraph>::edge_iterator
|
||||
vertex_descriptor add_vertex(subgraph& g);
|
||||
----
|
||||
|
||||
The type for the iterators returned by `edges`. (Required by
|
||||
xref:concepts/EdgeListGraph.adoc[EdgeListGraph].)
|
||||
Add a new vertex to the subgraph (and all ancestors up to root).
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
graph_traits<subgraph>::out_edge_iterator
|
||||
vertex_descriptor add_vertex(vertex_descriptor u_global, subgraph& g);
|
||||
----
|
||||
|
||||
The type for the iterators returned by `out_edges`. (Required by
|
||||
xref:concepts/IncidenceGraph.adoc[IncidenceGraph].)
|
||||
Add an existing global vertex to this subgraph. The vertex must already exist in
|
||||
the parent.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
graph_traits<subgraph>::in_edge_iterator
|
||||
std::pair<edge_descriptor, bool>
|
||||
add_edge(vertex_descriptor u, vertex_descriptor v, subgraph& g);
|
||||
----
|
||||
|
||||
The `in_edge_iterator` is the iterator type returned by the
|
||||
`in_edges` function. (Required by
|
||||
xref:concepts/BidirectionalGraph.adoc[BidirectionalGraph].)
|
||||
Add an edge between local vertices `u` and `v`. The edge is also added to all
|
||||
ancestor subgraphs.
|
||||
|
||||
'''''
|
||||
'''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
graph_traits<subgraph>::adjacency_iterator
|
||||
void remove_edge(vertex_descriptor u, vertex_descriptor v, subgraph& g);
|
||||
void remove_edge(edge_descriptor e, subgraph& g);
|
||||
----
|
||||
|
||||
The type for the iterators returned by `adjacent_vertices`.
|
||||
(Required by xref:concepts/AdjacencyGraph.adoc[AdjacencyGraph].)
|
||||
Remove an edge from the subgraph.
|
||||
|
||||
'''''
|
||||
=== Property Map Access
|
||||
|
||||
Property maps operate on local descriptors. Changes to properties through a
|
||||
subgraph are visible from all other subgraphs and the root, because all
|
||||
subgraphs share the same underlying property storage.
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
graph_traits<subgraph>::directed_category
|
||||
----
|
||||
|
||||
Provides information about whether the graph is directed
|
||||
(`directed_tag`) or undirected (`undirected_tag`). (Required by
|
||||
xref:concepts/Graph.adoc[Graph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
graph_traits<subgraph>::edge_parallel_category
|
||||
----
|
||||
|
||||
This describes whether the graph class allows the insertion of parallel
|
||||
edges (edges with the same source and target), which depends on the
|
||||
underlying `Graph` class. The two tags are
|
||||
`allow_parallel_edge_tag` and
|
||||
`disallow_parallel_edge_tag`. (Required by
|
||||
xref:concepts/Graph.adoc[Graph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
graph_traits<subgraph>::vertices_size_type
|
||||
----
|
||||
|
||||
The type used for dealing with the number of vertices in the graph.
|
||||
(Required by xref:concepts/VertexListGraph.adoc[VertexListGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
graph_traits<subgraph>::edges_size_type
|
||||
----
|
||||
|
||||
The type used for dealing with the number of edges in the graph.
|
||||
(Required by xref:concepts/EdgeListGraph.adoc[EdgeListGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
graph_traits<subgraph>::degree_size_type
|
||||
----
|
||||
|
||||
The type used for dealing with the number of out-edges of a vertex.
|
||||
(Required by xref:concepts/IncidenceGraph.adoc[IncidenceGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
template <typename PropertyTag>
|
||||
property_map<subgraph, PropertyTag>::type
|
||||
property_map<subgraph, PropertyTag>::const_type
|
||||
get(PropertyTag, subgraph& g);
|
||||
----
|
||||
|
||||
The map type for vertex or edge properties in the graph. The specific
|
||||
property is specified by the `PropertyTag` template argument, and must
|
||||
match one of the properties specified in the `VertexProperty` or
|
||||
`EdgeProperty` for the graph. (Required by
|
||||
xref:concepts/PropertyGraph.adoc[PropertyGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
....
|
||||
|
||||
subgraph::children_iterator
|
||||
....
|
||||
|
||||
The iterator type for accessing the children subgraphs of the graph.
|
||||
|
||||
==== Member Functions
|
||||
|
||||
'''''
|
||||
|
||||
....
|
||||
|
||||
subgraph(vertices_size_type n, const GraphProperty& p = GraphProperty())
|
||||
....
|
||||
|
||||
Creates the root graph object with `n` vertices and zero edges.
|
||||
|
||||
'''''
|
||||
|
||||
....
|
||||
|
||||
subgraph<Graph>& create_subgraph();
|
||||
....
|
||||
|
||||
Creates an empty subgraph object whose parent is _this_ graph.
|
||||
|
||||
'''''
|
||||
For bundled properties, use the `local()` and `global()` wrappers to
|
||||
disambiguate:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
template <typename VertexIterator>
|
||||
subgraph<Graph>&
|
||||
create_subgraph(VertexIterator first, VertexIterator last)
|
||||
auto lvm = get(local(&Node::value), sg); // local subgraph property
|
||||
auto gvm = get(global(&Node::value), sg); // root graph property
|
||||
----
|
||||
|
||||
Creates a subgraph object with the specified vertex set. The edges of
|
||||
the subgraph are induced by the vertex set. That is, every edge in the
|
||||
parent graph (which is _this_ graph) that connects two vertices in the
|
||||
subgraph will be added to the subgraph.
|
||||
== Associated Types
|
||||
|
||||
'''''
|
||||
[cols="1,3",options="header"]
|
||||
|===
|
||||
| Type | Description
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
| `vertex_descriptor`
|
||||
| Local descriptor within this subgraph.
|
||||
|
||||
vertex_descriptor local_to_global(vertex_descriptor u_local) const
|
||||
----
|
||||
| `edge_descriptor`
|
||||
| Local descriptor within this subgraph.
|
||||
|
||||
Converts a local vertex descriptor to the corresponding global vertex
|
||||
descriptor.
|
||||
| `children_iterator`
|
||||
| Iterator for accessing child subgraphs.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
vertex_descriptor global_to_local(vertex_descriptor u_global) const
|
||||
----
|
||||
|
||||
Converts a global vertex descriptor to the corresponding local vertex
|
||||
descriptor.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
edge_descriptor local_to_global(edge_descriptor e_local) const
|
||||
----
|
||||
|
||||
Converts a local edge descriptor to the corresponding global edge
|
||||
descriptor.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
edge_descriptor global_to_local(edge_descriptor u_global) const
|
||||
----
|
||||
|
||||
Converts a global edge descriptor to the corresponding local edge
|
||||
descriptor.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
std::pair<vertex_descriptor, bool> find_vertex(vertex_descriptor u_global) const
|
||||
----
|
||||
|
||||
If vertex _u_ is in this subgraph, the function returns the local vertex
|
||||
descriptor that corresponds to the global vertex descriptor
|
||||
`u_global` as the first part of the pair and `true` for the second
|
||||
part of the pair. If vertex _u_ is not in the subgraph then this
|
||||
function returns false in the second part of the pair.
|
||||
|
||||
'''''
|
||||
|
||||
....
|
||||
|
||||
subgraph& root()
|
||||
....
|
||||
|
||||
Returns the root graph of the subgraph tree.
|
||||
|
||||
'''''
|
||||
|
||||
....
|
||||
|
||||
bool is_root() const
|
||||
....
|
||||
|
||||
Return `true` if the graph is the root of the subgraph tree, and returns
|
||||
`false` otherwise.
|
||||
|
||||
'''''
|
||||
|
||||
....
|
||||
|
||||
subgraph& parent()
|
||||
....
|
||||
|
||||
Returns the parent graph.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
std::pair<children_iterator, children_iterator> children() const
|
||||
----
|
||||
|
||||
Return an iterator pair for accessing the children subgraphs.
|
||||
|
||||
==== Nonmember Functions
|
||||
|
||||
The functionality of `subgraph` depends on the `Graph` type. For
|
||||
example, if `Graph` in a
|
||||
xref:concepts/BidirectionalGraph.adoc[BidirectionalGraph] and supports
|
||||
`in_edges`, then so does `subgraph`. Here we list all the functions
|
||||
that `subgraph` could possibly support given a `Graph` type that is a
|
||||
model of xref:concepts/VertexListGraph.adoc[VertexListGraph],
|
||||
xref:concepts/EdgeListGraph.adoc[EdgeListGraph] and
|
||||
xref:concepts/BidirectionalGraph.adoc[BidirectionalGraph]. If the `Graph` type
|
||||
that you use with `subgraph` does not model these concepts and supports
|
||||
fewer functions, then the `subgraph` will also support fewer functions
|
||||
and some of the functions listed below will not be implemented.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
std::pair<vertex_iterator, vertex_iterator>
|
||||
vertices(const subgraph& g)
|
||||
----
|
||||
|
||||
Returns an iterator range providing access to the vertex set of subgraph
|
||||
_g_. (Required by xref:concepts/VertexListGraph.adoc[VertexListGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
std::pair<edge_iterator, edge_iterator>
|
||||
edges(const subgraph& g)
|
||||
----
|
||||
|
||||
Returns an iterator range providing access to the edge set of subgraph
|
||||
_g_. (Required by xref:concepts/EdgeListGraph.adoc[EdgeListGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
std::pair<adjacency_iterator, adjacency_iterator>
|
||||
adjacent_vertices(vertex_descriptor u_local, const subgraph& g)
|
||||
----
|
||||
|
||||
Returns an iterator range providing access to the vertices adjacent to
|
||||
vertex _u_ in subgraph _g_. (Required by
|
||||
xref:concepts/AdjacencyGraph.adoc[AdjacencyGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
std::pair<out_edge_iterator, out_edge_iterator>
|
||||
out_edges(vertex_descriptor u_local, const subgraph& g)
|
||||
----
|
||||
|
||||
Returns an iterator range providing access to the out-edges of vertex
|
||||
_u_ in subgraph _g_. If the graph is undirected, this iterator range
|
||||
provides access to all edge incident on vertex _u_. (Required by
|
||||
xref:concepts/IncidenceGraph.adoc[IncidenceGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
std::pair<in_edge_iterator, in_edge_iterator>
|
||||
in_edges(vertex_descriptor v_local, const subgraph& g)
|
||||
----
|
||||
|
||||
Returns an iterator range providing access to the in-edges of vertex _v_
|
||||
in subgraph _g_. (Required by
|
||||
xref:concepts/BidirectionalGraph.adoc[BidirectionalGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
vertex_descriptor
|
||||
source(edge_descriptor e_local, const subgraph& g)
|
||||
----
|
||||
|
||||
Returns the source vertex of edge _e_ in subgraph _g_. (Required by
|
||||
xref:concepts/IncidenceGraph.adoc[IncidenceGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
vertex_descriptor
|
||||
target(edge_descriptor e_local, const subgraph& g)
|
||||
----
|
||||
|
||||
Returns the target vertex of edge _e_ in subgraph _g_. (Required by
|
||||
xref:concepts/IncidenceGraph.adoc[IncidenceGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
degree_size_type
|
||||
out_degree(vertex_descriptor u_local, const subgraph& g)
|
||||
----
|
||||
|
||||
Returns the number of edges leaving vertex _u_ in subgraph _g_.
|
||||
(Required by xref:concepts/IncidenceGraph.adoc[IncidenceGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
degree_size_type in_degree(vertex_descriptor u_local, const subgraph& g)
|
||||
----
|
||||
|
||||
Returns the number of edges entering vertex _u_ in subgraph _g_.
|
||||
(Required by xref:concepts/BidirectionalGraph.adoc[BidirectionalGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
vertices_size_type num_vertices(const subgraph& g)
|
||||
----
|
||||
|
||||
Returns the number of vertices in the subgraph _g_. (Required by
|
||||
xref:concepts/VertexListGraph.adoc[VertexListGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
edges_size_type num_edges(const subgraph& g)
|
||||
----
|
||||
|
||||
Returns the number of edges in the subgraph _g_. (Required by
|
||||
xref:concepts/EdgeListGraph.adoc[EdgeListGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
vertex_descriptor vertex(vertices_size_type n, const subgraph& g)
|
||||
----
|
||||
|
||||
Returns the __n__th vertex in the subgraph's vertex list.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
std::pair<edge_descriptor, bool>
|
||||
edge(vertex_descriptor u_local, vertex_descriptor v_local, const subgraph& g)
|
||||
----
|
||||
|
||||
Returns the edge connecting vertex _u_ to vertex _v_ in subgraph _g_.
|
||||
(Required by xref:concepts/AdjacencyMatrix.adoc[AdjacencyMatrix].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
std::pair<edge_descriptor, bool>
|
||||
add_edge(vertex_descriptor u_local, vertex_descriptor v_local, subgraph& g)
|
||||
----
|
||||
|
||||
Adds edge _(u,v)_ to the subgraph _g_ and to all of the subgraph's
|
||||
ancestors in the subgraph tree. This function returns the edge
|
||||
descriptor for the new edge. If the edge is already in the graph then a
|
||||
duplicate will not be added and the Boolean flag will be false.
|
||||
(Required by xref:concepts/EdgeMutableGraph.adoc[EdgeMutableGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
std::pair<edge_descriptor, bool>
|
||||
add_edge(vertex_descriptor u_local, vertex_descriptor v_local,
|
||||
const EdgeProperty& p, subgraph& g)
|
||||
----
|
||||
|
||||
Adds edge _(u,v)_ to the graph and attaches `p` as the value of the
|
||||
edge's internal property storage. Also see the previous `add_edge`
|
||||
member function for more details.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
void remove_edge(vertex_descriptor u_local, vertex_descriptor v_local,
|
||||
subgraph& g)
|
||||
----
|
||||
|
||||
Removes the edge _(u,v)_ from the subgraph and from all of the ancestors
|
||||
of `g` in the subgraph tree. (Required by
|
||||
xref:concepts/EdgeMutableGraph.adoc[EdgeMutableGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
void remove_edge(edge_descriptor e_local, subgraph& g)
|
||||
----
|
||||
|
||||
Removes the edge `e` from the subgraph and from all of the ancestors of
|
||||
`g` in the subgraph tree. (Required by
|
||||
xref:concepts/EdgeMutableGraph.adoc[EdgeMutableGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
....
|
||||
|
||||
vertex_descriptor
|
||||
add_vertex(subgraph& g)
|
||||
....
|
||||
|
||||
Adds a vertex to the subgraph and returns the vertex descriptor for the
|
||||
new vertex. The vertex is also added to all ancestors of `g` in the
|
||||
subgraph tree to maintain the subgraph property. (Required by
|
||||
xref:concepts/VertexMutableGraph.adoc[VertexMutableGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
....
|
||||
|
||||
vertex_descriptor
|
||||
add_vertex(vertex_descriptor u_global, subgraph& g)
|
||||
....
|
||||
|
||||
Adds the vertex _u_ from the root graph to the subgraph `g`. (Required
|
||||
by xref:concepts/VertexMutableGraph.adoc[VertexMutableGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
template <class PropertyTag>
|
||||
property_map<subgraph, PropertyTag>::type
|
||||
get(PropertyTag, subgraph& g)
|
||||
|
||||
template <class PropertyTag>
|
||||
property_map<subgraph, PropertyTag>::const_type
|
||||
get(PropertyTag, const subgraph& g)
|
||||
----
|
||||
|
||||
Returns the property map object for the vertex or edge property
|
||||
specified by `PropertyTag`. The `PropertyTag` must match one of the
|
||||
properties specified in the graph's `PropertyTag` template argument.
|
||||
Vertex and edge properties are shared by all subgraphs, so changes to a
|
||||
property through a local vertex descriptor for one subgraph will change
|
||||
the property for the global vertex descriptor, and therefore for all
|
||||
other subgraphs. However, the key type for a subgraph's property map is
|
||||
a subgraph-local vertex or edge descriptor. (Required by
|
||||
xref:concepts/PropertyGraph.adoc[PropertyGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
template <class PropertyTag, class Key>
|
||||
typename property_traits<
|
||||
typename property_map<subgraph, PropertyTag>::const_type
|
||||
>::value_type
|
||||
get(PropertyTag, const subgraph& g, Key k_local)
|
||||
----
|
||||
|
||||
This returns the property value for the key `k_local`, which is
|
||||
either a local vertex or local edge descriptor. See the above `get`
|
||||
function for more information about the property maps. (Required by
|
||||
xref:concepts/PropertyGraph.adoc[PropertyGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
template <class PropertyTag, class Key, class Value>
|
||||
void
|
||||
put(PropertyTag, const subgraph& g, Key k_local, const Value& value)
|
||||
----
|
||||
|
||||
This sets the property value for the key `k_local` to `value`.
|
||||
`k_local` is either a local vertex or local edge descriptor. `Value`
|
||||
must be convertible to
|
||||
`typename property_traits<property_map<adjacency_matrix, PropertyTag>::type>::value_type`.
|
||||
(Required by xref:concepts/PropertyGraph.adoc[PropertyGraph].)
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
template <class GraphProperties, class GraphPropertyTag>
|
||||
typename property_value<GraphProperties, GraphPropertyTag>::type&
|
||||
get_property(subgraph& g, GraphPropertyTag);
|
||||
----
|
||||
|
||||
Return the property specified by `GraphPropertyTag` that is attached to
|
||||
the subgraph object `g`. The `property_value` traits class is
|
||||
defined in `boost/pending/property.hpp`.
|
||||
|
||||
'''''
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
template <class GraphProperties, class GraphPropertyTag>
|
||||
const typename property_value<GraphProperties, GraphPropertyTag>::type&
|
||||
get_property(const subgraph& g, GraphPropertyTag);
|
||||
----
|
||||
|
||||
Return the property specified by `GraphPropertyTag` that is attached to
|
||||
the subgraph object `g`. The `property_value` traits class is
|
||||
defined in `boost/pending/property.hpp`.
|
||||
|
||||
'''''
|
||||
|
||||
=== Notes
|
||||
|
||||
The subgraph template requires the underlying graph type to supply
|
||||
vertex and edge index properties. However, there is no default
|
||||
constructor of any adjacency list that satisfies both of these
|
||||
requirements. This is especially true of graphs using
|
||||
xref:property_maps/bundled.adoc[bundled properties], or any adjacency list whose
|
||||
vertex set is selected by anything other that `vecS`. However, this
|
||||
problem can be overcome by embedding your bundled (or otherwise)
|
||||
properties into a `property` that contains an appropriate index. For
|
||||
example:
|
||||
|
||||
[source,cpp]
|
||||
----
|
||||
|
||||
struct my_vertex { ... };
|
||||
typedef property<vertex_index_t, std::size_t, my_vertex> vertex_prop;
|
||||
|
||||
struct my_edge { ... };
|
||||
typedef property<edge_index_t, std::size_t, my_edge> edge_prop;
|
||||
|
||||
typedef adjacency_list<vecS, listS, undirectedS, vertex_prop, edge_prop> Graph;
|
||||
typedef subgraph<Graph> Subgraph;
|
||||
----
|
||||
| All other types
|
||||
| Same as the underlying `Graph` type.
|
||||
|===
|
||||
|
||||
Reference in New Issue
Block a user