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:
@@ -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
|
||||
|
||||
;
|
||||
@@ -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]
|
||||
@@ -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]]]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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[]'''δ'''] [/ 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] /]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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)
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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}
|
||||
@@ -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)
|
||||
@@ -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;
|
||||
};
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
|
||||
graph G {
|
||||
subgraph cluster_0 {
|
||||
0 -- 1 -- 2 -- 0;
|
||||
label = "Component 0";
|
||||
}
|
||||
subgraph cluster_1 {
|
||||
3 -- 4;
|
||||
label = "Component 1";
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
graph G {
|
||||
0 -- 1 -- 2 -- 0;
|
||||
3 -- 4;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
digraph G {
|
||||
0 -> 1;
|
||||
1 -> 2;
|
||||
2 -> 3;
|
||||
3 -> 5;
|
||||
5 -> 4;
|
||||
4 -> 1;
|
||||
4 -> 3;
|
||||
5 -> 2;
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
|
||||
graph G {
|
||||
0 -- 1;
|
||||
1 -- 2;
|
||||
2 -- 3;
|
||||
3 -- 5;
|
||||
5 -- 4;
|
||||
4 -- 1;
|
||||
4 -- 3;
|
||||
2 -- 5
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
digraph {
|
||||
0 -> 1 -> 2 -> 0;
|
||||
3 -> 4 -> 5 -> 3;
|
||||
0 -> 3 -> 0;
|
||||
1 -> 4 -> 1;
|
||||
2 -> 5 -> 2;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
@@ -1,3 +0,0 @@
|
||||
graph {
|
||||
0 -- 1 -- 2 -- 0;
|
||||
}
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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<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<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]
|
||||
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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<edge_iterator, edge_iterator><br>
|
||||
edges(const edge_list& 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& g)
|
||||
</tt>
|
||||
<br><br>
|
||||
Returns the source vertex of edge `e`.
|
||||
|
||||
<hr>
|
||||
|
||||
<tt>
|
||||
vertex_descriptor<br>
|
||||
target(edge_descriptor e, const edge_list& 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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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]]] /]
|
||||
@@ -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]
|
||||
Reference in New Issue
Block a user