Migrating all examples into example directory

[SVN r52509]
This commit is contained in:
Andrew Sutton 2009-04-20 14:34:59 +00:00
parent a18ee8efa5
commit c57722a10f
34 changed files with 333 additions and 265 deletions

View File

@ -1,14 +1,16 @@
//=======================================================================
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
// Copyright 2001 Jeremy G. Siek, Andrew Lumsdaine, Lie-Quan Lee,
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================
#include <boost/config.hpp>
#include <iostream>
#include <fstream>
#include <boost/graph/adjacency_list.hpp>
using namespace boost;
template < typename VertexDescriptor, typename VertexNameMap > void

View File

@ -8,11 +8,10 @@
//=======================================================================
#include <boost/config.hpp>
#include <iostream> // for std::cout
#include <utility> // for std::pair
#include <algorithm> // for std::for_each
#include <boost/utility.hpp> // for boost::tie
#include <boost/graph/graph_traits.hpp> // for boost::graph_traits
#include <iostream> // for std::cout
#include <utility> // for std::pair
#include <algorithm> // for std::for_each
#include <boost/utility.hpp> // for boost::tie
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
@ -24,7 +23,7 @@ template <class Graph> struct exercise_vertex {
void operator()(const Vertex& v) const
{
using namespace boost;
typename property_map<Graph, vertex_index_t>::type
typename property_map<Graph, vertex_index_t>::type
vertex_id = get(vertex_index, g);
std::cout << "vertex: " << get(vertex_id, v) << std::endl;
@ -32,7 +31,7 @@ template <class Graph> struct exercise_vertex {
std::cout << "\tout-edges: ";
typename graph_traits<Graph>::out_edge_iterator out_i, out_end;
typename graph_traits<Graph>::edge_descriptor e;
for (tie(out_i, out_end) = out_edges(v, g);
for (tie(out_i, out_end) = out_edges(v, g);
out_i != out_end; ++out_i)
{
e = *out_i;
@ -42,7 +41,7 @@ template <class Graph> struct exercise_vertex {
}
std::cout << std::endl;
// Write out the incoming edges
// Write out the incoming edges
std::cout << "\tin-edges: ";
typename graph_traits<Graph>::in_edge_iterator in_i, in_end;
for (tie(in_i, in_end) = in_edges(v, g); in_i != in_end; ++in_i)
@ -54,7 +53,7 @@ template <class Graph> struct exercise_vertex {
}
std::cout << std::endl;
// Write out all adjacent vertices
// Write out all adjacent vertices
std::cout << "\tadjacent vertices: ";
typename graph_traits<Graph>::adjacency_iterator ai, ai_end;
for (tie(ai,ai_end) = adjacent_vertices(v, g); ai != ai_end; ++ai)
@ -78,7 +77,7 @@ int main(int,char*[])
// writing out the edges in the graph
typedef std::pair<int,int> Edge;
Edge edge_array[] =
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]);
@ -101,7 +100,7 @@ int main(int,char*[])
transmission_delay, num_vertices);
#endif
boost::property_map<Graph, vertex_index_t>::type
boost::property_map<Graph, vertex_index_t>::type
vertex_id = get(vertex_index, g);
boost::property_map<Graph, edge_weight_t>::type
trans_delay = get(edge_weight, g);
@ -112,29 +111,29 @@ int main(int,char*[])
for (vp = vertices(g); vp.first != vp.second; ++vp.first)
std::cout << name[get(vertex_id, *vp.first)] << " ";
std::cout << std::endl;
std::cout << "edges(g) = ";
graph_traits<Graph>::edge_iterator ei, ei_end;
for (tie(ei,ei_end) = edges(g); ei != ei_end; ++ei)
std::cout << "(" << name[get(vertex_id, source(*ei, g))]
<< "," << name[get(vertex_id, target(*ei, g))] << ") ";
std::cout << std::endl;
std::for_each(vertices(g).first, vertices(g).second,
exercise_vertex<Graph>(g));
std::map<std::string,std::string> graph_attr, vertex_attr, edge_attr;
graph_attr["size"] = "3,3";
graph_attr["rankdir"] = "LR";
graph_attr["ratio"] = "fill";
vertex_attr["shape"] = "circle";
boost::write_graphviz(std::cout, g,
boost::write_graphviz(std::cout, g,
make_label_writer(name),
make_label_writer(trans_delay),
make_graph_attributes_writer(graph_attr, vertex_attr,
make_graph_attributes_writer(graph_attr, vertex_attr,
edge_attr));
return 0;
}

View File

@ -1,9 +1,8 @@
# Copyright John Maddock 2005. Use, modification, and distribution are
# subject to the Boost Software License, Version 1.0. (See accompanying
# 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

View File

@ -25,32 +25,42 @@
[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()]]]
[^breadth_first_search]]]
[template depth_first_search[] [link
boost_graph.reference.algorithms.fundamental.depth_first_search
[^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()]]]
[^dijkstra_shortest_paths]]]
[template bellman_ford_shortest_paths[] [link
boost_graph.reference.algorithms.shortest_paths.bellman_ford_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()]]]
[^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()]]]
[^johnson_all_pairs_shortest_paths]]]
[/ Connectivity /]
[template connected_components[] [link
boost_graph.reference.algorithms.connectivity.connected_components
[^connected_components()]]]
[^connected_components]]]
[template strong_connected_components[] [link
boost_graph.reference.algorithms.connectivity.strongly_connected_components
[^strongly_connected_components]]]
@ -58,80 +68,86 @@
[/ Subgraph/ ]
[template bron_kerbosch_visit_cliques[] [link
boost_graph.reference.algorithms.subgraph.bron_kerbosch_all_cliques
[^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()]]]
[^tiernan_all_cycles]]]
[template tiernan_girth[] [link
boost_graph.reference.algorithms.subgraph.tiernan_all_cycles.__tiernan_girth___
[^tiernan_girth()]]]
[^tiernan_girth]]]
[template tiernan_circumference[] [link
boost_graph.reference.algorithms.subgraph.tiernan_all_cycles.__tiernan_circumference___
[^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()]]]
[^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()]]]
[^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()]]]
[^bron_kerbosch_clique_number]]]
[/ Measures /]
[template degree_centrality[] [link
boost_graph.reference.algorithms.measures.degree_centrality.__degree_centrality___
[^degree_centrality()]]]
[^degree_centrality]]]
[template all_degree_centralities[] [link
boost_graph.reference.algorithms.measures.degree_centrality.__all_degree_centralities___
[^all_degree_centralities()]]]
[^all_degree_centralities]]]
[template closeness_centrality[] [link
boost_graph.reference.algorithms.measures.closeness_centrality.__closeness_centrality___
[^closeness_centrality()]]]
[^closeness_centrality]]]
[template all_closeness_centralities[] [link
boost_graph.reference.algorithms.measures.closeness_centrality.__all_closeness_centralities___
[^all_closeness_centralities()]]]
[^all_closeness_centralities]]]
[template mean_geodesic[] [link
boost_graph.reference.algorithms.measures.mean_geodesic.__mean_geodesic___
[^mean_geodesic()]]]
[^mean_geodesic]]]
[template all_mean_geodesics[] [link
boost_graph.reference.algorithms.measures.mean_geodesic.__all_mean_geodesics___
[^all_mean_geodesics()]]]
[^all_mean_geodesics]]]
[template small_world_distance[] [link
boost_graph.reference.algorithms.measures.mean_geodesic.__small_world_distance___
[^small_world_distance()]]]
[^small_world_distance]]]
[template eccentricity[] [link
boost_graph.reference.algorithms.measures.eccentricity.__eccentricity___
[^eccentricity()]]]
[^eccentricity]]]
[template eccentricities[] [link
boost_graph.reference.algorithms.measures.eccentricity.__eccentricities___
[^eccentricities()]]]
[^eccentricities]]]
[template radius[] [link
boost_graph.reference.algorithms.measures.eccentricity.__radius___
[^radius()]]]
[^radius]]]
[template diameter[] [link
boost_graph.reference.algorithms.measures.eccentricity.__diameter___
[^diameter()]]]
[^diameter]]]
[template radius_and_diameter[] [link
boost_graph.reference.algorithms.measures.eccentricity.__radius_and_diameter___
[^radius_and_diameter()]]]
[^radius_and_diameter]]]
[template clustering_coefficient[] [link
boost_graph.reference.algorithms.measures.clustering_coefficient.__clustering_coefficient___
[^clustering_coefficient()]]]
[^clustering_coefficient]]]
[template all_clustering_coefficients[] [link
boost_graph.reference.algorithms.measures.clustering_coefficient.__all_clustering_coefficients___
[^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()]]]
[^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()]]]
[^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]]]
@ -139,7 +155,7 @@
graph
[^exterior_edge_property]]]
[/ Import lots of examples to build code templates]
[/ Import a number of examples to build code templates /]
[import ../examples/degree_centrality.cpp]
[import ../examples/influence_prestige.cpp]
[import ../examples/closeness_centrality.cpp]

