2
0
mirror of https://github.com/boostorg/graph.git synced 2026-02-25 16:32:09 +00:00

Merge branch 'master' into develop

Conflicts:
	include/boost/graph/adjacency_matrix.hpp
	include/boost/graph/detail/adjacency_list.hpp
	include/boost/graph/named_graph.hpp
	include/boost/graph/r_c_shortest_paths.hpp
	include/boost/graph/vf2_sub_graph_iso.hpp
	test/Jamfile.v2
	test/make_connected_test.cpp
This commit is contained in:
Noel Belcourt
2014-05-16 15:14:57 -06:00
91 changed files with 0 additions and 12093 deletions

View File

@@ -1,25 +0,0 @@
# Copyright (C) 2007-2009 Andrew Sutton
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
xml graph : graph.qbk ;
boostbook standalone
:
graph
:
<xsl:param>boost.root=../../../..
# ToC and chunking
<xsl:param>chunk.section.depth=5
<xsl:param>chunk.first.sections=1
<xsl:param>toc.section.depth=5
<xsl:param>toc.max.depth=3
<xsl:param>generate.section.toc.level=5
# Misc options
<xsl:param>navig.graphics=1
<xsl:param>annotation.support=1
;

View File

@@ -1,19 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[bibliography]
[bibentry
[authors [Sutter, Herb], [Alexandrescu, Andrei]]
[title C++ Coding Standards: 101 Rules, Guidelines, and Best Practices]
[book
[publisher Addison Wesley]
[copyright 1985 Pearson Education, Inc.]
[pages 220]
]
[endbib]

View File

@@ -1,50 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/ Iterator concepts /]
[template MultiPassInputIterator[] [@http://www.boost.org/libs/utility/MultiPassInputIterator.html MultipPassInputIterator]]
[/ Property map concpepts /]
[template ReadablePropertyMap[] [@http://www.boost.org/libs/property_map/ReadablePropertyMap.html [^ReadablePropertyMap]]]
[template WritablePropertyMap[] [@http://www.boost.org/libs/property_map/WritablePropertyMap.html [^WritablePropertyMap]]]
[template ReadWritePropertyMap[] [@http://www.boost.org/libs/property_map/ReadWritePropertyMap.html [^ReadWritePropertyMap]]]
[/ Boost Graph concepts /]
[template Graph[] [link boost_graph.concepts.graph_concepts.graph [^Graph]]]
[template IncidenceGraph[] [link boost_graph.concepts.graph_concepts.incidence_graph [^IncidenceGraph]]]
[template BidirectionalGraph[] [link boost_graph.concepts.graph_concepts.bidirectional_graph [^BidirectionalGraph]]]
[template VertexListGraph[] [link boost_graph.concepts.graph_concepts.vertex_list_graph [^VertexListGraph]]]
[template EdgeListGraph[] [link boost_graph.concepts.graph_concepts.edge_list_graph [^EdgeListGraph]]]
[template VertexAndEdgeListGraph[] [link boost_graph.concepts.graph_concepts.vertex_and_edge_list_graph [^VertexAndEdgeListGraph]]]
[template AdjacencyGraph[] [link boost_graph.concepts.graph_concepts.adjacency_graph [^AdjacencyGraph]]]
[template AdjacencyMatrix[] [link boost_graph.concepts.graph_concepts.adjacency_matrix [^AdjacencyMatrix]]]
[template MutableGraph[] [link boost_graph.concepts.graph_concepts.mutable_graph [^MutableGraph]]]
[template PropertyGraph[] [link boost_graph.concepts.graph_concepts.property_graph [^PropertyGraph]]]
[template MutablePropertyGraph[] [link boost_graph.concepts.graph_concepts.mutable_property_graph [^MutablePropertyGraph]]]
[template VertexIndexGraph[] [link boost_graph.concepts.graph_concepts.vertex_index_graph [^VertexIndexGraph]]]
[template EdgeIndexGraph[] [link boost_graph.concepts.graph_concepts.edge_index_graph [^EdgeIndexGraph]]]
[/ Boost Graph Visitor concepts /]
[template Visitor[] [link boost_graph.concepts.visitor_concepts.visitor Visitor]]
[template BFSVisitor[] [link boost_graph.concepts.visitor_concepts.breadth_first_search_visitor BreadthFirstSearchVisitor]]
[template DFSVisitor[] [link boost_graph.concepts.visitor_concepts.depth_first_search_visitor DepthFirstSearchVisitor]]
[template DijkstraVisitor[] [link boost_graph.concepts.visitor_concepts.dijksta_visitor DijkstraVisitor]]
[template BellmanfordVisitor[] [link boost_graph.concepts.visitor_concepts.bellmanford_visitor BellmanFordVisitor]]
[template AStarVisitor[] [link boost_graph.concepts.visitor_concepts.a_star_visitor A\*Visitor]]
[template CliqueVisitor[] [link boost_graph.concepts.visitor_concepts.clique_visitor [^CliqueVisitor]]]
[template CycleVisitor[] [link boost_graph.concepts.visitor_concepts.cycle_visitor [^CycleVisitor]]]
[template EventVisitor[] [link boost_graph.concepts.visitor_concepts.event_visitor EventVisitor]]
[template EventVisitorList[] [link boost_graph.concepts.visitor_concepts.event_visitor_list EventVisitorList]]
[/ A bunch of miscellaneus graph-related concepts /]
[template ColorValue[] [link boost_graph.concepts.miscellaneous_concepts.color_value ColorValue]]
[template Descriptor[] [link boost_graph.concepts.graph_concepts.descriptor [^Descriptor]]]
[template NumericValue[] [link boost_graph.concepts.general_concepts.numeric_value [^NumericValue]]]
[template PropertyMap[] [link boost_graph.concepts.general_concepts.property_map [^PropertyMap]]]
[template PropertyMatrix[] [link boost_graph.concepts.general_concepts.property_matrix [^PropertyMatrix]]]
[template DegreeMeasure[] [link boost_graph.concepts.general_concepts.degree_measure [^DegreeMeasure]]]
[template DistanceMeasure[] [link boost_graph.concepts.general_concepts.distance_measure [^DistanceMeasure]]]

View File

@@ -1,180 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/ This contains macros that links against the reference section. /]
[template constant_property_map[] [link graph [^constant_property_map]]]
[/ Graph traits and types /]
[template graph_traits[] [link boost_graph.reference.traits_classes.graph_traits [^graph_traits]]]
[template undirected_graph[] [link boost_graph.reference.graph_types.undirected_graph [^undirected_graph]]]
[template directed_graph[] [link boost_graph.reference.graph_types.directed_graph [^directed_graph]]]
[template adjacency_list[] [link boost_graph.reference.graph_types.adjacency_list [^adjacecncy_list]]]
[template adjacency_matrix[] [link boost_graph.reference.graph_types.adjacency_matrix [^adjacecncy_matrix]]]
[template edge_list[] [link boost_graph.reference.graph_types.edge_list [^edge_list]]]
[/ Visitor types /]
[template null_visitor[] [link boost_graph.reference.visitor_types.null_visitor [^null_visitor]]]
[template bfs_visitor[] [link boost_graph.reference.visitor_types.bfs_visitor [^bfs_visitor]]]
[template dfs_visitor[] [link boost_graph.reference.visitor_types.dfs_visitor [^dfs_visitor]]]
[template astar_visitor[] [link boost_graph.reference.visitor_types.astar_visitor [^astar_visitor]]]
[template dijkstra_visitor[] [link boost_graph.reference.visitor_types.dijkstra_visitor [^dijkstra_visitor]]]
[template bellman_ford_visitor[] [link boost_graph.reference.visitor_types.bellman_ford_visitor [^bellman_ford_visitor]]]
[template clique_visitor[] [link boost_graph.reference.visitor_types.clique_visitor [^clique_visitor]]]
[template max_clique_visitor[] [link boost_graph.reference.visitor_types.max_clique_visitor [^max_clique_visitor]]]
[template cycle_visitor[] [link boost_graph.reference.visitor_types.cycle_visitor [^cycle_visitor]]]
[template min_max_cycle_visitor[] [link boost_graph.reference.visitor_types.min_max_cycle_visitor [^min_max_cycle_visitor]]]
[/ Event Visitors /]
[template predecessor_recorder[] [link boost_graph.reference.event_visitors.predecessor_recorder [^predecessor_recorder]]]
[template distance_recorder[] [link boost_graph.reference.event_visitors.distance_recorder [^distance_recorder]]]
[template time_stamper[] [link boost_graph.reference.event_visitors.time_stamper [^time_stamper]]]
[template property_writer[] [link boost_graph.reference.event_visitors.property_writer [^property_writer]]]
[/ Attribute BGL interface function back to concept definitions /]
[template add_vertex[] [link
boost_graph.concepts.graph_concepts.mutable_graph [^add_vertex]]]
[template remove_vertex[] [link
boost_graph.concepts.graph_concepts.mutable_graph [^remove_vertex]]]
[template add_edge[] [link
boost_graph.concepts.graph_concepts.mutable_graph [^add_edge]]]
[template remove_edge[] [link
boost_graph.concepts.graph_concepts.mutable_graph [^remove_edge]]]
[/ Fundamental /]
[template breadth_first_search[] [link
boost_graph.reference.algorithms.fundamental.breadth_first_search
[^breadth_first_search]]]
[template depth_first_search[] [link
boost_graph.reference.algorithms.fundamental.depth_first_search
[^depth_first_search]]]
[/ Shortest Path /]
[template dijkstra_shortest_paths[] [link
boost_graph.reference.algorithms.shortest_paths.dijkstra_shortest_paths
[^dijkstra_shortest_paths]]]
[template bellman_ford_shortest_paths[] [link
boost_graph.reference.algorithms.shortest_paths.bellman_ford_shortest_paths
[^bellman_ford_shortest_paths]]]
[template floyd_warshall_all_pairs_shortest_paths[] [link
boost_graph.reference.algorithms.shortest_paths.floyd_warshall_all_pairs_shortest_paths
[^floyd_warshall_all_pairs_shortest_paths]]]
[template johnson_all_pairs_shortest_paths[] [link
boost_graph.reference.algorithms.shortest_paths.johnson_all_pairs_shortest_paths
[^johnson_all_pairs_shortest_paths]]]
[/ Connectivity /]
[template connected_components[] [link
boost_graph.reference.algorithms.connectivity.connected_components
[^connected_components]]]
[template strong_connected_components[] [link
boost_graph.reference.algorithms.connectivity.strongly_connected_components
[^strongly_connected_components]]]
[/ Subgraph/ ]
[template bron_kerbosch_visit_cliques[] [link
boost_graph.reference.algorithms.subgraph.bron_kerbosch_all_cliques
[^bron_kerbosch_all_cliques]]]
[template tiernan_all_cycles[] [link
boost_graph.reference.algorithms.subgraph.tiernan_all_cycles.__tiernan_all_cycles___
[^tiernan_all_cycles]]]
[template tiernan_girth[] [link
boost_graph.reference.algorithms.subgraph.tiernan_all_cycles.__tiernan_girth___
[^tiernan_girth]]]
[template tiernan_circumference[] [link
boost_graph.reference.algorithms.subgraph.tiernan_all_cycles.__tiernan_circumference___
[^tiernan_circumference]]]
[template tiernan_girth_and_circumference[] [link
boost_graph.reference.algorithms.subgraph.tiernan_all_cycles.__tiernan_girth_and_circumference___
[^tiernan_girth_and_circumference]]]
[template bron_kerbosch_all_cliques[] [link
boost_graph.reference.algorithms.subgraph.bron_kerbosch_all_cliques.__bron_kerbosch_all_cliques___
[^bron_kerbosch_all_cliques]]]
[template bron_kerbosch_clique_number[] [link
boost_graph.reference.algorithms.subgraph.bron_kerbosch_all_cliques.__bron_kerbosch_clique_number___
[^bron_kerbosch_clique_number]]]
[/ Measures /]
[template degree_centrality[] [link
boost_graph.reference.algorithms.measures.degree_centrality.__degree_centrality___
[^degree_centrality]]]
[template all_degree_centralities[] [link
boost_graph.reference.algorithms.measures.degree_centrality.__all_degree_centralities___
[^all_degree_centralities]]]
[template closeness_centrality[] [link
boost_graph.reference.algorithms.measures.closeness_centrality.__closeness_centrality___
[^closeness_centrality]]]
[template all_closeness_centralities[] [link
boost_graph.reference.algorithms.measures.closeness_centrality.__all_closeness_centralities___
[^all_closeness_centralities]]]
[template mean_geodesic[] [link
boost_graph.reference.algorithms.measures.mean_geodesic.__mean_geodesic___
[^mean_geodesic]]]
[template all_mean_geodesics[] [link
boost_graph.reference.algorithms.measures.mean_geodesic.__all_mean_geodesics___
[^all_mean_geodesics]]]
[template small_world_distance[] [link
boost_graph.reference.algorithms.measures.mean_geodesic.__small_world_distance___
[^small_world_distance]]]
[template eccentricity[] [link
boost_graph.reference.algorithms.measures.eccentricity.__eccentricity___
[^eccentricity]]]
[template eccentricities[] [link
boost_graph.reference.algorithms.measures.eccentricity.__eccentricities___
[^eccentricities]]]
[template radius[] [link
boost_graph.reference.algorithms.measures.eccentricity.__radius___
[^radius]]]
[template diameter[] [link
boost_graph.reference.algorithms.measures.eccentricity.__diameter___
[^diameter]]]
[template radius_and_diameter[] [link
boost_graph.reference.algorithms.measures.eccentricity.__radius_and_diameter___
[^radius_and_diameter]]]
[template clustering_coefficient[] [link
boost_graph.reference.algorithms.measures.clustering_coefficient.__clustering_coefficient___
[^clustering_coefficient]]]
[template all_clustering_coefficients[] [link
boost_graph.reference.algorithms.measures.clustering_coefficient.__all_clustering_coefficients___
[^all_clustering_coefficients]]]
[template num_paths_through_vertex[] [link
boost_graph.reference.algorithms.measures.clustering_coefficient.__num_paths_through_vertex___
[^num_paths_through_vertex]]]
[template num_triangles_on_vertex[] [link
boost_graph.reference.algorithms.measures.clustering_coefficient.__num_triangles_on_vertex___
[^num_triangles_on_vertex]]]
[/ Tours /]
[template metric_tsp_approxp[] [link
boost.graph.reference.algorithms.tours.metrc_tsp_approx.__metric_tsp_approx__
[^metric_tsp_approx]]]
[/ Misc /]
[template exterior_vertex_property[] [link
graph
[^exterior_vertex_property]]]
[template exterior_edge_property[] [link
graph
[^exterior_edge_property]]]
[/ Import a number of example to build code templates /]
[import ../example/degree_centrality.cpp]
[import ../example/influence_prestige.cpp]
[import ../example/closeness_centrality.cpp]
[import ../example/scaled_closeness_centrality.cpp]
[import ../example/mean_geodesic.cpp]
[import ../example/inclusive_mean_geodesic.cpp]
[import ../example/eccentricity.cpp]
[import ../example/clustering_coefficient.cpp]
[import ../example/tiernan_print_cycles.cpp]
[import ../example/tiernan_girth_circumference.cpp]
[import ../example/bron_kerbosch_print_cliques.cpp]
[import ../example/bron_kerbosch_clique_number.cpp]

View File

@@ -1,72 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Graph]
The Graph concept contains a few requirements that are common to all the graph concepts.
These include some associated types for vertex_descriptor, edge_descriptor, etc. One
should note that a model of Graph is not required to be a model of Assignable, so algorithms
should pass graph objects by reference (or `const` reference).
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`graph_traits<G>::vertex_descriptor`]
[
A vertex descriptor corresponds to a unique vertex in a graph. A vertex descriptor
must be DefaultConstructible, Assignable, and EqualityComparable. Vertex
descriptors are almost always passed by value.
]
]
[
[`graph_traits<G>::edge_descriptor`]
[
An edge descriptor corresponds to a unqie edge /(u,v)/ in a graph. An edge descriptor
must be DefaultConstructible, Assignable, and EqualityComparable. Edge descriptors
are almost always passed by value.
]
]
[
[`graph_traits<G>::directed_category`]
[
This type shall be convertible to `directed_tag` or `undirected_tag`.
]
]
[
[`graph_traits<G>::edge_parallel_category`]
[
This describes whether the graph class allows the insertion of parallel edges
(multiple edges between the same source and target vertices). The two tags are
`allow_parallel_edge_tag` and `disallow_parallel_edge_tag`.
]
]
[
[`graph_traits<G>::traversal_category`]
[
This describes the ways in which the vertices and edge of the graph can be visited.
The choices are `incidence_graph_tag`, `adjacency_graph_tag`, `bidirectional_graph_tag`,
`vertex_list_graph_tag`, `edge_list_graph_tag`, and `adjacency_matrix_tag`.
]
]
]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`graph_traits<G>::null_vertex()`]
[
Returns a special `vertex_descriptor` which does not refer to any vertex for graphs
of type `G`. Note that default initialization of `vertex_descriptors` are /not/
guaranteed to be equal to then `null_vertex()`.
*Returns* `vertex_descriptor`
]
]
]
[endsect]

View File

@@ -1,69 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Adjacency Graph]
The AdjacencyGraph concept provides and interface for efficient access of the adjacent vertices
to a vertex in a graph. This is quite similar to the IncidenceGraph concept (the target of an
out-edge is an adjacent vertex). Both concepts are provided because in some contexts there is only
concern for the vertices, whereas in other contexts the edges are also important.
[h4 Refinement Of]
[Graph]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`graph_traits<G>::traversal_category`]
[
This tag type must be convertible to `adjacency_graph_tag`.
]
]
[
[`graph_traits<G>::adjacency_iterator`]
[
An adjacency iterator for a vertex v provides access to the vertices adjacent to v.
As such, the value type of an adjacency iterator is the vertex descriptor type of its
graph. An adjacency iterator must meet the requirements of [MultiPassInputIterator].
]
]
]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`adjacent_vertices(v,g)`]
[
Returns an iterator-range providing access to the vertices adjacent to vertex `v` in
the graph `g`.
*Returns* `std::pair<adjacency_iterator, adjacency_iterator>`
]
]
]
[h4 Complexity Guarantees]
The `adjacent_vertices(v,g)` function must return in constant time.
[h4 Design Rationale]
The AdjacencyGraph concept is somewhat frivolous since [IncidenceGraph] really covers the same
functionality (and more). The AdjacencyGraph concept exists because there are situations when
`adjacent_vertices()` is more convenient to use than `out_edges()`. If you are constructing a graph
class and do not want to put in the extra work of creating an adjacency iterator, have no fear. There
is an adaptor class named `adjacency_iterator` that you can use to create an adjacency iterator out
of an out-edge iterator.
[h4 Notes]
The case of a /multigraph/ (where multiple edges can connect the same two vertices) brings up an issue
as to whether the iterators returned by the `adjacent_vertices()` function access a range that includes
each adjacent vertex once, or whether it should match the behavior of the `out_edges()` function, and
access a range that may include an adjacent vertex more than once. For now the behavior is defined to
match that of `out_edges()`, though this decision may need to be reviewed in light of more experience
with graph algorithm implementations.
[endsect]

View File

@@ -1,50 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Adjacency Matrix]
The AdjacencyMatrix concept refines `Graph` concept and adds the requirement for efficient access
to any edge in the graph given the source and target vertices. No Boost.Graph algorithms currently
use this concept. However there are algorithms not yet implemented such as Floyd-Warshall that
would require this concept.
[h4 Refinement Of]
[Graph]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`graph_traits<G>::traversal_category`]
[
This tag type must be convertible to `adjacency_matrix_tag`.
]
]
]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`edge(u,v,g)`]
[
Returns a pair consisting of a flag saying whether there exists an edge between `u` and
`v` in graph g, and consisting of the edge descriptor if the edge was found.
*Returns* `std::pair<edge_iterator, bool>`
]
]
]
[h4 Complexity Guarantees]
The `edge(u,v,g)` function must return in constant time.
[h4 Notes]
A number of graph classes (notably [undirected_graph], [directed_graph] and
[adjacency_list]) provide non-constant time implementations of this interface. Although
the function exists, none of these classes are documented as modeling this concept.
[endsect]

View File

@@ -1,70 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Bellman Ford Visitor]
This concept defines the visitor interface for [bellman_ford_shortest_paths]. Users
can define a class with the Bellman Ford Visitor interface and pass and object of the
class to [bellman_ford_shortest_paths], thereby augmenting the actions taken during the
graph search.
[h4 Refinement Of]
[Visitor]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`vis.examine_edge(v,g)`]
[
This is invoked on every out-edge of each vertex after it is discovered.
*Returns* `void`
]
]
[
[`vis.edge_relaxed(e,g)`]
[
If the relaxation predicate holds for this given edge then this method is invoked.
See [dijkstra_shortest_paths] for more information on relaxation.
*Returns* `void`
]
]
[
[`vis.edge_not_relaxed(e,g)`]
[
If the relaxation predicate does not hold for this edge, then this method is invoked.
See [dijkstra_shortest_paths] for more information on relaxation.
*Returns* `void`
]
]
[
[`vis.edge_minimized(e,g)`]
[
After the `num_vertices(g)` iterators through the edge det of the graph is complete,
one last iteration is made to test whether each edge was minimized. If the edge is
minimized then this function is invoked.
*Returns* `void`
]
]
[
[`vis.edge_relaxed(e,g)`]
[
If the edge is not minimized then this function is invoked. This happens when there
is a negative weight cycle in the graph.
*Returns* `void`
]
]
]
[h4 Models]
* [bellman_ford_visitor]
[endsect]

View File

@@ -1,105 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Breadth-First Search Visitor]
This concept defines the visitor interface for [booost_breadth_first_search] algorithm. Users
can define a class with the BFS Visitor interface and pass and object of the class to
[breadth_first_search], thereby augmenting the actions taken during the graph search.
[h4 Refinement Of]
[Visitor]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`vis.initialize_vertex(v,g)`]
[
This is invoked on every vertex of the graph before the start of the graph search.
*Returns* `void`
]
]
[
[`vis.discover_vertex(v,g)`]
[
This is invoked when a vertex is encountered for the first time.
*Returns* `void`
]
]
[
[`vis.examine_vertex(v,g)`]
[
This is invoked on a vertex as it is popped from the queue. This happens immediately
before `examine_edge(v,g)` s invoked on each of the out-edges of vertex `v`.
*Returns* `void`
]
]
[
[`vis.examine_edge(e,g)`]
[
This is invoked on every out-edge of each vertex after it is discovered.
*Returns* `void`
]
]
[
[`vis.tree_edge(e,g)`]
[
This is invoked on each edge as it becomes a member of the eges that the form the
search tree.
*Returns* `void`
]
]
[
[`vis.non_tree_edge(v,g)`]
[
This is invoked on back or cross edges for directed graphs and cross edges
for undirected graphs.
*Returns* `void`
]
]
[
[`vis.gray_target(e,g)`]
[
This is invoked on the subset of non-tree-edges who's target vertex is colored gray
at the time of examination. The color gray indicates that the vertex is currently
in the queue.
*Returns* `void`
]
]
[
[`vis.black_target(v,g)`]
[
This is invoked on the subset of non-tree edges who's target vertex is colored black
at the time of examination. The color black indicates that the vertex has been removed
from the queue.
*Returns* `void`
]
]
[
[`vis.finish_vertex(v,g)`]
[
This is invoked on a vertex after all of its out edges have been added to the search
tree and all of the adjacenct vertices have been discovered, but before the out-edges
of the adjacent vertices have been examined.
*Returns* `void`
]
]
]
[h4 Models]
* [bfs_visitor]
[endsect]

View File

@@ -1,76 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Bidirectional Graph]
The BidirectionalGraph concept refines IncidenceGraph and adds the requirement for efficient
access to the in-edges of each vertex. This concept is separated from IncidenceGraph because for
directed graphs efficient access to in-edges typically requires more storage space, and many
algorithms do not require access to in-edges. For undirected graphs this is not an issue, since
the in_edges() and out_edges() functions are the same, they both return the edges incident to
the vertex.
[heading Refinement Of]
[IncidenceGraph]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`graph_traits<G>::traversal_category`]
[
This tag type must be convertible to `bidirectional_graph_tag`.
]
]
[
[`graph_traits<G>::in_edge_iterator`]
[
An in-edge iterator for a vertex v provides access to the in-edges of a vertex. As
such, the value type of an in-edge iterator is the edge descriptor type of its graph.
An in-edge iterator must meet the requirements of MultiPassInputIterator.
]
]
]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`in_edges(v,g)`]
[
Returns an iterator range providing access to the in-edges (for directed graphs)
or the incident edges (for undirected graphs). The target vertex of an edge obtained
via an in-edge iterator is guaranteed to be the vertex `v` in the call to
`in_edges(v,g)`, and the source vertex must be adjacenct to `v`.
*Returns* `std::pair<in_edge_iterator, in_edge_iterator>`
]
]
[
[`in_degree(v,g)`]
[
Returns the number of in-edges (for directed graphs) or the number of incident
edges (for undirected graphs) of the vertex `v`.
*Returns* `degree_size_type`.
]
]
]
[h4 Models]
* [undirected_graph]
* [directed_graph]
* [adjacency_list] with the `Directed` template parameter as `bidirectionalS` or
`undirectedS`.
[h4 Complexity Guarantees]
The `in_edges(g)` function is required to return in constant time.
The `in_degree()` and `degree()` functions must be linear in the number of in-edges (for
directed graph) or incident edges (for undirected graphs).
[endsect]

View File

@@ -1,44 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Clique Visitor]
The clique visitor concept defines requirements for types that act as visitors
of clique-detection algorithms. Objects of this type are passed to these
algorithms and are invoked when a clique is found within a graph.
[heading Refinement Of]
[Visitor]
[heading Expressions]
[table
[[Name] [Expression] [Result Type] [Description]]
[
[Visit Clique]
[`vis.clique(c,g)`]
[`void`]
[
The `clique()` member function of the visitor is invoked when a fully
connected subgraph, `c`, is identified in the graph `g`.
*Requirements:* `g` is an object whose type `G` is a refinement of the
[Graph] concept.
*Requirements:* `c` is an object whose type `C` is a refinement of the
[SgiContainer] concept, and the `value_type` of `C` must be the same
as the `vertex_descriptor` of `G`.
*Note:* All vertices in the `c` are connected. If `g` is a directed
graph, then all vertices, /u/ and /v/, are stringly connected (i.e.,
the edges /(u,v)/ and /(v,u)/ are in `g`).
]
]
]
[heading Models]
[clique_visitor], [max_clique_visitor]
[endsect]

View File

@@ -1,37 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Concepts]
This section provides a detailed listing of the type concepts in the Boost.Graph
library.
[heading Notation]
For the following sections, we use the following notional convents:
[table
[[Object] [Type]]
[[G] [A type that is a model of a [Graph] (or refinement thereof)]]
[[g] [An object of type G]]
[[u,v] [Objects of type `graph_traits<G>::vertex_descriptor`]]
[[e] [An object of type `graph_traits<G>::edge_descriptor`]]
[[vi] [An object of type `graph_traits<G>::vertex_iterator`]]
[[ei] [An object of type `graph_traits<G>::edge_iterator`]]
[[vp] [An object of type `G::vertex_property_type`]]
[[ep] [An object of type `G::edge_property_type`]]
[[Property] [A type used to specify a vertex or edge property. Also called a /tag/.]]
[[p] [An object of type Property]]
[[Predicate] [A function that, given an argument, returns true or false]]
[[pred] [An object of type [SgiPredicate]]]
[[V] [A type that is a model of a [Visitor] (or refinement thereof)]]
[[vis] [An object of type V]]
]
[include utility.qbk]
[include graphs.qbk]
[include visitors.qbk]
[endsect]

View File

@@ -1,43 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Cycle Visitor]
The cycle visitor concept defines requirements for types that act as visitors
of cycle-detection algorithms. Objects of this type are passed to these
algorithms and are invoked when a cycle is found within a graph.
[heading Refinement Of]
[Visitor]
[heading Valid Expressions]
[table
[[Name] [Expression] [Result Type] [Description]]
[
[Visit Cycle]
[`vis.cycle(c,g)`]
[`void`]
[
The `vis.cycle()` member function of the visitor is invoked when a
cycle is identified in the graph `g`. The vertices in `c` are arranged
such that first vertex is connected to the second, and that is connected
to the third, etc. The `back()` vertex is connected to the `front()`
to form the reported cycle.
*Requirements:* `g` is an object whose type `G` is a model of the
[Graph] concept.
*Requirements:* `c` is an object whose type `C` is a model of the
[SgiContainer] concept. The `value_type` of `C` must be the same type
as the `vertex_descriptor` of `G`.
]
]
]
[heading Models]
[cycle_visitor], [min_max_cycle_visitor]
[endsect]

View File

@@ -1,64 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/ TODO: Redefine this as a function taking a vertex and a graph. /]
[section Degree Measure]
The [DegreeMeasure] concept defines requirements for function objects
that are used in computations on the degree of a vertex.
[heading Notation]
The following expressions are used within this document:
[table
[[Expression] [Description]]
[[M] [A type modeling the [DegreeMeasure] concept.]]
[[m] [An object of type `M`.]]
[[G] [A type modeling the [Graph] concept.]]
[[g] [An object of type `G`.]]
[[v] [An object of type `graph_traits<G>::vertex_descriptor`.]]
]
[heading Associated Types]
[table
[[Name] [Type] [Description]]
[
[Degree Type]
[`M::degree_type`]
[
The result type of the computation. Note that unlike
`graph_traits<G>::degree_size_type`, the `degree_type` is not
required to be numeric.
]
]
]
[heading Expressions]
[table
[[Name] [Expression] [Result Type] [Description]]
[
[Function Call]
[`m(v, g)`]
[`M::degree_type`]
[
Invoke the measure on the vertex `v`, with respect
to the graph `g`. This returns the result as type `degree_type`.
]
]
]
[heading C++0x]
concept DegreeMeasure<M>
{
typename Graph;
typename Vertex;
typename M::degree_type;
degree_type M::operator(Vertex v, const Graph& g)
};
[endsect]

View File

@@ -1,27 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Descriptor]
The Descriptor concept describes requirements common to vertex and edge descriptors of
all graph types.
[heading Refinement Of]
[StdRegular] and [SgiLessThanComparable].
[heading Associated Types]
There are no associated types of a Descriptor.
[heading Valid Expressions]
Beyond the requirements of the refined concepts, the descriptor does not require any
additional valid expressions.
[heading Notes]
Note that because both model the [SgiLessThanComparable] concept, they can be used as
keys in any associative container modeling the [SgiAssociativeContainer] concept
(e.g., `std::map`, `std::set`, etc).
[endsect]

View File

@@ -1,99 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Depth-First Search Visitor]
This concept defines the visitor interface for [booost_depth_first_search] algorithm. Users
can define a class with the DFS Visitor interface and pass and object of the class to
[boost_depth_first_search], thereby augmenting the actions taken during the graph search.
[h4 Refinement Of]
[BoostVisitor]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`vis.initialize_vertex(v,g)`]
[
This is invoked on every vertex of the graph before the start of the graph search.
*Returns* `void`
]
]
[
[`vis.start_vertex(v,g)`]
[
This is invoked on the source vertex once before the start of the search.
*Returns* `void`
]
]
[
[`vis.discover_vertex(v,g)`]
[
This is invoked when a vertex is encountered for the first time.
*Returns* `void`
]
]
[
[`vis.examine_edge(e,g)`]
[
This is invoked on every out-edge of each vertex after it is discovered.
*Returns* `void`
]
]
[
[`vis.tree_edge(e,g)`]
[
This is invoked on each edge as it becomes a member of the edges that form the
search tree.
*Returns* `void`
]
]
[
[`vis.back_edge(v,g)`]
[
This is invoked on the back edges of the graph. For an undirected graph there
is some ambiguity between tree edges and back edges since the edge /(u,v)/
and /(v,u)/ are the same edge, but both `tree_edge(v,g)` and `back_edge(v,g)`
will be invoked. One way to resolve this ambiguity is to record the tree
edges and then disregard the back edges that are already marked as tree edges.
An easy way to record tree edges is to record predecessors at the `tree_edge`
event point.
*Returns* `void`
]
]
[
[`vis.forward_or_cross_edge(e,g)`]
[
This is invoked on forward or cross edges in the graph. In an undirected graph,
this method is never called.
*Returns* `void`
]
]
[
[`vis.finish_vertex(v,g)`]
[
This is invoked on a vertex after all `finish_vertex(x,g)` has been invoked for
all vertices in the search tree rooted at `v` (i.e., after all its children
have finished). If `v` is a leaf in the search tree, `finish_vertex(v,g)` is
called after all its out-edges have been examined.
*Returns* `void`
]
]
]
[h4 Models]
* [dfs_visitor]
[endsect]

View File

@@ -1,87 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Dijkstra Visitor]
This concept defines the visitor interface for [dijkstra_shortest_paths] and related
algorithms. The user can create a class that matches this interface, and then pass objects
of the class into [dijkstra_shortest_paths] to augment the actions taken during the
search.
[h4 Refinement Of]
[Visitor]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`vis.initialize_vertex(v,g)`]
[
This is invoked on every vertex of the graph before the start of the graph search.
*Returns* `void`
]
]
[
[`vis.discover_vertex(v,g)`]
[
This is invoked when a vertex is encountered for the first time. This happens immediately
before `examine_edge()` is invoked on each of the out-edges of `v`.
*Returns* `void`
]
]
[
[`vis.examine_vertex(v,g)`]
[
This is invoked on a vertex as it is popped from the queue. This happens immediately
before `examine_edge(v,g)` s invoked on each of the out-edges of vertex `v`.
*Returns* `void`
]
]
[
[`vis.examine_edge(v,g)`]
[
This is invoked on every out-edge of each vertex after it is discovered.
*Returns* `void`
]
]
[
[`vis.edge_relaxed(e,g)`]
[
If the relaxation predicate holds for this given edge then this method is invoked.
See [dijkstra_shortest_paths] for more information on relaxation.
*Returns* `void`
]
]
[
[`vis.edge_not_relaxed(e,g)`]
[
If the relaxation predicate does not hold for this edge, then this method is invoked.
See [dijkstra_shortest_paths] for more information on relaxation.
*Returns* `void`
]
]
[
[`vis.finish_vertex(v,g)`]
[
This is invoked on a vertex after all of its out edges have been added to the search
tree and all of the adjacent vertices have been discovered (but before their out edgs)
have been examined).
*Returns* `void`
]
]
]
[h4 Models]
* [boost_dijkstra_visitor]
[endsect]

View File

@@ -1,80 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/ TODO: Redefine this as a function taking some distance value and a graph. /]
[section Distance Measure]
The [DistanceMeasure] concept defines requirements for function objects
that are used in computations of distances.
[heading Notation]
The following expressions are used within this document:
[table
[[Expression] [Description]]
[[M] [A type modeling the [DistanceMeasure] concept.]]
[[m] [An object of type `M`.]]
[[d] [An object of type `M::distance_type`.]]
[[G] [A type modeling the [Graph] concept.]]
[[g] [An object of type `G`.]]
]
[heading Associated Types]
[table
[[Name] [Type] [Description]]
[
[Distance Type]
[`M::distance_type`]
[
The type used to measure distances in graphs. The `distance_type`
is typically derived from the value type of a distance map or
the edge-weight type of a graph type `G`. However, this is not
required.
*Requirements:* The `distance_type` must be a model of the
[NumericValue] concept.
]
]
[
[Result Type]
[`M::result_type`]
[
The type being computed as the measure.
*Requirements:* The `result_type` must be a model of the
[NumericValue] concept.
]
]
]
[heading Expressions]
[table
[[Name] [Expression] [Result Type] [Description]]
[
[Function Call]
[`m(d, g)`]
[`M::result_type`]
[
Invoke the measure on the sum distance `d`, with respect
to the graph `g`. This returns the result as type `result_type`.
Note that in many computations `d` is given as the sum of distances
from one vertex to all others in the graph and may be infinite.
]
]
]
[heading C++0x]
concept DistanceMeasure<M>
{
typename Graph;
typename M::distance_type;
typename M::result_type;
result_type M::operator(distance_type, const Graph&);
};
[endsect]

View File

@@ -1,112 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Edge Index Graph]
The [EdgeIndexGraph] concept requires that a graph type `G` provide edge indices
for each edge in the graph, and that those indices are ordered in the range
\[0, `num_edges(g)`).
Because the removal of edges causes "gaps" in the index space, graphs that model
this concept must also provide functions that allow them to re-index the edges.
[heading Refinement Of]
[MutablePropertyGraph]
[heading Notation]
[table
[[Expression] [Description]]
[[`G`] [A type that models the [Graph] concept.]]
[[`g`] [An object of type `G`.]]
[
[`P`]
[A synonym for `property_map<G,vertex_index_t>`.]
]
]
[heading Associated Types]
[table
[[Name] [Expression] [Result Type] [Description]]
[
[Edge Index Type]
[`property_traits<P::const_type>::value_type`]
[An unsigned integer type]
[
The unsigned integral type representing edge indices.
*Requirements:* `T` must model the [NoConcept UnsignedIntegral] concept.
]
]
[
[Edge Index Property Type]
[
`P::type`
]
[A mutable property map]
[
The type of property map through which edge indices are readable and
writable.
*Requirements:* This type must be a model of the [ReadWritePropertyMap]
concept. The `value_type` of the `property_traits` of this type must
be the same as `edge_index_type`.
]
]
[
[Edge Index Property Type]
[
`P::const_type`
]
[ A `const` property map]
[
The type of property map through which edge indices are readable.
*Requirements:* This type must be a model of the [ReadablePropertyMap]
concept. The `value_type` of the `property_traits` of this type must
be the same as `edge_index_type`.
]
]
]
[heading Requirements]
[table
[[Name] [Expression] [Result Type] [Description]]
[
[Edge Index Property]
[`get(edge_index,g)`]
[`P::type` or `P::const_type`]
[
Returns the property map that provides read/write access to the
edge indices of the graph.
*Complexity:* Constant.
]
]
[
[Edge Index]
[`get(edge_index,g,v)`]
[`G::edge_index_type`]
[
Returns the index of the given edge within the graph. This is
equvalent to `get(get(edge_index, g), v)`.
*Complexity:* Amortized constant.
]
]
[
[Renumber Edge Indices]
[`renumber_edge_indices(g)`]
[]
[
Renumbers all vertices in the graph such that each edge is in the
range \[0, `num_vertices(g)`).
*Complexity:* Linear in `num_vertices(g)`.
]
]
]
[endsect]

View File

@@ -1,98 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Edge List Graph]
The EdgeListGraph concept refines the [Graph] concept, and adds the requirement
for efficient access to all the edges in a graph.
[h4 Refinement Of]
[Graph]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`graph_traits<G>::traversal_category`]
[
This tag type must be convertible to `edge_list_graph_tag`.
]
]
[
[`graph_traits<G>::edge_iterator`]
[
An edge iterator (obtained via edges(g)) provides access to all of the edges
in a graph. An edge iterator type must meet the requirements of
[MultiPassInputIterator]. The value type of the edge iterator must be the
same as the edge descriptor of the graph.
]
]
[
[`graph_traits<G>::edges_size_type`]
[
The unsigned integer type used to represent the number of edges in the graph.
]
]
]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`edges(g)`]
[
Returns an iterator range providing access to all the edges in the graph `g`.
*Returns* `std::pair<edge_iterator, edge_iterator>`
]
]
[
[`num_edges(g)`]
[
Returns the number of edges in the graph `g`.
*Returns* `edges_size_type`
]
]
[
[`source(e,g)`]
[
If `e` is an edge /(u,v)/ in `g`, this function returns the source vertex `u`.
*Returns* `vertex_descriptor`
]
]
[
[`target(e,g)`]
[
If `e` is an edge /(u,v)/ in `g`, this function returns the target vertex `v`.
*Returns* `vertex_descriptor`
]
]
]
[h4 Models]
* [undirected_graph]
* [directed_graph]
* [adjacency_list]
* [edge_list]
[h4 Complexity Guarantees]
The `edges(g)`, `source(e,g)`, and `target(e,g)` functions must return in constant time.
[h4 Design Rationale]
One issue in the design of this concept is whether to include the refinement from the
[IncidenceGraph] and [AdjacencyGraph] concepts. The ability to traverse the vertices
of a graph is orthogonal to traversing out-edges, so it would make sense to have a edgeListGraph
concept that only includes edge traversal. However, such a concept would no longer really be a
graph, but would just be a set, and the STL already has concepts for dealing with such things.
However, there are many BGL algorithms that need to traverse the vertices and out-edges of a graph,
so for convenience a concept is needed that groups these requirements together, hence the edgeListGraph
concept.
[endsect]

View File

@@ -1,175 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Event Visitor]
This concept defines the interface for single-event visitors. An EventVisitor has an
/apply/ member function (`operator()`) which is invoked within the graph algorithm
at the event-point specified by the `event_filter` typedef within the type modeling
the EventVisitor concept. EventVisitors can be combined into an [EventVisitorList].
The following is the list of event tags that can be invoked in Boost.Graph algorithms.
Each tag corresponds to a member function of the visitor for an algorithm. For example,
the [BFSVisitor] has a `cycle_edge()` member function. The corresponding tag is
`on_cycle_edge`. The first argument in the event visitor's `operator()` must be
either an edge or vertex depending on the event tag.
[h4 Event Tags]
[table
[[Type] [Description]]
[
[`on_initialize_vertex`]
[
An event tag corresponding to the initialization of a vertex. The parameter
type associated with this event is `vertex_descriptor`.
]
]
[
[`on_start_vertex`]
[
In algorithms that without explicit starting points, this event tag
corresponds to the selection of a starting vertex. The parameter
type associated with this event is `vertex_descriptor`.
]
]
[
[`on_discover_vertex`]
[
An event tag that corresponds to a vertex that is being used for
the first time. The parameter type associated with this event is
`vertex_descriptor`.
]
]
[
[`on_examine_edge`]
[
An event tag that corresponds to the examination of edges for recently
discovered vertices. The parameter type associated with this event
is `edge_descriptor`.
]
]
[
[`on_tree_edge`]
[
For algorithms whose iterations of a vertex set implicitly define a
tree (such as [[breadth_first_search] or [[depth_first_search]),
this event tag corresponds to the identification of an edge that acts
as an edge in the search tree. The parameter type associated with this
event is `edge_descriptor`.
]
]
[
[`on_cycle_edge`]
[
For algorithms capable of detecting cycles in graphs such as
[[depth_first_search], this event tag is associated with discovery
of an edge that creates a cycle within the graph. The parameter type
associated with this event is `edge_descriptor`.
]
]
[
[`on_forward_or_cross_edge`]
[
Forward and cross edges refer to types of edges that can be found by
different types of searches on graph (e.g., [[depth_first_search]).
This event tag corresponds to the identification of such an edge by
the algorithm. The parameter type associated with this event is
`edge_descriptor`.
]
]
[
[`on_back_edge`]
[
Back edges refer to types of edges that can be found by different types
of searches on a graph (e.g., [[breadth_first_search] and
[[depth_first_search]). This event tag corresponds to the identification
of such an edge by the algorithm. The parameter type associated with this
event is `edge_descriptor`.
]
]
[
[`on_finish_vertex`]
[
The inverse event of `on_discover_vertex`, this event tag corresponds to
the completion of an iteration of an algorithm that is operating on a
vertex. The parametet type associated with this event is `edge_descriptor`.
]
]
[
[`on_edge_relaxed`]
[
For algorithms implementing edge relaxation (e.g.,
[[dijkstra_shortest_paths]), this event corresponds to the case
where an edge is relaxed. The parameter type associated with this event
is `edge_descriptor`.
]
]
[
[`on_edge_not_relaxed`]
[
For algorithms implementing edge relaxation (e.g.,
[[dijkstra_shortest_paths]), this event corresponds to the case
where an edge is not relaxed. The parameter type associated with this
event is `edge_descriptor`.
]
]
[
[`on_edge_minimized`]
[
For algorithms implementing edge minimization (e.g.,
[[bellman_ford_shortest_paths]), this event corresponds to the case
where an edge is minimized. The parameter type associated with this event
is `edge_descriptor`.
]
]
[
[`on_edge_not_minimized`]
[
For algorithms implementing edge minimization (e.g.,
[[bellman_ford_shortest_paths]), this event corresponds to the case
where an edge is not minimized. The parameter type associated with this
event is `edge_descriptor`.
]
]
]
[h4 Refinement Of]
[Visitor]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`V::event_filter`]
[
A tag to specify on which even the visitor should be invoked.
]
]
]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`vis(x,g)`]
[
Invokes the `operator()` member function of an object `vis` of type
`V`. The parameter `x` is either a vertex or edge of the graph `g`. The
specific type of parameter depends on `V::event_filter`.
*Returns* `void`
]
]
]
[h4 Models]
* [predecessor_recorder]
* [distance_recorder]
* [time_stamper]
* [property_writer]
* [null_visitor]
[endsect]

View File

@@ -1,70 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Event Visitor List]
An EventVisitorList is either an [EventVisitor], or a list of [EventVisitor]
combined using `std::pair`. Each graph algorithm defines visitor adaptors that convert an
EventVisitorList into the particular kind of visitor needed by the algorithm. In the
following example we will show how to combine event visitors into a list using `std::pair`
and how to use an algorithm's visitor adaptor class.
Suppose we would like to print out the parenthesis structure of the discover/finish times
of vertices in a depth-first search. We can use the Boost.Graph algorithm [depth_first_search]
and two event visitors to accomplish this. The complete source code for the following example
is in `examples/dfs_parenthesis.cpp`. First we define the two event visitors. We use
`on_discover_vertex` and `on_finish_vertex` as the event points, selected from the list of
event points specified in [DFSVisitor].
struct open_paren : public base_visitor<open_paren>
{
typedef on_discover_vertex event_filter;
template <class Vertex, class Graph>
void operator ()(Vertex v, Graph& G)
{
cout << "(" << v;
}
};
struct close_paren : public base_visitor<clsoe_paren>
{
typedef on_discover_vertex event_filter;
template <class Vertex, class Graph>
void operator ()(Vertex v, Graph& G)
{
cout << v << ")";
}
};
Next, we create two event visitor objects and combine them so the resultant type models
the EventVisitorList concept.
make_pair(open_paren(), close_paren());
Next we want to pass this list into [depth_first_search], but it is
expecting a [DFSVisitor], not a [EventVisitorList]. We therefore use the [[dfs_visitor]
adaptor which turns an [EventVisitor] list into a [DFSVisitor]. Like all of the visitor
adaptors, [dfs_visitor] has a creation function called [make_dfs_visitor].
make_dfs_visitor((open_paren(), close_paren()));
Now we can pass the resulting visitor object into [depth_first_search] as follows.
depth_first_search(
G,
make_dfs_visitor(make_pair(open_paren(), close_paren())));
For creating a list of more than two event visitors, nest calls to `make_pair` in the following way
to recursively produce an EventVisitorList.
make_pair(visitor1,
make_pair(visitor2, ...
make_pair(visitorN - 1, visitorN)...))
[endsect]

View File

@@ -1,72 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Graph]
The Graph concept contains a few requirements that are common to all the graph concepts.
These include some associated types for vertex_descriptor, edge_descriptor, etc. One
should note that a model of Graph is not required to be a model of Assignable, so algorithms
should pass graph objects by reference (or `const` reference).
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`graph_traits<G>::vertex_descriptor`]
[
A vertex descriptor corresponds to a unique vertex in a graph. A vertex descriptor
must be DefaultConstructible, Assignable, and EqualityComparable. Vertex
descriptors are almost always passed by value.
]
]
[
[`graph_traits<G>::edge_descriptor`]
[
An edge descriptor corresponds to a unique edge /(u,v)/ in a graph. An edge descriptor
must be DefaultConstructible, Assignable, and EqualityComparable. Edge descriptors
are almost always passed by value.
]
]
[
[`graph_traits<G>::directed_category`]
[
This type shall be convertible to `directed_tag` or `undirected_tag`.
]
]
[
[`graph_traits<G>::edge_parallel_category`]
[
This describes whether the graph class allows the insertion of parallel edges
(multiple edges between the same source and target vertices). The two tags are
`allow_parallel_edge_tag` and `disallow_parallel_edge_tag`.
]
]
[
[`graph_traits<G>::traversal_category`]
[
This describes the ways in which the vertices and edge of the graph can be visited.
The choices are `incidence_graph_tag`, `adjacency_graph_tag`, `bidirectional_graph_tag`,
`vertex_list_graph_tag`, `edge_list_graph_tag`, and `adjacency_matrix_tag`.
]
]
]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`graph_traits<G>::null_vertex()`]
[
Returns a special `vertex_descriptor` which does not refer to any vertex for graphs
of type `G`. Note that default initialization of `vertex_descriptors` are /not/
guaranteed to be equal to then `null_vertex()`.
*Returns* `vertex_descriptor`
]
]
]
[endsect]

View File

@@ -1,244 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Graph Concepts]
The heart of the Boost Graph Library (BGL) is the interface, or concepts (in the
parlance of generic programming), that define how a graph can be examined and
manipulated in a data-structure neutral fashion. In fact, the BGL interface need
not even be implemented using a data-structure, as for some problems it is easier
or more efficient to define a graph implicitly based on some functions.
The Boost.Graph interface does not appear as a single graph concept. Instead it is
factored into much smaller pieces. The reason for this is that the purpose of a
concept is to summarize the requirements for particular algorithms. Any one algorithm
does not need every kind of graph operation, typically only a small subset. Furthermore,
there are many graph data-structures that can not provide efficient implementations of
all the operations, but provide highly efficient implementations of the operations
necessary for a particular algorithm . By factoring the graph interface into many smaller
concepts we provide the graph algorithm writer with a good selection from which to choose
the concept that is the closest match for their algorithm.
Figure 1 shows the refinements relations between the graph concepts. The reason for
factoring the graph interface into so many concepts is to encourage algorithm interfaces
to require and use only the minimum interface of a graph, thereby increasing the
usability of the algorithm.
[$images/concepts/graph_concepts.png]
Table 1 gives a summary of the valid expressions and associated types for the graph
concepts and provides links to the detailed descriptions of each of the concepts.
The notation used in the table is as follows.
[table
[[Expression] [Return Type or Description]]
[[[*[Graph]]]]
[[`graph_traits<G>::vertex_descriptor`] [The type for vertex representative objects.]]
[[`graph_traits<G>::edge_descriptor`] [The type for edge representative objects.]]
[[`graph_traits<G>::directed_category`] [Graph is directed or undirected?]]
[[`graph_traits<G>::edge_parallel_category`] [Graph allows parallel edges?]]
[[`graph_traits<G>::traversal_category`] [The ways in which the vertices and edges can be traversed.]]
[[[*[IncidenceGraph]]]]
[[`graph_traits<G>::degree_size_type`] [The integer type for vertex degree.]]
[[`graph_traits<G>::out_edge_iterator`] [Type for iterating over out edges.]]
[[`out_edges(v,g)`] [`std::pair<out_edge_iterator, out_edge_iterator>`]]
[[`out_degree(v,g)`] [`degree_size_type`]]
[[`source(e,g)`] [`vertex_descriptor`]]
[[`target(e,g)`] [`vertex_descriptor`]]
[[[*[BidirectionalGraph]]]]
[[`graph_traits<G>::in_edge_iterator`] [Type for iterating over in edges.]]
[[`in_edges(v,g)`] [`std::pair<in_edge_iterator,in_edge_iterator>`]]
[[`in_degree(v,g)`] [`degree_size_type`]]
[[`degree(v,g)`] [`degree_size_type`]]
[[[*[AdjacencyGraph]]]]
[[`graph_traits<G>::adjacency_iterator`] [Type for iterating over adjacent vertices.]]
[[`adjacent_vertices(v,g)`] [`std::pair<adjacency_iterator,adjacency_iterator>`]]
[[[*[VertexListGraph]]]]
[[`graph_traits<G>::vertex_iterator`] [Type for iterating over vertices.]]
[[`graph_traits<G>::vertices_size_type`] [Unsigned integer type for the number of vertices.]]
[[`vertices(g)`] [`std::pair<vertex_iterator,vertex_iterator>`]]
[[`num_vertices(g)`] [`vertices_size_type`]]
[[[*[EdgeListGraph]]]]
[[`graph_traits<G>::edge_iterator`] [Type for iterating over edges.]]
[[`graph_traits<G>::edges_size_type`] [Unsigned integer type for the number of edges.]]
[[`edges(g)`] [`std::pair<edge_iterator, edge_iterator>`]]
[[`num_edges(g)`] [`edges_size_type`]]
[[`source(e,g)`] [`vertex_descriptor`]]
[[`target(e,g)`] [`vertex_descriptor`]]
[[[*[AdjacencyMatrix]]]]
[[`edge(u,v,g)`] [`std::pair<edge_descriptor,boo>`]]
[[[*[MutableGraph]]]]
[[`add_vertex(g)`] [`vertex_descriptor`]]
[[`clear_vertex(v,g)`] [`void`]]
[[`clear_out_edges(v,g)`] [`void`]]
[[`clear_in_edges(v,g)`] [`void`]]
[[`add_edge(u,v,g)`] [`std::pair<edge_descriptor,bool>`]]
[[`remove_edge(u,v,g)`] [`void`]]
[[`remove_edge(e,g)`] [`void`]]
[[`remove_edge(ei,g)`] [`void`]]
[[`remove_edge_if(pred,g)`] [`void`]]
[[`remove_out_edge_if(v,pred,g)`] [`void`]]
[[`remove_in_edge_if(v,pred,g)`] [`void`]]
[[[*[PropertyGraph]]]]
[[`property_map<G,Property>::type`] [Type for a mutable property map.]]
[[`property_map<G,Property>::const_type`] [Type for a non-mutable property map.]]
[[`get(p,g)`] [Function to get a property map.]]
[[`get(p,g,x)`] [Get the property value for vertex or edge `x`]]
[[`put(p,g,x,v`)] [Set the property value for vertex or edge `x` to value `v`.]]
[[[*[MutablePropertyGraph]]]]
[[`add_vertex(vp,g)`] [`vertex_descriptor`]]
[[`add_edge(u,v,ep,g)`] [`std::pair<edge_descriptor,bool>`]]
]
[include graph.qbk]
[include incidence_graph.qbk]
[include bidirectional_graph.qbk]
[include adjacency_graph.qbk]
[include vertex_list_graph.qbk]
[include edge_list_graph.qbk]
[include adjacency_matrix.qbk]
[include mutable_graph.qbk]
[include property_graph.qbk]
[include mutable_property_graph.qbk]
[heading Pseudo-Concepts]
The concepts above describe the syntactic and semantic requirements of graphs
types. However, these do not directly address common graph notions such as
"directed" graphs or "multigraphs". As such, there are a number of
pseudo-concepts with which we can also describe graph objects.
[heading Directed and Undirected Graphs]
The interface that Boost.Graph provides for accessing and manipulating an
undirected graph is the same as the interface for directed graphs described in
the following sections, however there are some differences in the behaviour and
semantics. For example, in a directed graph we can talk about out-edges and
in-edges of a vertex. In an undirected graph there is no "in" and "out", there
are just edges incident to a vertex. Nevertheless, in Boost.Graph we still use
the `out_edges()` function (or `in_edges()`) to access the incident edges in an
undirected graph. Similarly, an undirected edge has no "source" and "target" but
merely an unordered pair of vertices, but we still use `source()` and `target()`
to access these vertices. The reason Boost.Graph does not provide a separate
interface for undirected graphs is that many algorithms on directed graphs also
work on undirected graphs, and it would be inconvenient to have to duplicate the
algorithms just because of an interface difference. When using undirected graphs
just mentally disregard the directionality in the function names. The example
below demonstrates using the `out_edges()`, `source()`, and `target()` with an
undirected graph. The source code for this example and the following one can be
found in `examples/undirected.cpp`.
const int V = 2;
typedef ... UndirectedGraph;
UndirectedGraph graph(V);
std::cout << "the edges incident to v: ";
boost::graph_traits<UndirectedGraph>::out_edge_iterator e, e_end;
boost::graph_traits<UndirectedGraph>::vertex_descriptor s = vertex(0, graph);
for(tie(e, e_end) = out_edges(s, graph); e != e_end; ++e) {
std::cout << "(" << source(*e, graph)
<< "," << target(*e, graph)
<< ")" << endl;
}
Even though the interface is the same for undirected graphs, there are some
behavioral differences because edge equality is defined differently. In a
directed graph, edge /(u,v)/ is never equal to edge /(v,u)/, but in an
undirected graph they may be equal. If the undirected graph is a multigraph then
/(u,v)/ and /(v,u)/ might be parallel edges. If the graph is not a multigraph
then /(u,v)/ and /(v,u)/ must be the same edge.
In the example below the edge equality test will return false for the directed
graph and true for the undirected graph. The difference also affects the meaning
of `add_edge()`. In the example below, if we had also written `add_add(v, u,
graph)`, this would have added a parallel edge between `u` and `v` (provided the
graph type allows parallel edges - which most do). The difference in edge
equality also affects the association of edge properties. In the directed graph,
the edges /(u,v)/ and /(v,u)/ can have distinct weight values, whereas in the
undirected graph the weight of /(u,v)/ is the same as the weight of /(v,u)/
since they are the same edge.
typedef ... DirectedGraph;
typedef ... UndirectedGraph;
DirectedGraph digraph(V);
UndirectedGraph graph(V)
{
boost::graph_traits<DirectedGraph>::vertex_descriptor u, v;
u = vertex(0, digraph);
v = vertex(1, digraph);
add_edge(digraph, u, v, Weight(1.2));
add_edge(digraph, v, u, Weight(2.4));
boost::graph_traits<DirectedGraph>::edge_descriptor e1, e2;
bool found;
tie(e1, found) = edge(u, v, digraph);
tie(e2, found) = edge(v, u, digraph);
std::cout << "in a directed graph is ";
std::cout << "(u,v) == (v,u) ? " << (e1 == e2) << std::endl;
property_map<DirectedGraph, edge_weight_t>::type
weight = get(edge_weight, digraph);
cout << "weight[(u,v)] = " << get(weight, e1) << endl;
cout << "weight[(v,u)] = " << get(weight, e2) << endl;
}
{
boost::graph_traits<UndirectedGraph>::vertex_descriptor u, v;
u = vertex(0, graph);
v = vertex(1, graph);
add_edge(graph, u, v, Weight(3.1));
boost::graph_traits<UndirectedGraph>::edge_descriptor e1, e2;
bool found;
tie(e1, found) = edge(u, v, graph);
tie(e2, found) = edge(v, u, graph);
std::cout << "in an undirected graph is ";
std::cout << "(u,v) == (v,u) ? " << (e1 == e2) << std::endl;
property_map<UndirectedGraph, edge_weight_t>::type
weight = get(edge_weight, graph);
cout << "weight[(u,v)] = " << get(weight, e1) << endl;
cout << "weight[(v,u)] = " << get(weight, e2) << endl;
}
The output is:
[pre
in a directed graph is (u,v) == (v,u) ? 0
weight\[(u,v)\] = 1.2
weight\[(v,u)\] = 2.4
in an undirected graph is (u,v) == (v,u) ? 1
weight\[(u,v)\] = 3.1
weight\[(v,u)\] = 3.1
]
[heading Multigraphs]
A /multigraph/ is a graph (either directed or undirected) that has parallel edges
between vertices. The Boost.Graph types are mostly unrestrictive about the addition
of parallel edges, meaning that it is fairly easy to actually create multigraphs
without any additional work.
There are certain sets of graph types that do not allow the addition of parallel edges.
Specifically, if the EdgeList and OutEdgeList of an [adjacency_list] models
[StdUniqueAssociativeContainer], then the graph cannont be a multigraph.
[heading Indexed Graphs]
Indexed graph provide a specific property, an index, for vertices, edges or both.
Many algorithms require vertex or edge indices for "fast" property access, often
declaring exterior properties as `vector`s and using the indices as random access
iterators to access those properties. These concepts effectively require that
indices are accessible as interior properties of the graph.
These concepts are provided to help describe interface requirements for algorithms
that allow indices to be provided as an exterior property map. With these concepts,
requirements (and interfaces) can be written more distinctly for algorithms that accept
indexed graphs, and those that require adaptation through exterior properties.
There are two indexed graph concepts: [VertexIndexGraph] and [EdgeIndexGraph].
[include vertex_index_graph.qbk]
[include edge_index_graph.qbk]
[endsect]

View File

@@ -1,95 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Incidence Graph]
The IncidenceGraph concept provides an interface for efficient access to the out-edges
(for directed graphs) or incident edges (for undirected graphs) of each vertex in
the graph.
[h4 Refinement Of]
[BoostGraph]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`graph_traits<G>::traversal_category`]
[
This tag type must be convertible to `incidence_graph_tag`.
]
]
[
[`graph_traits<G>::degree_size_type`]
[
The unsigned integral type used for representing the number of edges incident
to a vertex. The `degree_size_type` must meet the requirements of the
UnsignedIntegral concept.
]
]
[
[`graph_traits<G>::out_edge_iterator`]
[
An out-edge iterator for a vertex /v/ provides access to the out-edges of the
vertex. As such, the value type of an out-edge iterator is the `edge_descriptor`
type of the graph. An out-edge iterator must meet the requirements of
MultiPassInputIterator.
]
]
]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`source(e,g)`]
[
If `e` represents the edge /(u,v)/, this function returns the vertex descriptor
for /u/.
*Returns* `vertex_descriptor`.
]
]
[
[`target(e,g)`]
[
If `e` represents the edge /(u,v)/, this function returns the vertex descriptor
for /v/.
*Returns* `vertex_descriptor`.
]
]
[
[`out_edges(v,g)`]
[
Returns an iterator range providing access to the out-edges (for directed graphs)
or the incident edges (for undirected graphs). The source vertex of an edge obtained
via an out-edge iterator is guaranteed to be the vertex `v` in the call to
`out_edges(v,g)`, and the target vertex must be adjacenct to `v`.
*Returns* `std::pair<out_edge_iterator, out_edge_iterator>`
]
]
[
[`out_degree(v,g)`]
[
Returns the number of out-edges (for directed graphs) or the number of incident
edges (for undirected graphs) of the vertex `v`.
*Returns* `degree_size_type`.
]
]
]
[h4 Notes]
For undirected graphs, the edge /(u,v)/ is the same as edge /(v,u)/, so without some extra
guarantee an implementation would be free use any ordering for the pair of vertices in an
out-edge. For example, if you call `out_edges(u, g)`, and `v` is one of the vertices adjacent
to `u`, then the implementation would be free to return /(v,u)/ as an out-edge which would be
non-intuitive and cause trouble for algorithms. Therefore, the extra requirement is added that
the out-edge connecting `u` and `v` must be given as /(u,v)/ and not /(v,u)/.
[endsect]

View File

@@ -1,174 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Mutable Graph]
A MutableGraph can be changed via the addition or removal of edges and vertices.
[h4 Refinement Of]
[Graph]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`add_edge(u,v,g)`]
[
Add a new vertex to the graph. The `vertex_descriptor` for the new vertex is returned.
*Returns* `vertex_descriptor`
]
]
[
[`clear_vertex(v,g)`]
[
Removes all edges incident (both in-edges and out-edges for directed graphs) to the
vertex `v`.
*Returns* `void`
*Precondition* `u` is a valid `vertex_descriptor` in `g`.
*Postcondition* `u` does not appear as a source or target of any edge in `g`.
]
]
[
[`clear_out_edges(v,g)`]
[
Removes all edges out-edges of the vertex `v`. For undirected graphs this is functionally
equivalent to `clear_vertex(v,g)`.
*Returns* `void`
*Precondition* `u` is a valid `vertex_descriptor` in `g`.
*Postcondition* `u` does not appear as a source of any edge in `g`.
]
]
[
[`clear_in_edges(v,g)`]
[
Removes all edges in-edges of the vertex `v`. For undirected graphs this is functionally
equivalent to `clear_vertex(v,g)`.
*Returns* `void`
*Precondition* `u` is a valid `vertex_descriptor` in `g`.
*Postcondition* `u` does not appear as a target of any edge in `g`.
]
]
[
[`remove_vertex(v,g)`]
[
Remove the vertex `v` from the vertex set of the graph. Note that undefined behavior may
result if there are edges remaining in the graph who's target is `u`. The `clear_vertex(v,g)`
function should be called first to ensure the preconditions.
*Returns* `vertex_descriptor`
*Precondition* `u` is a valid `vertex_descriptor` in `g` and does not appear as the source
or target of any edge in `g`.
*Postcondition* `u` is not longer in the vertex set of `g`, nor is `u` a valid descriptor.
]
]
[
[`add_edge(u,v,g)`]
[
Inserts the edge /(u,v)/ into the graph, and returns an edge descriptor pointing to the new edge.
If the graph disallows parallel edges, and the edge /(u,v)/ is already in the graph, then the boolean
flag returned is false and the returned edge descriptor points to the already existing edge. Note
that for undirected graphs, /(u,v)/ is the same edge as /(v,u)/, so after a call to the function
`add_edge(u,v,g)`, this implies that edge /(u,v)/ will appear in the out-edges of `u` and /(u,v)/
(or equivalently /(v,u)/) will appear in the out-edges of `v`. Put another way, `v` will be adjacent
to `u` and `u` will be adjacent to `v`.
*Returns* `vertex_descriptor`
*Precondition* `u` and `v` are valid vertex descriptors in `g`.
*Postcondition* The returned `edge_descriptor` points to a valid edge in `g`.
]
]
[
[`remove_edge(u,v,g)`]
[
Remove the edge (u,v) from the graph. If the graph allows parallel edges this remove all occurrences
of /(u,v)/.
*Returns* `void`
*Precondition* `u` and `v` are valid vertex descriptors in `g`.
*Postcondition* The edge /(u,v)/ is no longer in the edge set of `g`.
]
]
[
[`remove_edge(e,g)`]
[
Remove the edge `e` from the graph.
*Returns* `void`
*Precondition* `e` is an edge in the graph.
*Postcondition* The edge `e` is no longer in the edge set of `g`.
]
]
[
[`remove_edge(ei,g)`]
[
Remove the edge pointed to by the edge iterator `ei` from the graph. This expression is only required
when `g` also models [IncidenceGraph].
*Returns* `void`
*Precondition* `*ei` is an edge in the graph.
*Postcondition* The edge `*ei` is no longer in the edge set of `g`.
]
]
[
[`remove_edge_if(pred,g)`]
[
Remove all edges from the graph `g` for which the predicate `pred` returns true.
*Returns* `void`
]
]
[
[`remove_out_edge_if(v,pred,g)`]
[
Remove all out-edges of the vertex `v` for which the predicate `pred` returns true.
*Returns* `void`
]
]
[
[`remove_in_edge_if(v,pred,g)`]
[
Remove all in-edges of the vertex `v` for which the predicate `pred` returns true.
*Returns* `void`
]
]
]
[h4 Complexity Guarantees]
* Vertex insertion is guaranteed to be amortized constant time.
* Clearing avertex is /O(E + V)/.
* Vertex removal is /O(E + V)/.
* Edge insertion must be either amortized constant time of it can be /O(log(E/V))/ if the insertion checks
to prevent the addition of parallel edges (which is a "feature" of some graph types).
* Edge removal is guaranteed to be /O(E)/.
[h4 Models]
* [undirected_graph]
* [directed_graph]
* [adjacency_list]
[endsect]

View File

@@ -1,64 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Mutable Property Graph]
A MutablePropertyGraph is a [MutableGraph] with properties attached internally to the
vertices and edges. When adding vertices and edges the value of the properties can be given.
[h4 Refinement Of]
[MutableGraph] and [PropertyGraph]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`graph_traits<G>::vertex_property_type`]
[
The property type associated with vertices in the graph `G`. This type is not
guaranteed to be the same as the `VertexProperties` template parameter.
]
]
[
[`graph_traits<G>::edge_property_type`]
[
The property type associated with edges in the graph `G`. This type is not
guaranteed to be the same as the `EdgeProperties` template parameter.
]
]
]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`add_vertex(vp,g)`]
[
Add a new vertex to the graph and copy vertex properties `vp` into the property
for the new vertex. The `vertex_descriptor` is returned.
*Returns* `vertex_descriptor`
]
]
[
[`add_edge(u,v,ep,g)`]
[
Inserts the edge /(u,v)/ into the graph, and copies object `ep` into the property
for that edge.
*Returns* `property_traits<property_map<G,Property>::const_type>::value_type`
*Precondition* `u` and `v` are valid vertex descriptors in `g`.
*Postcondition* The returned `edge_descriptor` points to a valid edge in `g`.
]
]
]
[h4 Complexity Guarantees]
The `get(p,g)` function must return in constant time.
[endsect]

View File

@@ -1,80 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/ TODO: This concept is fundamentally broken. It's trying to capture the
/ association of named constants with a type or a particular use. We probably
/ need to explore the design space of named concepts before we can really
/ attribute this as a legitimate operation.
/
/ For example, why are these required to be scoped? Why not simply use the
/ functions zero<T>() and infinity<T>()?
/]
[section Numeric Value]
The [NumericValue] concept describes requirements for a type to behave
as if it were numeric. This concept is generally used by algorithms that
typically operate on numeric types, but can be specialized to operate on
user-defined numerics or discrete types that emulate numerics.
This concept requires that its models be regular (i.e., default and copy
constructible, assignable, and equality comparable). Additioanlly, this
concept requires all common mathematical operators (i.e., addition, subtraction,
multiplication and division).
Finally, this concept requires that its models define appropriate values of
zero and infinity. These are used within certain computations to represent
infinite and zero states.
[heading Notation]
The following expressions are used within this document:
[table
[[Expression] [Description]]
[[N] [A type modeling the [NumericValue] concept.]]
]
[heading Associated Types]
[table
[[Name] [Type] [Description]]
[
[Value Type]
[`numeric_value<N>::value_type`]
[
The underlying type of the numeric value.
*Requirements:* `N` is a [NumericValue], and the `value_type`
and `N` must be the same type.
]
]
]
[heading Expressions]
[table
[[Name] [Expression] [Result Type] [Description]]
[
[Zero Value]
[`numeric_value<N>::zero()`]
[`numeric_value<N>::value_type`]
[
Returns the zero-value of the numeric type.
]
]
[
[Infinite Value]
[`numeric_value<N>::infinity()`]
[`numeric_value<N>::value_type`]
[
Returns the designated value of infinity for the numeric type.
*Notes:* Some types such as `float` and `double` have values
that represent infinity. For other types, this must be explicitly
designated. For built-in integral types this is often chosen to
be `std::numeric_limits<N>::max()`.
]
]
]
[endsect]

View File

@@ -1,86 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Property Graph]
A PropertyGraph is a graph that has some property associated with each of the vertices or edges
in the graph. As a given graph may have several properties associated with each vertex or edge,
a /tag/ is used to identity which property is being accessed. The graph provides a function which
returns a property map object and also the value corresponding to a vertex or edge and its
indicated property.
[h4 Refinement Of]
[Graph]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`property_map<G, Property>::type`]
[
The type of the property map for the property specified by `Property`. This type must
be a model of [ReadWritePropertyMap] with a key type the same as the graph's
`vertex_descriptor` or `edge_descriptor` types.
]
]
[
[`property_map<G, Property>::const_type`]
[
The type of the property map for the property specified by `Property`. This type must
be a model of [ReadablePropertyMap] with a key type the same as the graph\'s
`vertex_descriptor` or `edge_descriptor` types.
]
]
]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`get(p,g)`]
[
Returns the property map specified by the property identified by the tag `p`. The parameter
`p` is only used to convey type information and has no value.
*Returns* `property_map<G,Property>::type` if `g` is mutable and
`property_map<G,Property>::const_type` otherwise.
]
]
[
[`get(p,g,x)`]
[
Returns the property /value/ specified by the type of property tag `p` for the given
vertex or edge descriptor `x`. The object `p` is only used to convey type information
and has no value. This function is equivalent to `get(get(p,g),x)`.
*Returns* `property_traits<property_map<G,Property>::const_type>::value_type`
]
]
[
[`put(p,g,x,v)`]
[
Set the property /value/ specified by the type of property tag `p` for the given
vertex or edge descriptor `x` to the value `v`. The object `p` is only used to
convey type information and has no value.
*Returns* `void`
]
]
[
[`out_degree(v,g)`]
[
Returns the number of out-edges (for directed graphs) or the number of incident
edges (for undirected graphs) of the vertex `v`.
*Returns* `degree_size_type`.
]
]
]
[h4 Complexity Guarantees]
The `get(p,g)` function must return in constant time.
[endsect]

View File

@@ -1,23 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section General Concepts]
This section describes utlity graph concepts - those that do not necessarily
pertain explicitly to graphs or visitors for algorithms.
[include descriptor.qbk]
[/ TODO: These concepts need some serious revisions, which means that the
algorithms requiring them need to be revised so that they don't need them or
use them in modified ways.
]
[/ [include numeric_value.qbk] ]
[/ [include degree_measure.qbk] ]
[/ [include distance_measure.qbk] ]
[endsect]

View File

@@ -1,112 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Vertex Index Graph]
The [VertexIndexGraph] concept requires that a graph type `G` provide vertex indices
for each vertex in the graph, and that those indices are ordered in the range
\[0, `num_vertices(g)`).
Because the removal of vertices causes "gaps" in the index space, graphs that model
this concept must also provide functions that allow them to re-index the vertices.
[heading Refinement Of]
[MutablePropertyGraph]
[heading Notation]
[table
[[Expression] [Description]]
[[`G`] [A type that models the [Graph] concept.]]
[[`g`] [An object of type `G`.]]
[
[`P`]
[A synonym for `property_map<G,vertex_index_t>`.]
]
]
[heading Associated Types]
[table
[[Name] [Expression] [Result Type] [Description]]
[
[Vertex Index Type]
[`property_traits<P::const_type>::value_type`]
[An unsigned integer type]
[
The unsigned integral type representing vertex indices.
*Requirements:* `T` must model the [NoConcept UnsignedIntegral] concept.
]
]
[
[Vertex Index Property Type]
[
`P::type`
]
[A mutable property map]
[
The type of property map through which vertex indices are readable and
writable.
*Requirements:* This type must be a model of the [ReadWritePropertyMap]
concept. The `value_type` of the `property_traits` of this type must
be the same as `vertex_index_type`.
]
]
[
[Vertex Index Property Type]
[
`P::const_type`
]
[ A `const` property map]
[
The type of property map through which vertex indices are readable.
*Requirements:* This type must be a model of the [ReadablePropertyMap]
concept. The `value_type` of the `property_traits` of this type must
be the same as `vertex_index_type`.
]
]
]
[heading Requirements]
[table
[[Name] [Expression] [Result Type] [Description]]
[
[Vertex Index Property]
[`get(vertex_index,g)`]
[`P::type` or `P::const_type`]
[
Returns the property map that provides read/write access to the
vertex indices of the graph.
*Complexity:* Constant.
]
]
[
[Vertex Index]
[`get(vertex_index,g,v)`]
[`G::vertex_index_type`]
[
Returns the index of the given vertex within the graph. This is
equivalent to `get(get(vertex_index, g), v)`.
*Complexity:* Amortized constant.
]
]
[
[Renumber Vertex Indices]
[`renumber_vertex_indices(g)`]
[`void`]
[
Renumbers all vertices in the graph such that each vertex is in the
range \[0, `num_vertices(g)`).
*Complexity:* Linear in `num_vertices(g)`.
]
]
]
[endsect]

View File

@@ -1,75 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Vertex List Graph]
The VertexListGraph concept refines the [Graph] concept, and adds the requirement
for efficient traversal of all the vertices in a graph.
[h4 Refinement Of]
[Graph]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`graph_traits<G>::traversal_category`]
[
This tag type must be convertible to `vertex_list_graph_tag`.
]
]
[
[`graph_traits<G>::vertex_iterator`]
[
A vertex iterator (obtained via vertices(g)) provides access to all of the vertices in
a graph. A vertex iterator type must meet the requirements of [MultiPassInputIterator].
The value type of the vertex iterator must be the vertex descriptor of the graph.
]
]
[
[`graph_traits<G>::vertices_size_type`]
[
The unsigned integer type used to represent the number of vertices in the graph.
]
]
]
[h4 Valid Expressions]
[table
[[Expression] [Description]]
[
[`vertices(g)`]
[
Returns an iterator range providing access to all the vertices in the graph `g`.
*Returns* `std::pair<vertex_iterator, vertex_iterator>`
]
]
[
[`num_vertices(g)`]
[
Returns the number of vertices in the graph `g`.
*Returns* `vertices_size_type`
]
]
]
[h4 Complexity Guarantees]
The `vertices(g)` function must return in constant time.
[h4 Design Rationale]
One issue in the design of this concept is whether to include the refinement from the
[IncidenceGraph] and [AdjacencyGraph] concepts. The ability to traverse the vertices
of a graph is orthogonal to traversing out-edges, so it would make sense to have a VertexListGraph
concept that only includes vertex traversal. However, such a concept would no longer really be a
graph, but would just be a set, and the STL already has concepts for dealing with such things.
However, there are many BGL algorithms that need to traverse the vertices and out-edges of a graph,
so for convenience a concept is needed that groups these requirements together, hence the VertexListGraph
concept.
[endsect]

View File

@@ -1,23 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Visitor]
The [Visitor] concept defines the basic requirements of all visitor concepts in
the Boost.Graph library.
[h4 Refinement Of]
[SgiCopyConstructible]
[h4 Design Rationale]
This concept is provided primarily as a base concept for its refinements. Its
sole purpose is to require that instances of concepts be copy-constructible,
which is how they are passed to different graph algorithms.
Note that visitor types are most often constructed over references to other
objects such as property maps or data local to the calling function. As such,
most [Visitor] types are almost /never/ [SgiDefaultConstructible].
[endsect]

View File

@@ -1,30 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Visitor Concepts]
The visitor concepts plays the same role in Boost.Graph as functors play in the STL.
Functors provide a mechanism for extending an algorithm; for customizing what is done
at each step of the algorithm. Visitors allow the user to insert their own operations
at various steps within a graph algorithm. Unlike the STL algorithms, graph algorithms
typically have multiple event points where one may want to insert a call-back via a
functor. Therefore visitors do not have a single operator() method like a functor, but
instead have several methods that correspond to the various event points. Each
algorithm has a different set of event points, which are described by the following
visitor concepts:
[include visitor.qbk]
[include bfs_visitor.qbk]
[include dfs_visitor.qbk]
[include dijkstra_visitor.qbk]
[include bellman_ford_visitor.qbk]
[include clique_visitor.qbk]
[include cycle_visitor.qbk]
[include event_visitor.qbk]
[include event_visitor_list.qbk]
[endsect]

View File

@@ -1,55 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[library Boost.Graph
[quickbook 1.4]
[authors [Siek, Jeremy], [Lee, Lie-Quan], [Lumsdaine, Andrew]]
[copyright 2000 2001 Jeremy Siek, Lie-Quan Lee, Andrew Lumsdaine]
[category graph]
[id graph]
[dirname graph]
[purpose
Graph data structures and algorithms.
]
[license
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
[@http://www.boost.org/LICENSE_1_0.txt])
]
]
[/ Templates /]
[template sup[x]'''<superscript>'''[x]'''</superscript>''']
[template sub[x]'''<subscript>'''[x]'''</subscript>''']
[template delta[]'''&#x3B4;'''] [/ d Greek small letter delta]
[template figure[path caption]
'''
<mediaobject>
<imageobject>
<imagedata fileref="'''[path]'''" align="center"/>
</imageobject>
<caption>
<para>'''[caption]'''</para>
</caption>
</mediaobject>
'''
]
[include sgi_concepts.qbk]
[include boost_concepts.qbk]
[include boost_reference.qbk]
[/ Contents ]
[include introduction.qbk]
[include history.qbk]
[include guide/guide.qbk]
[include concepts/concepts.qbk]
[include reference/reference.qbk]
[/ [include bibliography.qbk] /]

View File

@@ -1,480 +0,0 @@
[/
/ Copyright (c) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section The Adjacency List]
As mentioned in the Tour, the `adjacency_list` has seven template parameters. Three are
used to select storage types for the vertex list, the edge list and the out edge list,
and the remaining three define the interior properties of vertices, edges, and the
graph itself.
[h2 Choosing the Edgelist and VertexList]
This section focuses on how to decide which version of the `adjacency_list` class to use in different
situations. The adjacency_list is like a swiss-army knife in that it can be configured in many ways.
The parameters that we will focus on in this section are `OutEdgeList` and `VertexList`, which control
the underlying data structures that will be used to represent the graph. The choice of `OutEdgeList` and
`VertexList` affects the time complexity of many of the graph operations and the space complexity of the
graph object.
Boost.Graph uses containers from the STL such as `std::vector`, `std::list`, and `std::set` to represent
the set of vertices and the adjacency structure (out-edges and in-edges) of the graph. There are several
selector types that are used to specify the choice of container for `OutEdgeList` and `VertexList`.
* `vecS` selects `std::vector`.
* `listS` selects `std::list`.
* `slistS` selects `std::slist`.
* `setS` selects `std::set`.
* `multisetS` selects `std::multiset`.
* `hash_setS` selects `std::hash_set`.
[h3 Choosing the VertexList Type]
The VertexList parameter determines what kind of container will be used to represent the vertex set, or
two-dimensional structure of the graph. The container must model /Sequence/ or /RandomAccessContainer/. In
general, listS is a good choice if you need to add and remove vertices quickly. The price for this is extra
space overhead compared to choosing `vecS`.
[h4 Space Complexity of the VertexList]
The `std::list` has a higher per-vertex space overhead than the `std::vector`, storing three extra pointers
per vertex.
[h4 Time Complexity of the VertexList]
The choice of VertexList affects the time complexity of the following operations.
[table VertexList Storage Options
[[Operation] [Performance Considerations]]
[
[`add_vertex()`]
[
This operation is amortized constant time for both vecS and listS (implemented with
`push_back()`). However, when the VertexList type is `vecS` the time for this operation
is occasionally large because the vector will be reallocated and the whole graph copied
but is still amortized constant time.
]
]
[
[`remove_vertex()`]
[
This operation is constant time for listS and O(V + E) for vecS. The large time
complexity for vecS is because the vertex descriptors (which in this case are indices
that correspond to the vertices' place in the vertex list) must be adjusted in the
out-edges for the whole graph.
]
]
[
[`vertex()`]
[
This operation is constant time for vecS and for `listS`.
]
]
]
[h3 Choosing the OutEdgeList Type]
The OutEdgeList parameter determines what kind of container will be used to store the out-edges (and
possibly in-edges) for each vertex in the graph. The containers used for edge lists must either satisfy
the requirements for Sequence or for AssociativeContainer.
One of the first things to consider when choosing the OutEdgeList is whether you want `adjacency_list` to
enforce the absence of parallel edges in the graph (that is, enforce that the graph not become a multi-graph).
If you want this enforced then use the setS or hash_setS selectors. If you want to represent a
multi-graph, or know that you will not be inserting parallel edges into the graph, then choose one of
the Sequence types: `vecS`, `listS`, or `slistS`. You will also want to take into account the differences in
time and space complexity for the various graph operations. Below we use V for the total number of vertices
in the graph and E for the total number of edges. Operations not discussed here are constant time.
[h4 Space Complexity of the OutEdgeList]
The selection of the OutEdgeList affects the amount of space overhead per edge in the graph object. In the
order of least space to most space, the selectors are `vecS`, `slistS`, `listS`, and `setS`.
[h4 Time Complexity of the OutEdgeList]
In the following description of the time complexity for various operations, we use E/V inside of the "big-O"
notation to express the length of an out-edge list. Strictly speaking this is not accurate because E/V merely
gives the average number of edges per vertex in a random graph. The worst-case number of out-edges for a vertex
is V (unless it is a multi-graph). For sparse graphs E/V is typically much smaller than V and can be considered
a constant.
[table OutEdgeList Storage Options
[[Operation] [Performance Considerations]]
[
[`add_edge()`]
[
When the OutEdgeList is a UniqueAssociativeContainer like `std::set` the absence of
parallel edges is enforced when an edge is added. The extra lookup involved has time
complexity O(log(E/V)). The OutEdgeList types that model Sequence do not perform this
check and therefore add_edge() is amortized constant time. This means that it if you
don't care whether the graph has parallel edges, or know that the input to the
graph does not contain them, then it is better to use the sequence-based OutEdgeList.
The `add_edge()` for the sequence-based OutEdgeList is implemented with `push_front()`
or `push_back()`. However, for `std::list` and `std::slist` this operation will
typically be faster than with `std::vector` which occasionally reallocates
and copies all elements.
]
]
[
[`remove_edge()`]
[
For sequence-based OutEdgeList types this operation is implemented with `std::remove_if()`
which means the average time is E/V. For set-based OutEdgeList types this is implemented
with the `erase()` member function, which has average time log(E/V).
]
]
[
[`edge()`]
[
The time complexity for this operation is O(E/V) when the OutEdgeList type is a Sequence
and it is O(log(E/V)) when the OutEdgeList type is an AssociativeContainer.
]
]
[
[`clear_vertex()`]
[
For directed graphs with sequence-based OutEdgeList types the time complexity is O(V + E),
while for associative container based OutEdgeList types the operation is faster, with
time complexity O(V log(E/V)). For undirected graphs this operation is O(E2/V2) or
O(E/V log(E/V)).
]
]
[
[`remove_vertex()`]
[
The time complexity for this operation is O(V + E) regardless of the OutEdgeList type.
]
]
[
[`out_edge_iterator::operator++()`]
[
This operation is constant time and exhibits a similar speed ordering as
the `out_edge_iterator` with respect to the OutEdgeList selection.
]
]
[
[`in_edge_iterator::operator++()`]
[
This operation is constant time and fast (same speed as incrementing a pointer).
The selection of OneD does not affect the speed of this operation.
]
]
[
[`vertex_iterator::operator++()`]
[
This operation is constant time and exhibits a similar speed ordering as the
out_edge_iterator with respect to the OutEdgeList selection. Traversing through the
whole edge set is O(V + E).
]
]
[
[`adjacency_iterator::operator++()`]
[
This operation is constant time and exhibits a similar speed ordering as
the out_edge_iterator with respect to the OutEdgeList selection.
]
]
]
[h2 Directed and Undirected Adjacency Lists]
The `adjacency_list` class can be used to represent both directed and undirected graphs, depending on the
argument passed to the Directed template parameter. Selecting `directedS` or `bidirectionalS` choose a directed
graph, whereas `undirectedS` selects the representation for an undirected graph. See Section Undirected Graphs
for a description of the difference between directed and undirected graphs in Boost.Graph. The `bidirectionalS`
selector specifies that the graph will provide the `in_edges()` function as well as the `out_edges()` function.
This imposes twice as much space overhead per edge, which is why `in_edges()` is optional.
[h2 Internal Properties]
Properties can be attached to the vertices or edges of an `adjacency_list` graph via the property interface.
The template parameters VertexProperty and EdgeProperty of the `adjacency_list` class are meant to be filled
by these interior properties.
[note The Boost Graph Library supports two interchangeable methods for specifying interior properties:
bundled properties and property lists. The former is easier to use and requires less effort, whereas the
latter is compatible with older, broken compilers and is backward-compatible with Boost versions prior to
1.32.0. If you absolutely require these compatibility features, read on to learn about property lists.
Otherwise, we strongly suggest that you read about the bundled properties mechanism.]
One may specify internal properties via property lists, which are built from instances of the property class
declared as follows.
template <class PropertyTag, class T, class NextProperty = no_property> struct property;
The PropertyTag template parameter is a tag class that simply identifies or gives a unique name to the property.
There are several predefined tags, and it is easy to add more.
struct vertex_index_t { };
struct vertex_index1_t { };
struct vertex_index2_t { };
struct edge_index_t { };
struct graph_name_t { };
struct vertex_name_t { };
struct edge_name_t { };
struct edge_weight_t { };
struct edge_weight2_t { };
struct edge_capacity_t { };
struct edge_residual_capacity_t { };
struct edge_reverse_t { };
struct vertex_distance_t { };
struct vertex_root_t { };
struct vertex_all_t { };
struct edge_all_t { };
struct graph_all_t { };
struct vertex_color_t { };
struct vertex_rank_t { };
struct vertex_predecessor_t { };
struct vertex_isomorphism_t { };
struct vertex_invariant_t { };
struct vertex_invariant1_t { };
struct vertex_invariant2_t { };
struct vertex_degree_t { };
struct vertex_out_degree_t { };
struct vertex_in_degree_t { };
struct vertex_discover_time_t { };
struct vertex_finish_time_t { };
The T template parameter of property specifies the type of the property values. The type T must be Default
Constructible, Assignable, and Copy Constructible. Like the containers of the C++ Standard Library, the
property objects of type T are held by-value inside of the graph.
The NextProperty parameter allows property types to be nested, so that an arbitrary number of properties
can be attached to the same graph.
The following code shows how a vertex and edge property type can be assembled and used to create a graph type.
We have attached a distance property with values of type float and a name property with values of type
std::string to the vertices of the graph. We have attached a weight property with values of type float to
the edges of the graph.
// specify property types fora graph
typedef property<vertex_distance_t, float, property<vertex_name_t, std::string> > VertexProperty;
typedef property<edge_weight_t, float> EdgeProperty;
// specify the graph has having the above properties
typedef adjacency_list<mapS, vecS, undirectedS,
VertexProperty, EdgeProperty> Graph;
// instantiate the graph with N (a compile-time constant integer) vertices
Graph g(N);
The property values are then read from and written to using property maps. See Section Interior Properties
for a description of how to obtain property maps from a graph, and read Section Property Maps for how to use
property maps.
[h3 Built-in Vertex and Edge Properties]
Even if a graph type is instantiated without any user-specified properties, Boost.Graph will define a few
default properties for both vertices and edges. These are always available in algorithms through the
property map interfaces.
Vertices have the following properties:
Edges have the following properties:
[h3 Custom Edge Properties]
Creating your own property types and properties is easy; just define a tag class for your new property.
The property tag class will need to define num with a unique integer ID, and kind which should be either
edge_property_tag, vertex_property_tag, or graph_property_tag.
struct flow_t {
typedef edge_property_tag kind;
};
struct capacity_t {
typedef edge_property_tag kind;
};
You can also use enum's instead of struct's to create tag types. Create an enum type for each property.
The first part of the name of the enum type must be edge, vertex, or graph followed by an underscore,
the new property name, and a _t at the end. Inside the enum, define a value with the same name minus the
_t. Then invoke the BOOST_INSTALL_PROPERTY macro.
enum edge_flow_t { edge_flow };
enum edge_capacity_t { edge_capacity };
namespace boost {
BOOST_INSTALL_PROPERTY(edge, flow);
BOOST_INSTALL_PROPERTY(edge, capacity);
}
Now you can use your new property tag in the definition of properties just as you would one of the builtin tags.
typedef property<capacity_t, int> Cap;
typedef property<flow_t, int, Cap> EdgeProperty;
typedef adjacency_list<vecS, vecS, no_property, EdgeProperty> Graph;
Just as before, the property maps for these properties can be obtained from the graph via the get(Property, g) function.
property_map<Graph, capacity_t>::type capacity = get(capacity_t(), G);
property_map<Graph, flow_t>::type flow = get(flow_t(), G);
The file edge_property.cpp shows the complete source code for this example.
[h3 Custom Vertex Properties]
Creating your own properties to attach to vertices is just as easy as for edges. Here we want to attach people's
first names to the vertices in the graph.
struct first_name_t {
typedef vertex_property_tag kind;
};
Now we can use the new tag in the property class and use that in the assembly of a graph type. The following
code shows creating the graph type, and then creating the graph object. We fill in the edges and also assign
names to the vertices. The edges will represent "who owes who";
typedef property<first_name_t, std::string> FirstNameProperty;
typedef adjacency_list<vecS, vecS, directedS,
FirstNameProperty> MyGraphType;
typedef pair<int,int> Pair;
Pair edge_array[11] = { Pair(0,1), Pair(0,2), Pair(0,3),
Pair(0,4), Pair(2,0), Pair(3,0),
Pair(2,4), Pair(3,1), Pair(3,4),
Pair(4,0), Pair(4,1) };
MyGraphType G(5);
for (int i = 0; i < 11; ++i) {
add_edge(edge_array[i].first, edge_array[i].second, G);
}
property_map<MyGraphType, first_name_t>::type name = get(first_name_t(), G);
boost::put(name, 0, "Jeremy");
boost::put(name, 1, "Rich");
boost::put(name, 2, "Andrew");
boost::put(name, 3, "Jeff");
name[4] = "Kinis"; // you can also use the operator[] too
who_owes_who(edges(G).first, edges(G).second, G);
The `who_owes_who()` function written for this example was implemented in a generic style. The input is
templated so we do not know the actual graph type. To find out the type of the property map for our
first-name property, we need to use the property_map traits class. The const_type is used since the graph
parameter is const. Once we have the property map type, we can deduce the value type of the property using
the property_traits class. In this example, we know that the property's value type will be `std::string`, but
written in this generic fashion the `who_owes_who()` function could work with other property value types.
template <class EdgeIter, class Graph>
void who_owes_who(EdgeIter first, EdgeIter last, const Graph& G)
{
// Access the propety acessor type for this graph
typedef typename property_map<Graph, first_name_t>::const_type NameMap;
typedef typename boost::property_traits<NameMap>::value_type NameType;
NameMap name = get(first_name, G);
NameType src_name, targ_name;
while (first != last) {
src_name = boost::get(name, source(*first, G));
targ_name = boost::get(name, target(*first, G));
cout << src_name << " owes "
<< targ_name << " some money" << "\n";
++first;
}
}
The output is:
Jeremy owes Rich some money
Jeremy owes Andrew some money
Jeremy owes Jeff some money
Jeremy owes Kinis some money
Andrew owes Jeremy some money
Andrew owes Kinis some money
Jeff owes Jeremy some money
Jeff owes Rich some money
Jeff owes Kinis some money
Kinis owes Jeremy some money
Kinis owes Rich some money
The complete source code to this example is in the file interior_property_map.cpp.
[h3 Customizing the Adjacency List Storage]
The `adjacency_list` is constructed out of two kinds of containers. One type of container to hold all the
vertices in the graph, and another type of container for the out-edge list (and potentially in-edge list)
for each vertex. Boost.Graph provides selector classes that allow the user to choose between several of the
containers from the STL. It is also possible to use your own container types. When customizing the VertexList
you need to define a container generator as described below. When customizing the OutEdgeList you will need
to define a container generator and the parallel edge traits. The file container_gen.cpp has an example of
how to use a custom storage type.
[h4 Container Generator]
The `adjacency_list` class uses a traits class called `container_gen` to map the OutEdgeList and VertexList
selectors to the actual container types used for the graph storage. The default version of the traits class
is listed below, along with an example of how the class is specialized for the listS selector.
namespace boost {
template <class Selector, class ValueType>
struct container_gen { };
template <class ValueType>
struct container_gen<listS, ValueType> {
typedef std::list<ValueType> type;
};
}
To use some other container of your choice, define a selector class and then specialize the `container_gen`
for your selector.
struct custom_containerS { }; // your selector
namespace boost {
// the specialization for your selector
template <class ValueType>
struct container_gen<custom_containerS, ValueType> {
typedef custom_container<ValueType> type;
};
}
There may also be situations when you want to use a container that has more template parameters than
just ValueType. For instance, you may want to supply the allocator type. One way to do this is to
hard-code in the extra parameters within the specialization of container_gen. However, if you want more
flexibility then you can add a template parameter to the selector class. In the code below we show how
to create a selector that lets you specify the allocator to be used with the `std::list`.
template <class Allocator>
struct list_with_allocatorS { };
namespace boost {
template <class Alloc, class ValueType>
struct container_gen<list_with_allocatorS<Alloc>, ValueType>
{
typedef typename Alloc::template rebind<ValueType>::other Allocator;
typedef std::list<ValueType, Allocator> type;
};
}
// now you can define a graph using std::list and a specific allocator
typedef adjacency_list< list_with_allocatorS< std::allocator<int> >, vecS, directedS> MyGraph;
[h4 Push and Erase for the Custom Container]
You must also tell the `adjacency_list` how elements can be efficiently added and removed from the
custom container. This is accomplished by overloading the `push()` and `erase()` functions for the custom
container type. The `push()` function should return an iterator pointing to the newly inserted element
and a bool flag saying whether the edge was inserted.
template <class T>
std::pair<typename custom_container<T>::iterator, bool>
push(custom_container<T>& c, const T& v)
{
// this implementation may need to change for your container
c.push_back(v);
return std::make_pair(boost::prior(c.end()), true);
}
template <class T>
void erase(custom_container<T>& c, const T& x)
{
// this implementation may need to change for your container
c.erase(std::remove(c.begin(), c.end(), x), c.end());
}
There are default `push()` and `erase()` functions implemented for the STL container types.
[h4 Parallel Edge Traits]
When customizing the OutEdgeList, you must also specialize the `parallel_edge_traits` class to specify whether
the container type allows parallel edges (and is a Sequence) or if the container does not allow parallel
edges (and is an AssociativeContainer).
template <>
struct parallel_edge_traits<custom_containerS> {
typedef allow_parallel_edge_tag type;
};
[endsect]

View File

@@ -1,371 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Directed Graphs]
Like the previous section, here we take a look at how to solve different
types graph problems using the Boost.Graph library. In this case however,
the problems being addressed are better modeled with directed graphs. A
directed graph (also a /digraph/) is one in which edges can only be traversed
in a specific direction.
In this section we are concerned with /dependency graphs/. A dependency graph
describes a relationship between two entities in which one (/source/) requires
a second (/target/). The source is said to be dependant upon the target.
Dependency graphs arise in many, many real-world situations such as source
code analysis, software installation, "tech-trees" in computer games, etc.
In this example, we will look at a common dependency graph: dependencies
between software documents and build targets.
[h3 File Dependencies]
If you've ever typed `make` and wondered how the program decides the order
tasks to build, then this tutorial is for you. The make software relies on
dependency information explicitly encoded into Makefiles. Binaries (executable
programs and libraries) depend on sets of source files. Source files, which
implement program features, depend on header files, which expose type and
function declarations. These, in turn, might depend on generated source files
generated by `lex`, `yacc` or any other of an assortment of code-generating
tools. These dependencies can be modeled with a directed graph.
For this example, we're actually going to use some of the files that actually
implement the examples described in this user's guide. Their dependencies are
shown in figure 1. Path names have been omitted for readability.
[$images/guide/files.png]
From this graph, it should be relatively easy to see that the build should
start at the bottom and proceed "upwards" with the executable programs being
built last - maybe. There are actually two different approaches to bulding
these programs:
* One at a time. This is probably what you're used to seeing. The compiler
builds file A, followed by file B, and finally file C.
* In parallel. If you're lucky enough to have a multi-processor computer
available to you we might be able to process (compile) a number of different
files at the same time by distributing the tasks to different processors.
The solution to both of these problems is addressed by topologically sorting
the graph. This provies the schedule of files to be processed by ordering
the vertices based on their dependencies.
A third problem we might encounter is that of cycles in the dependency
graph. Cycles are bad since topological sorts will not work in their presence.
[h4 Makefiles and Graphs]
The first step in implementing a make-ordering for source files is acquiring
some data. For this example, we our program will parse files in a stripped down,
Makefile-like format. The input looks something like something like this.
[pre
undirected_graph.hpp : adjacency_list.hpp
directed_graph.hpp : adjacency_list.hpp
movies.hpp : undirected_graph.hpp
movies.cpp : movies.hpp tokenizer.hpp
kevin_bacon.cpp : movies.hpp visitors.hpp breadth_first_search.hpp
kevin_bacon.exe : movies.cpp kevin_bacon.cpp
build_order.cpp : directed_graph.hpp topological_sort.hpp
build_order.exe : build_order.cpp
]
Obviously, we're going to have to build a parser for this input format. Just as
before our program starts by defining aliases for commonly used template types.
struct Target;
typedef boost::directed_graph<Target> Graph;
typedef Graph::vertex_descriptor Vertex;
typedef Graph::edge_descriptor Edge;
In this graph, vertex properties are encapsulated in a `Target` structure. For
this application, a target is any named file that might appear in the dependency
graph. Unlike the previous example, we really don't have any need for edge propreties,
so we can simply omit that template parameter. The `Target` is defined as:
struct Target
{
int index;
std::string name;
};
[note
If you think you're seeing some similarities between the previous example, and this
one... just wait. There are a number of common properties and tasks in many graph
related problems such as indexing vertices, providing name labels, etc. Pay special
attention to the method of adding vertices to the graph - the mapping of a unique
name to a vertex is nearly ubiquitous in the setup of graph problems.
]
Likewise, we'll go ahead and predefine a property map that will be used later.
We also need a mapping of target name to vertex so we don't duplicate vertices
and have a convenient lookup tool later on.
typedef boost::property_map<Graph::type, int Target::*>::type TargetIndexMap;
typedef std::map<std::string, Vertex> TargetMap;
We can now start building a program to parse the input data and build a dependency
graph.
using namespace std;
using namespace boost;
int main()
{
typedef char_separator<char> separator;
typedef tokenizer<separator> tokenizer;
Graph grapg;
TargetMap targets;
for(string line; getline(cin, line); ) {
// skip comment and blank lines
if(line[0] == '#' || line.empty()) {
continue;
}
// split the string on the dependency
size_t index = line.find_first_of(':');
if(index == string::npos) {
continue;
}
string target = trim_copy(line.substr(0, index));
string deps = trim_copy(line.substr(index + 1));
// add the target to the build graph
Vertex u = add_target(graph, targets, target);
// tokenize the dependencies
separator sep(" \t");
tokenizer tok(deps, sep);
tokenizer::iterator i = tok.begin(), j = tok.end();
for( ; i != j; ++i) {
string dep = *i;
// add this dependency as a target
Vertex v = add_target(graph, targets, dep);
// add the edge
add_dependency(graph, u, v);
}
}
// ...to be continued...
This is a fairly large chunk of code that implements input parsing and graph construction
with the help of the `add_target()` and `add_dependency()` functions. Essentially, this
snippet creates a vertex (target) for each file named in the input file. A dependency
edge is added between the first target (preceeding the ':' character) and each subsequent
target (white space separated list following the ':'). The `add_target()` and `add_dependency()`
method are implemented as:
Vertex add_target(Graph& graph, TargetMap& targets, const string& name)
{
Vertex v;
TargetMap::iterator it;
bool inserted;
tie(it, inserted) = targets.insert(make_pair(name, Vertex()));
if(inserted) {
v = add_vertex(graph);
it->second = v;
graph[v].index = num_vertices(graph) - 1;
graph[v].name = name;
}
else {
v = it->second;
}
return v;
}
You may notice that the `add_target()` function is nearly line-for-line identical to the
`add_actor()` function in the previous example. This is no coincidence - both functions
do exactly the same thing. They associate a vertex with a unique name and assign it an
index that we can use later for various graph algorithms.
Edge add_dependency(Graph& graph, Vertex u, Vertex v)
{
return add_edge(v, u, graph).first;
}
The `add_dependency()` method is considerably more terse than its undirected counter part,
but essentially does the same thing. There is one very important difference, however:
the direction of the edge is reversed to create a subtly different graph. Although
the method is called to indicate that vertex `u` dependes on vertex `v`, the added edge
actually indicates that vertex `v` satisfies the dependency of vertex `u`. In fact, this
is the reverse of the original graph and is shown in Figure 2.
[$images/guide/reverse.png]
[h4 Obtaining the Make Order]
We are now ready to compute the make order by running a topological sort. Thanks to a
canned implementation, this is trivial.
int main()
{
// ...continued from above...
TargetIndexMap indices = get(&Target::index, graph);
typedef list<Vertex> MakeOrder;
MakeOrder order;
topological_sort(graph, front_inserter(order), vertex_index_map(indices));
BuildOrder::iterator i = order.begin(), j = order.end();
for( ; i != j; ++i) {
cout << graph[*i] << "\n";
}
}
The `topological_sort()` algorithm takes an output iterator as the second parameter.
Here, we use a standard front insertion iterator to prepend each target to the make
order. The `vertex_index_map()` named parameter is also required for the implementation.
After computation, we simply print the ordering to standard output.
[h4 Parallel Compilation]
What if we have multiple processors available? Surely there is a way to determine if
we can compile several independent files simultaneously, thereby reducing the overall
build time. In fact, there is. Consider rephrasing the question to "what is the earliest
time that a file can be built assuming that an unlimited number of files can be built
at the same time?". In our simplified example, the only criteria for when a file can
be built is that it has no dependencies (i.e., in edges). Further simplifiying the
example, we assume that each file takes the same amount of time to build (1 time unit).
For parallel compilation, we can build all files with zero dependencies in the first
time unit at the same time. For each file, the time at which it can be built is one
more than the maximum build time of the files on which it depends. In this example,
`adjacency_list.hpp` is one of the files that will compile first (in parallel).
The `directed_graph.hpp` file will compile in the second time step, and `build_order.cpp`
in the third.
To implement this, we need a vector that represents the time slots in which each vertex
will be built. By visiting the vertices in topological order, we ensure that we can
assigned the correct time slot to each vertex since values "propogate" down the ordering.
Just for fun, we'll merge the time ordering with the output so we can see a) the order
in which each file is built and b) the time slot it could be built in.
int main()
{
// ...continued from above...
vector<int> time(num_vertices(graph), 0);
BuildOrder::iterator i = order.begin(), j = order.end();
for( ; i != j; ++i) {
int slot = -1;
Graph::in_edge_iterator j, k;
for(tie(j, k) = in_edges(*i, graph); j != k; ++j) {
Vertex v = source(*j, graph);
slot = std::max(time[graph[v].index], slot);
}
time[g[*i].index] = slot + 1;
cout << g[*i].name << "\t[" << time[g[*i].index] << "]\n";
}
}
This is a code may be a little dense, but demonstrates two important aspects of
the Boost.Graph library. First this demonstrates the importantance of vertex
indices. Despite their instability with mutable graphs, many (most?) graph algorithms
use vertex indices to efficiently associate extra data with a vertex. In fact, this
approach is so ubiquitous in the examples that it leads many to believe the
`vertex_descriptor` is always the index of a vertex.
[warning
A `vertex_descriptor` is *not* its index in the graphs container of vectors!
]
The second important aspect this demonstrates is the construction of an /external
property/ for vertices. Although we don't use the `time` vector in any additional
computations, we could easily turn it into a property map for use with other
algorithms.
The output might something like this:
[pre
$ ./make_order < files
topological_sort.hpp [0]
breadth_first_search.hpp [0]
visitors.hpp [0]
tokenizer.hpp [0]
adjacency_list.hpp [0]
directed_graph.hpp [1]
build_order.cpp [2]
build_order.exe [3]
undirected_graph.hpp [1]
movies.hpp [2]
kevin_bacon.cpp [3]
movies.cpp [3]
kevin_bacon.exe [4]
]
Although it probably won't since I doctored the tabbing for display purposes.
[h4 Finding Cycles]
Admittedly, cycles in dependency graphs for software probably don't occur so often
that we need to develop special software to find them. However, if the dependency
graph is big (think about all the source code, binaries, data files and thier
dependencies that constitute a typical Linux distribution), then its possible that
cycles creep into the graph. It might be nice to determine if there is such a cycle
before actually trying to build it.
To do this, we are going to provide a customized visitor for a depth-first search (DFS).
Just like the custom visitors in our undirected graph examples, we overload a visitor
event (here, the `back_edge` event) to indicate that a cycle has been found. Using the
same setup as before, our visitor follows:
struct CycleDetector : public dfs_visitor<>
{
CycleDetector(bool& c)
: has_cycle(c)
{}
template <class Edge, class Graph>
void back_edge(Edge, Graph&)
{
has_cycle = true;
}
bool& has_cycle;
};
CycleDetector detect_cycles(bool& c)
{ return CycleDetector(c); }
That's it... When the `back_edge()` method is called, we know that a cycle exists
in the graph. This literally indicates that there is an edge to a vertex that we
have already visited, hence: a cycle. We also provide a helper function that
instantiates the visitor.
Using the cycle-detecting visitor is just as easy as before. After constructing the
graph, we would find the following in the `main()` program.
int main()
{
// ...continued from above...
TargetIndexMap indices = get(&Target::index, g);
bool cycle = false;
depth_first_search(g,
vertex_index_map(indices).
visitor(detect_cycles(cycle)));
cout << "has cycle: " << cycle << "\n";
}
Unfortunately, our test input file doesn't currently contain any cycles - a sign of
good engineering - so we'll have to add one. Add the following lines to the input
to create a completely superfluous cycle.
[pre
movies.exe : kevin_bacon.exe
kevin_bacon.exe : movies.exe
]
Running the program on the modified input should yield:
[pre
$ ./cycle < files
has cycle: 1
]
[endsect]

View File

@@ -1,22 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/
/ The user's guide encompasses non-reference documentation that includes
/ overviews of graph theory, different graph implementations, etc. For all
/ technical docuementation, see the concepts or reference material.
/]
[section User's Guide]
[include theory.qbk]
[include tour.qbk]
[include undirected_graph.qbk]
[include directed_graph.qbk]
[include adjacency_list.qbk]
[endsect]

View File

@@ -1,295 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Review of Elementary Graph Theory]
This chapter is meant as a refresher on elementary graph theory. If the reader
has some previous acquaintance with graph algorithms, this chapter should be
enough to get started. If the reader has no previous background in graph
algorithms we suggest a more thorough introduction such as /Introduction to
Algorithms/ by Cormen, Leiserson, and Rivest.
[h2 The Graph Abstraction]
A graph is a mathematical abstraction that is useful for solving many kinds of
problems. Fundamentally, a graph consists of a set of vertices, and a set of
edges, where an edge is something that connects two vertices in the graph. More
precisely, a graph is a pair (V,E), where V is a finite set and E is a binary
relation on V. V is called a vertex set whose elements are called vertices. E
is a collection of edges, where an edge is a pair (u,v) with u,v in V. In a
directed graph, edges are ordered pairs, connecting a source vertex to a target
vertex. In an undirected graph edges are unordered pairs and connect the two
vertices in both directions, hence in an undirected graph (u,v) and (v,u) are
two ways of writing the same edge.
This definition of a graph is vague in certain respects; it does not say what a
vertex or edge represents. They could be cities with connecting roads, or
web-pages with hyperlinks. These details are left out of the definition of a
graph for an important reason; they are not a necessary part of the graph
abstraction. By leaving out the details we can construct a theory that is
reusable, that can help us solve lots of different kinds of problems.
Back to the definition: a graph is a set of vertices and edges. For purposes of
demonstration, let us consider a graph where we have labeled the vertices with
letters, and we write an edge simply as a pair of letters. Now we can write down
an example of a directed graph as follows:
G = (V, E)
V = {v, b, x, z, a, y }
E = { (b,y), (b,y), (y,v), (z,a), (x,x), (b,x), (x,v), (a,z) }
Figure 1 gives a pictorial view of this graph. The edge (x,x) is called a
self-loop. Edges (b,y) and (b,y) are parallel edges, which are allowed in a
multigraph (but are normally not allowed in a directed or undirected graph).
[$../../images/review_figure_1.png]
Next we have a similar graph, though this time it is undirected. Figure 2 gives
the pictorial view. Self loops are not allowed in undirected graphs. This graph
is the undirected version(b,y)), meaning it has the same vertices and the same
edges with their directions removed. Also the self edge has been removed, and
edges such as (a,z) and (z,a) are collapsed into one edge. One can go the other
way, and make a directed version of an undirected graph be replacing each edge
by two edges, one pointing in each direction.
G = (V, E)
V = {v, b, x, z, a, y }
E = { (b,y), (y,v), (z,a), (b,x), (x,v) }
[$../../images/review_figure_2.png]
Now for some more graph terminology. If some edge (u,v) is in graph , then
vertex v is adjacent to vertex u. In a directed graph, edge (u,v) is an out-edge
of vertex u and an in-edge of vertex v. In an undirected graph edge (u,v) is
incident on vertices u and v.
In Figure 1, vertex y is adjacent to vertex b (but b is not adjacent to y). The
edge (b,y) is an out-edge of b and an in-edge of y. In Figure 2, y is adjacent
to b and vice-versa. The edge (y,b) is incident on vertices y and b.
In a directed graph, the number of out-edges of a vertex is its out-degree and
the number of in-edges is its in-degree. For an undirected graph, the number of
edges incident to a vertex is its degree. In Figure 1, vertex b has an
out-degree of 3 and an in-degree of zero. In Figure 2, vertex b simply has a
degree of 2.
Now a path is a sequence of edges in a graph such that the target vertex of each
edge is the source vertex of the next edge in the sequence. If there is a path
starting at vertex u and ending at vertex v we say that v is reachable from u. A
path is simple if none of the vertices in the sequence are repeated. The path
<(b,x), (x,v)> is simple, while the path <(a,z), (z,a)> is not. Also, the path
<(a,z), (z,a)> is called a cycle because the first and last vertex in the path
are the same. A graph with no cycles is acyclic.
A planar graph is a graph that can be drawn on a plane without any of the edges
crossing over each other. Such a drawing is called a plane graph. A face of a
plane graph is a connected region of the plane surrounded by edges. An important
property of planar graphs is that the number of faces, edges, and vertices are
related through Euler's formula: |F| - |E| + |V| = 2. This means that a simple
planar graph has at most O(|V|) edges.
[h2 Graph Data Structures]
The primary property of a graph to consider when deciding which data structure
to use is sparsity - the number of edges relative to the number of vertices in
the graph. A graph where E is close to V2 is a /dense graph/, whereas a graph
where E = alpha V and alpha is much smaller than V is a /sparse graph/. For
dense graphs, the adjacency-matrix representation is usually the best choice,
whereas for sparse graphs the adjacency-list representation is a better choice.
Also the edge-list representation is a space efficient choice for sparse graphs
that is appropriate in some situations.
[h3 Adjacency Matrix Representation]
An adjacency-matrix representation of a graph is a 2-dimensional V x V array.
Each element in the array auv stores a Boolean value saying whether the edge
(u,v) is in the graph. Figure 3 depicts an adjacency matrix for the graph in
Figure 1 (minus the parallel edge (b,y)). The ammount of space required to store
an adjacency-matrix is O(V2). Any edge can be accessed, added, or removed in
O(1) time. To add or remove a vertex requires reallocating and copying the whole
graph, an O(V2) operation. The `adjacency_matrix<>` class implements the
Boost.Graph interface in terms of the adjacency-matrix data structure.
[$../images/review_adjacency_matrix.gif]
[h3 Adjacency List Representation]
An adjacency-list representation of a graph stores an out-edge sequence for each
vertex. For sparse graphs this saves space since only O(V + E) memory is
required. In addition, the out-edges for each vertex can be accessed more
efficiently. Edge insertion is O(1), though accessing any given edge is
O(alpha), where alpha is the sparsity factor of the matrix (which is equal to
the maximum number of out-edges for any vertex in the graph). Figure 4 depicts
an adjacency-list representation of the graph in Figure 1. The adjacency_list
class is an implementation of the adjacency-list representation.
[$../images/review_adjacency_list.gif]
[h3 Edge List Representation]
An edge-list representation of a graph is simply a sequence of edges, where each
edge is represented as a pair of vertex ID's. The memory required is only O(E).
Edge insertion is typically O(1), though accessing a particular edge is O(E)
(not efficient). Figure 5 shows an edge-list representation of the graph in
Figure 1. The edge_list adaptor class can be used to create implementations of
the edge-list representation.
[$../images/review_edge_list.gif]
[h3 Other Respresentations]
Add something here to discuss optimized storage options for the graph.
Specifically, we might mention the compressed-sparse-row graph representation
and its possible uses.
[h2 Graph Algorithms]
Like all data structures, there are numerous algorithms that operate on them to
solve various problems. In fact, there are often several different approaches to
solving the same problem, each with different properties and complexities when
running on graphs with different properties (e.g., directed vs. undirected or
sparse vs. dense). The following sections briefly discuss a few such problems
and algorithms.
[h3 Graph Search Algorithms]
Tree edges are edges in the search tree (or forest) constructed (implicitly or
explicitly) by running a graph search algorithm over a graph. An edge (u,v) is a
tree edge if v was first discovered while exploring (corresponding to the
visitor explore() method) edge (u,v). Back edges connect vertices to their
ancestors in a search tree. So for edge (u,v) the vertex v must be the ancestor
of vertex u. Self loops are considered to be back edges. Forward edges are
non-tree edges (u,v) that connect a vertex u to a descendant v in a search tree.
Cross edges are edges that do not fall into the above three categories.
[h4 Breadth-First Search]
Breadth-first search (BFS) is a traversal through a graph that touches all of
the vertices reachable from a particular source vertex. In addition, the order
of the traversal is such that the algorithm will explore all of the neighbors of
a vertex before proceeding on to the neighbors of its neighbors. One way to
think of breadth-first search is that it expands like a wave emanating from a
stone dropped into a pool of water. Vertices in the same "wave" are the same
distance from the source vertex. A vertex is discovered the first time it is
encountered by the algorithm. A vertex is finished after all of its neighbors
are explored. Here's an example to help make this clear. A graph is shown in
Figure 6 and the BFS discovery and finish order for the vertices is shown below.
[$../images/review_bfs.gif]
order of discovery: s r w v t x u y
order of finish: s r w v t x u y
We start at vertex , and first visit r and w (the two neighbors of ). Once both
neighbors of are visited, we visit the neighbor of r (vertex v), then the
neighbors of w (the discovery order between r and w does not matter) which are t
and x. Finally we visit the neighbors of t and x, which are u and y.
For the algorithm to keep track of where it is in the graph, and which vertex to
visit next, BFS needs to color the vertices (see the section on Property Maps
for more details about attaching properties to graphs). The place to put the
color can either be inside the graph, or it can be passed into the algorithm as
an argument.
[h4 Depth-First Search]
A depth-first search (DFS) visits all the vertices in a graph. When choosing
which edge to explore next, this algorithm always chooses to go "deeper" into
the graph. That is, it will pick the next adjacent unvisited vertex until
reaching a vertex that has no unvisited adjacent vertices. The algorithm will
then backtrack to the previous vertex and continue along any as-yet unexplored
edges from that vertex. After DFS has visited all the reachable vertices from a
particular source vertex, it chooses one of the remaining undiscovered vertices
and continues the search. This process creates a set of depth-first trees which
together form the depth-first forest. A depth-first search categorizes the edges
in the graph into three categories: tree-edges, back-edges, and forward or
cross-edges (it does not specify which). There are typically many valid
depth-first forests for a given graph, and therefore many different (and equally
valid) ways to categorize the edges.
One interesting property of depth-first search is that the discover and finish
times for each vertex form a parenthesis structure. If we use an
open-parenthesis when a vertex is discovered, and a close-parenthesis when a
vertex is finished, then the result is a properly nested set of parenthesis.
Figure 7 shows DFS applied to an undirected graph, with the edges labeled in the
order they were explored. Below we list the vertices of the graph ordered by
discover and finish time, as well as show the parenthesis structure. DFS is used
as the kernel for several other graph algorithms, including topological sort and
two of the connected component algorithms. It can also be used to detect cycles
(see the Cylic Dependencies section of the File Dependency Example).
[$../images/review_dfs.gif]
order of discovery: a b e d c f g h i
order of finish: d f c e b a
parenthesis: (a (b (e (d d) (c (f f) c) e) b) a) (g (h (i i) h) g)
[h4 Minimum Spanning Tree Problem]
The minimum-spanning-tree (MST) problem is defined as follows: Given a graph
/G=(V,E)/ find an acyclic subset /T/ of /E/ that connects all of the vertices in
the graph and whose total weight is minimized, where the total weight is given
by
/w(T)/ = sum of /w(u,v)/ over all /(u,v)/ in T, where /w(u,v)/ is the weight on
the edge /(u,v)/.
/T/ is called the minimum spanning tree of /G/. It is important to note that a
graph may have multiple MSTs.
[h4 Shortest-Paths Algorithms]
One of the classic problems in graph theory is to find the shortest path between
two vertices in a graph. Formally, a path is a sequence of vertices
<v0,v1,...,vk> in a graph G = (V, E) such that each vertex is connected to the
next vertex in the sequence (the edges (vi,vi+1) for i=0,1,...,k-1 are in the
edge set E). In the shortest-path problem, each edge is given a real-valued
weight. We can therefore talk about the weight of a path
/w(p)/ = sum from /i=1..k/ of /w(vi-1,vi)/
The shortest path weight from vertex /u/ to /v/ is then
/delta(u,v)/ = min /{ w(p) : u --> v }/ if there is a path from u to v
/delta(u,v)/ = infinity otherwise.
A shortest path is any path who's path weight is equal to the shortest path
weight. So there may be several shortest paths within the same graph.
There are several variants of the shortest path problem. Above we defined the
single-pair problem, but there is also the single-source problem (all shortest
paths from one vertex to every other vertex in the graph), the equivalent
single-destination problem, and the all-pairs problem. It turns out that there
are no algorithms for solving the single-pair problem that are asymptotically
faster than algorithms that solve the single-source problem.
A shortest-paths tree rooted at vertex in graph /G=(V,E)/ is a directed subgraph
where /V'/ is a subset of /V/ and /E'/ is a subset of /(E, V')/ is the set of
vertices reachable from , /G'/ forms a rooted tree with root , and for all /v/
in /V'/ the unique simple path from to /v/ in /G'/ is a shortest path from to
/v/ in /G/. The result of a single-source algorithm is a shortest-paths tree.
[h4 Network Flow Algorithms]
A flow network is a directed graph /G=(V,E)/ with a source vertex /s/ and a sink
vertex /t/. Each edge has a positive real valued capacity function c and there
is a flow function f defined over every vertex pair. The flow function must
satisfy three contraints:
* /f(u,v) <= c(u,v)/ for all /(u,v)/ in /V/x /V/ (Capacity constraint)
* /f(u,v) = -f(v,u)/ for all /(u,v)/ in /V/ x /V/ (Skew symmetry)
* sum /v/ in /V/ /f(u,v)/ = 0 for all /u/ in /V/ - /{s,t}/ (Flow conservation)
The flow of the network is the net flow entering the sink vertex t (which is
equal to the net flow leaving the source vertex s).
/|f|/ = sum /u/ in /V/ /f(u,t)/ = sum /v/ in /V/ /f(s,v)/
The residual capacity of an edge is /r(u,v)/ = /c(u,v) - f(u,v)/. The edges with
/r(u,v) > 0/ are residual edges /Ef/ which induce the residual graph /Gf = (V,
Ef)/. An edge with /r(u,v) = 0/ is saturated.
The maximum flow problem is to determine the maximum possible value for |/f/|
and the corresponding flow values for every vertex pair in the graph. A flow
network is shown in Figure 8. Vertex A is the source vertex and H is the target
vertex.
[$../images/review_flow.gif]
Edges are labeled with the flow and capacity values. There is a long history of
algorithms for solving the maximum flow problem, with the first algorithm due to
Ford and Fulkerson. The best general purpose algorithm to date is the
push-relabel algorithm of Goldberg which is based on the notion of a preflow
introduced by Karzanov.
[endsect]

View File

@@ -1,551 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section A Quick tour of Boost.Graph]
[note This guide is taken from the old BGL documentation and may not reflect
current or best practice.]
The domain of graph data structures and algorithms is in some respects more
complicated than that of containers. The abstract iterator interface used by
STL is not sufficiently rich to encompass the numerous ways that graph
algorithms may traverse a graph. Instead, we formulate an abstract interface
that serves the same purpose for graphs that iterators do for basic containers
(though iterators still play a large role). Figure 1 depicts the analogy between
the STL and
Boost.Graph.
[$../images/tour_analogy.gif]
The graph abstraction consists of a set of vertices (or nodes), and a set of
edges (or arcs) that connect the vertices. Figure 2 depicts a directed graph
with five vertices (labeled 0 through 4) and 11 edges. The edges leaving a
vertex are called the out-edges of the vertex. The edges {(0,1),(0,2),(0,3),(0,4)}
are all out-edges of vertex 0. The edges entering a vertex are called the in-edges
of the vertex. The edges {(0,4),(2,4),(3,4)} are all in-edges of vertex 4.
[$../images/tour_graph.png]
In the following sections we will use Boost.Graph to construct this example
graph and manipulate it in various ways. The complete source code for this
example can be found in `examples/quick_tour.cpp`. Each of the following
sections discusses a "slice" of this example file. Excerpts from the output of
the example program will also be listed.
[h2 Constructing the Graph]
In this example we will use the [adjacency_list] class to demonstrate the main
ideas in the Boost.Graph interface. The [adjacency_list] class provides a
generalized version of the classic /adjacency list/ data structure. The
[adjacency_list] class is a template class with six template parameters, though
here we only fill in the first three parameters and use the defaults for the
remainder. The first two template arguments (`vecS`, `vecS`) determine the data
structure used to represent the out-edges for each vertex in the graph and the
data structure used to represent the graph's vertex set (see section Choosing
the Edgelist and VertexList for information about the tradeoffs of the different
data structures). The third argument, `bidirectionalS`, selects a directed graph
that provides access to both out and in-edges. The other options for the third
argument are `directedS` which selects a directed graph with only out-edges, and
`undirectedS` which selects an undirected graph.
Once we have the graph type selected, we can create the graph in Figure 2 by
declaring a graph object and filling in edges using the add_edge() function of
the MutableGraph interface (which `adjacency_list<>` implements). We use the
array of pairs edge_array merely as a convenient way to explicitly create the
edges for this example.
#include <iostream> // for std::cout
#include <utility> // for std::pair
#include <algorithm> // for std::for_each
#include <boost/graph/adjacency_list.hpp>
using namespace std;
using namespace boost;
int main(int, char*[])
{
// create a typedef for the Graph type
typedef adjacency_list<vecS, vecS, bidirectionalS> Graph;
// Make convenient labels for the vertices
enum { A, B, C, D, E, N };
const int num_vertices = N;
const char* name = "ABCDE";
// Create edges as pairs of of intengers
typedef pair<int, int> Edge;
Edge edge_array[] = {
Edge(A,B), Edge(A,D), Edge(C,A), Edge(D,C),
Edge(C,E), Edge(B,D), Edge(D,E)
};
const int num_edges = sizeof(edge_array) / sizeof(edge_array[0]);
// Declare a graph object with N vertices
Graph g(num_vertices);
// Add the edges to the graph
for (int i = 0; i < num_edges; ++i) {
add_edge(edge_array[i].first, edge_array[i].second, g);
}
// ... continue below
return 0;
}
Instead of calling the `add_edge()` function for each edge, we could use the
edge iterator constructor of the graph. This is typically more efficient than
using `add_edge()`. Pointers to the `edge_array` can be viewed as iterators, so
we can call the iterator constructor by passing pointers to the beginning and
end of the array.
Graph g(edges, edges + sizeof(edge_array) / sizeof(edge_array[0]), num_vertices);
Instead of creating a graph with a certain number of vertices to begin with, it
is also possible to add and remove vertices with the [add_vertex] and
[remove_vertex] functions, also of the [MutableGraph] interface.
[h2 Accessing the Vertex Set]
Now that we have created a graph, we can use the graph interface to access the
graph data in different ways. First we can access all of the vertices in the
graph using the `vertices()` function of the /VertexListGraph/ interface. This
function returns a `std::pair<>` of vertex iterators (the first iterator points
to the "beginning" of the vertices and the second iterator points "past the
end"). Dereferencing a vertex iterator gives a vertex object. The type of the
vertex iterator is given by the graph_traits class. Note that different graph
classes can have different associated vertex iterator types, which is why we
need the `graph_traits<>` class. Given some graph type, the `graph_traits<>`
class will provide access to the vertex_iterator type.
The following example prints out the index for each of the vertices in the
graph. All vertex and edge properties, including index, are accessed via
property map objects. The `property_map<>` class is used to obtain the property
map type for a specific property (specified by `vertex_index_t`, one of the
Boost.Graph predefined properties) and function call `get(vertex_index, g)`
returns the actual property map object.
// ...
int main(int,char*[])
{
// ... continued from above
// Get the property map for vertex indices
typedef property_map<Graph, vertex_index_t>::type IndexMap;
IndexMap index = get(vertex_index, g);
cout << "vertices(g) = ";
typedef graph_traits<Graph>::vertex_iterator vertex_iter;
pair<vertex_iter, vertex_iter> vp;
for(vp = vertices(g); vp.first != vp.second; ++vp.first) {
cout << index[*vp.first] << " ";
}
cout << "\n";
// ...
return 0;
}
The output is:
[pre
vertices(g) = 0 1 2 3 4
]
[h2 Accessing the Edge Set]
The set of edges for a graph can be accessed with the edges() function of the
/EdgeListGraph/ interface. Similar to the `vertices()` function, this returns a
pair of iterators, but in this case the iterators are edge iterators.
Dereferencing an edge iterator gives an edge object. The `source()` and
`target()` functions return the two vertices that are connected by the edge.
Instead of explicitly creating a `std::pair<>` for the iterators, this time we
will use the `tie()` helper function. This handy function can be used to assign
the parts of a std::pair into two separate variables, in this case `ei` and
`ei_end`. This is usually more convenient than creating a `std::pair` and is our
method of choice for Boost.Graph.
// ...
int main(int,char*[])
{
// ... continued from above
cout << "edges(g) = ";
graph_traits<Graph>::edge_iterator ei, ei_end;
for(tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) {
cout << "(" << index[source(*ei, g)] << "," << index[target(*ei, g)] << ") ";
}
cout << "\n";
// ...
return 0;
}
The output is:
[pre
edges(g) = (0,1) (0,2) (0,3) (0,4) (2,0) (2,4) (3,0) (3,1) (3,4) (4,0) (4,1)
]
[h2 The Adjacency Structure]
In the next few examples we will explore the adjacency structure of the graph
from the point of view of a particular vertex. We will look at the vertices'
in-edges, out-edges, and its adjacent vertices. We will encapsulate this in an
"exercise vertex" function, and apply it to each vertex in the graph. To
demonstrate the STL-interoperability of Boost.Graph, we will use the STL
`for_each()` function to iterate through the vertices and apply the function.
//...
int main(int,char*[])
{
// ...
for_each(vertices(g).first, vertices(g).second, exercise_vertex<Graph>(g));
return 0;
}
We use a functor for exercise_vertex instead of just a function because the
graph object will be needed when we access information about each vertex; using
a functor gives us a place to keep a reference to the graph object during the
execution of the `std::for_each()`. Also we template the functor on the graph
type so that it is reusable with different graph classes. Here is the start of
the exercise_vertex functor:
template <class Graph> struct exercise_vertex {
exercise_vertex(Graph& g_) : g(g_)
{ }
// ...
Graph& g;
};
[h3 Vertex Descriptors]
The first thing we need to know in order to write the operator() method of the functor is the type
for the vertex objects of the graph. The vertex type will be the parameter to the `operator()`
method. To be precise, we do not deal with actual vertex objects, but rather with vertex descriptors.
Many graph representations (such as adjacency lists) do not store actual vertex objects, while
others do (e.g., pointer-linked graphs). This difference is hidden underneath the "black-box"
of the vertex descriptor object. The vertex descriptor is something provided by each graph type
that can be used to access information about the graph via the `out_edges()`, `in_edges()`,
`adjacent_vertices()`, and property map functions that are described in the following sections. The
vertex_descriptor type is obtained through the graph_traits class. The typename keyword used below
is necessary because the type on the left hand side of the scope :: operator (the `graph_traits<Graph>`
type) is dependent on a template parameter (the `Graph` type). Here is how we define the functor's
apply method:
template <class Graph> struct exercise_vertex {
// ... continued from above
typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
void operator()(const Vertex& v) const
{
// ... this is where we will "exercise" the vertex
}
// ...
};
[h3 Out-Edges, In-Edges, and Edge Descriptors]
The out-edges of a vertex are accessed with the `out_edges()` function of the
/IncidenceGraph/ interface. The out_edges() function takes two arguments: the
first argument is the vertex and the second is the graph object. The function
returns a pair of iterators which provide access to all of the out-edges of a
vertex (similar to how the vertices() function returned a pair of iterators).
The iterators are called out-edge iterators and dereferencing one of these
iterators gives an edge descriptor object. An edge descriptor plays the same
kind of role as the vertex descriptor object, it is a "black box" provided by
the graph type. The following code snippet prints the source-target pairs for
each out-edge of vertex, v.
template <class Graph>
struct exercise_vertex {
//... continued from above
void operator()(const Vertex& v) const
{
typedef graph_traits<Graph> GraphTraits;
typedef typename property_map<Graph, vertex_index_t>::type IndexMap;
IndexMap index = get(vertex_index, g);
cout << "out-edges: ";
typename GraphTraits::out_edge_iterator out_i, out_end;
typename GraphTraits::edge_descriptor e;
for(tie(out_i, out_end) = out_edges(v, g); out_i != out_end; ++out_i) {
e = *out_i;
Vertex src = source(e, g), tgt = target(e, g);
cout << "(" << index[src] << "," << index[targ] << ") ";
}
std::cout << "\n";
// ...
}
// ...
};
For vertex 0 the output is:
[pre
out-edges: (0,1) (0,2) (0,3) (0,4)
]
The `in_edges()` function of the BidirectionalGraph interface provides access to
all the in-edges of a vertex through in-edge iterators. The in_edges() function
is only available for the `adjacency_list<>` if `bidirectionalS` is supplied for
the Directed template parameter. There is an extra cost in space when
`bidirectionalS` is specified instead of `directedS`.
template <class Graph> struct exercise_vertex {
// ... continued from above
void operator()(const Vertex& v) const
{
// ...
cout << "in-edges: ";
typedef typename graph_traits<Graph> GraphTraits;
typename GraphTraits::in_edge_iterator in_i, in_end;
for (tie(in_i, in_end) = in_edges(v,g); in_i != in_end; ++in_i) {
e = *in_i;
Vertex src = source(e, g), targ = target(e, g);
cout << "(" << index[src] << "," << index[targ] << ") ";
}
cout << "\n";
// ...
}
// ...
};
For vertex 0 the output is:
[pr
in-edges: (2,0) (3,0) (4,0)
]
[h3 Adjacent Vertices]
Given the out-edges of a vertex, the target vertices of these edges are adjacent
to the source vertex. Sometimes an algorithm does not need to look at the edges
of the graph and only cares about the vertices. Therefore the graph interface
also includes the `adjacent_vertices()` function of the AdjacencyGraph interface
which provides direct access to the adjacent vertices. This function returns a
pair of adjacency iterators. Dereferencing an adjacency iterator gives a vertex
descriptor for an adjacent vertex.
template <class Graph> struct exercise_vertex {
// ... continued from above
void operator()(Vertex v) const
{
//...
cout << "adjacent vertices: ";
typename graph_traits<Graph>::adjacency_iterator ai;
typename graph_traits<Graph>::adjacency_iterator ai_end;
for(tie(ai, ai_end) = adjacent_vertices(v, g); ai != ai_end; ++ai) {
std::cout << index[*ai] << " ";
}
std::cout << "\n";
}
//...
};
For vertex 4 the output is:
[pre
adjacent vertices: 0 1
]
[Adding Some Color to your Graph]
Boost.Graph attempts to be as flexible as possible in terms of accommodating how
properties are attached to a graph. For instance, a property such as edge weight
may need to be used throughout a graph object's lifespan and therefore it would
be convenient to have the graph object also manage the property storage. On the
other hand, a property like vertex color may only be needed for the duration of
a single algorithm, and it would be better to have the property stored
separately from the graph object. The first kind of property is called an
internally stored property while the second kind is called an externally stored
property. Boost.Graph uses a uniform mechanism to access both kinds of
properties inside its graph algorithms called the property map interface,
described in Section Property Map Concepts. In addition, the PropertyGraph
concept defines the interface for obtaining a property map object for an
internally stored property.
The Boost.Graph adjacency_list class allows users to specify internally stored
properties through plug-in template parameters of the graph class. How to do
this is discussed in detail in Section Internal Properties. Externally stored
properties can be created in many different ways, although they are ultimately
passed as separate arguments to the graph algorithms. One straightforward way to
store properties is to create an array indexed by vertex or edge index. In the
adjacency_list with `vecS` specified for the VertexList template parameter,
vertices are automatically assigned indices, which can be accessed via the
property map for the vertex_index_t. Edges are not automatically assigned
indices. However the property mechanism can be used to attach indices to the
edges which can be used to index into other externally stored properties.
In the following example, we construct a graph and apply
`dijkstra_shortest_paths()`. The complete source code for the example is in
examples/dijkstra-example.cpp. Dijkstra's algorithm computes the shortest
distance from the starting vertex to every other vertex in the graph.
Dijkstra's algorithm requires that a weight property is associated with each
edge and a distance property with each vertex. Here we use an internal property
for the weight and an external property for the distance. For the weight
property we use the property class and specify int as the type used to represent
weight values and edge_weight_t for the property tag (which is one of the
Boost.Graph predefined property tags). The weight property is then used as a
template argument for `adjacency_list<>`. The listS and vecS types are selectors
that determine the data structure used inside the `adjacency_list<>` (see
Section Choosing the Edgelist and VertexList). The directedS type specifies that
the graph should be directed (versus undirected). The following code shows the
specification of the graph type and then the initialization of the graph. The
edges and weights are passed to the graph constructor in the form of iterators
(a pointer qualifies as a [SgiRandomAccessIterator]).
typedef adjacency_list<listS, vecS, directedS,
no_property, // no additional vertex properties
property<edge_weight_t, int> // edges have integer edge weight
> Graph;
typedef graph_traits<Graph>::vertex_descriptor Vertex;
typedef std::pair<int,int> E;
const int num_nodes = 5;
E edges[] = { E(0,2),
E(1,1), E(1,3), E(1,4),
E(2,1), E(2,3),
E(3,4),
E(4,0), E(4,1) };
int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1};
Graph G(edges + sizeof(edges) / sizeof(E), weights, num_nodes);
For the external distance property we will use a std::vector for storage.
Boost.Graph algorithms treat random access iterators as property maps, so we can
just pass the beginning iterator of the distance vector to Dijkstra's algorithm.
Continuing the above example, the following code shows the creation of the
distance vector, the call to Dijkstra's algorithm (implicitly using the internal
edge weight property), and then the output of the results.
// vector for storing distance property
std::vector<int> d(num_vertices(G));
// get the first vertex
Vertex s = *(vertices(G).first);
// invoke variant 2 of Dijkstra's algorithm
dijkstra_shortest_paths(G, s, distance_map(&d[0]));
std::cout << "distances from start vertex:" << ;
graph_traits<Graph>::vertex_iterator vi;
for(vi = vertices(G).first; vi != vertices(G).second; ++vi)
std::cout << "distance(" << index(*vi) << ") = "
<< d[*vi] << ;
std::cout << ;
The output is:
[pre
distances from start vertex:
distance(0) = 0
distance(1) = 6
distance(2) = 1
distance(3) = 4
distance(4) = 5
]
[Extending Algorithms with Visitors]
Often times an algorithm in a library almost does what you need, but not quite.
For example, in the previous section we used Dijkstra's algorithm to calculate
the shortest distances to each vertex, but perhaps we also wanted to record the
tree of shortest paths. One way to do this is to record the predecessor (parent)
for each node in the shortest-paths tree.
It would be nice if we could avoid rewriting Dijkstra's algorithm, and just add
that little bit extra needed to record the predecessors [1]. In the STL, this
kind of extensibility is provided by functors, which are optional parameters to
each algorithm. In Boost.Graph this role is fulfilled by visitors.
A visitor is like a functor, but instead of having just one "apply" method, it
has several. Each of these methods get invoked at certain well-defined points
within the algorithm. The visitor methods are explained in detail in Section
Visitor Concepts. Boost.Graph provides a number of visitors for some common
tasks including a predecessor recording visitor. The user is encouraged to write
his or her own visitors as a way of extending Boost.Graph. Here we will take a
quick look at the implementation and use of the predecessor recorder. Since we
will be using the `dijkstra_shortest_paths()` algorithm, the visitor we create
must be a Dijkstra Visitor.
The functionality of the record_predecessors visitor is separated into two
parts. For the storage and access of the predecessor property, we will use a
property map. The predecessor visitor will then only be responsible for what
parent to record. To implement this, we create a `record_predecessors` class and
template it on the predecessor property map `PredecessorMap`. Since this visitor
will only be filling in one of the visitor methods, we will inherit from
`dijkstra_visitor` which will provide empty methods for the rest. The
constructor of the `predecessor_recorder` will take the property map object and
save it away in a data member.
template <class PredecessorMap>
class record_predecessors : public dijkstra_visitor<>
{
public:
record_predecessors(PredecessorMap p)
: m_predecessor(p)
{ }
template <class Edge, class Graph>
void edge_relaxed(Edge e, Graph& g) {
// set the parent of the target(e) to source(e)
put(m_predecessor, target(e, g), source(e, g));
}
protected:
PredecessorMap m_predecessor;
};
The job of recording the predecessors is quite simple. When Dijkstra's algorithm
relaxes an edge (potentially adding it to the shortest-paths tree) we record the
source vertex as the predecessor of the target vertex. Later, if the edge is
relaxed again the predecessor property will be overwritten by the new
predecessor. Here we use the put() function associated with the property map to
record the predecessor. The `edge_filter` of the visitor tells the algorithm
when to invoke the `explore()` method. In this case we only want to be notified
about edges in the shortest-paths tree so we specify `tree_edge_tag`.
As a finishing touch, we create a helper function to make it more convenient to
create predecessor visitors. All Boost.Graph visitors have a helper function
like this.
template <class PredecessorMap>
record_predecessors<PredecessorMap>
make_predecessor_recorder(PredecessorMap p) {
return record_predecessors<PredecessorMap>(p);
}
We are now ready to use the `record_predecessors` in Dijkstra's algorithm.
Luckily, Boost.Graph's Dijkstra's algorithm is already equipped to handle
visitors, so we just pass in our new visitor. In this example we only need to
use one visitor, but Boost.Graph is also equipped to handle the use of multiple
visitors in the same algorithm (see Section Visitor Concepts).
using std::vector;
using std::cout;
using std::endl;
vector<Vertex> p(num_vertices(G), graph_traits<G>::null_vertex()); //the predecessor array
dijkstra_shortest_paths(G, s, distance_map(&d[0]).
visitor(make_predecessor_recorder(&p[0])));
cout << "parents in the tree of shortest paths:" << endl;
for(vi = vertices(G).first; vi != vertices(G).second; ++vi) {
cout << "parent(" << *vi;
if (p[*vi] == graph_traits<G>::null_vertex())
cout << ") = no parent" << endl;
else
cout << ") = " << p[*vi] << endl;
}
The output is:
[pre
parents in the tree of shortest paths:
parent(0) = no parent
parent(1) = 4
parent(2) = 0
parent(3) = 2
parent(4) = 3
]
[endsect]

View File

@@ -1,473 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Undirected Graphs]
In this section, our example revolves around a particular type of /social network/.
A social network is a graph that models the relationships between people. Specifically,
in this example we are looking at a graph that connects co-stars of films.
[h3 Co-Star Graphs]
The first example problem we want to look at is the "Six Degrees of Kevin Bacon"
problem. In this problem, two actors are related if they appear in the same movie,
which can be trivially represented using an undirected graph.
For the Six Degrees problem, we define a citation graph such that each vertex in
the graph represents an actor, and each edge connects two actors if and only if
they appear in the same movie. Consider the example in Figure 1. Here we have
ten relatively well-known actors and the movies in which they appear together -
and yes, Kevin Bacon is actually in /Animal House/ (he plays a snotty Omega pledge
in his film debut).
[$images/guide/movie.png]
Although this is a relatively simple graph, it isn't hard to imagine that it
scales up fairly quickly. Consider what would happen if we added all of Kevin
Bacon's co-stars from major motion picture in which he starred - and all of
their co-stars. It's not hard to imagine that only three iterations might
actually encompass all of Hollywood and beyond (Bollywood?). So what can we do
with these graphs?
For starters, we can identify two different problems of the "Six Degrees".
* How far is every actor in the graph from Kevin Bacon? This gives us the number
of steps between Mr. Bacon and any other actor. The distances from a central actor
can give clues to the size (especially the diameter) of a graph.
* What is the "fastest" way to travel along the co-star graph from Kevin Bacon
to any other actor? This is more commonly known as the "Six Degrees of Kevin
Bacon Game".
These are actually two different instances of the same problem and can be solved
using the same algorithm - a simple breadth-first search (BFS).
[note
The term "six degrees of separation" refers to the total distance one must travel
in a social network to get from one's self to any other person in the network.
This notion is supported through a number of social experiments, namely that of
Stanley Milgram who coined the term "small world" with respect to social networks.
His experiment showed that Americans are connected, on average by six friendships.
The notion of a "small world" social network is now nearly synonymous with a
graph having an average degree of connectivity (formally known as its /mean geodesic
distance/) of just six steps.
On a side note, the name "Six Degrees of Kevin Bacon" can be attributed to a
producer on /The Jon Stewart Show/ when the creators (students from Abright
College) made an appearence to discuss and demonstrate the concept.
]
[h4 Actors, Movies, and Graphs]
Our program begins by inlcuding required headers and creating some convenient
type aliases.
#include <string>
#include <map>
#include <boost/graph/undirected_graph.hpp>
#include <boost/graph/breadth_first_search.hpp>
struct Actor;
struct Movie;
typedef boost::undirected_graph<Actor, Movie> Graph;
typedef Graph::vertex_descriptor Vertex;
typedef Graph::edge_descriptor Edge;
In this snippet, our `Actor` structure is going to represent the properties of each
vertex in the graph while the `Movie` structure encapsulates edge information (i.e.,
the movie that two actors appear in).
The graph itself is defined by the type `boost::undirected_graph<Actor, Movie>`.
Essentially, this states that each vertex will have properties given in the `Actor`
structure, and that edges will have properties in the `Movie` structure. We also
create some aliases for the graph's vertex and edge descriptors.
[important
Many of the examples in the Boost Graph Library treat vertex descriptors as the
index of a vertex within the graph. It must be noted however, that this is not
a reliable approach to indexing vertices and /will not/ work with the `undirected_graph`
and `directed_graph` classes. Try to get in the habit of thinking of vertex and
edge descriptors as opaque types and values - they are simply keys that provide
access to the properties of their respective types.
]
In order to fully model our problem, we need to finish defining the `Actor` and
`Movie` structures for our graph.
struct Actor
{
int distance;
std::string name;
};
struct Movie
{
std::string name;
};
In this example, we are "internalizing" a couple of properties for each vertex.
The `Actor::distance` property will be used to record the distance from each actor
to Kevin Bacon. The `Actor::name` and `Movie::name` properties should be fairly
self-explanatory. However in this example, we are going to require that all actors
have unique names. We'll see why in a bit.
We're also going to define a number of other types related to the graphs properties:
/property maps/. These maps provide a mechanism for accessing the interior and exterior
properties of vertices and edges in a uniform manner. In this example, all of the
vertex and edge properties are internal, but we could easily make them external and
have the program run just as quickly.
typedef boost::property_map<Graph, int Actor::*>::type ActorDistanceMap;
The first template argument `Graph` defines the type of the graph that
the property map is going to access. The second template argument with the somewhat
peculiar syntax is the type of the property. These are pointers to `Actor` member
variables of type `int`.
Now that the preliminaries are out of the way, we need to concentrate on the construction
of our graph. For this task, we're going to need another data structure that maps actor
names to vertices in the graph. We're going to use this to prevent adding mulitple
vertices for the same actor and later, to find the vertex in the graph that corresponds to
Kevin Bacon.
This program reads an input file from standard input. The input file is given in an edge-
list format with semicolon separators. Each line corresponds to an edge, giving the two
actors as the endpoints and the name of the movie they both appear in. For example:
[pre
Tim Matheson;Kevin Bacon;Animal House (1978)
John Belushi;Kevin Bacon;Animal House (1978)
Carrie Fisher;John Belushi;The Blues Brothers (1980)
Mark Hamill;Carrie Fisher;Star Wars (1977)
]
The following function implements the input parser for the graph data.
#include <boost/tokenizer.hpp>
// the very important actor-to-vertex mapping
typedef std::map<std::string, Vertex> ActorMap;
using namespace std;
using namespace boost;
void build_costar_graph(istream& is, Graph& graph, ActorMap&)
{
// pull all of the data from std in.
for(string line; getline(is, line); ) {
// skip any comment or blank lines
if(line[0] == '#' || line.empty()) {
continue;
}
// tokenize the string
char_delimiters_separator<char> sep(false, "", ";");
tokenizer<> tok(line, sep);
tokenizer<>::iterator i = tok.begin();
// grab the names of the two actors and the movie title
string first = *i++;
string second = *i++;
string movie = *i++;
// get the vertices associated with the actors adding them
// to the graph if necessary
Vertex
u = add_actor(g, actors, first),
v = add_actor(g, actors, second);
// create an edge (movie) linking the actors
add_movie(g, u, v, movie);
}
}
To finish graph construction, we need to implement the `add_actor()` and `add_movie()`
functions:
Vertex add_actor(Graph& graph, ActorMap& actors, const string& name)
{
// try inserting the actors name into the actors map
Vertex v;
ActorMap::iterator it;
bool inserted;
tie(it, inserted) = actors.insert(make_pair(name, Vertex()));
if(inserted) {
// if the vertex was inserted into the map, we need to
// create a new vertex in the graph and make sure that
// the map references the correct vertex
v = add_vertex(graph);
it->second = v;
// configure the vertex properties
g[v].name = name;
}
else {
// otherwise, the name is already in the map, so
// return the vertex associated with it
v = it->second;
}
return v;
}
Edge add_movie(Graph& g, Vertex u, Vertex v, const string& movie)
{
Edge e;
bool inserted;
tie(e, inserted) = add_edge(u, v, g);
if(inserted) {
g[e].name = movie;
}
return e;
}
There are several important features of these two functions to pay special attention to.
The first is the use of the `tie()` constructor. This is arguably one of the most useful
and most used functions (it's actually a type) in Boost.Graph. It simply takes the
values returned in a `std::pair` and assigns them to the variables passed to the
constructor. In this function it is more or less equivalent to:
std::pair<ActorMap::Iterator, bool> x = actors.insert(...);
ActorMap::iterator iter = x.first;
bool inserted = x.second;
The second (and most important) is the assignment of the vertex properties. These
two lines of code use the /bundled properties/ syntax to assign both an index
and a name to the vertex that was just added to the graph.
Our main program looks like this:
int main()
{
Graph graph;
ActorMap actors;
build_costar_graph(cin, graph, actors);
// ...to be continued...
}
[h4 Distance To Kevin Bacon]
Now, all we have left to do is assign distances to Kevin Bacon. To do this, we're going
to use a breadth-first search (starting from Kevin Bacon) and simply record the "depth"
of each vertex as the distance from Kevin to every other actor. Fortunately, Boost.Graph
gives us lots of help in this area so we don't have to write much more code. Let's look
at the main program.
int main()
{
// ...continued from above...
// find kevin (our starting point)
Vertex kevin = actors["Kevin Bacon"];
// get a property map and zero out kevin's distance-to-self
ActorDistanceMap distances = get(&Actor::distance, graph)
distances[kevin] = 0;
breadth_first_search(graph, kevin,
visitor(
make_bfs_visitor(record_distances(distances, on_tree_edge()))
)
);
// ...to be continued...
This is actually the "meat" of the solution. First, get a reference to the vertex that
represents Kevin Bacon - our `ActorMap` is very good at this. Next we have to get the
property map for our actor's distances so we can set Kevin's distance to zero. In this
case, the actor's distance is actually a /bundled property/ of the `Actor` structure.
Finally, we invoke the `breadth_first_search()` on `graph` with `kevin` as our starting
vertex. The `visitor()` function is actually a /named parameter/ - a function that assigns
a value to a parameter of an algorithm. In this case, the parameter is the /visitor/
parameter (as indicated by the function name). The value is in turn provided by the
`make_bfs_visitor()` function, which creates visitor object depnding on the parameters.
The `record_distances()` function creates a `distance_recorder` visitor. The `distances`
argument is our property map, indicating that the visitor will operate on those values.
Finally, the `on_tree_edge()` call instructs the `distance_recorder` to record distances
when a new edge in the BFS tree is encountered. This BFS visitor will effectively compute
the distance from a root vertex to all other vertices in the graph.
This is a somewhat verbose way of writing the code. We could write it a little more
succinctly, although it's somewhat less readable:
graph[kevin].distance = 0;
breadth_first_search(graph, kevin,
visitor(make_bfs_visitor(record_distances(get(&Actor::distance, graph), on_tree_edge())))
);
After finishing, each vertex's distance property will be assigned. All there is left to do
is display the numbers:
int main()
{
// ...continued from above...
Graph::vertex_iterator i, j;
for(tie(i, j) = vertices(g); i != j; ++i) {
cout << graph[*i].distance << " : " << graph[*i].name << "\n";
}
}
The output should look something like this (note that $ is a shell prompt):
[pre
$ ./kevin_bacon < movies
1 : Chris Penn
1 : Sarah Jessica Parker
2 : James Belushi
2 : David Ogden Stiers
3 : Mark Hamill
3 : Dan Akroyd
1 : John Belushi
1 : Tim Matheson
2 : Tom Hulce
2 : Peter Riegert
2 : Karen Allen
2 : Mike Meyers
2 : Sylvester Stallone
2 : Eddie Murphy
]
[h4 The Kevin Bacon Game]
Using the above algorithm we can find how far away each actor is from Kevin Bacon, but what
if we want to know how to get there. For example, we know that Dan Akroyd is three steps away
so what are the movies? We could look at the input file, but that won't really give us any
advantage. A better solution would be to modify the program to record the shortest paths.
Since the term /shortest paths/ arises in the problem description, we might be tempted to
use a shortest paths algorithm such as Dijkstra's. However, if we think about the problem a
little bit, we should realize that there aren't any edge weights - something required for
Dijkstra's algorithm. We could implicitly treat all edges as having a weight of one, but
that turns out to be somewhat ineffective. It turns out that we can use the same BFS
algorithm to record shortest paths instead of (or in addition to) actors' distances to
Kevin Bacon. Specifically, we can record each the parent of each vertex in the BFS tree
and simply backtrack from a given actor to Kevin Bacon.
There are only a couple of modifications that we really need to make. First, we want to
add an extra property for each actor: its parent vertex in the search tree. For convenience,
we are also going to add a new property map type.
struct Actor
{
// ...same as before...
Vertex parent;
};
// ...
typedef boost::property_map<Graph::type, &Vertex Actor::*>::type ActorParentMap;
The only other changes are going to be in the `main()` program.
int main(int argc, char *argv[])
{
string src = "Kevin Bacon";
string tgt;
if(argc < 2) {
cerr << "usage: actor_paths actor [actor] < movies";
return -1;
}
else if(argc == 2) {
tgt = argv[1];
}
else {
src = argv[1];
tgt = argv[2];
}
Graph graph;
ActorMap actors;
build_costar_graph(cin, graph, actors);
// ...to be continued...
This program accepts a couple of command line parameters. If one actor is given then
we find the path to Kevin Bacon. If two actors are given, we find the shortest path
between the two actors. We can now get the vertices for specified actors, and find
the paths between them.
// ...continued from before...
Vertex u = find_actor_vertex(g, actors, src);
Vertex v = find_actor_vertex(g, actors, tgt);
if(u == Graph::null_vertex()) {
cerr << "could not find actor " << src << "\n";
return -1;
}
if(v == Graph::null_vertex()) {
cerr << "could not find actor " << tgt << "\n";
return -1;
}
// get the parents map for later use.
ActorParentMap parents = get(&Actor::parent, g);
breadth_first_search(graph, kevin,
visitor(
make_bfs_visitor(record_predecessors(distances, on_tree_edge()))
)
);
// ...to be continued...
The `find_actor_vertex()` method is relatively trivial. We extracted it as a function
so the program wouldn't be quite so repetitive.
Vertex find_actor_vertex(const Graph& g, const ActorMap& actors, const std::string& name)
{
Vertex v = Graph::null_vertex();
ActorMap::const_iterator i = actors.find(name);
if(i != actors.end()) {
v = i->second;
}
return v;
}
Otherwise, the code is essentially the same as above. In this case, we're constructing
a `predecessor_recorder` as the visitor to the BFS. In contrast to the `distance_recorder`
this method stores the parents (or predecessor) of each vertex in the BFS tree. This is
an important property because it allows us to backtrack from one endpoint in the graph
to the starting point, showing the path from, say Kevin Bacon to any another actor.
Backtracking is relatively easy.
int main(...)
{
// ...continued from before...
while(v != u) {
Vertex p = parents[v];
string from = g[v].name;
string to = g[p].name;
// find the edge so we can print the movie
Edge e;
bool found;
tie(e, found) = edge(v, p, g);
string movie = g[e].name;
cout << from << " starred with " << to << " in '" << movie << "'\n";
v = p;
}
return 0;
}
Althgough we could simply backtrack over the parents and print the actors in a chain,
we think it's more entertaining to know the movies that each pair co-stars in. To do
this we use the `edge()` function to locate the edge corresponding edge connecting
the two actors who costarred in a movie.
The output might look something like:
[pre
$ ./six_degrees "Dan Akroyd" < movies
Dan Akroyd starred with Carrie Fisher in 'The Blues Brothers (1980)'
Carrie Fisher starred with Elisabeth Shue in 'Soapdish (1991)'
Elisabeth Shue starred with Kevin Bacon in 'Hollow Man (2000)'
]
You now have a completely /unbeatable/ implementation of the "Six Degrees of Kevin
Bacon" game - provided of course that you add a lot more movie data to the simple
data set provided with this example.
[endsect]

View File

@@ -1,120 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section History]
The Boost Graph Library began its life as the Generic Graph Component Library (GGCL), a software
project at the Lab for Scientific Computing (LSC) at the University of Notre Dame, under the
direction of Professor Andrew Lumsdaine. The Lab's research directions include numerical linear
algebra, parallel computing, and software engineering (including generic programming).
Soon after the Standard Template Library was released, work began at the LSC to apply generic
programming to scientific computing. The Matrix Template Library (Jeremy Siek's masters thesis)
was one of the first projects. Many of the lessons learned during construction of the MTL were
applied to the design and implementation of the GGCL.
Graph algorithms play an important role in sparse matrix computations, so the LSC had a need for
a good graph library. However, none of the available graph libraries (LEDA, GTL, Stanford GraphBase)
were written using the generic programming style of the STL, and hence did not fulfill the flexibility
and high-performance requirements of the LSC. Others were also expressing interest in a generic C++
graph library. During a meeting with Bjarne Stroustrup we were introduced to several people at AT&T
who needed such a library. There had also been earlier work in the area of generic graph algorithms,
including some codes written by Alexander Stepanov, and Dietmar Kuhl's masters thesis.
With this in mind, and motivated by homework assignments in his algorithms class, Jeremy began
prototyping an interface and some graph classes in the spring on 1998. Lie-Quan Lee then developed
the first version of GGCL, which became his masters thesis project.
The following year, Jeremy went to work for SGI with Alexander Stepanov and Matt Austern. During
this time Alex's disjoint-sets based connected components algorithm was added to GGCL, and Jeremy
began working on the concept documentation for GGCL similar to Matt's STL documentation.
While working at SGI, Jeremy heard about Boost and was excited to find a group of people interested
in creating high-quality C++ libraries. At Boost there were several people interested in generic
graph algorithms, most notably Dietmar Kuhl. Some discussions about generic interfaces for graph
structures resulted in the a revision of GGCL which closely resembles the current Boost Graph Library
interface.
On September 4, 2000 GGCL passed the Boost formal review and became the Boost Graph Library (BGL).
The first release of BGL was September 27, 2000.
[h2 Changes by Revision]
* Version 1.38.0
* New algorithms
* Travelling Salesman Problem approximation by Matyas Egyhazy ([metric_tsp_approx]).
* Support for named vertices in `adjacency_list`.
* Bug Fixes
* Fixed spelling of `edmonds_karp` algorithm name.
* Correctly remove loop edges from undirected [adjacency_list].
* Correctly handle infinite edge weights in [floyd_warshall_all_pairs_shortest_paths].
* Edge counts are no longer modified if [remove_edge] fails.
* Version 1.35.0
* New algorithms and components
* boykov_kolmogorov_max_flow (formerly kolmogorov_max_flow), from Stephan Diederich as part of the 2006 Google Summer of Code.
* read_dimacs_max_flow and write_dimacs_max_flow for max-flow problems, from Stephan Diederich.
* read_graphml and write_graphml for GraphML input/output, from Tiago de Paula Peixoto.
* Enhancements
* LEDA Adaptor improvements, from Jens Muller.
* Version 1.34.0
* New algorithms and components
* edmonds_maximum_cardinality_matching, from Aaron Windsor.
* lengauer_tarjan_dominator_tree, from JongSoo Park.
* compressed_sparse_row_graph, from Jeremiah Willcock and Douglas Gregor of Indiana University.
* sorted_erdos_renyi_iterator, from Jeremiah Willcock of Indiana University.
* Enhancements
* biconnected_components now has a visitor parameter and supports named parameters, from Janusz Piwowarski.
* adjacency_matrix now models the Bidirectional Graph concept.
* adjacency_list is now Serializable, from Jeremy Siek of Rice University.
* Added edges_size_type and vertices_size_type to adjacency_list_traits, from Jeremy Siek of Rice University.
* Added operator< , etc. to the edge descriptor of adjacency_list, from Jeremy Siek of Rice University.
* Bug Fixes
* Fixed a bug that causes the relaxed heap to fail on x86 Linux.
* Bundled properties now work with adjacency list I/O.
* floyd_warshall_all_pairs_shortest_paths now properly uses its compare, inf, and zero parameters.
* johnson_all_pairs_shortest_paths now supports compare, combine, inf, and zero.
* Fixed a bug in smallest_last_vertex_ordering.hpp which could cause a vertex to be moved to the wrong bucket during an BucketSorter update.
* Version 1.33.1
* Bug Fixes
* fruchterman_reingold_force_directed_layout: Fixed enumeration of grid-force pairs, which caused some odd graph formations along grid lines.
* king_ordering and cuthill_mckee_ordering: Fixed bug that caused failures with the multi-component version of these algorithms.
* Version 1.33.0
* New algorithms and components
* Experimental Python bindings, from Doug Gregor and Indiana University.
* floyd_warshall_all_pairs_shortest_paths, from Lauren Foutz and Scott Hill.
* astar_search, from Kristopher Beevers and Jufeng Peng.
* fruchterman_reingold_force_directed_layout, from Doug Gregor and Indiana University.
* biconnected_components and articulation_points, from Indiana University.
* gursoy_atun_layout, from Jeremiah Willcock and Doug Gregor of Indiana University.
* king_ordering, from D. Kevin McGrath of Indiana University.
* erdos_renyi_iterator
* plod_iterator
* small_world_iterator
* Enhancements
* bellman_ford_shortest_paths now permits one to specify the starting vertex, so that it will perform its own initialization.
* undirected_dfs is now data-recursive, resulting in improved performance in some cases, from Synge Todo.
* dijkstra_shortest_paths now uses a relaxed heap [61] as its priority queue, improving its complexity to O(V log V) and improving real-world performance for larger graphs.
* read_graphviz now has a new, Spirit-based parser that works for all graph types and supports arbitrary properties on the graph, from Ron Garcia. The old, Bison-based GraphViz reader has been deprecated and will be removed in a future Boost release.
* write_graphviz now supports output of dynamic properties (as read in through the new read_graphviz).
* cuthill_mckee_ordering has been recast as an invocation of breadth_first_search and now supports graphs with multiple components.
* subgraph now supports bundled properties. get_property now refers to the subgraph property, not the root graph's property.
* filtered_graph now supports bundled properties.
* reverse_graph now supports bundled properties, set_property, and get_property.
* Bug fixes
* bellman_ford_shortest_paths now deals with unreachable vertices better.
* adjacency_list: parallel edge removal with OutEdgeListS = listS has been fixed. Copying and swapping has been fixed.
* Incremental connected components: fixed a bug in the incremental_components routine that may have caused incorrect results.
* The remove_out_edge_if function for an undirected adjacency_list has been rewritten and should no longer dereference singular iterators.
* write_graphviz now accepts a vertex_id parameter that is used to name the nodes.
* read_graphviz now accepts empty attribute lists.
* sequential_vertex_coloring has been updated, tested, and documented.
[endsect]

View File

@@ -1,40 +0,0 @@
# Copyright (C) 2007-2009 Andrew Sutton
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
src = \
mean_geodesic.tex \
small_world.tex \
closeness.tex \
scaled_closeness.tex \
betweenness.tex \
relative_betweenness.tex \
central_point_dominance.tex \
num_paths_directed.tex \
num_paths_undirected.tex \
num_triangles.tex \
clustering_coef.tex
dvi = $(src:%.tex=%.dvi)
ps = $(src:%.tex=%.ps)
png = $(src:%.tex=%.png)
aux = $(src:%.tex=%.aux)
log = $(src:%.tex=%.log)
%.png: %.ps
convert -density 120 $< $@
%.ps: %.dvi
dvips -E $< -o $@
%.dvi: %.tex
latex --interaction=nonstopmode $<
all: $(png)
make clean-aux
clean:
rm -f $(png) $(ps) $(dvi) $(aux) $(log)
clean-aux:
rm -rf $(aux) $(log) $(dvi)

View File

@@ -1,15 +0,0 @@
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
\[
C_B\left(v\right) = \sum_{s \neq v \neq t \in V}
\frac{\delta_{st}\left(v\right)}{\delta_{st}}
\]
\end{document}

View File

@@ -1,16 +0,0 @@
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
\[
C'_B\left(G\right) = \frac
{\sum_{v \in V}{C_B\left(v^{*}\right) - C'_B\left(v\right)}}
{n - 1}
\]
\end{document}

View File

@@ -1,15 +0,0 @@
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
\[
C\left(u\right) =
\frac{1}{\sum_{v \in V}{d\left(u,v\right)}}
\]
\end{document}

View File

@@ -1,14 +0,0 @@
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
\[
CC\left(v\right) = \frac {P\left(v\right)}{T\left(v\right)}
\]
\end{document}

View File

@@ -1,15 +0,0 @@
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
\[
\bar{D}\left(u\right) =
\frac{\sum_{v \in V}{d\left(u,v\right)}}{\left|V\right|-1}
\]
\end{document}

View File

@@ -1,14 +0,0 @@
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
\[
P(v) = d\left(v\right) \cdot \left(d\left(v\right) - 1\right)
\]
\end{document}

View File

@@ -1,16 +0,0 @@
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
\[
P(v) =\frac
{d\left(v\right) \cdot \left(d\left(v\right) - 1\right)}
{2}
\]
\end{document}

View File

@@ -1,14 +0,0 @@
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
\[
T(v) = \left|e_{pq} \in E\right|
\]
\end{document}

View File

@@ -1,16 +0,0 @@
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
\[
C'_B\left(v\right) = C_B\left(v\right)\frac{2}{\left(n - 1\right)\left(n - 2\right)}
=
C_B\left(v\right)\frac{2}{n^2-3n+2}
\]
\end{document}

View File

@@ -1,15 +0,0 @@
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
\[
C\left(u\right) =
\frac{n}{\sum_{v \in V}{d\left(u,v\right)}}
\]
\end{document}

View File

@@ -1,20 +0,0 @@
\documentclass[12pt]{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{pst-plot}
\usepackage{color}
\pagestyle{empty}
\begin{document}
\[
\bar{D}\left(G\right)
= \frac
{\displaystyle\sum_{u \in V}{\bar{D}\left(u\right)}}
{\left(\left|V\right|\right)}
= \frac
{\displaystyle\sum_{u \in V}\sum_{v \in V}{d\left(u,v\right)}}
{\left|V\right| \cdot \left(\left|V\right|-1\right)}
\]
\end{document}

View File

@@ -1,50 +0,0 @@
# Copyright (C) 2007-2009 Andrew Sutton
#
# Distributed under the Boost Software License, Version 1.0. (See accompanying
# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
GVFLAGS = -Tpng
dot_src = \
connected_components_before.dot \
connected_components_after.dot \
geodesic.dot \
info_network.dot
circo_src = \
distribution_undirected.circo \
distribution_directed.circo \
triangle.circo \
prism_3_2.circo
fdp_src = \
social_network.fdp
neato_src = \
comm_network.neato
dot_png = $(dot_src:%.dot=%.png)
circo_png = $(circo_src:%.circo=%.png)
fdp_png = $(fdp_src:%.fdp=%.png)
neato_png = $(neato_src:%.neato=%.png)
%.png: %.dot
dot $(GVFLAGS) -o $@ $<
convert $@ -resize 80% $@
%.png: %.circo
circo $(GVFLAGS) -o $@ $<
convert $@ -resize 80% $@
%.png: %.fdp
fdp $(GVFLAGS) -o $@ $<
convert $@ -resize 80% $@
%.png: %.neato
neato $(GVFLAGS) -o $@ $<
convert $@ -resize 80% $@
all: $(dot_png) $(circo_png) $(fdp_png) $(neato_png)
clean:
rm -rf $(dot_png)
rm -rf $(circo_png)
rm -rf $(fdp_png)
rm -rf $(neato_png)

View File

@@ -1,17 +0,0 @@
graph {
// make this look like a directed graph
edge [dir=forward];
Mary -- Jill;
Jill -- Scott;
Scott -- Mary;
Scott -- Bill;
Bill -- Josh;
Josh -- Frank;
Frank -- Scott;
Frank -- Anne;
Anne -- Howard [len=2];
Howard -- Frank;
Frank -- Laurie;
Laurie -- Mary;
};

View File

@@ -1,12 +0,0 @@
graph G {
subgraph cluster_0 {
0 -- 1 -- 2 -- 0;
label = "Component 0";
}
subgraph cluster_1 {
3 -- 4;
label = "Component 1";
}
}

View File

@@ -1,5 +0,0 @@
graph G {
0 -- 1 -- 2 -- 0;
3 -- 4;
}

View File

@@ -1,11 +0,0 @@
digraph G {
0 -> 1;
1 -> 2;
2 -> 3;
3 -> 5;
5 -> 4;
4 -> 1;
4 -> 3;
5 -> 2;
}

View File

@@ -1,11 +0,0 @@
graph G {
0 -- 1;
1 -- 2;
2 -- 3;
3 -- 5;
5 -- 4;
4 -- 1;
4 -- 3;
2 -- 5
}

View File

@@ -1,15 +0,0 @@
graph G {
0 -- 1;
1 -- 2;
1 -- 3;
2 -- 4;
3 -- 5;
4 -- 6;
4 -- 7;
4 -- 8;
5 -- 8;
6 -- 9;
7 -- 9;
8 -- 9;
}

View File

@@ -1,13 +0,0 @@
digraph {
slashdot -> wikipedia;
slashdot -> bbc;
digg -> slashdot;
digg -> wikipedia;
blogspot -> wikipedia;
blogspot-> slashdot;
blogger -> digg;
blogger -> slashdot;
blogger -> wikipedia;
bbc -> wikipedia;
myspace -> digg;
}

View File

@@ -1,7 +0,0 @@
digraph {
0 -> 1 -> 2 -> 0;
3 -> 4 -> 5 -> 3;
0 -> 3 -> 0;
1 -> 4 -> 1;
2 -> 5 -> 2;
}

View File

@@ -1,14 +0,0 @@
graph {
Scott -- Jill;
Mary -- Scott;
Jill -- Mary;
Bill -- Scott;
Josh -- Bill;
Scott -- Frank;
Laurie -- Frank;
Anne -- Frank;
Howard -- Anne;
Frank -- Howard;
Josh -- Frank;
Laurie -- Mary;
};

View File

@@ -1,3 +0,0 @@
graph {
0 -- 1 -- 2 -- 0;
}

View File

@@ -1,242 +0,0 @@
[/
/ Copyright (c) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Introduction]
Graphs are mathematical abstractions that are useful for solving many types of
problems in computer science. Consequently, these abstractions must also be
represented in computer programs. A standardized generic interface for traversing
graphs is of utmost importance to encourage reuse of graph algorithms and data
structures. Part of the Boost Graph Library is a generic interface that allows
access to a graph's structure, but hides the details of the implementation.
This is an "open" interface in the sense that any graph library that implements
this interface will be interoperable with the BGL generic algorithms and with
other algorithms that also use this interface. The BGL provides some general
purpose graph classes that conform to this interface, but they are not meant to
be the /only/ graph classes; there certainly will be other graph classes that
are better for certain situations. We believe that the main contribution of the
The BGL is the formulation of this interface.
The BGL graph interface and graph components are generic, in the same sense as
the the Standard Template Library (STL). In the following sections, we review
the role that generic programming plays in the STL and compare that to how we
applied generic programming in the context of graphs.
Of course, if you are already are familiar with generic programming, please dive
right in! Here's the Table of Contents.
The source for the BGL is available as part of the Boost distribution, which you
can download from here.
[h2 How to Build Boost.Graph]
[*DON'T!] The Boost Graph Library is a header-only library and does not need to
be built to be used. The only exception is the GraphViz input parser.
When compiling programs that use the BGL, be sure to compile with optimization.
For instance, select "Release" mode with Microsoft Visual C++ or supply the flag
`-O2` or `-O3` to GCC. Compiling in "Debug" mode can sometimes result in
algorithms that execute slower by an order magnitude!
[h2 Genericity in the STL]
There are three ways in which the STL is generic.
[h3 Algorithm/Data Structure Interoperability in the STL]
First, each algorithm is written in a data-structure neutral way, allowing a
single template function to operate on many different classes of containers. The
concept of an iterator is the key ingredient in this decoupling of algorithms
and data-structures. The impact of this technique is a reduction in the STL's
code size from O(M*N) to O(M+N), where M is the number of algorithms and N is
the number of containers. Considering a situation of 20 algorithms and 5
data-structures, this would be the difference between writing 100 functions
versus only 25 functions! And the differences continues to grow faster and
faster as the number of algorithms and data-structures increase.
[h3 Extension Through Function Objects]
The second way that STL is generic is that its algorithms and containers are
extensible. The user can adapt and customize the STL through the use of function
objects. This flexibility is what makes STL such a great tool for solving
real-world problems. Each programming problem brings its own set of entities and
interactions that must be modeled. Function objects provide a mechanism for
extending the STL to handle the specifics of each problem domain
[h3 Element Type Parameterization]
The third way that STL is generic is that its containers are parameterized on
the element type. Though hugely important, this is perhaps the least "interesting"
way in which STL is generic. Generic programming is often summarized by a brief
description of parameterized lists such as `std::list<T>`. This hardly scratches
the surface!
[h2 Genericity in Boost.Graph]
Like the STL, there are three ways in which the BGL is generic.
[h3 Algorithm/Data Structure Interoperability in Boost.Graph]
First, the graph algorithms of the BGL are written to an interface that abstracts
away the details of the particular graph data-structure. Like the STL, the BGL
uses iterators to define the interface for data-structure traversal. There are
three distinct graph traversal patterns: traversal of all vertices in the graph,
through all of the edges, and along the adjacency structure of the graph (from a
vertex to each of its neighbors). There are separate iterators for each pattern
of traversal.
This generic interface allows template functions such as breadth_first_search()
to work on a large variety of graph data-structures, from graphs implemented
with pointer-linked nodes to graphs encoded in arrays. This flexibility is
especially important in the domain of graphs. Graph data structures are often
custom-made for a particular application. Traditionally, if programmers want to
reuse an algorithm implementation they must convert/copy their graph data into
the graph library's prescribed graph structure. This is the case with libraries
such as LEDA, GTL, Stanford GraphBase; it is especially true of graph algorithms
written in Fortran. This severely limits the reuse of their graph algorithms.
In contrast, custom-made (or even legacy) graph structures can be used as-is
with the generic graph algorithms of the BGL, using external adaptation (see
Section How to Convert Existing Graphs to the BGL). External adaptation wraps a
new interface around a data-structure without copying and without placing the
data inside adaptor objects. The BGL interface was carefully designed to make
this adaptation easy. To demonstrate this, we have built interfacing code for
using a variety of graph dstructures (LEDA graphs, Stanford GraphBase graphs,
and even Fortran-style arrays) in BGL graph algorithms.
[h3 Extension through Visitors]
Second, the graph algorithms of the BGL are extensible. The BGL introduces the
notion of a visitor, which is just a function object with multiple methods. In
graph algorithms, there are often several key /event points/ at which it is
useful to insert user-defined operations. The visitor object has a different
method that is invoked at each event point. The particular event points and
corresponding visitor methods depend on the particular algorithm. They often
include methods like `start_vertex`, `discover_vertex`, `examine_edge`,
`tree_edge`, and `finish_vertex`.
[h3 Vertex and Edge Property Multi-Parameterization]
The third way that the BGL is generic is analogous to the parameterization of
the element-type in STL containers, though again the story is a bit more
complicated for graphs. We need to associate values (called "properties") with
both the vertices and the edges of the graph. In addition, it will often be
necessary to associate multiple properties with each vertex and edge; this is
what we mean by multi-parameterization. The STL `std::list<T>` class has a
parameter `T` for its element type. Similarly, BGL graph classes have template
parameters for vertex and edge "properties". A property specifies the
parameterized type of the property and also assigns an identifying tag to the
property. This tag is used to distinguish between the multiple properties which
an edge or vertex may have. A property value that is attached to a particular
vertex or edge can be obtained via a property map. There is a separate property
map for each property.
Traditional graph libraries and graph structures frequently fall down when it
comes to the parameterization of graph properties. This is one of the primary
reasons that graph data-structures must be custom-built for applications. The
parameterization of properties in the BGL graph classes makes them well suited
for reuse.
[h2 Algorithms]
Boost.Graph algorithms consist of a core set of algorithm patterns (implemented
as generic algorithms) and a larger set of graph algorithms. The core algorithm
patterns are:
* Breadth First Search
* Depth First Search
* Uniform Cost Search
By themselves, the algorithm patterns do not compute any meaningful quantities
over graphs; they are merely building blocks for constructing graph algorithms.
The graph algorithms in the BGL currently include:
* Dijkstra's Shortest Paths
* Bellman-Ford Shortest Paths
* Johnson's All-Pairs Shortest Paths
* Kruskal's Minimum Spanning Tree
* Prim's Minimum Spanning Tree
* Connected Components
* Strongly Connected Components
* Dynamic Connected Components (using Disjoint Sets)
* Topological Sort
* Transpose
* Reverse Cuthill Mckee Ordering
* Smallest Last Vertex Ordering
* Sequential Vertex Coloring
[h2 Data Structures]
Boost.Graph currently provides two graph classes and an edge list adaptor:
* adjacency_list
* adjacency_matrix
* edge_list
The adjacency_list class is the general purpose "swiss army knife" of graph
classes. It is highly parameterized so that it can be optimized for different
situations: the graph is directed or undirected, allow or disallow parallel
edges, efficient access to just the out-edges or also to the in-edges, fast
vertex insertion and removal at the cost of extra space overhead, etc.
The adjacency_matrix class stores edges in a |V| x |V| matrix (where |V| is the
number of vertices). The elements of this matrix represent edges in the graph.
Adjacency matrix representations are especially suitable for very dense
graphs, i.e., those where the number of edges approaches |V|[sup 2].
The `edge_list` class is an adaptor that takes any kind of edge iterator and
implements an Edge List Graph.
[h2 Projects Using This Library]
Here is an abbreviated list of projects that use the BGL or are based on the
graph concepts in the BGL.
* [@http://www.cs.rpi.edu/~musser/gsd/ Generic Software Design Course at RPI]
* [@http://alps.comp-phys.org/ The ALPS quantum mechanics project]
* [@http://bioinformatics.icmb.utexas.edu/lgl/ Large Graph Layout at University of Texas]
* [@http://www.cs.concordia.ca/~gregb/home/c691R-w2004.html Bioinformatics Algorithms at Concordia University]
* [@http://photon.poly.edu/~hbr/cs903/ Algorithm Course at Polytechnic University in Brooklyn]
* [@http://www.bioconductor.org/repository/devel/vignette/RBGL.pdf BGL interface for language R]
* [@http://www.cuj.com/documents/s=8470/cuj0307tan/ CUJ Article about Electronic Design Automation]
* [@http://rubyforge.org/projects/rgl/ A BGL-inspired Ruby Graph Library]
* [@http://www.codeproject.com/cs/miscctrl/quickgraph.asp A BGL-inspired C# Graph Library]
* [@http://map1.squeakfoundation.org/sm/package/5729d80a-822b-4bc2-9420-ef7ecaea8553 A BGL-inspired Squeak (Smalltalk) Graph Library]
* [@http://www.datasim.nl/education/coursedetails.asp?coursecategory=CPP&coursecode=ADCPP BGL course at DataSim]
* [@http://www.vrjuggler.org/ VR Juggler: Virtual Reality Tools]
* [@http://hyperworx.org Hyperworx Platform Project]
[h2 Publications about this Library]
Here is a short list of publications about the BGL.
* Dr. Dobb's Sept. 2000 Article
* OOPSLA'99 GGCL Paper
* Lie-Quan Lee's Master's Thesis about GGCL(ps) (pdf)
* Dietmar Kuhl's Master's Thesis: Design Pattern for the Implementation of Graph Algorithms
* ISCOPE'99 Sparse Matrix Ordering (pdf)
* C++ Template Workshop 2000, Concept Checking
[h2 Acknowledgements]
We owe many debts of thanks to a number of individuals who both inspired and
encouraged us in developing the Boost Graph Library.
A most profound thanks goes to Alexander Stepanov for his pioneering work in
generic programming, for his encouragement, and for his algorithm contributions
to the BGL. We thank Matthew Austern for his work on documenting the concepts
of STL which provided a foundation for creating the concepts in the BGL. We
thank Dietmar Kuhl for his work on generic graph algorithms and design patterns;
especially for the property map abstraction.
Dave Abrahams, Jens Maurer, Beman Dawes, Gary Powell, Greg Colvin, Valentin
Bonnard, and the rest of the group at Boost provided valuable input to the BGL
interface, numerous suggestions for improvement, proof reads of the
documentation, and help with polishing the code. A special thanks to Dave
Abrahams for managing the formal review.
We also thank the following BGL users whose questions helped to improve the
BGL: Gordon Woodhull, Dave Longhorn, Joel Phillips, and Edward Luke.
A special thanks to Jeffrey Squyres for editing and proof reading of the
documentation.
Our original work on the Boost Graph Library was supported in part by NSF grant
ACI-9982205 and by the Director, Office of Science, Division of Mathematical,
Information, and Computational Sciences of the U.S. Department of Energy under
contract number DE-AC03-76SF00098.
In our work we also used resources of the National Energy Research Scientific
Computing Center, which is supported by the Office of Science of the U.S.
Department of Energy.
[endsect]

View File

@@ -1,696 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Adjacency List]
template <
typename OutEdgeList = vecS,
typename VertexList = vecS,
typename Directed = directedS,
typename VertexProperty = no_property,
typename EdgeProperty = no_property,
typename GraphProperty = no_property,
typename EdgeList = listS>
class adjacency_list;
The `adjacency_list` class implements a generalized adjacency list graph structure.
The template parameters provide many configuration options so that you can pick a
version of the class that best meets your needs. An adjacency-list is basically a
two-dimensional structure, where each element of the first dimension represents a
vertex, and each of the vertices contains a one-dimensional structure that is its
edge list. Figure 1 shows an adjacency list representation of a directed graph.
The VertexList template parameter of the adjacency_list class controls what kind
of container is used to represent the outer two-dimensional container. The
OutEdgeList template parameter controls what kind of container is used to represent
the edge lists. The choices for OutEdgeList and VertexList will determine the space
complexity of the graph structure, and will determine the time complexity of the
various graph operations. The possible choices and tradeoffs are discussed in
Section Choosing the Edgelist and VertexList.
The Directed template parameter controls whether the graph is directed, undirected,
or directed with access to both the in-edges and out-edges (which we call
bidirectional). The bidirectional graph takes up twice the space (per edge) of a
directed graph since each edge will appear in both an out-edge and in-edge list.
Figure 2 shows an adjacency list representation of an undirected graph.
A tutorial on how to use the [adjacency_list] class is in Section
[link boost_graph.guide.the_adjacnecy_list The Adjacency List].
[heading Where Defined]
`boost/graph/adjacency_list.hpp`
[heading Template Parameters]
[table
[[Parameter] [Description] [Default]]
[
[`OutEdgeList`]
[
The selector for the container used to represent the edge-list for each
of the vertices.
]
[`vecS`]
]
[
[`VertexList`]
[
The selector for the container used to represent the vertex-list of the graph.
]
[`vecS`]
]
[
[`Directed`]
[
A selector to choose whether the graph is directed, undirected, or
directed with bidirectional edge access (access to both out-edges
and in-edges). The options are directedS, undirectedS, and
bidirectionalS.
]
[`directedS`]
]
[
[`VertexProperty`]
[Specifies internal properties for vertices.]
[`no_property`]
]
[
[`EdgeProperty`]
[Specifies internal properties for edges.]
[`no_property`]
]
[
[`GraphProperty`]
[Specifies internal properties for the graph object.]
[`no_property`]
]
[
[`EdgeList`]
[
The selector for the container used to represent the edge-list for
the graph.
]
[`listS`]
]
]
[heading Model of]
All adjacency lists model these concepts: [VertexAndEdgeListGraph], [IncidenceGraph]
[MutablePropertyGraph], [SgiCopyConstructible], and [SgiAssignable]. If the template
parameter `Directed` is given as `bidirectionalS`, then the adjacency graph models
the [BidirectionalGraph] concept as well.
[heading Associated Types]
[table
[[Type] [Description]]
[
[`graph_traits<adjancency_list>::vertex_descriptor`]
[The type of vertex descriptors associated with the `adjacency_list`.]
]
[
[`graph_traits<adjancency_list>::edge_descriptor`]
[The type of edge descriptors associated with the `adjacency_list`.]
]
[
[`graph_traits<adjancency_list>::vertex_iterator`]
[
The type for iterators returned by `vertices()`. The concept modeled by this
type varies with the type of the `VertexList` parameter. If the `VertexList`
selector is `vecS`, then this type models the [SgiRandomAccessIterator] concept.
In all other cases, it is a model of [SgiBidirectionalIterator].
]
]
[
[`graph_traits<adjancency_list>::out_edge_iterator`]
[
The type for iterators returned by `edges()`. The concept modeled by this type
depends on the `OutEdgeList` parameter. If the selector is `vecS` then the
iterator is a model of [SgiRandomAccessIterator]. If the selector is `slistS`
then it is a model of [SgiForwardIterator]. Otherwise, the iterator models
[SgiBidirectionalIterator].
]
]
[
[`graph_traits<adjancency_list>::in_edge_iterator`]
[
This type is only valid if the `Directed` parameter is given as `bidirectionalS`.
The concepts modeled by this type are the same as the `out_edge_iterator`.
]
]
[
[`graph_traits<adjancency_list>::adjacency_iterator`]
[
The type for iterators returned by `adjacent_vertices()`. The concepts modeled
by this type are the same as `out_edge_iterator`. Dereferencing these types,
however, will result in vertex descriptors rather than edge descriptors.
]
]
[
[`graph_traits<adjancency_list>::inv_adjacency_iterator`]
[
The type for iterators returned by `inv_adjacent_vertices()`. The concepts
modeled by this type are identical to hose of the `adjacency_iterator`.
]
]
[
[`graph_traits<adjancency_list>::directed_category`]
[
Provides inforamtion about whether the graph is undirected (`undirected_tag`),
directed (`directed_tag`), or bidirectional (`bidirectional_tag`).
]
]
[
[`graph_traits<adjacency_list>::edge_parallel_category`]
[
This describes whether the class allows the insertion of parallel edges; those
with the same source and target. When `EdgeList` is selected as `setS` or
`hash_setS`, this type is set to `disallow_parallel_edge_tag`. Otherwise it
is `allow_parallel_edge_tag`.
]
]
[
[`graph_traits<adjacency_list>::vertices_size_type`]
[The type used for dealing with the number of vertices in the graph. ]
]
[
[`graph_traits<adjacency_list>::edge_size_type`]
[The type used for dealing with the number of edges in the graph. ]
]
[
[`graph_traits<adjacency_list>::degree_size_type`]
[The type used for dealing with the number of edges incident to a vertex in the graph. ]
]
[
[
`property_map<adjacency_list, Property>::type`
`property_map<adjacency_list, Property>::const_type`
]
[
The property map type for vertex or edge properties in the graph. The specific
property is specified by the `Property` template argument, and must match one of
the properties specified in the `VertexProperty` or `EdgeProperty` for the
graph.
]
]
[
[`graph_property<adjacency_list, Property>::type`]
[
The value type ofor the graph property specified by the `Property` parameter.
]
]
[
[`adjacency_list::out_edge_list_selector`]
[The instantiated type of the `OutEdgeList` template parameter.]
]
[
[`adjacency_list::vertex_list_selector`]
[The instantiated type of the `VertexList` template parameter.]
]
[
[`adjacency_list::directed_selector`]
[The instantiated type of the `Directed` template parameter.]
]
[
[`adjacency_list::edge_list_selector`]
[The instantiated type of the `EdgeList` template parameter.]
]
]
[heading Member Functions]
[/ Constructors ]
adjacency_list(const GraphProperty& p = GraphProperty())
The default constructor creates an empty graph with no vertices or edges, optionally
assigning the given graph properties `p`.
adjacency_list(const adjacency_list& x)
Construct the graph as a copy of `x`.
adjacency_list(vertices_size_type n, const GraphProperty& p = GraphProperty())
Construct the graph with `n` vertices and no edges. An optional graph property
may be given.
template <typename Iter>
adjacency_list(Iter f, Iter l,
vertices_size_type n, edges_size_type m = 0,
const GraphProperty& p = GraphProperty())
Construct the graph over `n` vertices and the edges given in the range \[f, l).
The `Iter` type must be an [InputIterator] and its `value_type` must be a `pair`
of integral types. The integral values of each `pair` refer to vertices in the
range \[0, n).
template <typename EdgeIter, typename PropIter>
adjacency_list(EdgeIter f, EgeIter l, PropIter p,
vertices_size_type n, edges_size_type m = 0,
const GraphProperty& p = GraphProperty())
[/ Assignment Operator]
Construct the graph over `n` vertices and the edges given in the range \[f, l).
The `EdgeIter` and `PropIter` types must model the [InputIterator] concept. The
`value_type` of `EdgeIter` must be a `pair` of integral types. The integral
values of each `pair` refer to vertices in the range \[0, n). The `value_type`
of `PropIter` must be `EdgeProperty`.
adjacency_list& operator=(adjacency_list const& x)
Assign this graph to be a copy of `x`.
void swap(adjacency_list& x)
Swap this graph with `x`.
void clear()
Reset the graph so that it has no vertices or edges.
[heading Non-Member Observers]
[table
[[Member Function] [Description]]
[
[
``
vertices_size_type
num_vertices(const adjacency_list& g)
``
]
[Return the number of vertices in `g`.]
]
[
[
``
edges_size_type
num_edges(const adjacency_list& g)
``
]
[Return the edges in vertices in `g`.]
]
[
[
``
vertex_descriptor
vertex(vertices_size_type n, const adjacency_list& g)
``
]
[Return a descriptor to the `n`th vertex in `g`.]
]
[
[
``
pair<edge_descriptor, bool>
edge(vertex_descriptor u, vertex_descriptor v,
const adjacency_list& g)
``
]
[
Returns a pair containing a descriptor for the edge connecting vertices
`u` and `v` in `g`, and a boolean value that indicates whether the
edge exists (`true`) or not (`false`).
]
]
[
[
``
vertex_descriptor
source(edge_descriptor e, const adjacency_list& g)
``
]
[Return the source vertex of the edge `e` in `g`.]
]
[
[
``
vertex_descriptor
target(edge_descriptor e, const adjacency_list& g)
``
]
[Return the target vertex of the edge `e` in `g`.]
]
[
[
``
pair<vertex_iterator, vertex_iterator>
vertices(const adjacency_list& g)
``
]
[Returns an iterator range to the vertex set of `g`.]
]
[
[
``
pair<edge_iterator, edge_iterator>
edges(const adjacency_list& g)
``
]
[Returns an iterator range to the edge set of `g`.]
]
[
[
``
pair<out_edge_iterator, out_edge_iterator>
out_edges(vertex_descriptor v, const adjacency_list& g)
``
]
[
Returns an iterator range to the out-edge set of the vertex `v` in `g`.
If the graph is undirected, the iterator range provides access to all
incident edges.
]
]
[
[
``
pair<in_edge_iterator, in_edge_iterator>
in_edges(vertex_descriptor v, const adjacency_list& g)
``
]
[
Returns an iterator range to the in-edge set of the vertex `v` in `g`.
If the graph is undirected, this operation is equivalent to `out_edges`.
]
]
[
[
``
pair<adjacency_iterator, adjacency_iterator>
adjacent_vertices(vertex_descriptor v, const adjacency_list& g)
``
]
[Returns an iterator range providing access to the adjacent vertices of `v` in `g`.]
]
[
[
``
degree_size_type
out_degree(vertex_descriptor v, const adjacency_list& g)``
]
[
Return the out-degree of vertex `v` in `g`.
*Complexity:* /O(|V|)/
]
]
[
[
``
degree_size_type
in_degree(vertex_descriptor v, const adjacency_list& g)
``
]
[
Return the in-degree of vertex `v` in `g`.
*Complexity:* /O(|V|)/
]
]
]
[heading Non-Member Mutators]
[table
[[Member Function] [Description]]
[
[
``
pair<edge_descriptor, bool>
add_edge(vertex_descriptor u, vertex_descriptor v,
adjacency_list& g)
``
]
[]
]
[
[
``
pair<edge_descriptor, bool>
add_edge(vertex_descriptor u, vertex_descriptor v,
EdgeProperty const& p, adjacency_list& g)
``
]
[]
]
[
[
``
void remove_edge(vertex_descriptor u, vertex_descriptor v,
adjacency_list& g)
``
]
[]
]
[
[
``
void remove_edge(edge_descriptor v, adjacency_list& g)
``
]
[]
]
[
[
``
void clear_vertex(edge_descriptor v, adjacency_list& g)
``
]
[]
]
]
[heading Property Accessors]
[table
[[Member Function] [Description]]
[
[
``
template <typename Property>
typename property_map<adjancecy_list, Property>::type
get(Property, adjaceny_list& g);
``
]
[]
]
[
[
``
template <typename Property>
typename property_map<adjancecy_list, Property>::const_type
get(Property, adjaceny_list const& g);
``
]
[]
]
[
[
``
template <typename Property, typename X>
typename property_traits<
property_map<adjancecy_list, Property>::const_type
>::value_type
get(Property, adjaceny_list const& g, X x);
``
]
[]
]
[
[
``
template <typename Property, typename X, typename Value>
void put(Property, X, adjaceny_list const& g,
X x, const Value&);
``
]
[]
]
[
[
``
template <typename Property>
typename graph_property<adjacency_list, Property>::type
void get_property(adjaceny_list const& g, Property);
``
]
[]
]
[
[
``
template <typename Property, typename Value>
void set_property(adjaceny_list const& g, Property,
const Value&);
``
]
[]
]
]
[heading Vertex and Edge Properties]
Properties such as color, distance, weight, and user-defined properties can be
attached to the vertices and edges of the graph using properties. The property
values can be read from and written to via the property maps provided by the
graph. The property maps are obtained via the `get(property, g)` function. How
to use properties is described in Section Internal Properties . The property
maps are objects that implement the interface defined in Section Property Map
Concepts or may be bundled properties, which have a more succinct syntax. The
types of all property values must be [SgiCopyConstructible], [SgiAssignable], and
[SgiDefaultConstructible]. The property maps obtained from the adjacency_list class
are models of the [LvaluePropertyMap] concept. If the `adjacency_list` is `const`,
then the property map is constant, otherwise the property map is mutable.
If the VertexList of the graph is vecS, then the graph has a builtin vertex
indices accessed via the property map for the vertex_index_t property. The
indices fall in the range \[0, num_vertices(g)) and are contiguous. When a
vertex is removed the indices are adjusted so that they retain these
properties. Some care must be taken when using these indices to access exterior
roperty storage. The property map for vertex index is a model of Readable
Property Map.
[heading Iterator and Descriptor Stability/Invalidation]
Some care must be taken when changing the structure of a graph (via adding or
removing edges). Depending on the type of adjacency_list and on the operation,
some of the iterator or descriptor objects that point into the graph may become
invalid. For example, the following code will result in undefined (bad)
behavior:
typedef adjacency_list<listS, vecS> Graph; // VertexList = vecS
Graph G(N);
// Fill in the graph...
// Attempt to remove all the vertices. Wrong!
graph_traits<Graph>::vertex_iterator vi, vi_end;
for(tie(vi, vi_end) = vertices(G); vi != vi_end; ++vi) {
remove_vertex(*vi, G);
}
// Remove all the vertices. This is still wrong!
graph_traits<Graph>::vertex_iterator vi, vi_end, next;
tie(vi, vi_end) = vertices(G);
for(next = vi; vi != vi_end; vi = next) {
++next;
remove_vertex(*vi, G);
}
The reason this is a problem is that we are invoking remove_vertex(), which
when used with an adjacency_list where VertexList=vecS, invalidates all
iterators and descriptors for the graph (such as vi and vi_end), thereby
causing trouble in subsequent iterations of the loop.
If we use a different kind of `adjacency_list`, with `VertexList` as `listS`,
then the iterators are not invalidated by calling remove_vertex unless the
iterator is pointing to the actual vertex that was removed. The following code
demonstrates this.
typedef adjacency_list<listS, listS> Graph; // VertexList = listS
Graph G(N);
// Fill in the graph...
// Attempt to remove all the vertices. Wrong!
graph_traits<Graph>::vertex_iterator vi, vi_end;
for(tie(vi, vi_end) = vertices(G); vi != vi_end; ++vi) {
remove_vertex(*vi, G);
}
// Remove all the vertices. This is OK.
graph_traits<Graph>::vertex_iterator vi, vi_end, next;
tie(vi, vi_end) = vertices(G);
for(next = vi; vi != vi_end; vi = next) {
++next;
remove_vertex(*vi, G);
}
The stability issue also affects vertex and edge descriptors. For example,
suppose you use vector of vertex descriptors to keep track of the parents
(or predecessors) of vertices in a shortest paths tree (see
`examples/dijkstra-example.cpp`). You create the parent vector with a call
to dijkstra_shortest_paths(), and then remove a vertex from the graph.
Subsequently you try to use the parent vector, but since all vertex descriptors
have become invalid, the result is incorrect.
std::vector<Vertex> parent(num_vertices(G));
std::vector<Vertex> distance(num_vertices(G));
dijkstra_shortest_paths(G, s,
distance_map(&distance[0])
.predecessor_map(&parent[0]));
remove_vertex(s, G); // Bad idea! Invalidates vertex descriptors in parent vector.
// The following will produce incorrect results
for(tie(vi, vend) = vertices(G); vi != vend; ++vi) {
std::cout << p[*vi] << " is the parent of " << *vi << std::endl;
}
Note that in this discussion iterator and descriptor invalidation is concerned
with the invalidation of iterators and descriptors that are not directly
affected by the operation. For example, performing `remove_edge(u, v, g)` will
always invalidate any edge descriptor for /(u,v)/ or edge iterator pointing to
/(u,v)/, regardless of the kind `adjacency_list`. In this discussion of iterator
and descriptor invalidation, we are only concerned with the affect of
`remove_edge(u, v, g)` on edge descriptors and iterators that point to other
edges (not /(u,v)/).
In general, if you want your vertex and edge descriptors to be stable (never
invalidated) then use listS or setS for the VertexList and OutEdgeList template
parameters of adjacency_list. If you are not as concerned about descriptor and
iterator stability, and are more concerned about memory consumption and graph
traversal speed, use vecS for the VertexList and/or OutEdgeList template
parameters.
The following table summarizes which operations cause descriptors and iterators
to become invalid. In the table, OEL is an abbreviation for OutEdgeList and VL
means VertexList. The "Adjacency Iterator" category includes the `out_edge_iterator`,
`in_edge_iterator`, and `adjacency_iterator types`. A more detailed description of
descriptor and iterator invalidation is given in the documentation for each
operation.
[table
[[Function] [Vertex Descriptor] [Edge Descriptor] [Vertex Iterator] [Edge Iterator] [Adjacency Iterator]]
[
[`add_edge()`]
[Valid] [Valid] [Valid]
[
OEL = `vecS` &&
Directed = `directedS`]
[OEL = `vecS`]
]
[
[
`remove_edge()`
`remove_edge_if()`
`remove_out_edge_if()`
`remove_in_edge_if()`
`clear_vertex()`
]
[Valid] [Valid] [Valid]
[
OEL = `vecS` &&
Directed = `directedS`
]
[OEL = `vecS`]
]
[
[`add_vertex()`]
[Valid] [Valid] [Valid] [Valid] [Valid]
]
[
[`remove_vertex()`]
[VL = `vecS`] [VL = `vecS`] [VL = `vecS`] [VL = `vecS`] [VL = `vecS`]
]
]
[endsect]

View File

@@ -1,478 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Adjacency Matrix]
template <
typename Directed = directedS,
typename VertexProperty = no_property,
typename EdgeProperty = no_property,
typename GraphProperty = no_property,
typename Allocator = std::allocator<...> >
class adjacency_matrix;
The `adjacency_matrix` class implements the Boost.Graph interface using the
traditional adjacency matrix storage format. For a graph with /V/ vertices, a
/V x V/ matrix is used, where each element ['a[sub ij]] is a boolean flag that
says whether there is an edge from vertex /i/ to vertex /j/. Figure 1 shows
the adjacency matrix representation of a graph.
[note TODO: Rebuild image]
The advantage of this matrix format over the adjacency list is that edge insertion
and removal is constant time. There are several disadvantages. The first is that
the amount of memory used is ['O(V[sup 2])] instead of /O(V + E)/ (where /E/ is
the number of edges). The second is that operations that traverse all the out-edges
of each vertex (such as breadth-first search) run in ['O(V[sup 2])] time instead
of /O(V + E)/ time for the adjacency list. In short, it is better to use the
`adjacency_matrix` for dense graphs (where /E/ is close to ['V[sup 2]]) and it is
better to use [adjacency_list] for sparse graphs (where /E/ is much smaller than
['V[sup2]]).
The `adjacency_matrix` class extends the traditional data structure by allowing
objects to be attached to vertices and edges using the same property template
parameters supported by [adjacency_list]. These may be
[link boost_graph.guide.bundled_properties bundled properties]
or standard (backward-compatible)
[link boost_graph.guide.interior_properties interior properties].
The types of all property values must be [StdRegular].
In the case of an undirected graph, the `adjacency_matrix`. class does not use a
full /V x V/ matrix but instead uses a lower triangle (the diagonal and below)
since the matrix for an undirected graph is symmetric. This reduces the storage
to ['(V[sup 2])/2]. Figure 2</a> shows an adjacency matrix representation of an
undirected graph.
[note TODO: Rebuild image.]
[heading Where Defined]
`boost/graph/adjacency_matrix.hpp`
[heading Template Parameters]
[table
[[Parameter] [Description] [Default]]
[
[`Directed`]
[
A selector to choose whether the graph is directed or undirected.
The options are directedS and undirectedS.
]
[`directedS`]
]
[
[`VertexProperties`]
[Specifies internal properties for vertices.]
[`no_property`]
]
[
[`EdgeProperties`]
[Specifies internal properties for edges.]
[`no_property`]
]
[
[`GraphProperties`]
[Specifies internal properties for the graph object.]
[`no_property`]
]
[
[`Alloator`]
[
The allocator type for the adjacency matrix.
]
[`std::allocator<...>`]
]
]
[heading Model Of]
[VertexAndEdgeListGraph], [BidirecitonalGraph], [AdjacencyMatrix],
[MutablePropertyGraph], [SgiCopyConstructible], [SgiAssignable]
[heading Associated Types]
[table
[[Type] [Description]]
[
[`graph_traits<adjancency_list>::vertex_descriptor`]
[The type of the graph's vertex descriptors.]
]
[
[`graph_traits<adjancency_list>::edge_descriptor`]
[The type of the graph's edge descriptors.]
]
[
[`graph_traits<adjancency_list>::vertex_iterator`]
[
The type for iterators returned by `vertices()`, modeling the
[SgiRandomAccessIterator] concept.
]
]
[
[`graph_traits<adjancency_list>::edge_iterator`]
[
The type for iterators returned by `edges()`, modeling the
[SgiForwardIterator] concept.
]
]
[
[`graph_traits<adjancency_list>::out_edge_iterator`]
[
The type for iterators returned by `out_edges()`, modeling the
[SgiForwardIterator] concept.
]
]
[
[`graph_traits<adjancency_list>::in_edge_iterator`]
[
The type for iterators returned by `in_edges()`, modeling the
[SgiForwardIterator] concept.
]
]
[
[`graph_traits<adjancency_list>::adjacency_iterator`]
[
The type for iterators returned by `adjacent_vertices()`, modeling the
[SgiForwardIterator] concept.
]
]
[
[`graph_traits<adjancency_list>::directed_category`]
[
Provides inforamtion about whether the graph is undirected (`undirected_tag`),
or directed (`directed_tag`).
]
]
[
[`graph_traits<adjacency_list>::edge_parallel_category`]
[
Adjacency matrices do not allow the insertion of parallel edges so
this type is always `disallow_parallel_edges`.
]
]
[
[`graph_traits<adjacency_list>::vertices_size_type`]
[The type used for dealing with the number of vertices in the graph. ]
]
[
[`graph_traits<adjacency_list>::edge_size_type`]
[The type used for dealing with the number of edges in the graph. ]
]
[
[`graph_traits<adjacency_list>::degree_size_type`]
[The type used for dealing with the number of edges incident to a vertex in the graph.]
]
[
[
`property_map<adjacency_list, Property>::type`
`property_map<adjacency_list, Property>::const_type`
]
[
The property map type for vertex or edge properties in the graph. The specific
property is specified by the `Property` template argument, and must match one of
the properties specified in the `VertexProperties` or `EdgeProperties` for the
graph.
]
]
[
[`graph_property<adjacency_list, Property>::type`]
[
The value type ofor the graph property specified by the `Property` parameter.
]
]
]
[heading Member Functions]
[table
[[Member Function] [Description]]
[
[`adjacency_matrix(vertices_size_type n, const GraphProperties& = GraphProperties()`]
[Construct a graph with `n` vertices and no edges.]
]
[
[
``
template <typename Iter>
adjacency_matrix(Iter f, Iter l, vertices_size_type n, const GraphProperties& = GraphProperties())
``
]
[
Construct a graph with `n` vertices and and the edges specified by
the iterator range \[f, l). The `value_type` of `Iter` must be a
`std::pair` of `int`s whose values are in the range \[0, n), and
indicate the given vertex.
]
]
[
[
``
template <typename EdgeIter, typename PropIter>
adjacency_matrix(Iter f, Iter l, PropIter p, vertices_size_type n, const GraphProperties& = GraphProperties())
``
]
[
Construct a graph with `n` vertices and and the edges specified by
the iterator range \[f, l), with the edge properties given by the
iterator range starting at `p`. The `value_type` of `EdgeIter` must
be a `std::pair` of `int`s whose values are in the range \[0, n), and
indicate the given vertex. The `value_type` of the `PropIter` must be
the same as the template parameter `EdgeProperty`.
]
]
]
[heading Non-Member Observers]
[table
[[Member Function] [Description]]
[
[`vertices_size_type num_vertices(const adjacency_matrix& g)`]
[Return the number of vertices in `g`.]
]
[
[`edges_size_type num_edges(const adjacency_matrix& g)`]
[Return the edges in vertices in `g`.]
]
[
[`vertex_descriptor vertex(vertices_size_type n, const adjacency_matrix& g)`]
[Return a descriptor to the `n`th vertex in `g`.]
]
[
[`pair<edge_descriptor, bool> edge(vertex_descriptor u, vertex_descriptor v, const adjacency_matrix& g)`]
[
Returns a pair containing a descriptor for the edge connecting vertices
`u` and `v` in `g`, and a boolean value that indicates whether the
edge exists (`true`) or not (`false`).
]
]
[
[`vertex_descriptor source(edge_descriptor e, const adjacency_matrix& g)`]
[Return the source vertex of the edge `e` in `g`.]
]
[
[`vertex_descriptor target(edge_descriptor e, const adjacency_matrix& g)`]
[Return the target vertex of the edge `e` in `g`.]
]
[
[`pair<vertex_iterator, vertex_iterator> vertices(const adjacency_matrix& g)`]
[Returns an iterator range to the vertex set of `g`.]
]
[
[`pair<edge_iterator, edge_iterator> edges(const adjacency_matrix& g)`]
[Returns an iterator range to the edge set of `g`.]
]
[
[`pair<out_edge_iterator, out_edge_iterator> out_edges(vertex_descriptor v, const adjacency_matrix& g)`]
[
Returns an iterator range to the out-edge set of the vertex `v` in `g`.
If the graph is undirected, the iterator range provides access to all
incident edges.
]
]
[
[`pair<in_edge_iterator, in_edge_iterator> in_edges(vertex_descriptor v, const adjacency_matrix& g)`]
[
Returns an iterator range to the in-edge set of the vertex `v` in `g`.
If the graph is undirected, this operation is equivalent to `out_edges`.
]
]
[
[`pair<adjacency_iterator, adjacency_iterator> adjacent_vertices(vertex_descriptor v, const adjacency_matrix& g)`]
[Returns an iterator range providing access to the adjacent vertices of `v` in `g`.]
]
[
[`degree_size_type out_degree(vertex_descriptor v, const adjacency_matrix& g)`]
[
Return the out-degree of vertex `v` in `g`.
*Complexity:* /O(|V|)/
]
]
[
[`degree_size_type in_degree(vertex_descriptor v, const adjacency_matrix& g)`]
[
Return the in-degree of vertex `v` in `g`.
*Complexity:* /O(|V|)/
]
]
]
[heading Non-Member Mutators]
[table
[[Member Function] [Description]]
[
[`pair<edge_descriptor, bool> add_edge(vertex_descriptor u, vertex_descriptor v, adjacency_matrix& g)`]
[]
]
[
[`pair<edge_descriptor, bool> add_edge(vertex_descriptor u, vertex_descriptor v, EdgeProperty const& p, adjacency_matrix& g)`]
[]
]
[
[`void remove_edge(vertex_descriptor u, vertex_descriptor v, adjacency_matrix& g)`]
[]
]
[
[`void remove_edge(edge_descriptor v, adjacency_matrix& g)`]
[]
]
[
[`void clear_vertex(edge_descriptor v, adjacency_matrix& g)`]
[]
]
]
[heading Property Accessors]
[table
[[Member Function] [Description]]
[
[
``
template <typename Property>
typename property_map<adjancecy_matrix, Property>::type
get(Property, adjaceny_matrix& g);
``
]
[]
]
[
[
``
template <typename Property>
typename property_map<adjancecy_matrix, Property>::const_type
get(Property, adjaceny_matrix const& g);
``
]
[]
]
[
[
``
template <typename Property, typename X>
typename property_traits<
property_map<adjancecy_matrix, Property>::const_type
>::value_type
get(Property, adjaceny_matrix const& g, X x);
``
]
[]
]
[
[
``
template <typename Property, typename X, typename Value>
void put(Property, X, adjaceny_matrix const& g, X x, const Value&);
``
]
[]
]
[
[
``
template <typename Property>
void get_property(adjaceny_matrix const& g, Property);
``
]
[]
]
[
[
``
template <typename Property, typename Value>
void set_property(adjaceny_matrix const& g, Property, const Value&);
``
]
[]
]
]
[heading Example]
Create the graph of Figure 1.
enum { A, B, C, D, E, F, N };
const char* name = "ABCDEF";
typedef boost::adjacency_matrix&lt;boost::directedS> Graph;
Graph g(N);
add_edge(B, C, g);
add_edge(B, F, g);
add_edge(C, A, g);
add_edge(C, C, g);
add_edge(D, E, g);
add_edge(E, D, g);
add_edge(F, A, g);
std::cout << "vertex set: ";
boost::print_vertices(g, name);
std::cout << std::endl;
std::cout << "edge set: ";
boost::print_edges(g, name);
std::cout << std::endl;
std::cout << "out-edges: " << std::endl;
boost::print_graph(g, name);
std::cout << std::endl;
The output is:
[pre
vertex set: A B C D E F
edge set: (B,C) (B,F) (C,A) (C,C) (D,E) (E,D) (F,A)
out-edges:
A -->
B --> C F
C --> A C
D --> E
E --> D
F --> A
]
Create the graph of Figure 2.
enum { A, B, C, D, E, F, N };
const char* name = "ABCDEF";
typedef boost::adjacency_matrix&lt;boost::undirectedS> UGraph;
UGraph ug(N);
add_edge(B, C, ug);
add_edge(B, F, ug);
add_edge(C, A, ug);
add_edge(D, E, ug);
add_edge(F, A, ug);
std::cout << "vertex set: ";
boost::print_vertices(ug, name);
std::cout << std::endl;
std::cout << "edge set: ";
boost::print_edges(ug, name);
std::cout << std::endl;
std::cout << "incident edges: " << std::endl;
boost::print_graph(ug, name);
std::cout << std::endl;
The output is:
[pre
vertex set: A B C D E F
edge set: (C,A) (C,B) (E,D) (F,A) (F,B)
incident edges:
A <--> C F
B <--> C F
C <--> A B
D <--> E
E <--> D
F <--> A B
]
[endsect]

View File

@@ -1,185 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Betweenness Centrality]
template<typename Graph, typename CentralityMap>
void
brandes_betweenness_centrality(const Graph& g, CentralityMap cm)
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap>
void
brandes_betweenness_centrality(const Graph& g,
CentralityMap cm,
EdgeCentralityMap ecm)
// Named Parameter Interface
template<typename Graph, ...>
void brandes_betweenness_centrality(const Graph& g, ...);
The /betweenness centrality/ measure is commonly used in network analysis to identify
vertices (also called actors) that are lie many shortest paths between other vertices
in a graph. Intuitively, vertices with high betweenness centrality act as "hubs" through
which more information flows. The betweenness centrality of a vertex is given as
[$images/eq/betweenness.png]
Where ['[delta][sub st]] is the number of shortest paths between the vertices /s/ and
/t/ and ['[delta][sub st](v)] is the number of shortest paths that pass through the
vertex /v/. Note that the ratio inside the sum an be interpreted as the probability
that /v/ lies on a shortest path between the vertices /s/ and /t/.
This function can also consider the /edge betweenness centrality/, which is defined
as, fro each edge, the betweenness centrality that was contribuetd to the targets
of the edge. This is plural for undirected graphs. Like vertex betweenness, this
measure can be used to determine the edges through which most shortest paths must
pass.
These functions measure the /absolute/ betweenness centrality for vertices. These
values can be converted to /relative/ betweenness centrality by scaling each of
the absolute values by:
[$images/eq/relative_betweenness.png]
Where /n/ is the number of vertices in the graph. Also, given the relative betwenness
centrality, one can compute the /central point dominance/, which is a mueasure of the
maximum betweenness of any point in the graph. For example, this value will be 0 for
complete graphs and 1 for star graphs (where all paths cross a central vertex).
The central point dominance of a graph is defined as:
[$images/eq/central_point_dominance.png]
This module provides a number of functions for computing both vertex and edge
centrality and related measures.
[heading Where Defined]
`boost/graph/betweenness_centrality.hpp`
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which the betweenness centrality of vertices or edges
is being computed.
*Requirements:* The `Graph` type must be a model of the [VertexListGraph]
and [IncidenceGraph] concepts. If the `EdgeCentralityMap` parameter
is present, this parameter type must also model the [EdgeListGraph].
]
]
[
[required, out] [`CentralityMap cm`]
[
The graph for which the betweenness centrality of vertices or edges
is being computed.
*Requirements:*
]
]
[
[required, in] [`DistanceMap dm`]
[
Given a vertex `v`, the `dm` parameter provides the length of the
shortest path between a vertex `u` and `v`. The vertex `u` is the
vertex for which the distance map was initially computed.
*Requirements:* `DistanceMap` must be a model of [ReadablePropertyMap].
The `key_type` of the distance map must be the same as the `vertex_descriptor`
of the `Graph` parameter. The `value_type` is required to be a model of
[NumericValue].
]
]
[
[required, in] [`DistanceMatrixMap dm`]
[
Given vertices /u/ and /v/, the `dm` parameter provides the length
of the shortest path between the two vertices. Note that the
distance between a vertex and itself should be 0 (i.e., `dm[u][u] == 0`).
*Requirements:* `DistanceMatrixMap` must be a model of [ReadablePropertyMap].
The `key_type` of the distance matrixc must be the same as the `vertex_descriptor`
of the `Graph` parameter. The `value_type` must be a [ReadWritePropertyMap]
whose `key_type` is also the `vertex_descriptor` of the `Graph` and
whose `value_type` is a model of [NumericValue].
]
]
[
[required, out] [`ClosenessMap cm`]
[
The cm parameter stores the output of the computed closeness (or
distance) for each vertex in `g`.
*Requirements:* The type of `close` must be model the [WritablePropertyMap]
concepts. The `key_type` of the property map must be the same as the
`vertex_descriptor` of the `Graph`, and the `value_type` must be a model
of [NumericValue].
]
]
[
[optional, in] [`Measure measure`]
[
The 'measure' parameter is an instance of a closeness measure that
performs the final operation (the reciprocal) for this computation.
*Requirements:* The `Measure` type must be a model of the [DistanceMeasure]
concept. The `distance_type` must be the same type as the `value_type`
of the `DistanceMap` or `DistanceMatrixMap`. The `result_type` of the
`Measure` must model the [NumericValue] concept.
]
]
]
[heading Return]
The `vertex_closeness_centrality()` function returns the closeness of a vertex.
If the source vertex is disconnected from any vertices in the graph, this value is 0.
[heading Complexity]
The `closenesss_centrality()` function returns in ['O(n[sup 2]*O(M))] where /n/
is the number of vertices in the graph and /M/ is the complexity of the given distance
measure. This is ['O(n[sup 2])] by default
The `vertex_closeness_centrality()` function returns in ['O(n*O(M))]. This is
linear by default.
[heading Example (Closeness Centrality)]
[heading Undocumented Functions]
These functions are also part of the betweenness centrality module, but are not
documented since they are more appropriately called using the named parameter
interface.
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename IncomingMap, typename DistanceMap, typename DependencyMap,
typename PathCountMap, typename VertexIndexMap>
void
brandes_betweenness_centrality(const Graph& g,
CentralityMap centrality,
EdgeCentralityMap edge_centrality,
IncomingMap incoming,
DistanceMap distance,
DependencyMap dependency,
PathCountMap path_count,
VertexIndexMap vertex_index)
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename IncomingMap, typename DistanceMap, typename DependencyMap,
typename PathCountMap, typename VertexIndexMap, typename WeightMap>
void
brandes_betweenness_centrality(const Graph& g,
CentralityMap centrality,
EdgeCentralityMap edge_centrality,
IncomingMap incoming,
DistanceMap distance,
DependencyMap dependency,
PathCountMap path_count,
VertexIndexMap vertex_index,
WeightMap weight_map)
[endsect]

View File

@@ -1,153 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Breadth-First Search]
template <class Graph, class P, class T, class R>
void
breadth_first_search(Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
bgl_named_params<P,T,R>& params = ``/defaults/``)
template <class Graph, class Buffer, class Visitor, class P, class T, class R>
void
breadth_first_search(Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
Buffer& q,
Visitor vis,
bgl_named_params<P,T,R>& params = ``/defaults/``)
The `breadth_first_search()` function performs a breadth-first traversal \[49\] of a directed or
undirected graph. A breadth-first traversal visits vertices that are closer to the source before
visiting vertices that are further away. In this context "distance" is defined as the number of edges
in the shortest path from the source vertex. The `breadth_first_search()` function can be used to
compute the shortest path from the source to all reachable vertices and the resulting shortest-path
distances. For more definitions related to BFS, see section Breadth-First Search.
BFS uses two data structures to to implement the traversal: a color marker for each vertex and
a queue. White vertices are undiscovered while gray vertices are discovered but have undiscovered
adjacent vertices. Black vertices are discovered and are adjacent to only other black or gray
vertices. The algorithm proceeds by removing a vertex /u/ from the queue and examining each out-edge
/(u,v)/. If an adjacent vertex /v/ is not already discovered, it is colored gray and placed in the
queue. After all of the out-edges are examined, vertex u is colored black and the process is
repeated. Pseudo-code for the BFS algorithm is a listed below.
[pre
BFS(G, s)
for each vertex u in V\[G\] initialize vertex u
color\[u\] := WHITE
d\[u\] := infinity
p\[u\] := u
end for
color\[s\] := GRAY
d\[s\] := 0
ENQUEUE(Q, s) discover vertex s
while not EMPTY(Q)
u := DEQUEUE(Q) examine vertex u
for each vertex v in adj\[u\] examine edge /(u,v)/
if(color\[v\] = WHITE) /(u,v)/ is a tree edge
color\[v\] := GRAY
d\[v\] := d\[u\] + 1
p\[v\] := u
ENQUEUE(Q, v) discover vertex v
else /(u,v)/ is a non-tree edge
if (color\[v\] = GRAY) /(u,v)/ has a gray target
...
else /(u,v)/ has a black target
...
end if
end for
color\[u\] := BLACK finsih vertex u
end while
return (d, p)
]
[heading Where Defined]
`boost/graph/breadth_first_search.hpp`
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[in] [`Graph& g`]
[
A directed or undirected graph. The graph type must be a model of [VertexListGraph]
and [IncidenceGraph].
]
]
[
[in] [`vertex_descriptor s`]
[
The source vertex where the search is started. This must be a valid vertex descriptor of
`g`.
]
]
]
[heading Named Parameters]
[table
[[Type] [Parameter] [Description]]
[
[in] [`visitor(Visitor vis)`]
[
A visitor object that is inovked inside the algorithm at event points specified by the
[BFSVisitor]. The `vis` object must be model the [BFSVisitor] concept.
*Default* `bfs_visitor<null_visitor>`.
]
]
[
[in] [`vertex_index_map(VeretxIndexMap index_map)`]
[
This maps each vertex to an integer in the range \[0, `num_vertices(g)`).
This parameter is only necessary when the default color property map is
used. The type VertexIndexMap must be a model of ReadablePropertyMap. The
value type of the map must be an integer type. The vertex descriptor type
of the graph needs to be usable as the key type of the map.
*Default* `get(vertex_index, g)`. Note if you use this default, make sure
that your graph has an interior `vertex_index` property. For example
`adjacency_list` with `VertexList=listS` does not have an interior
`vertex_index` property.
]
]
[
[util] [`color_map(ColorMap color)`]
[
This is used by the algorithm to keep track of its progress through the
graph. The type ColorMap must be a model of ReadWritePropertyMap and
its key type must be the graph's `vertex_descriptor` type and the value
type of the color map must model ColorValue.
*Default* An `iterator_property_map` create from a `std::vector` of
`default_color_type` of size `num_vertices(g)` and using `index_map` as
the index map (to access colors for a vertex).
]
]
[
[util] [`buffer(Buffer& q)`]
[
The queue used to determine the order in which vertices will be discovered.
If a FIFO queue is used, then the traversal will be according to the usual
BFS ordering. Other types of queues can be used, but the traversal order will
be different. For example Dijkstra's algorithm can be implemented using a
priority queue. The type Buffer must be a model of [NoConcept Buffer].
The `value_type` of the buffer must be the vertex_descriptor type for the graph.
*Default* `boost::queue`
]
]
]
[heading Complexity]
The time complexity is /O(E + V)/.
[heading Example]
[endsect]

View File

@@ -1,191 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Bron Kerbosch All Cliques]
[template ex_bron_kerbosch_printing_cliques[] [link
boost_graph.reference.algorithms.subgraph.bron_kerbosch_all_cliques.examples.printing_cliques
Printing Cliques Example]]
[template ex_bron_kerbosch_clique_number[] [link
boost_graph.reference.algorithms.subgraph.bron_kerbosch_all_cliques.examples.clique_number
Clique Number Example]]
[heading Overview]
This algorithm finds all /cliques/ of the given graph, invoking a visitor when
each clique is found. A clique is formally defined as a maxiamally connected
subgraph of a graph. This means that there are no more (and no fewer) vertices
in the graph that are connected to all other vertices in the graph. A vertex can
participate in many cliques. Note that the smallest clique contains two vertices
since each vertex is connected to the other.
Consider the social network (represented by an undirected graph) in Figure 1.
[figure
images/reference/social_network.png
*Figure 1.* A network of friends.
]
There are a number of cliques in the graph. We can easily identify the two largest:
* Scott, Jill, and Mary
* Frank, Howard, and Anne
There are six other cliques represented by pairs of actors. Note that the Scott,
Mary, Frank, and Laurie do not form a clique because Mary and Frank are not directly
connected. See the [ex_bron_kerbosch_printing_cliques] for more details.
The /clique number/ of a graph is defined as the size (the number of vertices) of
the largest clique in the graph. The social network in Figure 1 has a clique number
of 3. The [bron_kerbosch_clique_number] implements this measure. See the
[ex_bron_kerbosch_clique_number] for an example of its use.
The Bron-Kerbosch algorithm was originally developed to operate over adjacency
matrices representing /undirected graphs/. The algorithm can also be applied to
/directed graphs/ using a more restrictive definition of a connected subgraph.
A /directed clique/ is a maximally connected subgraph in which each pair of vertices
/u/ and /v/ are connected by the edges /(u, v)/ and /(v, u)/.
Although the algorithm can be used with adjacency list-based graph classes, it
will perform less efficiently than an adjacency matrix. Also, running this algorithm
on a directed graph will double the performance penalty (which is generally negligible).
[section [^bron_kerbosch_all_cliques()]]
#include <boost/graph/bron_kerbosch_all_cliques.hpp>
template <typename Graph, typename Visitor>
void bron_kerbosch_all_cliques(const Graph& g, Visitor vis)
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which cliques are being visited.
*Preconditions:* The indices of vertices in the graph must be
in the range \[0, `num_vertices(g)`).
*Requirements:* The `Graph` type must be a model of the [AdjacencyMatrix],
[IncidenceGraph] concept and the [VertexIndexGraph]
concepts[footnote Any `Graph` type that implements the `edge()`
function will satisfy the expression requirements for the
[AdjacencyMatrix], but may incur additional overhead due non-constant
time complexity.].
]
]
[
[required, in] [`Visitor vis`]
[
The visitor object to the algorithm.
*Requirements:* This `Visitor` class must model the
[CliqueVisitor] class.
]
]
[
[optional, in] [`std::size_t min`]
[
The minimum size of a clique to visit.
*Default:* 2 - the size of the smallest possible clique.
]
]
]
[heading Complexity]
This problem has a loose upper bound of ['O(2[sup n])] if one considers all possible
combinations of subsets of vertices as cliques (i.e., the powerset of vertices).
The original publication, however, approximates the runtime of the algorithm as
being proportional to ['O(3.14[sup n])].
Graphs that do not meet the constant-time requirements of the [AdjacencyMatrix]
concept will incur additional runtime costs during execution (usually by a linear
factor). Examples of such graphs include the [undirected_graph], [directed_graph],
and the [adjacency_list] classes.
Note that using the Bron-Kerbosch algorithm on directed graphs will doubles the
amount of time it takes to determine edge connection.
[endsect]
[section [^bron_kerbosch_clique_number()]]
#include <boost/graph/bron_kerbosch_all_cliques.hpp>
template <typename Graph, typename Visitor>
std::size_t bron_kerbosch_clique_number(const Graph& g)
The `bron_kerbosch_clique_number()` function returns the size of the largest
clique in a graph - its clique number.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which cliques are being visited.
*Preconditions:* The indices of vertices in the graph must be
in the range \[0, `num_vertices(g)`).
*Requirements:* The `Graph` type must be a model of the [AdjacencyMatrix],
[IncidenceGraph] concept and the [VertexIndexGraph]
concepts[footnote Any `Graph` typen that implements the `edge()`
function will satisfy the expression requirements for the
[AdjacencyMatrix], but may incur additional overhead due non-constant
time complexity.].
]
]
]
[heading Return]
The `bron_kerbosch_clique_number()` function returns the size of the largest
clique in the the graph `g`.
[heading Complexity]
The `bron_kerbosch_clique_number()` function has the same complexity as the
[bron_kerbosch_all_cliques] function.
[endsect]
[section Examples]
[heading Printing Cliques]
This example demonstrates how to find and print all the cliques in a graph.
[code_bron_kerbosch_print_cliques]
If given the input file `social_network.graph`, which represents the social network
pictured in Figure 1 of the
[link boost_graph.reference.algorithms.subgraph.bron_kerbosch_all_cliques.overview Overview],
the program will produce the following output:
[pre
Scott Jill Mary
Scott Bill
Scott Frank
Mary Laurie
Bill Josh
Josh Frank
Frank Laurie
Frank Anne Howard
]
[heading Clique Number]
This example demonstrates the use of the [bron_kerbosch_clique_number] example.
[code_bron_kerbosch_clique_number]
If given the input file `social_network.graph`, which represents the social network
pictured in Figure 1 of the
[link boost_graph.reference.algorithms.subgraph.bron_kerbosch_all_cliques.overview Overview],
the program will produce the following output:
[pre
clique number: 3
]
[endsect]
[endsect]

View File

@@ -1,302 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Closeness Centrality]
[template ex_closeness_centrality[] [link
boost_graph.reference.algorithms.measures.closeness_centrality.examples.closeness_centrality
Closeness Centrality Example]]
[template ex_scaled_closeness[] [link
boost_graph.reference.algorithms.measures.closeness_centrality.examples.scaled_closeness_centrality
Scaled Closeness Centrality Example]]
[heading Overview]
The /closeness centrality/ measure is commonly used in network analysis to identify
vertices (also called actors) that are "close" to all others. To phrase differently,
actors that are closer to all others have a greater reach, making them more
influential in the network. The closeness measure is defined as the inverse of the
sum of all geodesic distances (lengths of shortest paths) from one vertex to all
others (excluding itself) in the graph. Closeness is computed as:
[$images/eq/closeness.png]
Where /d(u,v)/ is the shortest path (geodesic distance) from /u/ to /v/.
Note that if any vertex in the graph is unreachable from any other, then distance
between those two unonnected vertices is infinite. This imlplies that the closeness
of that vertex is zero. If an undirected graph has unconnected components, then
all vertices will have a closeness of zero. This is not necessarily true for
unconnected directed graphs since some vertex might reach all others, but may
not itself be reachable by any others. An example of such a graph is a tree whose
direted edges from from the root toward the leaves.
Consider the following social network represented by an undirected graph in
Figure 1.
[figure
images/reference/social_network.png
*Figure 1.* A network of friends.
]
Computing the closeness for each person in the graph, we find that Frank is the
most central person in the network, with a closeness centrality of approximiately
0.091 (1/11). We also find that Jill, Mary, and Laurie are the least central
people in the network (with closeness centralities of .056 or 1/18). See the
[ex_closeness_centrality] for details on computing the closeness centralites of
undirected graphs.
The same measure can also be applied to directed graphs, but has dubious meaning
if the graph is not /strongly connected/. Consider the communication networks
between the friends listed above. For this graph, we connect two people /a/ and
/b/ if /a/ sends a text message to /b/ (for example).
[figure
images/reference/comm_network.png
*Figure 2.* Communications between friends.
]
In this network, Frank is once again the most central (with a closeness centrality
of 0.067) because he is "closer" to each of the various communication cycles in the
network. Laurie is the furthest removed, with a closeness centrality of .028.
In these examples, distance is defined as the number of "hops" in the shortest path
from one vertex to another. It should be noted, however, that distance can also be
represented as the sum of edge-weights on the shortest path between the two vertices.
The definition of distance for this measure is outside the scope of this computation.
This is to say that distance is defined and computed before closeness centrality
can be computed.
This framework also allows for a specialization of the measure through the use
of a function object. This measure defaults to the reciprocal in the equation
above, but can be easily redefined to perform alternative computations or, in
the case of non-trivial types, re-define the notion of reciprocal.
See the [ex_scaled_closeness] for an example of how to overload the
default measures used to compute closeness centrality.
[section [^closeness_centrality()]]
#include <boost/graph/closeness_centrality.hpp>
template <typename Graph, typename DistanceMap>
float closeness_centrality(const Graph& g, DistanceMap dm)
template <typename ResultType, typename Graph, typename DistanceMap>
ResultType closeness_centrality(const Graph& g, DistanceMap dm)
template <typename Graph, typename DistanceMap, typename Measure>
typename Measure::result_type
closeness_centrality(const Graph& g, DistanceMap dm, Measure m)
The `vertex_closeness_centrality()` function can be used to compute the closeness
centrality of a single vertex. This function requires a distance map that contains
the distance from one vertex (the source) to all others in the graph. This
distance map can be computed as the result of a "shortest paths" algorithm (e.g.,
[dijkstra_shortest_paths], [bellman_ford_shortest_paths], or [dag_shortest_paths]),
or recording distances from a [breadth_first_search].
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[template] [`ResultType`]
[
The `ResultType` template parmeter explitly specifies the the
return type of the `closeness()` function. If not
given, the return type is `float`.
*Requirements:* The return type is required to model the
[NumericValue] concept.
]
]
[
[required, in] [`const Graph& g`]
[
The graph for which vertex measures are being comptued.
*Requirements:* The `Graph` type must be a model of the
[VertexListGraph] concept.
]
]
[
[required, in] [`DistanceMap dm`]
[
Given a vertex `v`, the `dm` parameter provides the length of the
shortest path between a vertex `u` and `v`. The vertex `u` is the
vertex for which the distance map was initially computed.
*Requirements:* `DistanceMap` must be a model of [ReadablePropertyMap].
The `key_type` of the distance map must be the same as the `vertex_descriptor`
of the `Graph` parameter. The `value_type` is required to be a model of
[NumericValue].
]
]
[
[optional, in] [`Measure measure`]
[
The 'measure' parameter is an instance of a closeness measure that
performs the final operation (the reciprocal) for this computation.
*Requirements:* The `Measure` type must be a model of the [DistanceMeasure]
concept. The `distance_type` must be the same type as the `value_type`
of the `DistanceMap` or `DistanceMatrixMap`. The `result_type` of the
`Measure` must model the [NumericValue] concept.
]
]
]
[heading Return]
The `closeness_centrality()` function returns the closeness of a vertex.
If the source vertex is disconnected from any vertices in the graph, this value is 0.
[heading Complexity]
The `closeness_centrality()` function returns in ['O(n*O(M))]. This is linear by
default where /n/ is the number of vertices is in the graph and /O(M)/ is the
omplexity of the measure. If no measure is given, this function returns in linear
time.
[endsect]
[section [^all_closeness_centralities()]]
#include <boost/graph/closeness_centrality.hpp>
template <typename Graph, typename DistanceMatrixMap, typename ClosenessMap>
void all_closeness_centralities(const Graph& g, DistanceMatrixMap dm, ClosenessMap cm)
template <typename Graph, typename DistanceMatrixMap, typename ClosenessMap, typename Measure>
void all_closeness_centralities(const Graph& g, DistanceMatrixMap dm, ClosenessMap cm, Measure m)
This module defines a flexible framework for computing the closeness centrality
of vertices in a graph for previously computed geodesics by providing two generic
functions. The first function, `closeness_centrality()` computes the closeness of
each vertex in a graph given a matrix containing the distances between vertices.
This matrix can be computed as the output of an "all pairs shortest path" algorithm
(e.g, [floyd_warshall_all_pairs_shortest_paths] or [johnson_all_pairs_shortest_paths])
or as the result of a [breadth_first_search] (if the graph is unweighted).
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which closeness centrality values are being comptued.
*Requirements:* The `Graph` type must be a model of the
[VertexListGraph] concept.
]
]
[
[required, in] [`DistanceMatrixMap dm`]
[
Given vertices /u/ and /v/, the `dm` parameter provides the length
of the shortest path between the two vertices. Note that the
distance between a vertex and itself should be 0 (i.e., `dm[u][u] == 0`).
*Requirements:* `DistanceMatrixMap` must be a model of [ReadablePropertyMap].
The `key_type` of the distance matrixc must be the same as the `vertex_descriptor`
of the `Graph` parameter. The `value_type` must be a [ReadWritePropertyMap]
whose `key_type` is also the `vertex_descriptor` of the `Graph` and
whose `value_type` is a model of [NumericValue].
]
]
[
[required, out] [`ClosenessMap cm`]
[
The cm parameter stores the output of the computed closeness (or
distance) for each vertex in `g`.
*Requirements:* The type of `close` must be model the [WritablePropertyMap]
concepts. The `key_type` of the property map must be the same as the
`vertex_descriptor` of the `Graph`, and the `value_type` must be a model
of [NumericValue].
]
]
[
[optional, in] [`Measure measure`]
[
The 'measure' parameter is an instance of a closeness measure that
performs the final operation (the reciprocal) for this computation.
*Requirements:* The `Measure` type must be a model of the [DistanceMeasure]
concept. The `distance_type` must be the same type as the `value_type`
of the `DistanceMap` or `DistanceMatrixMap`. The `result_type` of the
`Measure` must model the [NumericValue] concept.
]
]
]
[heading Complexity]
The `all_closenesss_centralities()` function returns in ['O(n[sup 2]*O(M))] where /n/
is the number of vertices in the graph and /O(M)/ is the complexity of the distance
measure. If no distance measure is given, this functions returns in ['O(n[sup 2])]
time.
[endsect]
[section Examples]
[heading Closeness Centrality]
This example computes the closeness centrality for all vertices (people) a social
network such as the one pictured in Figure 1. The program also sorts the vertices by
their corresponding closeness in descending order. This example includes the
following files:
* [^examples/closeness_centrality.hpp]
* [^examples/helper.hpp]
[closeness_centrality_example]
If this program is given the `social_network.graph` file as input, the output
will be:
[pre
Scott 0.0833333
Jill 0.0588235
Mary 0.0625
Bill 0.0588235
Josh 0.0625
Frank 0.0909091
Laurie 0.0666667
Anne 0.0588235
Howard 0.0588235
]
Note that this program can be easily modified to work on directed graphs. In the
file `social_network.hpp`, simply replace `typedef undirected_graph<Actor> ...` to
`typedef directed_graph<Actor> ...`.
[heading Scaled Closeness Centrality]
In some literature, closeness is defined as the number of vertices divided by the
sum of distances, or more formally.
[$images/eq/scaled_closeness.png]
Where /n/ is the number of vertices in the graph. While this example demonstrates
the implementation of a [DistanceMeasure], the resulting value can be also
obtained by multiplying the default result by the number of vertices in the graph.
This example uses the following files:
* [^examples/scaled_closeness_centrality.hpp]
* [^examples/helper.hpp]
[scaled_closeness_centrality_example]
If given the same social network as input, the output of this program will be:
[pre
Scott 0.75
Jill 0.529412
Mary 0.5625
Bill 0.529412
Josh 0.5625
Frank 0.818182
Laurie 0.6
Anne 0.529412
Howard 0.529412
]
It is relatively easy to verify that each of these values is nine times the values
given in the previous example.
[endsect]
[endsect]

View File

@@ -1,199 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Clustering Coefficient]
[template ex_clustering_coefficient[] [link
boost_graph.reference.algorithms.measures.closeness_centrality.examples.closeness_centrality
Closeness Centrality Example]]
[heading Overview]
The /clustering coefficient/ is a measure used in network analysis to describe a
connective property of vertices. The clustering coefficient of a vertex gives the
probability that two neighbors of that vertex are, themselves, connected. In social
networks, this is often interpreted as the probability that a persons friends are
also friends.
This measure is derived from two different properties of a vertex /v/. The first is the
number of possible paths through that vertex. The number of paths through a vertex
can be counted as the number of possible ways to connect the neighbors (adjacent
vertices) of /v/. This number differs for directed and undirected graphs. For directed
graphs it is given as:
[$images/eq/num_paths_directed.png]
Where /d(v)/ is the out-degree of the vertex /v/. For undirected graphs:
[$images/eq/num_paths_undirected.png]
Note that for undirected graphs the out-degree of /v/ is the same as the degree
of /v/.
The second property is the number of triangles centered on the vertex /v/. Triangles
are counted as each pair of neighbors (adjacent vertices) /p/ and /q/ that are
connected (i.e., and edge exists between /p/ and /q/). Note that if /p/ and /q/
are connected, they form a distinct triangle /{v, p, q}/. For directed graphs, the
edges /(p, q)/ and /(q, p)/ can form two distinct triangles. The number of triangles
centered on a vertex is given as:
[$images/eq/num_triangles.png]
Where ['e[sub pq]] is an edge connecting vertices /p/ and /q/ in the edge set of
the graph. The clustering coefficient of the vertex is then computed as:
[$images/eq/clustering_coef.png]
Note that the clustering coefficient of a vertex /v/ is 0 if none of its neighbors
are connected to each other. Its clustering coefficient is 1 if all of its neighbors
are connected to each other.
The /mean clustering coefficient/ can be computed for the entire graph as quantification
of the /small-world property/. A graph is a small world property if its clustering
coefficient is significantly higher than a random graph over the same vertex set.
Consider the following social network represented by an undirected graph in
Figure 1.
[figure
images/reference/social_network.png
*Figure 1.* A network of friends.
]
Computing the clustering coefficient for each person in this network shows that
Frank has a clustering coefficient of 0.1. This implies that while Frank has many
friends, his friends are not necessarily friendly with each other. On the other
hand Jill, Anne, and Howard each have a value of 1.0, meaning that they enjoy
participation in a social clique.
The mean clustering coefficient of this graph is 0.4. Unfortunately, since the
graph is so small, one cannot determine whether or not this network does exhibit
the small-world property.
[section [^clustering_coefficient()]]
#include <boost/graph/clustering_coefficient.hpp>
template <typename Graph, typename Vertex>
float clustering_coefficient(const Graph& g, Vertex v)
template <typename ResultType, typename Graph, typename Vertex>
ResultType clustering_coefficient(const Graph& g, Vertex v)
The `clustering_coefficient()` function returns the clustering coefficient of
the given vertex. The second variant allows the caller to explicitly specify
the type of the clustering coefficient.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[template] [`ResultType`]
[
The `ResultType` template parmeter explitly specifies the the
return type of the function. If not given, the return type is `float`.
*Requirements:* The return type is required to model the [NumericValue]
concept.
]
]
[
[required, in] [`const Graph& g`]
[
The graph for which vertex measures are being comptued.
*Requirements:* The `Graph` type must be a model of the [IncidenceGraph],
[AdjacencyGraph] and [AdjacencyMatrix] concepts[footnote Any `Graph` type
that implements the `edge()` function will satisfy the expression requirements
for the [AdjacencyMatrix], but may incur additional overhead due non-constant
time complexity.].
]
]
]
[heading Return]
The `clustering_coefficient()` function returns the clustering coefficient of the
vertex. The return type is either `float` or the type specified by the user.
[heading Complexity]
The `clustering_coefficient()` function returns in ['O(d(v)[sup 2]] where
/d(v)/ is the degree of /v/.
[endsect]
[section [^all_clustering_cofficients()]]
#include <boost/graph/clustering_coefficient.hpp>
template <typename Graph, typename ClusteringMap>
typename property_traits<ClusteringMap>::value_type
all_clustering_coefficients(const Graph& g, ClusteringMap cm)
Compute the clustering coefficients for each vertex and return the mean clustering
coefficient to the caller.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which vertex measures are being comptued.
*Requirements:* The `Graph` type must be a model of the [VertexListGraph],
[IncidenceGraph], [AdjacencyGraph] and [AdjacencyMatrix] concepts[footnote Any
`Graph` type that implements the `edge()` function will satisfy the expression
requirements for the [AdjacencyMatrix], but may incur additional overhead due
non-constant time complexity.].
]
]
[
[required, in] [`ClusteringMap cm`]
[
The clustering map `cm` stores the clustering coefficient of each
vertex in the graph `g`.
*Requirements:* The `ClusteringMap` type must modelt the [WritablePropertyMap]
concept.
]
]
]
[heading Complexity]
The `all_clustering_coefficients()` function returns in ['O(nd[sup 2])] where
/d/ is the mean (average) degree of vertices in the graph.
[endsect]
[section [^num_paths_through_vertex()]]
[endsect]
[section [^num_triangles_on_vertex()]]
[endsect]
[section Examples]
[heading Clustering Coefficient]
This example computes both the clustering coefficient for each vertex in a graph and
the mean clustering coefficient for the graph, printing them to standard output.
[code_clustering_coefficient]
If this program is given the `social_network.graph` file as input which represents
the graph shown in the
[link boost_graph.reference.algorithms.measures.clustering_coefficient.overview Overview],
the output will be:
[pre
Scott 0.166667
Jill 1
Mary 0.333333
Bill 0
Josh 0
Frank 0.1
Laurie 0
Anne 1
Howard 1
mean clustering coefficient: 0.4
]
[endsect]
[endsect]

View File

@@ -1,94 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Connected Components]
template <class Graph, class ComponentMap, class P, class T, class R>
typename property_traits<ComponentMap>::value_type
connected_components(const Graph &g, ComponentMap c,
const bgl_named_params<P,T,R>& params = ``/defaults/``);
The connected_components() functions compute the connected components of an undirected
graph using a DFS-based approach. A connected component of an undirected graph is a
set of vertices that are all reachable from each other. If the connected components
need to be maintained while a graph is growing the disjoint-set based approach of
function `incremental_components()` is faster. For "static" graphs this DFS-based
approach is faster \[8\].
The output of the algorithm is recorded in the component property map, which will
contain numbers giving the component number assigned to each vertex. This algorithm
returns the total number of connected components in the graph.
[heading Where Defined]
`boost/graph/connected_components.hpp`
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[in] [`const Graph& g`]
[
The /undirected/ graph for which connected components are being found.
This graph must be a model of VertexListGraph and Incidence Graph.
]
]
[
[out] [`ComponentMap c`]
[
The algorithm computes how many connected components are in the graph,
and assigning each component an integer label. The algorithm then records
which component each vertex in the graph belongs to by recording the
component number in the component property map. The ComponentMap type
must be a model of WritablePropertyMap. The value type shouch be an
integer type, preferably the same as the `vertices_size_type` of the
graph. The key type must be the graph's `vertex_descriptor` type.
]
]
]
[heading Named Parameters]
[table
[[Type] [Parameter] [Description]]
[
[util] [`color_map(ColorMap color)`]
[
This is used by the algorithm to keep track of its progress through the
graph. The type ColorMap must be a model of ReadWritePropertyMap and
its key type must be the graph's `vertex_descriptor` type and the value
type of the color map must model ColorValue.
*Default* An `iterator_property_map` create from a `std::vector` of
`default_color_type` of size `num_vertices(g)` and using `index_map` as
the index map (to access colors for a vertex).
]
]
[
[in] [`vertex_index_map(VertexIndexMap index_map)`]
[
This maps each vertex to an integer in the range \[0, `num_vertices(g)`).
This parameter is only necessary when the default color property map is
used. The type VertexIndexMap must be a model of ReadablePropertyMap. The
value type of the map must be an integer type. The vertex descriptor type
of the graph needs to be usable as the key type of the map.
*Default* `get(vertex_index, g)`. Note if you use this default, make sure
that your graph has an interior `vertex_index` property. For example
`adjacency_list` with `VertexList=listS` does not have an interior
`vertex_index` property.
]
]
]
[heading Complexity]
This algorithm runs in /O(V + E)/.
[heading Notes]
This algorithm will not compile if passed a /directed/ graph.
[heading Examples]
[endsect]

View File

@@ -1,440 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Degree Centrality]
[template ex_degree_centrality[] [link
boost_graph.reference.algorithms.measures.degree_centrality.examples.degree_centrality
Degree Centrality Example]]
[template ex_influence_prestige[] [link
boost_graph.reference.algorithms.measures.degree_centrality.examples.influence_and_prestige
Influence and Prestige Example]]
[template degree_centrality_measures[] [link
boost_graph.reference.algorithms.measures.degree_centrality.measures
Measures Section]]
[heading Overview]
The /degree centrality/ measure is used in social network analysis to help
determine which vertices (or more specifically actors) are the most central
or important to a network. Degree centrality of a vertex is computed over the number
of connections (adjacent vertices) of that vertex. This definition varies for
undirected and directed graphs. For undirected graphs, the degree centrality of a
vertex is equivalent to its degree. For directed graphs it is equivalent to either
its in- or out-degree.
Consider the social network represented by an undirected graph in Figure 1.
[figure
images/reference/social_network.png
*Figure 1.* A network of friends.
]
This graph depicts a set of friends and their relationships (friendship, dating, etc.)
The degree centrality of each person in this graph is their number of friends.
Here, Frank has the highest degree centrality with five friends, whereas Laurie,
Jill, Bill, Anne, and Howard are the least central with two friends apiece. See
the [ex_degree_centrality] for details on computing the degree centrality of
undirected graphs.
For directed graphs, there are related two interpretations of degree centrality.
When degree centrality is measured over the out-degree of a vertex, it is called
/influence/. When the in-degree is measured, the measure is called /prestige/.
See the [degree_centrality_measures] for information types and functions related
to the computation of influence and prestige.
Consider the information network represented by the directed graph in Figure 2.
[figure
images/reference/info_network.png
*Figure 2.* A network of informational websites.
]
This graph represents links between information websites, presumably regarding a
specific topic. The most influential (out-degree centrality) is blogger with
three outgoing links while wikipedia is the least influential. The most prestigous
(in-degree centrality) is wikipedia with five incoming references. The least
prestigous websites are myspace, blogger, and blogspot each of which have no
incoming links. See the [ex_influence_prestige] for details on computing the
influence and prestige of directed graphs.
[section [^degree_centrality()]]
#include <boost/graph/degree_centrality.hpp>
template <typename Graph, typename Vertex>
typename graph_traits<Graph>::degree_size_type
degree_centrality(const Graph& g, Vertex v);
template <typename Graph, typename Vertex, typename Measure>
typename Measure::degree_type
degree_centrality(const Graph& g, Vertex v, Measure measure);
The `degree_centrality()` function computes this measure for a single vertex,
returning the value to the caller. Optionally, a degree measure can be given,
specializing the computation of degree centrality. See the [degree_centrality_measures]
section for more details on the influence and prestige measures.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& graph`]
[
The graph object for which the degree centralities will be computed.
*Requirements:* The `Graph` type must be a model of the [IncidenceGraph]
concept. If the `Measure` parameter is given as `prestige_measure`,
then the graph must be a model of the [BidirectionalGraph] concept.
]
]
[
[required, in] [`Vertex v`]
[
The vertex descriptor for which the degree centrality is computed.
*Requirements:* The `Vertex` type must be the same as the `vertex_descriptor`
of the `Graph` parameter.
]
]
[
[optional, in] [`Measure measure`]
[
The `measure` parameter allows the caller to override the default
computation of degree centrality for a vertex.
*Requirements:* The `Measure` type must be a model of the
[DegreeMeasure] concept. The `degree_type` of `Measure` must
be the same as the `value_type` of the `CentralityMap` type.
]
]
]
[heading Return Value]
The `degree_centrality()` function returns the centrality of a vertex.
If no `measure` parameter is given, the return type is the same as the
`degree_size_type` of the `Graph`. Otherwise, it is the `degree_type` of
the `Measure`.
[heading Complexity]
The `degree_centrality()` returns in /O(M)/. If the measure is not given,
or the measure is given as `influence_measure` or `prestige_measure`, this function
returns in constant time.
[endsect]
[section [^influence()]]
template <typename Graph, typename Vertex>
typename graph_traits<Graph>::degree_size_type
influence(const Graph& g, Vertex v);
The `influence()` function the influence of the vertex to the caller. The influence
of a vertex is the same as its out-degree.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& graph`]
[
The graph object for which the degree centralities will be computed.
*Requirements:* The `Graph` type must be a model of the [IncidenceGraph]
concept. If the `Measure` parameter is given as `prestige_measure`,
then the graph must be a model of the [BidirectionalGraph] concept.
]
]
[
[required, in] [`Vertex v`]
[
The vertex descriptor for which the degree centrality is computed.
*Requirements:* The `Vertex` type must be the same as the `vertex_descriptor`
of the `Graph` parameter.
]
]
]
[heading Return Value]
The `influence()` function returns the influence of the vertex, which is the same
as its out-degree.
[heading Complexity]
The `influence()` function returns in constant time.
[endsect]
[section [^prestige()]]
template <typename Graph, typename Vertex>
typename graph_traits<Graph>::degree_size_type
prestige(const Graph& g, Vertex v);
The `prestige()` function the prestige of the vertex to the caller. The prestige
of a vertex is the same as its in-degree.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& graph`]
[
The graph object for which the degree centralities will be computed.
*Requirements:* The `Graph` type must be a model of the [IncidenceGraph]
concept. If the `Measure` parameter is given as `prestige_measure`,
then the graph must be a model of the [BidirectionalGraph] concept.
]
]
[
[required, in] [`Vertex v`]
[
The vertex descriptor for which the degree centrality is computed.
*Requirements:* The `Vertex` type must be the same as the `vertex_descriptor`
of the `Graph` parameter.
]
]
]
[heading Return Value]
The `prestige()` function returns the influence of the vertex, which is the same
as its out-degree.
[heading Complexity]
The `prestige()` returns in constant time.
[endsect]
[section [^all_degree_centralities()]]
#include <boost/graph/degree_centrality.hpp>
template <typename Graph, typename CentralityMap>
void all_degree_centralities(const Graph& g, CentralityMap cent);
template <typename Graph, typename CentralityMap, typename Measure>
void all_degree_centralities(const Graph& g, CentralityMap cent, Measure measure);
The `all_degree_centralities()` computes the degree centrality for each vertex in the
graph, assigning the values to an output property map. Optionally, a degree measure
can be given, specializing the computation of degree centrality. See the
[degree_centrality_measures] section for more details on the influence and
prestige measures.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& graph`]
[
The graph object for which the degree centralities will be computed.
*Requirements:* The `Graph` type must model the [VertexListGraph]
and [IncidenceGraph] concepts. If the `Measure` parameter is given
as `prestige_measure`, then the graph must be a model of the
[BidirectionalGraph] concept.
]
]
[
[required, out] [`CentralityMap cent`]
[
The property map that contains the degree centralities of all vertices
in a graph after calling the `degree_centrality()` function.
*Requirements:* The `CentralityMap` type must be a model of the
[WritablePropertyMap] concept. The `key_type` of the map must
be the same as the `vertex_descriptor` of the `Graph` type. If the
`Measure` parameter is given in the call, then the `value_type`
of `CentralityMap` must be the same as `Measure::degree_type`.
Otherwise, the `value_type` must be the same as the `degree_size_type`
of the graph.
]
]
[
[optional, in] [`Measure measure`]
[
The `measure` parameter allows the caller to override the default
computation of degree centrality for a vertex.
*Requirements:* The `Measure` type must be a model of the
[DegreeMeasure] concept. The `degree_type` of `Measure` must
be the same as the `value_type` of the `CentralityMap` type.
]
]
]
[heading Complexity]
The `all_degree_centralities()` function returns in /O(n*O(M))/ where /n/ is the
number of vertices in the graph and /M/ is a measure of a vertex. If the measure
is not specified or is `influence_measure` or `prestige_measure`, this function
returns in linear time.
[endsect]
[section [^all_influence_values()]]
#include <boost/graph/degree_centrality.hpp>
template <typename Graph, typename CentralityMap>
void all_influence_values(const Graph& g, CentralityMap cent);
The `all_influence_values()` function computes the influence of each vertex in the
graph, assigning the values to an output property map.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& graph`]
[
The graph object for which the degree centralities will be computed.
*Requirements:* The `Graph` type must model the [VertexListGraph]
and [IncidenceGraph] concepts. If the `Measure` parameter is given
as `prestige_measure`, then the graph must be a model of the
[BidirectionalGraph] concept.
]
]
[
[required, out] [`CentralityMap cent`]
[
The property map that contains the degree centralities of all vertices
in a graph after calling the `degree_centrality()` function.
*Requirements:* The `CentralityMap` type must be a model of the
[WritablePropertyMap] concept. The `key_type` of the map must
be the same as the `vertex_descriptor` of the `Graph` type. If the
`Measure` parameter is given in the call, then the `value_type`
of `CentralityMap` must be the same as `Measure::degree_type`.
Otherwise, the `value_type` must be the same as the `degree_size_type`
of the graph.
]
]
]
[heading Complexity]
The `all_influence_values()` function returns linear time with respect to the
number of vertices in the graph.
[endsect]
[section [^all_prestige_values()]]
#include <boost/graph/degree_centrality.hpp>
template <typename Graph, typename CentralityMap>
void all_prestige_values(const Graph& g, CentralityMap cent);
The `all_prestige_values()` function computes the prestige of each vertex in the
graph, assigning the values to an output property map.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& graph`]
[
The graph object for which the degree centralities will be computed.
*Requirements:* The `Graph` type must model the [VertexListGraph]
and [IncidenceGraph] concepts. If the `Measure` parameter is given
as `prestige_measure`, then the graph must be a model of the
[BidirectionalGraph] concept.
]
]
[
[required, out] [`CentralityMap cent`]
[
The property map that contains the degree centralities of all vertices
in a graph after calling the `degree_centrality()` function.
*Requirements:* The `CentralityMap` type must be a model of the
[WritablePropertyMap] concept. The `key_type` of the map must
be the same as the `vertex_descriptor` of the `Graph` type. If the
`Measure` parameter is given in the call, then the `value_type`
of `CentralityMap` must be the same as `Measure::degree_type`.
Otherwise, the `value_type` must be the same as the `degree_size_type`
of the graph.
]
]
]
[heading Complexity]
The `all_prestige_values()` function returns linear time with respect to the
number of vertices in the graph.
[endsect]
[section Measures]
template <typename Graph> struct influence_measure;
template <typename Graph> struct prestige_measure;
template <typename Graph>
influence_measure<Graph> measure_influence(const Graph&);
template <typename Graph>
prestige_measure<Graph> measure_prestige(const Graph&);
These functions in this module can be specialized throught the use of different
/measure/ functors. These funtors are called to compute the degree centraltiy of a
vertex within the computational framework. This module provides the two default
measures for /influence/ and /prestige/ and functions to help instantiate them.
Custom measures can also be used.
The `influence_measure` returns the out-degree of a vertex. Using this measure
requires the `Graph` to model the [IncidenceGraph] concept.
The `prestige_measure` returns the in-degree of a vertex. Using this measure
requires the `Graph` to model the [BidirectionalGraph] concept.
The `measure_influence()` and `measure_prestige()` functions can be used to
create the corresponding measure objects.
[endsect]
[section Examples]
[heading Degree Centrality]
This example reads a graph from standard input (in a simple edge-list format),
computes the degree-centrality of each vertex, and prints them to standard
output. This example includes of the following files:
* [^examples/degreee_centrality.hpp]
* [^examples/helper.hpp]
[degree_centrality_example]
If given the `social_network.graph` file as input, the program will produce the
following output:
[pre
Scott: 4
Jill: 2
Mary: 2
Bill: 2
Josh: 2
Frank: 5
Laurie: 1
Anne: 2
Howard: 2
]
[heading Influence and Prestige]
This example is nearly identical to the previous in that it computes the degree
centrality over vertices in a graph. However, this example constructs a directed
graph and computes both influence and prestige. This example consist of the following
files:
* [^examples/influence_prestige.hpp]
* [^examples/helper.hpp]
[influence_prestige_example]
If given the `info_network.graph` file as input, the program will produce
the following output where the second column is influence and the third is prestige:
[pre
myspace 1 0
digg 2 2
blogger 3 0
slahsdot 0 1
wikipedia 0 5
slashdot 2 2
blogspot 2 0
bbc 1 1
]
[endsect]
[endsect]

View File

@@ -1,161 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Depth-First Search]
template <class Graph, class P, class T, class R>
void
depth_first_search(Graph& g,
bgl_named_params<P,T,R>& params = ``/defaults/``)
template <class Graph, class Visitor, class ColorMap>
void
depth_first_search(Graph& g,
Visitor vis,
ColorMap color,
typename graph_traits<Graph>::vertex_descriptor s)
The `depth_first_search()` function performs a depth-first traversal of the vertices
in a directed graph. When possible, a depth-first traversal chooses a vertex adjacent
to the current vertex to visit next. If all adjacent vertices have already been
discovered, or there are no adjacent vertices, then the algorithm backtracks to the
last vertex that had undiscovered neighbors. Once all reachable vertices have been
visited, the algorithm selects from any remaining undiscovered vertices and continues
the traversal. The algorithm finishes when all vertices have been visited. Depth-first
search is useful for categorizing edges in a graph, and for imposing an ordering on the
vertices. Section /Depth-First Search/ describes the various properties of DFS and
walks through an example.
Similar to BFS, color markers are used to keep track of which vertices have been
discovered. White marks vertices that have yet to be discovered, gray marks a
vertex that is discovered but still has vertices adjacent to it that are undiscovered.
A black vertex is discovered vertex that is not adjacent to any white vertices.
The `depth_first_search()` function invokes user-defined actions at certain event-points
within the algorithm. This provides a mechanism for adapting the generic DFS algorithm
to the many situations in which it can be used. In the pseudo-code below, the event
points for DFS are indicated in by the triangles and labels on the right. The user-defined
actions must be provided in the form of a visitor object, that is, an object whose type
meets the requirements for a [DFSVisitor]. In the pseudo-code we show the algorithm
computing predecessors /p/, discovery time /d/ and finish time /t/. By default, the
`depth_first_search()` function does not compute these properties, however there are
pre-defined visitors such as [predecessor_recorder] and [time_stamper] that
can be used to do this.
[pre
DFS(G)
for each vertex u in V initialize vertex u
color\[u\] := WHITE
p\[u\] = u
end for
time := 0
if there is a starting vertex s
call DFS-VISIT(G, s) start vertex /s/
for each vertex u in V
if color\[u\] = WHITE start vertex /u/
call DFS-VISIT(G, u)
end for
return (p,d_time,f_time)
DFS-VISIT(G, u)
color\[u\] := GRAY discover vertex /u/
d_time\[u\] := time := time + 1
for each v in Adj\[u\] examine edge /(u,v)/
if (color\[v\] = WHITE) /(u,v)/ is a tree edge
p\[v\] = u
call DFS-VISIT(G, v)
else if (color\[v\] = GRAY) /(u,v)/ is a back edge
...
else if (color\[v\] = BLACK) /(u,v)/ is a cross or forward edge
...
end for
color\[u\] := BLACK finish vertex /u/
f_time\[u\] := time := time + 1
]
[heading Where Defined]
`boost/graph/depth_first_search.hpp`
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[in] [`Graph& g`]
[
A directed or undirected graph. The graph type must be a model of [VertexListGraph]
and [IncidenceGraph].
]
]
[
[in] [`vertex_descriptor s`]
[
This specifies the vertex that the depth-first search should originate from. Note
that this can also be given as a named parameter.
]
]
]
[heading Named Parameters]
[table
[[Type] [Parameter] [Description]]
[
[in] [`visitor(Visitor vis)`]
[
A visitor object that is inovked inside the algorithm at event points specified by the
[DFSVisitor]. The `vis` object must be model the [DFSVisitor] concept.
*Default* `bfs_visitor<null_visitor>`.
]
]
[
[in] [`root_vertex(vertex_descriptor s)`]
[
This specifies the vertex that the depth-first search should originate from.
*Default* `*vertices(g).first`
]
]
[
[in] [`vertex_index_map(VeretxIndexMap index_map)`]
[
This maps each vertex to an integer in the range \[0, `num_vertices(g)`).
This parameter is only necessary when the default color property map is
used. The type VertexIndexMap must be a model of ReadablePropertyMap. The
value type of the map must be an integer type. The vertex descriptor type
of the graph needs to be usable as the key type of the map.
*Default* `get(vertex_index, g)`. Note if you use this default, make sure
that your graph has an interior `vertex_index` property. For example
`adjacency_list` with `VertexList=listS` does not have an interior
`vertex_index` property.
]
]
[
[util] [`color_map(ColorMap color)`]
[
This is used by the algorithm to keep track of its progress through the
graph. The type ColorMap must be a model of ReadWritePropertyMap and
its key type must be the graph's `vertex_descriptor` type and the value
type of the color map must model ColorValue.
*Default* An `iterator_property_map` create from a `std::vector` of
`default_color_type` of size `num_vertices(g)` and using `index_map` as
the index map (to access colors for a vertex).
]
]
]
[heading Complexity]
The time complexity is /O(E + V)/.
[heading Example]
[endsect]

View File

@@ -1,779 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Directed Graph]
This section provides detailed information about the `directed_graph` class,
its associated types, member functions and non-member interface. A directed
graph is one in which edges have distinct direction. Edges flow from a /source/
vertex to a /target/ and are generally only traversed through the outgoing
edges of a vertex. However, incoming edges are also accessible. The class
provides a general purpose implementation of directed graphs and can be
used with algorithms in the Boost Graph Library.
[h4 Notation]
The following notation is used in this documentation. The following type names
are generally meant to mean the following:
[table
[[Used Type] [Actual Type]]
[
[`directed_graph`]
[
`directed_graph<VP,EP,GP>` where `VP`, `EP` and `GP` are template
arguments that correspond to user-defined or default verex properties,
edge properties, and graph properties.
]
]
[
[`vertex_descriptor`]
[`directed_graph<VP,EP,GP>::vertex_descriptor`]
]
[
[`edge_descriptor`]
[`directed_graph<VP,EP,GP>::edge_descriptor`]
]
[
[`vertex_iterator`]
[`directed_graph<VP,EP,GP>::vertex_iterator`]
]
[
[`edge_iterator`]
[`directed_graph<VP,EP,GP>::edge_iterator`]
]
]
Moreover, objects with the following names are generally expected to have the
following types.
[table
[[Object Name] [Type]]
[[`g`] [`directed_graph`]]
[[`u`, `v`] [`vertex_descriptor`]]
[[`e`] [`edge_descriptor`]]
[[`i`] [`vertex_iterator` or `edge_iterator`]]
[[`p`] [A property tag (usually a template parameter)]]
[[`d`] [A vertex or edge descriptor (usually a template parameter)]]
[[`v`] [The value of a property (usually a template parameter)]]
]
[h4 Descriptor and Iterator Stability]
With the `directed_graph` class, descriptors and iterators remain stable after
all operations except descriptors and iterators to those edges or vertices being
removed. Removing a vertex or edge will not invalidate descriptors or iterators
referencing other vertices or edges.
For example, consider the following code:
directed_graph<> g;
directed_graph<>::vertex_descriptor u = add_vertex(g);
directed_graph<>::vertex_descriptor v = add_vertex(g);
directed_graph<>::vertex_descriptor w = add_vertex(g);
remove_vertex(u);
add_edge(v, w, g);
After running this program, the descriptor `u` will be invalid but `v` and `w` will
still be valid so the call to `add_edge(v,w,g)` is also valid. Note that this
property does not hold for all graph types.
[h4 Vertex Indexing and Stability]
The `directed_graph` class provides a built-in internal properties for vertex
types, and will provide some degree of automated index management. Algorithms
that use vertex indices generally assume that they are in the range
\[0, `num_vertices(g)`). With the `directed_graph` class vertex indices will
be in this continuous range until a vertex is removed from the graph. This is
the only operation that invalidates vertex indices, but the vertices will need
to be renumbered using the `renumber_vertex_indices()` function.
The `remove_vertex_and_renumber_indices(vi,g)` function can be used to autmoatically
renumber indices after removing the vertex referenced by the given iterator. Because
this function runs in linear time, it should not be used for repeated removals.
[h4 Template Parameters]
There are three parameters to the `directed_graph` class.
[table
[[Parameter] [Description] [Default]]
[
[`VertexProperties`]
[Specifies internal properties for vertices of the graph.]
[`no_property`]
]
[
[`EdgeProperties`]
[Specifies internal properties for edges of the graph.]
[`no_property`]
]
[
[`GraphProperties`]
[Specifies internal properties for the graph itself.]
[`no_property`]
]
]
[h5 Model Of]
[IncidenceGraph], [VertexListGraph], [EdgeListGraph], [AdjacencyGraph],
[MutableGraph], and [PropertyGraph].
[h5 Where Defined]
`boost/graph/directed_graph.hpp`
[h4 Associated Types]
There are a number of useful types associated with the `directed_graph` class.
Most of these are accessed through [graph_traits] or other template classes.
For convenience these types have been grouped by purpose.
[h5 Descriptor Types]
[table
[[Type] [Description]]
[
[`graph_traits<directed_graph>::vertex_descriptor`]
[
The type for the vertex descriptors associated with the graph. The `vertex_descriptor`
models the [Descriptor] and [NoConcept Hashable] concepts.
]
]
[
[`graph_traits<directed_graph>::edge_descriptor`]
[
The type for the edge descriptors associated with the graph. The `edge_descriptor`
models the [Descriptor] and [NoConcept Hashable] concepts.
]
]
]
Note that edge and vertex descriptors for the `unsigned_graph` can be used as keys for both
[SgiSortedAssociativeContainer]s and [SgiHashedAssociativeContainer]s such as `std::map` and
`std::tr1::unordered_map` respectively.
[h5 Iterator Types]
[table
[[Type] [Description]]
[
[`graph_traits<directed_graph>::vertex_iterator`]
[
The type for iterators returned by `vertices()`. Verex iterators are
models of the [SgiBidirectionalIterator] concept.
]
]
[
[`graph_traits<directed_graph>::edge_iterator`]
[
The type for iterators returned by `edges()`. Edge iterators are
models of the [SgiBidirectionalIterator] concept.
]
]
[
[`graph_traits<directed_graph>::out_edge_iterator`]
[
The type for iterators returned by `out_edges()`. Out-edge iterators
are models of the [SgiBidirectionalIterator] concept.
]
]
[
[`graph_traits<directed_graph>::in_edge_iterator`]
[
The type for iterators returned by `in_edges()`. In-edge iterators
are models of the [SgiBidirectionalIterator] concept.
]
]
[
[`graph_traits<directed_graph>::adjacency_iterator`]
[
The type for iterators returned by `adjacent_vertices`. Adjacency
iterators are models of the [SgiBidirectionalIterator] concept.
]
]
]
[h5 Miscellaneous Types]
[table
[[Type] [Description]]
[
[`graph_traits<directed_graph>::vertices_size_type`]
[The type used for dealing with the number of vertices in the graph.]
]
[
[`graph_traits<directed_graph>::edge_size_type`]
[The type used for dealing with the number of edges in the graph.]
]
[
[`graph_traits<directed_graph>::degree_size_type`]
[The type used for dealing with the number of edges incident to a vertex in the graph.]
]
[
[`directed_graph::vertex_index_type`]
[The integral type representing vertex indices (generally `unsigned int`).]
]
[
[
`property_map<directed_graph, Property>::type`
`property_map<directed_graph, Property>::const_type`
]
[
The property map type for vertex or edge properties in the graph. The specific
property is specified by the `Property` template argument, and must match one of
the properties specified in the `VertexProperties` or `EdgeProperties` for the
graph.
]
]
[
[`graph_property<directed_graph, Property>::type`]
[
The value type for the graph property specified by the `Property` parameter.
`Property` must be one of the types in the `GraphProperties` template argument.
]
]
[
[`graph_traits<directed_graph>::directed_category`]
[
This is always `bidirectional_tag`, indicating that the graph supports in- and
out-edge operations.
]
]
[
[`graph_traits<directed_graph>::edge_parallel_category`]
[
This is always `allow_parallel_edges_tag`, indicating that multiple edges
may be added between two vertices (i.e., graphs can be /multigraphs/).
]
]
]
[h4 Member Functions]
[table
[[Function] [Description]]
[
[
``
directed_graph(const GraphProperties& p = GraphProperties())
``
]
[The default constructor creates a graph with no vertices or edges.]
]
[
[
``directed_graph(const directed_graph& g)
``
]
[The copy constructor creates a copy of the given graph `g`.]
]
[
[
``
directed_graph(vertices_size_type n,
const GraphProperties& p = GraphProperties())
``
]
[The default constructor creates a graph with `n` vertices and no edges.]
]
[
[
``directed_graph& operator =(const directed_graph& g)
``
]
[Copies the edges and vertices of the graph `g`.]
]
]
[h4 Non-member Functions]
[h5 Non-member Accessors]
[table
[[Function] [Description]]
[
[
``
std::pair<vertex_iterator, vertex_iterator>
vertices(const directed_graph& g)
``
]
[Returns an iterator range providing access to the vertex list of `g`.]
]
[
[
``
std::pair<edge_iterator, edge_iterator>
edges(const directed_graph& g)
``
]
[Returns an iterator range providing access to the edge list of `g`.]
]
[
[
``
std::pair<out_edge_iterator, out_edge_iterator>
out_edges(vertex_descriptor v,
const directed_graph& g)
``
]
[
Returns an iterator range providing access to the out-edges of
vertex `v` in the graph `g`.
]
]
[
[
``
std::pair<in_edge_iterator, in_edge_iterator>
in_edges(vertex_descriptor v,
const directed_graph& g)
``
]
[
Returns an iterator range providing access to the in-edges of
vertex `v` in the graph `g`.
]
]
[
[
``
std::pair<adjacency_iterator, adjacency_iterator>
adjacent_vertices(vertex_descriptor v,
const directed_graph& g)
``
]
[
Returns an iterator range providing access to the adjacenct vertices
of vertex `v` in the graph `g`. Note that this is functionally
equivalent to iterating over the targets of all out-edges of `v`.
]
]
[
[
``
vertices_size_type
num_vertices(const directed_graph& g)
``
]
[Returns the number of vertices in the graph `g`.]
]
[
[
``
edge_size_type
num_edges(const directed_graph& g)
``
]
[Returns the number of edges the graph `g`.]
]
[
[
``
degree_size_type
degree(vertex_descriptor v,
const directed_graph& g)
``
]
[
Returns the total degree of vertex `v` in the graph `g`. This is
functionally equivalent `out_degree(v,g) + in_degree(v,g)`.
]
]
[
[
``
degree_size_type
out_degree(vertex_descriptor v,
const directed_graph& g)
``
]
[
Returns the out-degree of vertex `v` in the graph `g`. In an
`directed_graph` this is equal to `in_degree(v, g)`.
]
]
[
[
``
degree_size_type
in_degree(vertex_descriptor v,
const directed_graph& g)
``
]
[
Returns the in-degree of vertex `v` in the graph `g`. In an
`directed_graph` this is equal to `out_degree(v, g)`.
]
]
[
[
``
vertex_descriptor
vertex(vertices_size_type n
const directed_graph& g)
``
]
[
Returns the /nth/ vertex in the graph `g`. With directed graphs,
this method is /O(n)/. As such its use with this type of graph is
discouraged.
]
]
[
[
``
std::pair<edge_descriptor, bool>
edge(vertex_descriptor u,
vertex_descriptor v,
const directed_graph& g)
``
]
[
If the edge /(u,v)/ is in `g`, then this function returns the
descriptor for the edge connecting `u` and `v` with boolean value
set to `true`. Otherwise, the boolean value is `false` and the
edge descriptor is invalid.
]
]
[
[
``
vertex_size_type
get_vertex_index(vertex_descriptor v,
const directed_graph& g)
``
]
[
Returns the vertex index of the given vertex descriptor v. Note
that indices are /not/ required to be in the range \[0, `num_vertices(g)`).
This function is an alias for `get(vertex_index,g,v)`.
]
]
[
[
``
vertex_size_type
max_vertex_index(vertex_descriptor v,
const directed_graph& g)
``
]
[
Returns the vertex index of the given vertex descriptor v. Note
that indices are /not/ required to be in the range \[0, `num_vertices(g)`).
This function is an alias for `get(vertex_index,g,v)`.
]
]
]
[h5 Non-member Modifiers]
[table
[[Function] [Description]]
[
[
``
vertex_descriptor
add_vertex(directed_graph& g)
``
]
[Adds a vertex to `g` and returns a descriptors for the new vertex.]
]
[
[
``
void
clear_vertex(vertex_descriptor v,
directed_graph& g)
``
]
[
Removes all in- and out-edges of `v`, but leaves `v` in the graph `g`.
This is functioanlly equivalent to invoking `remove_edge()` on all
in- or out-edges of `v`, invalidating descriptors and iterators that
reference edges incident to `v`.
]
]
[
[
``
void
clear_out_edges(vertex_descriptor v,
directed_graph& g)
``
]
[
Removes all out-edges from vertex `v`, but does not remove the vertex
itself. This is functionally equivalent to calling `remove_edge()` for
all out-edges of `v`, invalidating any descriptors and iterators that
reference edges incident to that vertex.
]
]
[
[
``
void
clear_in_edges(vertex_descriptor v,
directed_graph& g)
``
]
[
Removes all in-edges from vertex `v`, but does not remove the vertex
itself. This is functionally equivalent to calling `remove_edge()` for
all in-edges of `v`, invalidating any descriptors and iterators that
reference edges incident to that vertex.
]
]
[
[
``
vertex_descriptor
remove_vertex(vertex_descriptor v,
directed_graph& g)
``
]
[
Removes vertex `v` from the graph `g`. It is assumed that `v` has no
incident edges before removal. To ensure this is, call `clear_vertex(v, g)`
before removing it.
Assuming that the vertex indices were in the range \[0, `num_vertices(g)`)
before calling this method, this operation will invalidate all vertex indices
in the range (vertex_index(v, g), `num_vertices(g)`), requiring indices to
be renumbered using the `renumber_vertex_indices(g)` method. If possible,
prefer to remove groups of vertices at one time before renumbering since
renumbering is a /O(n)/ time operation.
]
]
[
[
``
void
remove_vertex_and_renumber_indices(vertex_iterator i,
directed_graph& g)
``
]
[
Removes the vertex indicated by the iterator `i` from the graph `g`. Like
the `remove_vertex(v,g)` function, it is expected that `*i` have no
incident edges at the time of removal.
As indicated by the name, this method will also renumber vertex indices
after the removal of `*i`. This operation iterates over vertices after
`i`, decrementing their index by 1. If your program removes several
vertices at once, prefer to call several `remove_vertex(v,g)` methods,
followed by `renumber_vertices(g)` before using `g` in an algorithm.
]
]
[
[
``
void
renumber_vertex_indices(directed_graph& g)
``
]
[
Renumbers all interior vertex indices such that each vertex has an index
in the range \[0, `num_vertices(g)`). Generally, this function needs to
be called after removing vertices and before invoking different graph
algorithms.
]
]
[
[
``
std::pair<edge_descriptor, bool>
add_edge(vertex_descriptor u,
vertex_descriptor v,
directed_graph& g)
``
]
[
Adds the edge /(u,v)/ to the graph and returns a descriptor for the new
edge. For `directed_graph`s, the boolean value of the pair will always
be true.
]
]
[
[
``
void
remove_edge(vertex_descriptor u,
vertex_descriptor v,
directed_graph& g)
``
]
[
Removes the edge /(u,v)/from the graph. This operation invalidates any
descriptors or iterators referencing the edge. Note that `u` and `v` must
be valid descriptors and /(u,v)/ must be in the graph. If `g` is a multigraph
(with multiple edges between /(u,v)/, this mehtod will cause the removal of
all such edges connecting `u` and `v`.
]
]
[
[
``
void
remove_edge(edge_descriptor e,
directed_graph& g)
``
]
[
Removes the edge `e` from the graph. If multuple edges exist from
/(`source(e,g)`, `target(e,g)`)/, then this method will remove only
the single, specified edge.
]
]
[
[
``
void
remove_edge(out_edge_iterator i,
directed_graph& g)
``
]
[
This is functionally equivalent to `remove_edge(*i, g)`.
]
]
[
[
``
void
remove_edge_if(Predicate p,
directed_graph& g)
``
]
[
Removes all edges from the graph that satisfy `predicate`. That is, if
`p()` returns true when applied to an edge, then that edge is removed.
The affect on descriptor and iterator is the same as that of invoking
`remove_edge()` for on each of the removed vertices.
]
]
[
[
``
template <class Predicate>
void
remove_out_edge_if(vertex_descriptor v,
Predicate p,
directed_graph& g)
``
]
[
Removes all edges out-edges from vertex`v` that satisfy `predicate`.
That is, if `p()` returns true when applied to an edge, then that edge
is removed. The affect on descriptor and iterator is the same as that
of invoking `remove_edge()` for on each of the removed vertices.
]
]
[
[
``
template <class Predicate>
void
remove_in_edge_if(vertex_descriptor v,
Predicate p,
directed_graph& g)
``
]
[
Removes all edges in-edges from vertex`v` that satisfy `predicate`.
That is, if `p()` returns true when applied to an edge, then that edge
is removed. The affect on descriptor and iterator is the same as that
of invoking `remove_edge()` for on each of the removed vertices.
]
]
]
[h5 Proprety Map Acessors]
[table
[[Function] [Description]]
[
[
``
template <class Property>
property_map<directed_graph, Property>::type
get(Property, directed_graph& g)
``
``
template <class Property>
property_map<directed_graph, Property>::const_type
get(Property, const directed_graph& g)
``
]
[
Returns the property map object for the vertex property specified by the
type `Property`. This type must match one of the properties specified in
the `VertexProperties` template argument.
]
]
[
[
``
template <class Property, class Descriptor>
typename
property_traits<
property_map<directed_graph, Property>::const_type
>::value_type
get(Property,
const directed_graph& g,
Descriptor d)
``
]
[
Returns the property value specified by the type `Property` for either
the `vertex_descriptor` or `edge_descriptor` denoted by `d`.
]
]
[
[
``
template <class Property, class Descriptor, class Value>
void
put(Property,
const directed_graph& g,
Descriptor d,
Value v)
``
]
[
Sets the property value denoted by the type `Property` for either edge
or vertex descriptor `d` to the given value `v`.
]
]
[
[
``
template <class GraphProprety>
typename graph_property<directed_graph, GraphProperty>::type&
get_property(directed_graph& g, GraphProperty)
``
``
template <class GraphProprety>
const typename graph_property<directed_graph, GraphProperty>::type&
get_property(const directed_graph& g, GraphProperty)
``
]
[
Returns the graph property specified by the type `GraphProperty` for
the graph `g`.
]
]
[
[
``
template <class GraphProprety, class Value>
void
set_property(const directed_graph& g, GraphProperty, Value v)
``
]
[
Sets the graph proeprty specified by the type `GraphProperty` to
the given value `v`. Note that `GraphProperty` must be one of
the properties in the `GraphProperties` template argument.
]
]
]
[h4 Rationale]
Unlike most graph classes in Boost.Graph, the `directed_graph` does not model the
[MutablePropertyGraph] concept. The reason for this is that it is relatively
difficult from a usability standpoint to easily deduce the type to be passed as a
property when adding vertices and edges - but especially vertices.
[endsect]

View File

@@ -1,99 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Distance Recorder]
template <class DistanceMap, class EventTag>
class distance_recorder;
This is an [EventVisitor] that records the distance of a vertex (using a property
map) from some source vertex during a graph search. When applied to edge /e = (u,v)/,
the distance of /v/ is recorded to be one more than the distance of /u/. The distance
recorder is typically used with the `on_tree_edge` or `on_relax_edge` events, and cannot
be used with vertex events.
The [distance_recorder] class can be used with graph algorithms by wrapping it with
the algorithm specific adaptor, such as [bfs_visitor] and [dfs_visitor]. Also,
this event visitor can be combined with other event visitors using `std::pair` to form
an [EventVisitorList].
[h4 Model Of]
[EventVisitor]
[h4 Where Defined]
`boost/graph/visitors.hpp`
[h4 Template Parameters]
[table
[[Parameter] [Description] [Default]]
[
[`DistanceMap`]
[
A [WritablePropertyMap] where the key type is of type `vertex_descriptor`
and the value type is numeric (usually an integer or the same type as the
edge weight).
]
]
[
[`EventTag`]
[
A tag used to specify when the recorder should be applied during the graph
algorithm. `EventTag` must be an edge event.
]
]
]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`distance_recorder::event_filter`]
[
This type will be the same as the template parameter `EventTag`.
]
]
]
[h4 Member Functions]
[table
[[Function] [Description]]
[
[`distance_recorder(DistanceMap pa)`]
[Construct a distance recorder object with a predecessor property map `pa`.]
]
[
[
``
template <class Edge, class Graph>
void operator()(Edge e, const Graph& g)
``
]
[
Given edge `e` as /(u,v)/, this records the distance of `v` as one
plus the distance of `u`.
]
]
]
[h4 Non-Member Functions]
[table
[[Function] [Description]]
[
[
``
template <class DistanceMap, class EventTag>
distance_recorder<DistanceMap, EventTag>
record_distances(DistanceMap pa, EventTag)
``
]
[
A convenience function for creating [distance_recorder] instances.
]
]
]
[endsect]

View File

@@ -1,337 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Eccentricity]
[template ex_eccentricity[] [link
boost_graph.reference.algorithms.measures.eccentricity.examples.eccentricity__radius__and_diameter
Eccentricity Example]]
[heading Overview]
The /eccentricity/ of a vertex is the maximum geodesic distance (shortest path) from
that vertex to any other vertex in the graph. Intuitively, vertices with low
eccentricity can reach all other vertices in the graph more "quickly" than vertices
with high eccentricity. Eccentricity values are used to help compute the /radius/ and
/diameter/.
Note that if vertex /u/ is disconnected from any other vertex /v/ the distance from
/u/ to /v/ is infinite. This implies the eccentricity of /v/ is infinite as well.
If any vertex in a graph has infinite eccentricity, the graph also has an infinite
diameter.
Consider the following social network represented by an undirected, unweighted
graph.
[figure
images/reference/social_network.png
*Figure 1.* A network of friends
]
Because the graph is small and relatively well, connected the eccentricies are
exaclty 2 or 3 for all vertices. The radius (the smaller of these numbers)
is 2, and the diameter is 3. See the [ex_eccentricity] for details on computing
eccentricity and related measures.
[section [^eccentricity()]]
#include <boost/graph/eccentricity.hpp>
template <typename Graph, typename DistanceMap>
typename property_traits<DistanceMap>::value_type
eccentricity(const Graph& g, DistanceMap dm)
The `eccentricity()` function computes the eccentricty of a single vertex
given the shortest paths to every other vertex in the graph. The distance map can
be computed using a shortest paths algorithms (e.g., [dijkstra_shortest_paths] or a
[breadth_first_search]. The output of this function is returned to the caller.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which the eccentricity measures are being comptued.
*Requirements:* The `Graph` type must be a model of the
[VertexListGraph] concepts.
]
]
[
[required, in] [`DistanceMap dm`]
[
Given a vertex `v`, the `dm` parameter provides the length of the
shortest path between a vertex `u` and `v`. The vertex `u` is the
vertex for which the distance map was initially computed.
*Requirements:* `DistanceMap` must be a model of [ReadablePropertyMap].
The `key_type` of the distance map must be the same as the `vertex_descriptor`
of the `Graph` parameter. The `value_type` is required to be a model of
[NumericValue].
]
]
]
[heading Return Value]
The `eccentricity()` function returns the eccentricity of the vertex. If the graph
is unconnected, this returns the infinite value of the distance map's `value_type`.
[heading Complexity]
The `eccentricity()` returns in linear with respect to the number of vertices
in the graph.
[endsect]
[section [^eccentricities()]]
#include <boost/graph/eccentricity.hpp>
template <typename Graph, typename DistanceMatrixMap, typename EccentricityMap>
std::pair<typename property_traits<EccentricityMap>::value_type,
typename property_traits<EccentricityMap>::value_type>
eccentricity(const Graph& g, DistanceMatrixMap dm, EccentricityMap em)
The `eccentricities()` function computes the eccentricity of each vertix in the graph,
given a matrix that provides the shortest paths between all pairs of vertices. This
matrix can be computed as the output of an all-pairs shortest paths algorithm (e.g., [floyd_warshall_all_pairs_shortest_paths]) or repeated application of a
[breadth_first_search] (if the graph is unweighted). Theoutput of this function is
stored in the eccentricity property map.
This function also computes the radius and diameter of the graph, returning those
values in a pair.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which the eccentricity measures are being comptued.
*Requirements:* The `Graph` type must be a model of the
[VertexListGraph] concepts.
]
]
[
[required, in] [`DistanceMatrixMap dm`]
[
Given vertices /u/ and /v/, the `dm` parameter provides the length
of the shortest path between the two vertices. Note that the
distance between a vertex and itself should be 0 (i.e., `dm[u][u] == 0`).
*Requirements:* `DistanceMatrixMap` must be a model of [ReadablePropertyMap].
The `key_type` of the distance matrixc must be the same as the `vertex_descriptor`
of the `Graph` parameter. The `value_type` must be a [ReadWritePropertyMap]
whose `key_type` is also the `vertex_descriptor` of the `Graph` and
whose `value_type` is a model of [NumericValue].
]
]
[
[required, out] [`EccentricityMap em`]
[
The eccentricity map `em` stores the computed eccentricity values for
each vertex in the graph.
*Requirements:* The `EccentricityMap` type must model the [WritablePropertyMap]
concept. The `key_type` of the property map must be the `vertex_descriptor`
of the `Graph` parameter. The `value_type` must be the same type as the
`value_type` of the `DistanceMatrixMap` parameter.
]
]
]
[heading Return]
The `eccentricities()` function returns a pair containing the radius and diameter
as the `first` and `second` elements respectively.
[heading Complexity]
The `eccentricities()` function returns in ['O(n[sup 2])] where /n/ is the number
of vertices in the graph.
[endsect]
[section [^radius()]]
#include <boost/graph/eccentricity.hpp>
template <typename Graph, typename EccentricityMap>
inline typename property_traits<EccentricityMap>::value_type
radius(const Graph& g, EccentricityMap ecc)
The `radius()` function returns the radius of the graph, which is defined as the
minimum eccentricity of any vertex in the graph. The radius is computed from the
eccentricities that have been previously computed using the [eccentricity] function.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which the eccentricity measures are being comptued.
*Requirements:* The `Graph` type must be a model of the
[VertexListGraph] concepts.
]
]
[
[required, out] [`EccentricityMap em`]
[
The eccentricity map `em` provides access to the previously computed
eccentricities of all vertices in the graph.
*Requirements:* The `EccentricityMap` type must model the [ReadablePropertyMap]
concept. The `key_type` of the property map must be the `vertex_descriptor`
of the `Graph` parameter. The `value_type` must model the [NumericValue]
concept.
]
]
]
[heading Return Value]
The `radius()` function return the radius of the graph. The return type of
this function is the same as the `value_type` of the `EccentricityMap` parameter.
[heading Complexity]
The `radius()` function returns in linear time with respect to the number
of vertices in the graph.
[endsect]
[section [^diameter()]]
#include <boost/graph/eccentricity.hpp>
template <typename Graph, typename EccentricityMap>
inline typename property_traits<EccentricityMap>::value_type
diameter(const Graph& g, EccentricityMap ecc)
The `diameter()` function returns the diameter of the graph, which is defined as the
maximum eccentricity of any vertex in the graph. The diameter is computed from the
eccentricities that have been previously computed using the [eccentricity] function.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which the eccentricity measures are being comptued.
*Requirements:* The `Graph` type must be a model of the
[VertexListGraph] concepts.
]
]
[
[required, out] [`EccentricityMap em`]
[
The eccentricity map `em` provides access to the previously computed
eccentricities of all vertices in the graph.
*Requirements:* The `EccentricityMap` type must model the [ReadablePropertyMap]
concept. The `key_type` of the property map must be the `vertex_descriptor`
of the `Graph` parameter. The `value_type` must model the [NumericValue]
concept.
]
]
]
[heading Return Value]
The `diameter()` function return the diameter of the graph. If any vertices
are disconnected from the graph, the diameter will be infinite. The return type of
this function is the same as the `value_type` of the `EccentricityMap` parameter.
[heading Complexity]
The `diameter()` function returns in linear time with respect to the number
of vertices in the graph.
[endsect]
[section [^radius_and_diameter()]]
#include <boost/graph/eccentricity.hpp>
template <typename Graph, typename EccentricityMap>
std::pair<typename property_traits<EccentricityMap>::value_type,
typename property_traits<EccentricityMap>::value_type>
radius_and_diameter(const Graph& g, EccentricityMap ecc)
The `radius_and_diameter()` function returns both the radius and diameter of the
graph as a pair such that the `first` element of the pair is the radius and the
`second` element is the diameter. These values are computed from the eccentricities
that have been previously computed using the [eccentricity] function.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which the eccentricity measures are being comptued.
*Requirements:* The `Graph` type must be a model of the
[VertexListGraph] concepts.
]
]
[
[required, out] [`EccentricityMap em`]
[
The eccentricity map `em` provides access to the previously computed
eccentricities of all vertices in the graph.
*Requirements:* The `EccentricityMap` type must model the [ReadablePropertyMap]
concept. The `key_type` of the property map must be the `vertex_descriptor`
of the `Graph` parameter. The `value_type` must model the [NumericValue]
concept.
]
]
]
[heading Return Value]
The `radius_and_diameter()` funtion returns a pair containing both the radius (`first`)
and diameter (`second`) of the graph. The types of these values are the same as the
`value_type` of the `EccentricityMap`.
[heading Complexity]
The `radius_radius_diameter()` returns in linear time with respect to the number of vertices
in the graph.
[endsect]
[section Examples]
[heading Eccentricity, Radius, and Diameter]
This example computes the eccentricities for all vertices in a graph, and the radius
and diameter of the graph itself. This example includes the following files:
* [^examples/eccentricity.cpp]
* [^examples/helper.hpp]
[eccentricity_example]
Note that we can also compute the radius and diameter separatel. For exmaple:
// Compute the radius and diameter after computing eccentricites,
// but separately.
int r = radius(g, em);
int d = diameter(g, em);
// Compute the radius and diameter after computing eccentricities,
// but in one step.
int r, d;
tie(r, d) = radius_diameter(g, em);
For small graphs, choosing one method over the other makes little difference. For
large graphs, however, multiple iterations over the vertex set may result in lower
performance.
If given the `social_network.graph` file as input, the output will be:
[pre
Scott 2
Jill 3
Mary 3
Bill 3
Josh 3
Frank 2
Laurie 3
Anne 3
Howard 3
radius: 2
diamter: 3
]
[endsect]
[endsect]

View File

@@ -1,179 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Edge List]
template <
typename EdgeIter,
typename ValueType = typename iterator_traits<EdgeIter>::value_type,
typename DiffereneType = typename iterator_traits<EdgeIter>::difference_type
typename Category = typename iterator_traits<EdgeIter>::iterator_category>
class edge_list;
The `edge_list` class is an adaptor that turns a pair of edge iterators into a
graph type that models the [EdgeListGraph] concept. The `value_type` of the edge
iterator must be a `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 `DifferenceType`
template parameters are only needed if your compiler does not support partial
specialization. Otherwise they default to the correct types.
[heading Where Defined]
#incldue <boost/graph/edge_list.hpp>
[heading Template Parameters]
[table
[[Parameter] [Description] [Default]]
[
[`EdgeIter`]
[
Must be a model of [SgiInputIterator], and its `value_type` must be
`pair<vertex_descriptor, vertex_descriptor>`.
]
[ ]
]
[
[`ValueType`]
[The `value_type` of `EdgeIter`.]
[`iterator_traits<EdgeIter>::value_type`]
]
[
[`DifferenceType`]
[The `difference_type` of `EdgeIter`.]
[`iterator_traits<EdgeIter>::difference_type`]
]
[
[`Category`]
[The `iterator_category` of `EdgeIter`.]
[`iterator_traits<EdgeIter>::iterator_category`]
]
]
[heading Model Of]
[EdgeListGraph]
[heading Associated Types]
[table
[[Type] [Description]]
[
[`graph_traits<adjancency_list>::vertex_descriptor`]
[The type of vertex descriptors associated with the `edge_list`.]
]
[
[`graph_traits<adjancency_list>::edge_descriptor`]
[The type of edge descriptors associated with the `edge_list`.]
]
[
[`graph_traits<edge_list>::edge_size_type`]
[The type used for dealing with the number of edges in the graph.]
]
[
[`graph_traits<edge_list>::edge_iterator`]
[The type used for iterating over edges in the graph. The same as `EdgeIter`.]
]
]
[/
<h3>Member Functions</h3>
<hr>
<tt>
edge_list(EdgeIterator first, EdgeIterator last)
</tt>
<br><br>
Creates a graph object with `n` vertices and with the
edges specified in the edge list given by the range \first,last).
<hr>
<H3>Non-Member Functions</H3>
<hr>
<tt>
std::pair&lt;edge_iterator, edge_iterator&gt;<br>
edges(const edge_list&amp; g)
</tt>
<br><br>
Returns an iterator-range providing access to the edge set of graph `g`.
<hr>
<tt>
vertex_descriptor<br>
source(edge_descriptor e, const edge_list&amp; g)
</tt>
<br><br>
Returns the source vertex of edge `e`.
<hr>
<tt>
vertex_descriptor<br>
target(edge_descriptor e, const edge_list&amp; g)
</tt>
<br><br>
Returns the target vertex of edge `e`.
<hr>
]
[heading Example]
Applying the Bellman-Ford shortest paths algorithm to an `edge_list`.
enum { u, v, x, y, z, N };
char name[] = { 'u', 'v', 'x', 'y', 'z' };
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;
}
The output is the distance from the root and the parent of each vertex in the
shortest paths tree.
[pre
u: 2 v
v: 4 x
x: 7 z
y: -2 u
z: 0 z
]
[endsect]

View File

@@ -1,106 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Exterior Vertex Property]
template <typename Graph, typename Value>
class exterior_vertex_property;
The `exterior_vertex_property` class is a utility for generically creating
and initializing exterior properties for graph classes.
[note
In fact, this class is the /only/ way to generically create exterior properties
for graphs.
]
[heading Notation]
The following expressions are used in this document:
[table
[[Expression] [Description]]
[[`G`] [A graph type modeling a refinement of the [Graph] concept.]]
[[`V`] [A value type that models the [SgiAssignable] concept.]]
]
[heading Model Of]
[ExteriorProperty]
[heading Template Parameters]
[table
[[Parameter] [Description]]
[
[`Graph`]
[
*Semantics:* Specifies the type of graph for which the property
is being declared.
*Requirements:* `Graph` must model a refinement of the the
[Graph] concept.
]
]
[
[`Value`]
[
*Semantics:* Specifies the value type of the exterior property.
]
]
]
[heading Where Defined]
`boost/graph/exterior_property.hpp`
[heading Associated Types]
[table
[[Type] [Description]]
[
[`P<G,V>::value_type`]
[
This is the same as the template parameter `Value`.
]
]
[
[`P<G,V>::key_type`]
[
This is the same as `graph_traits<G>::vertex_descriptor`.
]
]
[
[`P<G,V>::container_type`]
[
This type selects the preferred property container based on the
type of graph such that values are accessed in constant time
on average.
]
]
[
[`P<G,V>::map_type`]
[
This type selects the preferred property map type based on the
type of graph.
]
]
]
[heading Examples]
Using the `exterior_vertex_property` it is possible to generically create
exterior properties for a graph. Consider the following template function:
template <typename Graph, typename Weight>
void
do_shortest_paths(const Graph& g, Weight w = ())
{
typedef exterior_vertex_property<Graph, Weight> DistanceProperty;
typedef DistanceProperty::container_type DistanceContainer;
typedef DistanceProeprty::map_type DistanceMap;
DistanceContainer distances(num_vertices(g));
DistanceMap dist(make_property_map(distances));
dijkstra_shortest_paths(g, *vertices(g).first, distance_map(dist));
}
[endsect]

View File

@@ -1,361 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Mean Geodesic]
[template ex_mean_geodesic[] [link
boost_graph.reference.algorithms.measures.mean_geodesic.examples.mean_geodesic_distance
Mean Geodesic Example]]
[template ex_inclusive_mean_geodesic[] [link
boost_graph.reference.algorithms.measures.mean_geodesic.examples.inclusive_mean_geodesic_distance
Inclusive Mean Geodesic Example]]
[heading Overview]
The /mean geodesic distance/ measure is used in large network analysis to identify
central vertices and as a measure of the /small-world phenomenon/. The mean geodesic
distance of a vertex is defined as the average of geodesic distances from that
vertex every /other/ vertex in the graph. It is computed as:
[$images/eq/mean_geodesic.png]
Where /d(u,v)/ is the shortest path (geodesic distance) from /u/ to /v/. Note
that this excludes /d(u,u)/ from the average, even if /d(u,u)/ is non-zero, which
is rare for social networks. Note that if any vertex in the graph is unreachable
from any other, then the graph is unconnected, and the distance between those two
unonnected vertices is infinite. This imlplies that the closeness of every vertex
in an unconnected (and undirected) graph is also infinite. This is not necessarily
the case for directed graphs.
The mean geodesic distance is often used to quantify whether or not a graph exhibits
the so-called small-world phenomenon. If the mean geodesic distance of a graph is
small with respect to its density (the ratio of vertices to edges), then the graph
is said to exhibit the small-world phenomenon. This implies that vertices are
The mean geodesic distance of a graph, it's so-called /small-world distance/, is
the average of the mean geodesics for each vertex. It is computed as:
[$images/eq/small_world.png]
Note that computing the measure in this fashion means that the small-world distance
of the graph may lie outside the minimum and maximum mean geodesic distances of its
vertices.
Consider a social network of friends, which is represented by an undirected graph.
[figure
images/reference/social_network.png
*Figure 1.* A network of friends.
]
In this network, Frank has the lowest mean geodesic distance with an average of
1.375. Scott and Laurie have the second lowest distances with values of 1.5 and
1.875 respectively. The small-world distance of this graph is approximately 1.92.
See the [ex_mean_geodesic] for details on computing the mean geodesic and small
world distances of undirected graphs.
This framework also allows for a specialization of measures used to compute these
values. The default measures used in this framework implement the formulas given
above. In some instances, it may be worthwhile to redefine the measure. For example,
if a graph has meaningful non-zero distance-to-self, the averages should be computed
over all vertices instead of excluding the vertex for which distances are being
averaged. See the [ex_inclusive_mean_geodesic] for details on defining alternative
measures, and using weighted graphs to find shortest paths.
[section [^mean_geodesic()]]
#include <boost/graph/geodesic_distance.hpp>
template <typename Graph, typename DistanceMap>
float mean_geodesic(const Graph& g, DistanceMap dm)
template <typename ResultType, typename Graph, typename DistanceMap>
ResultType mean_geodesic(const Graph& g, DistanceMap dm)
template <typename Graph, typename DistanceMap, typename Measure>
typename Measure::result_type
mean_geodesic(const Graph& g, DistanceMap dm, Measure m)
The `mean_geodesic()` function can be used to compute the mean geodesic distance
(its average distance to all other vertices) for a single vertex. This function
requires a distance map that contains the distance from one vertex (the source) to
all others in the graph. This distance map can be computed as the result of a
shortest paths algorithm such as [dijkstra_shortest_paths] or [bellman_ford_shortest_paths].
If the graph is unweighted, distances can be recorded from a [breadth_first_search].
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[template] [`ResultType`]
[
The `ResultType` template parmeter explitly specifies the the
return type of the `closeness()` function. If not
given, the return type is `float`.
*Requirements:* The return type is required to model the
[NumericValue] concept.
]
]
[
[required, in] [`const Graph& g`]
[
The graph for which vertex measures are being comptued.
*Requirements:* The `Graph` type must be a model of the
[VertexListGraph] concepts.
]
]
[
[required, in] [`DistanceMap dm`]
[
Given a vertex `v`, the `dm` parameter provides the length of the
shortest path between a vertex `u` and `v`. The vertex `u` is the
vertex for which the distance map was initially computed.
*Requirements:* `DistanceMap` must be a model of [ReadablePropertyMap].
The `key_type` of the distance map must be the same as the `vertex_descriptor`
of the `Graph` parameter. The `value_type` is required to be a model of
[NumericValue].
]
]
[
[optional, in] [`Measure measure`]
[
The 'measure' parameter is an instance of a closeness measure that
performs the final division for this computation.
*Requirements:* The `Measure` type must be a model of the [DistanceMeasure]
concept. The `distance_type` must be the same type as the `value_type`
of the `DistanceMap` parameter. The `result_type` of the `Measure` must
model the [NumericValue] concept.
]
]
]
[heading Return]
The `mean_geodesic()` function returns the average of geodesic distances
to other vertices from a source. If the source vertex is not connected to one other
in the graph, this value is infinite.
[heading Complexity]
The `mean_geodesic()` function returns in /O(n*O(M))/ where /n/ is the number of
vertices in the graph and /O(M)/ is the complexity of the given measure. If no
measure is given, this function returns in linear time.
[endsect]
[section [^all_mean_geodesics()]]
#include <boost/graph/geodesic_distance.hpp>
template <typename Graph, typename DistanceMatrixMap, typename GeodesicMap>
typename property_traits<GeodesicMap>::value_type
all_mean_geodesics(const Graph& g, DistanceMatrixMap dm, GeodesicMap gm)
template <typename Graph, typename DistanceMatrixMap, typename GeodesicMap, typename Measure>
typename property_traits<GeodesicMap>::value_type
all_mean_geodesics(const Graph& g, DistanceMatrixMap dm, GeodesicMap gm, Measure m)
The `all_mean_geodesics()` function computes the average distance of each vertex in a
graph to every other vertex using a matrix that contains the distances between
each pair of vertices. This matrix can be computed as the output of an all-pairs shortest
path algorithm (e.g., [floyd_warshall_all_pairs_shortest_paths] or [johnson_all_pairs_shortest_paths])
or as the result of repeated [breadth_first_search]s (if the graph is unweighted).
This function returns the average of all mean geodesic distances, also known as the
small-world distance. If any vertices have infinite mean geodesic distance, this
return value will be infinite.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which vertex measures are being comptued.
*Requirements:* The `Graph` type must be a model of the
[VertexListGraph] concepts.
]
]
[
[required, in] [`DistanceMatrixMap dm`]
[
Given vertices /u/ and /v/, the `dm` parameter provides the length
of the shortest path between the two vertices.
*Requirements:* `DistanceMatrixMap` must be a model of [ReadablePropertyMap].
The `key_type` of the distance matrixc must be the same as the `vertex_descriptor`
of the `Graph` parameter. The `value_type` must be a [ReadWritePropertyMap]
whose `key_type` is also the `vertex_descriptor` of the `Graph` and whose
`value_type` is a model of [NumericValue].
]
]
[
[required, both] [`GeodesicMap gm`]
[
The geodesic map `gm` stores the resulting mean geodesic distances for
each vertex in the graph.
*Requirements:* The `GeodesicMap` type must be a model of the
[WritablePropertyMap] concept. The `key_type` of this parameter
must be the same as the `vertex_descriptor` of the `Graph` parameter,
and the `value_type` must be a model of the [NumericValue] concept.
]
]
[
[optional, in] [`Measure measure`]
[
The 'measure' parameter is an instance of a closeness measure operates
on the sum of distances of a vertex.
*Requirements:* The `Measure` type must be a model of the [DistanceMeasure]
concept. The `distance_type` must be the same type as the `value_type`
of the `DistanceMap` or `DistanceMatrixMap`. The `result_type` of the
`Measure` must model the [NumericValue] concept.
]
]
]
[heading Return]
The `all_mean_geodesics()` function returns the small-world distance for the graph.
This is the average of the mean geodesic distances of all vertices in the graph.
If any vertices have infinite mean geodesic distance, then the small-world distance
will also be infinite.
[heading Complexity]
The `all_mean_geodesics()` function returns in ['O(n[sup 2]*O(M))] where /n/ is the
number of vertices in the graph, and /O(M)/ is the complexity of the given measure.
If no measure is given, this function returns in quadratic time.
[endsect]
[section [^small_world_distance()]]
#include <boost/graph/geodesic_distance.hpp>
template <typename Graph, typename GeodesicMap, typename Measure>
typename Measure::result_type
small_world_distance(const Graph& g, GeodesicMap gm, Measure m)
template <typename Graph, typename GeodesicMap>
typename property_traits<GeodesicMap>::value_type
small_world_distance(const Graph& g, GeodesicMap gm)
The `small_world_distance()` function computes the mean geodesic distance for the
entire graph by averaging the mean geodesic distances of each vertex in the geodesic
distance map. Note that this function does not compute the mean geodesic distances
of each vertex. Those values must be computed by using the [mean_goedesic] function.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which vertex measures are being comptued.
*Requirements:* The `Graph` type must be a model of the
[VertexListGraph] concepts.
]
]
[
[required, both] [`GeodesicMap gm`]
[
The geodesic map `gm` contains the previously computed mean geodesic
distances for each vertex in the graph.
*Requirements:* The `GeodesicMap` type must model the [ReadablePropertyMap]
concept. The `key_type` of this parameter must be the same as the
`vertex_descriptor` of the `Graph` parameter, and the `value_type` must
be a model of the [NumericValue] concept.
]
]
[
[optional, in] [`Measure measure`]
[
The 'measure' parameter is an instance of a closeness measure that
performs the final division for this computation.
*Requirements:* The `Measure` type must be a model of the [DistanceMeasure]
concept. The `distance_type` must be the same type as the `value_type`
of the `GeodesicMap`. The `result_type` must model the [NumericValue]
concept.
]
]
]
[heading Return]
The `small_world_distance()` function returns the mean geodesic distance for the
entire graph - a common measure of the small-world property. If the graph is
unconnected, the mean geodesic distance is infinite.
[heading Complexity]
The `small_world_distance()` function returns in /O(n*O(M))/ where /n/ is the number
of vertices in the graph and /O(M)/ is the complexity of the measure. If not measure
is given, then this function returns in linear time.
[endsect]
[section Examples]
[heading Mean Geodesic Distance]
This example shows how to compute the mean geodesic distance for each vertex
in a social network, and the mean geodesic distance for the graph as a whole.
This example includes the files
* [^examples/mean_geodesic.hpp]
* [^examples/helper.hpp]
[mean_geodesic_example]
In this example, the small world distance (`sw`) can be computed separetly from
the mean geodesic distances if need be.
// Compute the small-world distance after computing mean geodesics
float sw = small_world_distance(g, gm);
If given the file `social_network.graph` as input, the output of this program will
be:
[pre
Scott 1.5
Jill 2.125
Mary 2
Bill 2.125
Josh 2
Frank 1.375
Laurie 1.875
Anne 2.125
Howard 2.125
small world distance: 1.91667
]
Note that this program can be easily modified to work on directed graphs. In the
file `social_network.hpp`, simply replace `typedef undirected_graph<Actor> ...` to
`typedef directed_graph<Actor> ...`.
[heading Inclusive Mean Geodesic Distance]
This example shows how to implement alternative measures for the [mean_geodesic]
and [graph_mean_geodesic] functions to account for non-zero length self-loop
distances. Mean geodesic distances are computed both ways and the results printed
to standard output. This example includes the files:
* [^examples/mean_geodesic.hpp]
* [^examples/helper.hpp]
[inclusive_mean_geodesic_example]
If given the file `prob_network.graph` as input, the output of this program will
be:
[pre
vertex excluding including
myspace 0.941667 0.807143
digg 0.538333 0.461429
blogger 0.496667 0.425714
slashdot 0.721667 0.618571
wikipedia 0.498333 0.427143
blogspot 0.763333 0.654286
bbc 0.818333 0.701429
small world (excluding self-loops): 0.682619
small world (including self-loops): 0.585102
]
[endsect]
[endsect]

View File

@@ -1,103 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Predecessor Recorder]
template <class PredecessorMap, class EventTag>
class predecessor_recorder;
This is an [EventVisitor] that records the predecessor (or parent) of a vertex in
a predecessor property map. This is particularly useful in graph search algorithms where
recording the predecessors is an efficient way to encode the search tree that was traversed
during the search. The predecessor recorder is typically used with the `on_tree_edge` or
`on_relax_edge events`, and cannot be used with vertex events.
[predecessor_recorder] can be used with graph algorithms by wrapping it with the
algorithm specific adaptor, such as [bfs_visitor] and [dfs_visitor]. Also, this
event visitor can be combined with other event visitors using `std::pair` to form an [EventVisitorList].
Algorithms such as Dijkstra's and breadth-first search will not assign a predecessor
to the source vertex (which is the root of the search tree). Often times it is useful to
initialize the source vertex's predecessor to itself, thereby identifying the root vertex
as the only vertex which is its own parent. When using an algorithm like depth-first search
that creates a forest (multiple search trees), it is useful to intialize the predecessor
of every vertex to itself, so that all the root nodes can be distinguished.
[h4 Model Of]
[EventVisitor]
[h4 Where Defined]
`boost/graph/visitors.hpp`
[h4 Template Parameters]
[table
[[Parameter] [Description] [Default]]
[
[`PredecessorMap`]
[
A [WritablePropertyMap] where the key type and value type are of type
`vertex_descriptor`.
]
]
[
[`EventTag`]
[
A tag used to specify when the recorder should be applied during the graph
algorithm. `EventTag` must be an edge event.
]
]
]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`predecessor_recorder::event_filter`]
[
This type will be the same as the template parameter `EventTag`.
]
]
]
[h4 Member Functions]
[table
[[Function] [Description]]
[
[`predecessor_recorder(PredecessorMap pa)`]
[Construct a predecessor recorder object with a predecessor property map `pa`.]
]
[
[
``
template <class Edge, class Graph>
void operator()(Edge e, const Graph& g)
``
]
[
Given edge `e` as /(u,v)/, this records `u` as the predecessor (parent) of `v`.
]
]
]
[h4 Non-Member Functions]
[table
[[Function] [Description]]
[
[
``
template <class PredecessorMap, class EventTag>
predecessor_recorder<PredecessorMap, EventTag>
record_predecessors(PredecessorMap pa, EventTag)
``
]
[
A convenience function for creating [predecessor_recorder] instances.
]
]
]
[endsect]

View File

@@ -1,103 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Property Writer]
template <class PropertyMap, class OutputIterator, class EventTag>
class property_writer;
This is an [EventVisitor] that can be used to output the property of a vertex
or edge at some event-point within an algorithm.
The [property_writer] class can be used with graph algorithms by wrapping it with
the algorithm specific adaptor, such as [bfs_visitor] and [dfs_visitor].
Also, this event visitor can be combined with other event visitors using `std::pair` to
form an [EventVisitorList].
[h4 Model Of]
[EventVisitor]
[h4 Where Defined]
`boost/graph/visitors.hpp`
[h4 Template Parameters]
[table
[[Parameter] [Description] [Default]]
[
[`PropertyMap`]
[
A [ReadablePropertyMap] where the `key_type` is of type `vertex_descriptor`
of `edge_descriptor` (depending on the event tag) and the `value_type` type is
of the property is convertible to the `value_type` of the `OutputIterator`.
]
]
[
[`OutputIterator`]
[
The iterator type used to write the property values must be a model of
[SgiOutputIterator].
]
]
[
[`EventTag`]
[
A tag used to specify when the property writer should be applied during the graph
algorithm.
]
]
]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`property_writer::event_filter`]
[
This type will be the same as the template parameter `EventTag`.
]
]
]
[h4 Member Functions]
[table
[[Function] [Description]]
[
[`property_writer(PropertyMap pa, OutputIterator out)`]
[Construct a property writer object with a property map `pa` and an output iterator `out`.]
]
[
[
``
template <class X, class Graph>
void operator()(X x, const Graph& g)
``
]
[
This writes the property value for `x` to the output iterator. Specifically,
`*out++ = get(pa, x)`.
]
]
]
[h4 Non-Member Functions]
[table
[[Function] [Description]]
[
[
``
template <class PropertyMap, class OutputIterator, class EventTag>
time_stamper<PropertyMap, OutputIterator, EventTag>
stamp_times(Property pa, OutputIterator out, EventTag)
``
]
[
A convenience function for creating [property_writer] instances.
]
]
]
[endsect]

View File

@@ -1,87 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Reference]
[section Graph Types]
[include undirected_graph.qbk]
[include directed_graph.qbk]
[include adjacency_list.qbk]
[include adjacency_matrix.qbk]
[include edge_list.qbk]
[endsect]
[section Traits Classes]
[/
/ [include graph_traits.qbk]
/ [include exterior_vertex_property.qbk]
/]
[endsect]
[section Visitor Adaptors]
[/
[include bfs_visitor.qbk]
[include dfs_visitor.qbk]
[include dijkstra_visitor.qbk]
[include bellman_visitor.qbk]
[include astar_visitor.qbk]
[include clique_visitor.qbk]
[inblude cycle_visitor.qbk]
/]
[endsect]
[section Event Visitors]
[include predecessor_recorder.qbk]
[include distance_recorder.qbk]
[include time_stamper.qbk]
[include property_writer.qbk]
[endsect]
[section Algorithms]
[section Fundamental]
[include breadth_first_search.qbk]
[include depth_first_search.qbk]
[endsect]
[section Connectivity]
[include connected_components.qbk]
[include strong_components.qbk]
[endsect]
[section Shortest Paths]
[endsect]
[section Minimum Spanning Tree]
[endsect]
[section Subgraph]
[include tiernan_all_cycles.qbk]
[include bron_kerbosch_all_cliques.qbk]
[endsect]
[section Maximum Flow]
[endsect]
[section Sparse Matrix Ordering]
[endsect]
[section Layout]
[endsect]
[section Measures]
[include degree_centrality.qbk]
[include closeness_centrality.qbk]
[include betweenness_centrality.qbk]
[include mean_geodesic.qbk]
[include eccentricity.qbk]
[include clustering_coefficient.qbk]
[endsect] [/Measures]
[endsect] [/Algorithms]
[endsect] [/Reference]

View File

@@ -1,116 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Strongly Connected Components]
template <class Graph, class ComponentMap, class P, class T, class R>
typename property_traits<ComponentMap>::value_type
strong_components(const Graph &g, ComponentMap c,
const bgl_named_params<P,T,R>& params = ``/defaults/``);
The `strong_components()` functions compute the strongly connected components of a
directed graph using Tarjan's algorithm based on DFS \[41\].
The output of the algorithm is recorded in the component property map, which will
contain numbers giving the component number assigned to each vertex. This algorithm
returns the number of strongly connected components in the graph.
[heading Where Defined]
`boost/graph/strong_components.hpp`
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[in] [`const Graph& g`]
[
The /directed/ graph for which connected components are being found.
This graph must be a model of VertexListGraph and Incidence Graph.
]
]
[
[out] [`ComponentMap c`]
[
The algorithm computes how many connected components are in the graph,
and assigning each component an integer label. The algorithm then records
which component each vertex in the graph belongs to by recording the
component number in the component property map. The ComponentMap type
must be a model of WritablePropertyMap. The value type shouch be an
integer type, preferably the same as the `vertices_size_type` of the
graph. The key type must be the graph's `vertex_descriptor` type.
]
]
]
[heading Named Parameters]
[table
[[Type] [Parameter] [Description]]
[
[util] [`root_map(RootMap root_map)`]
[
This is used by the algorithm to record the candidate root vertex for each
vertex. By the end of the algorithm, there is a single root vertex for each
component and `get(root_map, v)` returns the root vertex for whichever
component vertex `v` is a member. The `RootMap` must be a ReadWritePropertyMap,
where the key type and the value type are the vertex descriptor type of the
graph.
*Default* An iterator_property_map created from a `std::vector` of
`vertex_descriptor`s of size `num_vertices(g)` and using the `index_map`
for accessing root vertices.
]
]
[
[util] [`discover_time_map(TimeMap time_map)`]
[
This is used by the algorithm to keep track of the DFS ordering of the vertices.
The `TimeMap` must be a model of ReadWritePropertyMap and its value type must
be an integer type. The key type must be the vertex descriptor type of the graph.
*Default* An iterator_property_map created from a `std::vector` of integers
of size `num_vertices(g)` and using the `index_map` for accessing root vertices.
]
]
[
[util] [`color_map(ColorMap color)`]
[
This is used by the algorithm to keep track of its progress through the
graph. The type ColorMap must be a model of ReadWritePropertyMap and
its key type must be the graph's `vertex_descriptor` type and the value
type of the color map must model ColorValue.
*Default* An `iterator_property_map` create from a `std::vector` of
`default_color_type` of size `num_vertices(g)` and using `index_map` as
the index map (to access colors for a vertex).
]
]
[
[in] [`vertex_index_map(VertexIndexMap index_map)`]
[
This maps each vertex to an integer in the range \[0, `num_vertices(g)`).
This parameter is only necessary when the default color property map is
used. The type VertexIndexMap must be a model of ReadablePropertyMap. The
value type of the map must be an integer type. The vertex descriptor type
of the graph needs to be usable as the key type of the map.
*Default* `get(vertex_index, g)`. Note if you use this default, make sure
that your graph has an interior `vertex_index` property. For example
`adjacency_list` with `VertexList=listS` does not have an interior
`vertex_index` property.
]
]
]
[heading Complexity]
This algorithm runs in /O(V + E)/.
[heading Notes]
This algorithm will not compile if passed a /directed/ graph.
[heading Examples]
[endsect]

View File

@@ -1,299 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Tiernan All Cycles]
[template ex_tiernan_printing_cycles[] [link
boost_graph.reference.algorithms.subgraph.tiernan_all_cycles.examples.printing_cycles
Printing Cycles Example]]
[template ex_tiernan_girth_circumference[] [link
boost_graph.reference.algorithms.subgraph.tiernan_all_cycles.examples.girth_and_circumference
Girth and Circumference Example]]
[heading Overview]
This function uses the Tiernan algorithm to find all /cycles/ within a given graph,
invoking a visitor when each cycle is found. A cycle is a path (a sequence of
connected vertices) within a graph, and whose tail (the last vertex in the path)
is connected to its head (the first vertex in the path).
Consider the directed graph in Figure 1.
[figure
images/reference/prism_3_2.png
*Figure 1.* A directed graph.
]
This graph has 11 distinct cycles. Some of the more obvious are:
* 0, 1, 2
* 3, 4, 5
* 0, 3
* 1, 4
* 2, 5
For more details see the [ex_tiernan_printing_cycles].
The order in which cycles are visited is determined by the algorithm. It iterates
over each vertex in the order of its vertex indices. The algorithm identifies cycles
by first finding long paths and determining if they form cycles. Once the paths
have been examined, the algorithm backtracks along the path searching for alternate
cycles. The result (as shown in the output of the [ex_tiernan_printing_cycles]) is a
listing that visits longer cycles first in the lexicographical order of vertex
indices. Note that the order of visitation does /not/ imply anything about the
relative importance of the cycle within the graph.
The Tiernan algorithm is designed to work on directed graphs, but works for undirected
graphs as well. When running on undirected graphs, however, the algorithm treats each
edge connecting two vertices /(u,v)/ as if it were two distinct edges /(u,v)/ and
/(v,u)/. As result the algorithm will report cycles in both directions. Consider the
following undirected graph in Figure 2.
[figure
images/reference/triangle.png
*Figure 2.* An undirected triangle.
]
If the Tiernan algorithm is run on this graph, it will visit the paths 0, 1, 2 and
0, 2, 1.
There are two properties of a graph that are derived from knowing a graphs cycles:
/girth/ and /circumference/. The girth of a graph is defined as the minimum-length
cycle in the graph, and the circumference is defined as the largest-length cycle.
This module provides functions for computing these values using Tiernan's algorithm.
See the [ex_tiernan_girth_circumference] for details.
[section [^tiernan_all_cycles()]]
#include <boost/graph/tiernan_all_cycles.hpp>
template <typename Graph, typename Visitor>
void tiernan_all_cycles(const Graph& g, Visitor vis)
template <typename Graph, typename Visitor>
void tiernan_all_cycles(const Graph& g, Visitor vis, std::size_t max)
template <typename Graph, typename Visitor>
void tiernan_all_cycles(const Graph& g, Visitor vis, std::size_t min, std::size_t max)
The `tiernan_all_cycles()` function visits all cycles in a graph. There are three
variants of this algorithm. The first will simply find and visit all cycles in the
target graph. The second variant allows the caller to specify an upper bound to the
length of cycles visited, and the third variant allows the user to specify both
upper and lower bounds on the lengths of paths being visited. The minimum cycle
length must be at least two.
Note that the default minimum cycle length differs between directed and undirected
graphs. For directed graphs, the algorithm allows the discovery and visitation
of length-two cycles. For undirected graphs, the default minimum cycle length is
three. This prevents the algorithm from visiting every pair of connected vertices
in an undirected graph as a cycle.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which cliques are being visited.
*Requirements:* The `Graph` type must be a model of the
[IncidenceGraph] and [VertexIndexGraph] concepts.
]
]
[
[required, in] [`Visitor vis`]
[
The visitor object to the algorithm.
*Requirements:* This `Visitor` class must model the
[CliqueVisitor] class.
]
]
[
[optional, in] [`std::size_t max`]
[
The maximum-length path that will be visited by the algorithm.
*Default:* `std::numeric_limits<std::size_t>::max()`.
]
]
[
[optional, in] [`std::size_t min`]
[
The minimum-length path that will be visited by the algorithm. The
default minimum length path is determined by the type of graph.
*Precondition:* `min >= 2`
*Default:* If `Graph` is directed, this value defaults to 2. Otherwise
the default value is 3.
]
]
]
[heading Complexity]
This function has a (loose) upper bound of ['O(2[sup n])] where /n/ is the
number of vertices a graph. This bound is derived from the powerset of vertices
in /g/ and does not account for the vertex of origin or directionality of edges
connecting vertices in a path. If one considers the paths in a triangle {1, 2, 3}
and {3, 2, 1} to be distinct cycles within a graph, then this bound can potentially
be much greater. From a practical standpoint, it is unlikely that real graphs will
ever approach a number of paths remotely close to this number.
This function requires ['O(n[sup 2])] space where /n/ is the number of vertices
in a graph.
[endsect]
[section [^tiernan_girth()]]
#include <boost/graph/tiernan_all_cycles.hpp>
template <typename Graph>
std::size_t tiernan_girth(const Graph& g)
Comptutes the girth (the minimum length cycle) of the graph `g` by visiting all
cycles using Tiernan's algorithm. If the graph is acyclic, it has no cycles and
an infinite girth. If computing both girth and circumference, use the
[tiernan_girth_and_circumference] function since this computation can be fairly
time consuming.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which the girth is computed.
*Requirements:* The `Graph` type must be a model of the
[IncidenceGraph] and [VertexIndexGraph] concepts.
]
]
]
[heading Return]
The `tiernan_girth()` function returns the girth of the given graph.
[heading Complexity]
The `tiernan_girth()` function has the same time complexity as the [tiernan_all_cycles]
function.
[endsect]
[section [^tiernan_circumference()]]
#include <boost/graph/tiernan_all_cycles.hpp>
template <typename Graph>
std::size_t tiernan_circumference(const Graph& g)
Comptutes the circumference (the maximum length cycle) of the graph `g` by visiting all
cycles using Tiernan's algorithm. If the graph is acyclic, it has no cycles and an
infinite circumference. If computing both girth and circumference, use the
[tiernan_girth_and_circumference] function since this computation can be fairly
time consuming.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which the circumference is being computed.
*Requirements:* The `Graph` type must be a model of the
[IncidenceGraph] and [VertexIndexGraph] concepts.
]
]
]
[heading Return]
The `tiernan_circumference()` function returns the girth of the given graph.
[heading Complexity]
The `tiernan_circumference()` function has the same time complexity as the
[tiernan_all_cycles] function.
[endsect]
[section [^tiernan_girth_and_circumference()]]
#include <boost/graph/tiernan_all_cycles.hpp>
template <typename Graph>
std::pair<std::size_t, std::size_t>
tiernan_girth_and_circumference(const Graph& g)
Comptutes the both the girth (minimum length cycle) and circumference (maximum length
cycle) of the graph `g` by visiting all cycles using Tiernan's algorithm. If the
graph is acyclic, it has no cycles and both girth and cicumference are infinite.
[heading Parameters]
[table
[[Type] [Parameter] [Description]]
[
[required, in] [`const Graph& g`]
[
The graph for which the girth and circumference are being computed.
*Preconditions:* The indices of vertices in the graph must be
in the range...
*Requirements:* The `Graph` type must be a model of the
[IncidenceGraph] and [VertexIndexGraph] concepts.
]
]
]
[heading Return]
The `tiernan_girth_and_circumference()` function returns the girth of the given graph.
[heading Complexity]
The `tiernan_girth_and_circumference()` function has the same time complexity as the
[tiernan_all_cycles] function.
[endsect]
[section Examples]
[heading Printing Cycles]
This example demonstrates the construction of a cycle visitor and its use with
the `tiernan_all_cycles()` function. This file includes the following files:
* [^examples/tiernan_print_cycles.cpp]
* [^examples/helper.hpp]
[tiernan_print_cycles]
If this program is given the `prism_3_2.graph` file as input, it will print all
the cycles in the graph shown in Figure 1.
[pre
0 1 2 5 3
0 1 2
0 1 4 5 3
0 1 4 5 2
0 3 4 5 2
0 3 4 1 2
0 3
1 2 5 3 4
1 4
2 5
3 4 5
]
[heading Girth and Circumference]
This example demonstrates the use of Tiernan's algorithm to compute the girth
and circumference of a directed graph. This example includes the following files:
* [^examples/tiernan_girth_circumference.cpp]
* [^examples/helper.hpp]
[tiernan_girth_circumference]
If this program is given the `prism_3_2.graph` file as input, it will print the
following output:
[pre
girth: 2
circumference: 5
]
[endsect]
[endsect]

View File

@@ -1,104 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Time Stamper]
template <class TimeMap, class TimeT, class EventTag>
class time_stamper;
This is an [EventVisitor] that can be used to "stamp" a time at some event-point
within an algorithm. An example of this is recording the discover or finish time of
a vertex during a graph search.
The [time_stamper] class can be used with graph algorithms by wrapping it with
the algorithm specific adaptor, such as [bfs_visitor] and [dfs_visitor]. Also,
this event visitor can be combined with other event visitors using `std::pair` to
form an [EventVisitorList].
[h4 Model Of]
[EventVisitor]
[h4 Where Defined]
`boost/graph/visitors.hpp`
[h4 Template Parameters]
[table
[[Parameter] [Description] [Default]]
[
[`TimeMap`]
[
A [WritablePropertyMap] where the key type is of type `vertex_descriptor`
of `edge_descriptor` (depending on the event tag) and `TimeT` must be convertible
to the value type.
]
]
[
[`TimeT`]
[
The type of the time counter, which should be convertible to the `value_type` of
TimeMap.
]
]
[
[`EventTag`]
[
A tag used to specify when the time stamper should be applied during the graph
algorithm.
]
]
]
[h4 Associated Types]
[table
[[Type] [Description]]
[
[`time_stamper::event_filter`]
[
This type will be the same as the template parameter `EventTag`.
]
]
]
[h4 Member Functions]
[table
[[Function] [Description]]
[
[`time_stamper(Timemap pa, TimeT& t)`]
[Construct a time stamper object with a timestamp property map `pa` and time counter `t`.]
]
[
[
``
template <class X, class Graph>
void operator()(X x, const Graph& g)
``
]
[
This records the current timestamp for the edge or vertex in the property map
and increments the time count.
]
]
]
[h4 Non-Member Functions]
[table
[[Function] [Description]]
[
[
``
template <class TimeMap, class TimeT, class EventTag>
time_stamper<TimeMap, EventTag>
stamp_times(TimeMap pa, TimeT& t, EventTag)
``
]
[
A convenience function for creating [time_stamper] instances.
]
]
]
[endsect]

View File

@@ -1,743 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Undirected Graph]
template <class VertexProperties, class EdgeProperties, class GraphProperties>
class undirected_graph;
This section provides detailed information about the `undirected_graph` class,
its associated types, member functions and non-member interface. An undirected graph
is one in which edges have no direction - this is to say that edges can be "traveled"
in both directions. This class provides general purpose implementation of undirected
graphs and can be used with algorithms in the Boost Graph Library.
[h4 Notation]
The following notation is used in this documentation. The following type names
are generally meant to mean the following:
[table
[[Used Type] [Actual Type]]
[
[`undirected_graph`]
[
`undirected_graph<VP,EP,GP>` where `VP`, `EP` and `GP` are template
arguments that correspond to user-defined or default verex properties,
edge properties, and graph properties.
]
]
[
[`vertex_descriptor`]
[`undirected_graph<VP,EP,GP>::vertex_descriptor`]
]
[
[`edge_descriptor`]
[`undirected_graph<VP,EP,GP>::edge_descriptor`]
]
[
[`vertex_iterator`]
[`undirected_graph<VP,EP,GP>::vertex_iterator`]
]
[
[`edge_iterator`]
[`undirected_graph<VP,EP,GP>::edge_iterator`]
]
]
Moreover, objects with the following names are generally expected to have the
following types.
[table
[[Object Name] [Type]]
[[`g`] [`undirected_graph`]]
[[`u`, `v`] [`vertex_descriptor`]]
[[`e`] [`edge_descriptor`]]
[[`i`] [`vertex_iterator` or `edge_iterator`]]
[[`p`] [A property tag (usually a template parameter)]]
[[`d`] [A vertex or edge descriptor (usually a template parameter)]]
[[`v`] [The value of a property (usually a template parameter)]]
]
[h4 Descriptor and Iterator Stability]
With the `undirected_graph` class, descriptors and iterators remain stable after
all operations except descriptors and iterators referencing the vertices and edges
that have been removed. Removing a vertex or edge will not invalidate descriptors
and iterators to other vertices or edges.
For example, consider the following code:
undirected_graph<> g;
undirected_graph<>::vertex_descriptor u = add_vertex(g);
undirected_graph<>::vertex_descriptor v = add_vertex(g);
undirected_graph<>::vertex_descriptor w = add_vertex(g);
remove_vertex(u);
add_edge(v, w, g);
After running this program, the descriptor `u` will be invalid but `v` and `w` will
still be valid so the call to `add_edge(v,w,g)` is also valid. Note that this
property does not hold for all graph types.
[h4 Vertex Indexing and Stability]
The `undirected_graph` class provides a built-in internal properties for vertex
types, and will provide semi-automated index management. Algorithms that use vertex
indices generally assume that they are in the range \[0, `num_vertices(g)`). With
the `undirected_graph` class vertex indices will be in this continuous range until
a vertex is removed from the graph. This is the only operation that invalidates
vertex indices, but the vertices will need to be renumbered using the
`renumber_vertex_indices(g)` function.
The `remove_vertex_and_renumber_indices(vi,g)` function can be used to autmoatically
renumber indices after removing the vertex referenced by the given iterator. Because
this function runs in linear time, it should not be used for repeated removals.
[h4 Function Names for Directed and Undirected Graphs]
Many of the operations in the Boost Graph library are named in accordance
with the concepts of directed graphs, specifically the use of out-edges as the
canonical adjacencty list for vertices. As a result, undirected graphs also
use the out-edge terminology to refern to its incident edges, but in-edge operations
are identical in behavior to out-edge operations.
There are three sets of operations that have multiple names and duplicate behaviors:
`*degree()`-computing functions, `*_edge()`-iterating accessors, and the `remove_*_edge()`
predicate-based functions. These functions are grouped together in their reference
sections.
This class also introduces two new functions, `incident_edges(g)` that returns an
iterator range to the incident edges of `g`, and `remove_incident_edges_if(v,p,g)`.
These are identical in behavior to their `in` and `out` counterparts. These
functions are only provided for semantic consistency so developers should be aware
that these new functions are /not/ defined for any other graph classes in the
Boost Graph Library.
Developers of generic algoriths should be aware that, when generalizing an algorithm
for both directed and undirected graphs, it is better to use the `out_degree(g)`
function to access out-edges since it is guaranteed by every other graph class.
[h5 Model Of]
[IncidenceGraph], [VertexListGraph], [EdgeListGraph], [AdjacencyGraph],
[MutableGraph], and [PropertyGraph].
[h4 Template Parameters]
There are only three parameters to the `undirected_graph` class.
[table
[[Parameter] [Description] [Default]]
[
[`VertexProperties`]
[Specifies internal properties for vertices of the graph.]
[`no_property`]
]
[
[`EdgeProperties`]
[Specifies internal properties for edges of the graph.]
[`no_property`]
]
[
[`GraphProperties`]
[Specifies internal properties for the graph itself.]
[`no_property`]
]
]
Additionally, the `undirected_graph` class provides a non-constant time implementation
of the [AdjacencyMatrix] associated function `edge(u,v,g)`, but does not model
the concept.
[h4 Where Defined]
`boost/graph/undirected_graph.hpp`
[h4 Associated Types]
There are a number of useful types associated with the `undirected_graph` class.
Most of these are accessed through `graph_traits` or other template classes.
For convenience these types have been grouped by purpose.
[h5 Descriptor Types]
[table
[[Type] [Description]]
[
[`graph_traits<undirected_graph>::vertex_descriptor`]
[
The type for the vertex descriptors associated with the graph. The `vertex_descriptor`
models the [Descriptor] and [NoConcept Hashable] concepts.
]
]
[
[`graph_traits<undirected_graph>::edge_descriptor`]
[
The type for the edge descriptors associated with the graph. The `edge_descriptor`
models the [Descriptor] and [NoConcept Hashable] concepts.
]
]
]
Note that edge and vertex descriptors for the `unsigned_graph` can be used as keys for both
[SgiSortedAssociativeContainer]s and [SgiHashedAssociativeContainer]s such as `std::map` and
`std::tr1::unordered_map` respectively.
[h5 Iterator Types]
[table
[[Type] [Description]]
[
[`graph_traits<undirected_graph>::vertex_iterator`]
[
The type for iterators returned by `vertices()`. Verex iterators are
models of the [SgiBidirectionalIterator] concept.
]
]
[
[`graph_traits<undirected_graph>::edge_iterator`]
[
The type for iterators returned by `edges()`. Edge iterators are
models of the [SgiBidirectionalIterator] concept.
]
]
[
[`graph_traits<undirected_graph>::out_edge_iterator`]
[
The type for iterators returned by `out_edges()`. Out-edge iterators
are models of the [SgiBidirectionalIterator] concept.
]
]
[
[`graph_traits<undirected_graph>::in_edge_iterator`]
[
The type for iterators returned by `in_edges()`. In-edge iterators
are models of the [SgiBidirectionalIterator] concept.
]
]
[
[`graph_traits<undirected_graph>::adjacency_iterator`]
[
The type for iterators returned by `adjacent_vertices`. Adjacency
iterators are models of the [SgiBidirectionalIterator] concept.
]
]
]
[h5 Miscellaneous Types]
[table
[[Type] [Description]]
[
[`graph_traits<undirected_graph>::vertices_size_type`]
[The type used for dealing with the number of vertices in the graph.]
]
[
[`graph_traits<undirected_graph>::edge_size_type`]
[The type used for dealing with the number of edges in the graph.]
]
[
[`graph_traits<undirected_graph>::degree_size_type`]
[The type used for dealing with the number of edges incident to a vertex in the graph.]
]
[
[`undirected_graph::vertex_index_type`]
[The integral type representing vertex indices (generally `unsigned int`).]
]
[
[
`property_map<undirected_graph, Property>::type`
`property_map<undirected_graph, Property>::const_type`
]
[
The property map type for vertex or edge properties in the graph. The specific
property is specified by the `Property` template argument, and must match one of
the properties specified in the `VertexProperties` or `EdgeProperties` for the
graph.
]
]
[
[`graph_property<undirected_graph, Property>::type`]
[
The value type for the graph property specified by the `Property` parameter.
`Property` must be one of the types in the `GraphProperties` template argument.
]
]
[
[`graph_traits<undirected_graph>::directed_category`]
[
This is always `undirectedS`, indicating that the graph supports operations
for undirected graphs.
]
]
[
[`graph_traits<undirected_graph>::edge_parallel_category`]
[
This is always `allow_parallel_edges_tag`, indicating that multiple edges
may be added between two vertices (i.e., graphs can be /multigraphs/).
]
]
]
[h4 Member Functions]
[table
[[Function] [Description]]
[
[`undirected_graph(const GraphProperties& p = GraphProperties()`]
[The default constructor creates a graph with no vertices or edges.]
]
[
[`undirected_graph(const undirected_graph& x`)]
[The copy constructor creates a copy of the given graph `x`.]
]
[
[
``
undirected_graph(vertices_size_type n,
const GraphProperties& p = GraphProperties())
``
]
[The default constructor creates a graph with `n` vertices and no edges.]
]
[
[`undirected_graph& operator =(const undirected_graph& x)`]
[Copies the edges and vertices of the graph `x`.]
]
]
[h4 Non-member Functions]
[h5 Non-member Accessors]
[table
[[Function] [Description]]
[
[
``
std::pair<vertex_iterator, vertex_iterator>
vertices(const undirected_graph& g)
``
]
[Returns an iterator range providing access to the vertex list of `g`.]
]
[
[
``
std::pair<edge_iterator, edge_iterator>
edges(const undirected_graph& g)
``
]
[Returns an iterator range providing access to the edge list of `g`.]
]
[
[
``
std::pair<out_edge_iterator, out_edge_iterator>
incident_edges(vertex_descriptor v, const undirected_graph& g)
``
``
std::pair<out_edge_iterator, out_edge_iterator>
out_edges(vertex_descriptor v, const undirected_graph& g)
``
``
std::pair<in_edge_iterator, in_edge_iterator>
in_edges(vertex_descriptor v, const undirected_graph& g)
``
]
[
Returns an iterator range providing access to the incident edges
of the vertex `v`. Because `g` is an undirected graph, these three
functions are guaranteed to return identical iterator ranges.
]
]
[
[
``
std::pair<adjacency_iterator, adjacency_iterator>
adjacent_vertices(vertex_descriptor v,
const undirected_graph& g)
``
]
[
Returns an iterator range providing access to the adjacenct vertices
of vertex `v` in the graph `g`. Note that this is functionally
equivalent to iterating over the targets of all incident edges of `v`.
]
]
[
[
``
vertices_size_type
num_vertices(const undirected_graph& g)
``
]
[Returns the number of vertices in the graph `g`.]
]
[
[
``
edge_size_type
num_edges(const undirected_graph& g)
``
]
[Returns the number of edges the graph `g`.]
]
[
[
``
degree_size_type
degree(vertex_descriptor v,
const undirected_graph& g)
``
``
degree_size_type
out_degree(vertex_descriptor v,
const undirected_graph& g)
``
``
degree_size_type
in_degree(vertex_descriptor v,
const undirected_graph& g)
``
]
[
Returns the degree of the vertex `v`, which is the number of
edges incident to it. Because `g` is undirected, all three
functions return equal values.
]
]
[
[
``
vertex_descriptor
vertex(vertices_size_type n
const undirected_graph& g)
``
]
[
Returns the /nth/ vertex in the graph `g`. With undirected graphs,
this method is /O(n)/. As such its use with this type of graph is
discouraged.
]
]
[
[
``
std::pair<edge_descriptor, bool>
edge(vertex_descriptor u,
vertex_descriptor v,
const undirected_graph& g)
``
]
[
If the edge (`u`,`v`) is in `g`, then this function returns the
descriptor for the edge connecting `u` and `v` with boolean value
set to `true`. Otherwise, the boolean value is `false` and the
edge descriptor is invalid.
]
]
[
[
``
vertex_size_type
get_vertex_index(vertex_descriptor v,
const undirected_graph& g)
``
]
[
Returns the vertex index of the given vertex descriptor v. Note
that indices are /not/ required to be in the range \[0, `num_vertices(g)`).
This function is an alias for `get(vertex_index,g,v)`.
]
]
[
[
``
vertex_size_type
max_vertex_index(vertex_descriptor v,
const undirected_graph& g)
``
]
[
Returns the vertex index of the given vertex descriptor v. Note
that indices are /not/ required to be in the range \[0, `num_vertices(g)`).
This function is an alias for `get(vertex_index,g,v)`.
]
]
]
[h5 Non-member Modifiers]
[table
[[Function] [Description]]
[
[
``
vertex_descriptor
add_vertex(undirected_graph& g)
``
]
[Adds a vertex to `g` and returns a descriptors for the new vertex.]
]
[
[
``
void
clear_vertex(vertex_descriptor v,
undirected_graph& g)
``
]
[
Removes all in- and out-edges of `v`, but leaves `v` in the graph `g`.
This is functioanlly equivalent to invoking `remove_edge()` on all
in- or out-edges of `v`, potentially invalidating descriptors and
iterators.
]
]
[
[
``
vertex_descriptor
remove_vertex(vertex_descriptor v,
undirected_graph& g)
``
]
[
Removes vertex `v` from the graph `g`. It is assumed that `v` has no
incident edges before removal. To ensure this is, call `clear_vertex(v, g)`
before removing it.
Assuming that the vertex indices were in the range \[0, `num_vertices(g)`)
before calling this method, this operation will invalidate all vertex indices
in the range (vertex_index(v, g), `num_vertices(g)`), requiring indices to
be renumbered using the `renumber_vertex_indices(g)` method. If possible,
prefer to remove groups of vertices at one time before renumbering since
renumbering is a /O(n)/ time operation.
]
]
[
[
``
void
remove_vertex_and_renumber_indices(vertex_iterator i,
undirected_graph& g)
``
]
[
Removes the vertex indicated by the iterator `i` from the graph `g`. Like
the `remove_vertex(v,g)` function, it is expected that `*i` have no
incident edges at the time of removal.
As indicated by the name, this method will also renumber vertex indices
after the removal of `*i`. This operation iterates over vertices after
`i`, decrementing their index by 1. If your program removes several
vertices at once, prefer to call several `remove_vertex(v,g)` methods,
followed by `renumber_vertices(g)` before using `g` in an algorithm.
]
]
[
[
``
void
renumber_vertex_indices(undirected_graph& g)
``
]
[
Renumbers all interior vertex indices such that each vertex has an index
in the range \[0, `num_vertices(g)`). Generally, this function needs to
be called after removing vertices and before invoking graph algorithms.
]
]
[
[
``
std::pair<edge_descriptor, bool>
add_edge(vertex_descriptor u,
vertex_descriptor v,
undirected_graph& g)
``
]
[
Adds the edge /(u,v)/ to the graph and returns a descriptor for the new
edge. For `undirected_graph`s, the boolean value of the pair will always
be true.
]
]
[
[
``
void
remove_edge(vertex_descriptor u,
vertex_descriptor v,
undirected_graph& g)
``
]
[
Removes the edge /(u,v)/ from the graph. This operation invalidates any
descriptors or iterators referencing the edge. Note that `u` and `v` must
be valid descriptors and /(u,v)/ must be in the graph. If `g` is a multigraph
(with multiple edges between /(u,v)/, this mehtod will cause the removal of
all such edges connecting `u` and `v`.
]
]
[
[
``
void
remove_edge(edge_descriptor e,
undirected_graph& g)
``
]
[
Removes the edge `e` from the graph. If multuple edges exist from
(`source(e,g)`, `target(e,g)`), then this method will remove only
the single, specified edge.
]
]
[
[
``
void
remove_edge(out_edge_iterator i,
undirected_graph& g)
``
]
[
This is functionally equivalent to `remove_edge(*i, g)`.
]
]
[
[
``
template <class Predicate> void
remove_edge_if(Predicate p, undirected_graph& g)
``
]
[
Removes all edges from the graph that satisfy `predicate`. That is, if
`p()` returns true when applied to an edge, then that edge is removed.
The affect on descriptor and iterator is the same as that of invoking
`remove_edge()` for on each of the removed vertices.
]
]
[
[
``
template <class Predicate> void
remove_incident_edge_if(vertex_descriptor v, Predicate p
undirected_graph& g)
``
``
template <class Predicate> void
remove_out_edge_if(vertex_descriptor v, Predicate p,
undirected_graph& g)
``
``
template <class Predicate> void
remove_in_edge_if(vertex_descriptor v, Predicate p,
undirected_graph& g)
``
]
[
Removes all edges incident-edges from vertex`v` that satisfy `predicate`.
That is, if `p()` returns true when applied to an edge, then that edge
is removed. The affect on descriptor and iterator is the same as that
of invoking `remove_edge()` for on each of the removed vertices.
Because this graph is undirected, these three funtions are identical
in behavior and run time.
]
]
]
[h5 Proprety Map Acessors]
[table
[[Function] [Description]]
[
[
``
template <class Property>
property_map<undirected_graph, Property>::type
get(Property,
const undirected_graph& g)
``
]
[
Returns the property map object for the vertex property specified by the
type `Property`. This type must match one of the properties specified in
the `VertexProperties` template argument.
]
]
[
[
``
template <class Property, class Descriptor>
typename
property_traits<
property_map<undirected_graph, Property>::const_type
>::value_type
get(Property,
const undirected_graph& g,
Descriptor d)
``
]
[
Returns the property value specified by the type `Property` for either
the `vertex_descriptor` or `edge_descriptor` denoted by `d`.
]
]
[
[
``
template <class Property, class Descriptor, class Value>
void
put(Property,
const undirected_graph& g,
Descriptor d,
Value v)
``
]
[
Sets the property value denoted by the type `Property` for either edge
or vertex descriptor `d` to the given value `v`.
]
]
[
[
``
template <class GraphProperty>
typename graph_property<undirected_graph, GraphProperty>::type&
get_property(undirected_graph& g, GraphProperty)
``
``
template <class GraphProperty>
const typename graph_property<undirected_graph, GraphProperty>::type&
get_property(const undirected_graph& g, GraphProperty)
``
]
[
Returns the graph property specified by the type `GraphProperty` for
the graph `g`. Here, GraphProperty must be one of the properties
in the `GraphProperties` template argument.
]
]
[
[
``
template <class GraphProprety, class Value>
void
set_property(const undirected_graph& g, GraphProperty, Value v)
``
]
[
Sets the graph proeprty specified by the type `GraphProperty` to
the given value `v`. Note that `GraphProperty` must be one of
the properties in the `GraphProperties` template argument.
]
]
]
[h4 Rationale]
Unlike most graph classes in Boost.Graph, the `undirected_graph` does not model the
[MutablePropertyGraph] concept. The reason for this is that it is relatively
difficult (from a usability standpoint) to easily deduce the type to be passed as a
property when adding vertices and edges - but especially vertices.
[endsect]

View File

@@ -1,54 +0,0 @@
[/
/ Copyright (C) 2007-2009 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[/ NOTE: This file defines templates that expand to links to standard concepts
/ that are primarily documented by the SGI site. Note that some concepts have
/ been added or deprecated since then. Unfortunately, they can't be documented.
/
/ Concepts appearing in the C++0x Draft Standard are prefixed with 'Std'. Those
/ whose documentation can be found in the SGI docs are prefixed with 'Sgi'.
/]
[/ Missing documentation /]
[template NoConcept[x] [^[x]]]
[template SgiAssignable[] [@http://www.sgi.com/tech/stl/Assignable.html [^Assignable]]]
[template SgiDefaultConstructible[] [@http://www.sgi.com/tech/stl/DefaultConstructible.html [^DefaultConstructible]]]
[template SgiCopyConstructible[] [@http://www.sgi.com/tech/stl/CopyConstructible.html [^CopyConstructible]]]
[template SgiEqualityComparable[] [@http://www.sgi.com/tech/stl/EqualityComparable.html [^EqualityComparable]]]
[template SgiLessThanComparable[] [@http://www.sgi.com/tech/stl/LessThanComparable.html [^LessThanComparable]]]
[template StdSemiregular [^Semiregular]]
[template StdRegular[] [^Regular]]
[template SgiContainer[] [@http://www.sgi.com/tech/stl/Container.html [^Container]]]
[template SgiForwardContainer[] [@http://www.sgi.com/tech/stl/ForwardContainer.html [^ForwardContainer]]]
[template SgiReversibleContainer[] [@http://www.sgi.com/tech/stl/ReversibleContainer.html [^ReversibleContainer]]]
[template SgiRandomAccessContainer[] [@http://www.sgi.com/tech/stl/RandomAccessContainer.html [^RandomAccessContainer]]]
[template SgiSequence[] [@http://www.sgi.com/tech/stl/Sequence.html [^Sequence]]]
[template SgiFrontInsertionSequence[] [@http://www.sgi.com/tech/stl/FrontInsertionSequence.html [^FrontInsertionSequence]]]
[template SgiBackInsertionSequence[] [@http://www.sgi.com/tech/stl/BackInsertionSequence.html [^BackInsertionSequence]]]
[template SgiAssociativeContainer[] [@http://www.sgi.com/tech/stl/AssociativeContainer.html [^AssociativeContainer]]]
[template SgiSimpleAssociativeContainer[] [@http://www.sgi.com/tech/stl/SimpleAssociativeContainer.html [^SimpleAssociativeContainer]]]
[template SgiPairAssociativeContainer[] [@http://www.sgi.com/tech/stl/PairAssociativeContainer.html [^PairAssociativeContainer]]]
[template SgiSortedAssociativeContainer[] [@http://www.sgi.com/tech/stl/SortedAssociativeContainer.html [^SortedAssociativeContainer]]]
[template SgiHashedAssociativeContainer[] [@http://www.sgi.com/tech/stl/HashedAssociativeContainer.html [^HashedAssociativeContainer]]]
[template SgiUniqueAssociativeContainer[] [@http://www.sgi.com/tech/stl/UniqueAssociativeContainer.html [^UniqueAssociativeContainer]]]
[template SgiMultipleAssociativeContainer[] [@http://www.sgi.com/tech/stl/MultipleAssociativeContainer.html [^MultipleAssociativeContainer]]]
[template SgiInputIterator[] [@http://www.sgi.com/tech/stl/InputIterator.html [^BidirectionalIterator]]]
[template SgiOutputIterator[] [@http://www.sgi.com/tech/stl/OutputIterator.html [^OutputIterator]]]
[template SgiForwardIterator[] [@http://www.sgi.com/tech/stl/ForwardIterator.html [^ForwardIterator]]]
[template SgiBidirectionalIterator[] [@http://www.sgi.com/tech/stl/BidirectionalIterator.html [^BidirectionalIterator]]]
[template SgiRandomAccessIterator[] [@http://www.sgi.com/tech/stl/RandomAccessIterator.html [^RandomAccessIterator]]]
[template SgiPredicate[] [@http://www.sgi.com/tech/stl/Predicate.html [^Predicate]]]
[template SgiMonoid[] [@http://www.sgi.com/tech/stl/Monoid.html [^Monoid]]]
[/ [template StdIndexable[] [link boostgraph [^Indexable]]] /]

View File

@@ -1,17 +0,0 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[section Tutorial]
This section contains a tutorial for the Boost.Graph library. It builds on the
quick tour but discusses the concepts in much greater detail.
[include tut_properties.qbk]
[include tut_adjacency_list.qbk]
[endsect]