View File

@ -23,7 +23,7 @@
]
[/ Templates /]
[template super[x]'''<superscript>'''[x]'''</superscript>''']
[template sup[x]'''<superscript>'''[x]'''</superscript>''']
[template sub[x]'''<subscript>'''[x]'''</subscript>''']
[template delta[]'''&#x3B4;'''] [/ d Greek small letter delta]

View File

@ -10,7 +10,7 @@
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).
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)
@ -23,11 +23,11 @@ were written using the generic programming style of the STL, and hence did not f
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.
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 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
@ -37,15 +37,25 @@ While working at SGI, Jeremy heard about Boost and was excited to find a group o
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.
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
* New algorithms and components
* 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.
@ -53,7 +63,7 @@ The first release of BGL was September 27, 2000.
* LEDA Adaptor improvements, from Jens Muller.
* Version 1.34.0
* New algorithms and components
* 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.
@ -69,15 +79,15 @@ The first release of BGL was September 27, 2000.
* 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.
* 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
* 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
* 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.

View File

@ -1,129 +1,148 @@
[/
/ Copyright (c) 2007 Andrew Sutton
/ 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.
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.
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.
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.
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.
[*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.
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.
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
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!
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.
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.
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.
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()`.
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.
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 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 re-use.
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
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:
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
@ -146,21 +165,23 @@ Boost.Graph currently provides two graph classes and an edge list adaptor:
* 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_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|2.
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.
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]
This section should probably be merged into the global "Who's using me now page". But, for completeness
here's the list (with links, too):
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]
@ -177,6 +198,8 @@ here's the list (with links, too):
* [@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)
@ -185,30 +208,35 @@ here's the list (with links, too):
* 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.
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;
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.
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.
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.
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.
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.
In our work we also used resources of the National Energy Research Scientific
Computing Center, which is supported by the Office of Science of the U.S.
Department of Energy.
[endsect]

View File

@ -141,9 +141,9 @@ 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[super 2]*O(M))] where /n/
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[super 2])] by default
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.

View File

@ -97,10 +97,10 @@ on a directed graph will double the performance penalty (which is generally negl
]
[heading Complexity]
This problem has a loose upper bound of ['O(2[super n])] if one considers all possible
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[super n])].
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

View File

@ -228,9 +228,9 @@ or as the result of a [breadth_first_search] (if the graph is unweighted).
]
[heading Complexity]
The `all_closenesss_centralities()` function returns in ['O(n[super 2]*O(M))] where /n/
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[super 2])]
measure. If no distance measure is given, this functions returns in ['O(n[sup 2])]
time.
[endsect]

View File

@ -117,7 +117,7 @@ The `clustering_coefficient()` function returns the clustering coefficient of th
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)[super 2]] where
The `clustering_coefficient()` function returns in ['O(d(v)[sup 2]] where
/d(v)/ is the degree of /v/.
[endsect]
@ -159,7 +159,7 @@ coefficient to the caller.
]
[heading Complexity]
The `all_clustering_coefficients()` function returns in ['O(nd[super 2])] where
The `all_clustering_coefficients()` function returns in ['O(nd[sup 2])] where
/d/ is the mean (average) degree of vertices in the graph.
[endsect]

View File

@ -145,7 +145,7 @@ The `eccentricities()` function returns a pair containing the radius and diamete
as the `first` and `second` elements respectively.
[heading Complexity]
The `eccentricities()` function returns in ['O(n[super 2])] where /n/ is the number
The `eccentricities()` function returns in ['O(n[sup 2])] where /n/ is the number
of vertices in the graph.
[endsect]

View File

@ -223,7 +223,7 @@ If any vertices have infinite mean geodesic distance, then the small-world dista
will also be infinite.
[heading Complexity]
The `all_mean_geodesics()` function returns in ['O(n[super 2]*O(M))] where /n/ is the
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]

View File

@ -134,7 +134,7 @@ in an undirected graph as a cycle.
]
[heading Complexity]
This function has a (loose) upper bound of ['O(2[super n])] where /n/ is the
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}
@ -142,7 +142,7 @@ and {3, 2, 1} to be distinct cycles within a graph, then this bound can potentia
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[super 2])] space where /n/ is the number of vertices
This function requires ['O(n[sup 2])] space where /n/ is the number of vertices
in a graph.
[endsect]

View File

@ -6,43 +6,55 @@
/]
[section A Quick tour of Boost.Graph]
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
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.
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.
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<>` 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
In this example
[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
@ -83,16 +95,17 @@ edges for this example.
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.
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.
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
@ -108,7 +121,7 @@ The following example prints out the index for each of the vertices in the graph
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.
property map object.
// ...
@ -132,7 +145,7 @@ property map object.
return 0;
}
The output is:
The output is:
[pre
vertices(g) = 0 1 2 3 4
@ -147,7 +160,7 @@ functions return the two vertices that are connected by the edge. Instead of exp
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*[])
{
@ -173,8 +186,8 @@ In the next few examples we will explore the adjacency structure of the graph fr
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.
function to iterate through the vertices and apply the function.
//...
int main(int,char*[])
{
@ -187,8 +200,8 @@ We use a functor for exercise_vertex instead of just a function because the grap
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:
of the exercise_vertex functor:
template <class Graph> struct exercise_vertex {
exercise_vertex(Graph& g_) : g(g_)
{ }
@ -210,8 +223,8 @@ that can be used to access information about the graph via the `out_edges()`, `i
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:
apply method:
template <class Graph> struct exercise_vertex {
// ... continued from above
@ -234,8 +247,9 @@ iterators). The iterators are called out-edge iterators and dereferencing one of
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 {
template <class Graph>
struct exercise_vertex {
//... continued from above
void operator()(const Vertex& v) const
@ -260,7 +274,7 @@ the source-target pairs for each out-edge of vertex, v.
// ...
};
For vertex 0 the output is:
For vertex 0 the output is:
[pre
out-edges: (0,1) (0,2) (0,3) (0,4)
]
@ -268,8 +282,8 @@ For vertex 0 the output is:
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`.
extra cost in space when `bidirectionalS` is specified instead of `directedS`.
template <class Graph> struct exercise_vertex {
// ... continued from above
@ -291,7 +305,7 @@ extra cost in space when `bidirectionalS` is specified instead of `directedS`.
// ...
};
For vertex 0 the output is:
For vertex 0 the output is:
[pr
in-edges: (2,0) (3,0) (4,0)
]
@ -302,8 +316,8 @@ vertex. Sometimes an algorithm does not need to look at the edges of the graph a
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.
for an adjacent vertex.
template <class Graph> struct exercise_vertex {
// ... continued from above
@ -322,7 +336,7 @@ for an adjacent vertex.
//...
};
For vertex 4 the output is:
For vertex 4 the output is:
[pre
adjacent vertices: 0 1
]
@ -337,7 +351,7 @@ the graph object. The first kind of property is called an internally stored prop
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.
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
@ -347,11 +361,11 @@ properties is to create an array indexed by vertex or edge index. In the adjacen
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.
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.
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
@ -362,9 +376,9 @@ The listS and vecS types are selectors that determine the data structure used in
`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 /RandomAccessIterator/).
graph constructor in the form of iterators (a pointer qualifies as a /RandomAccessIterator/).
typedef adjacency_list<listS, vecS, directedS,
typedef adjacency_list<listS, vecS, directedS,
no_property, // no additional vertex properties
property<edge_weight_t, int> // edges have integer edge weight
> Graph;
@ -372,9 +386,9 @@ graph constructor in the form of iterators (a pointer qualifies as a /RandomAcce
typedef std::pair<int,int> E;
const int num_nodes = 5;
E edges[] = { E(0,2),
E edges[] = { E(0,2),
E(1,1), E(1,3), E(1,4),
E(2,1), E(2,3),
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};
@ -385,8 +399,8 @@ For the external distance property we will use a std::vector for storage. Boost.
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.
internal edge weight property), and then the output of the results.
// vector for storing distance property
std::vector<int> d(num_vertices(G));
@ -399,11 +413,11 @@ internal edge weight property), and then the output of the results.
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) << ") = "
std::cout << "distance(" << index(*vi) << ") = "
<< d[*vi] << ;
std::cout << ;
The output is:
The output is:
[pre
distances from start vertex:
distance(0) = 0
@ -417,7 +431,7 @@ The output is:
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.
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
@ -439,7 +453,7 @@ then only be responsible for what parent to record. To implement this, we create
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<>
{
@ -466,8 +480,8 @@ to invoke the `explore()` method. In this case we only want to be notified about
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.
visitors. All Boost.Graph visitors have a helper function like this.
template <class PredecessorMap>
record_predecessors<PredecessorMap>
make_predecessor_recorder(PredecessorMap p) {
@ -477,25 +491,25 @@ visitors. All Boost.Graph visitors have a helper function like this.
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).
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)); //the predecessor array
dijkstra_shortest_paths(G, s, distance_map(&d[0]).
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] == Vertex())
cout << ") = no parent" << endl;
else
cout << ") = no parent" << endl;
else
cout << ") = " << p[*vi] << endl;
}
The output is:
The output is:
[pre
parents in the tree of shortest paths:
parent(0) = no parent