diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..a4ce58c4 --- /dev/null +++ b/.clang-format @@ -0,0 +1,16 @@ +BasedOnStyle: WebKit +Standard: Cpp11 +AlignAfterOpenBracket: false +AlignEscapedNewlinesLeft: true +AlwaysBreakAfterDefinitionReturnType: None +BreakBeforeBraces: Allman +BreakConstructorInitializersBeforeComma: false +ColumnLimit: 80 +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 0 +IndentCaseLabels: false +SortIncludes: false +AlignTrailingComments: false + +SpacesInAngles: true + diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..07aa1b3b --- /dev/null +++ b/.travis.yml @@ -0,0 +1,65 @@ +# Use, modification, and distribution are +# subject to 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) +# +# Mael Valais, 2016 +# This travis file has been inspired from boostorg/geometry/circle.yml. +# +# This file is intended to make use of travis-ci, a continuous integration +# service. The purpose is to build and run the tests on the graph module +# on every push, and be able to know if those commits are "clean" or if +# they break the build. +# + +# I think that we shouldn't restrict on branches: PRs must also be tested +# So for now, I disabled the "only on branches" feature +#branches: +# only: +# - master +# - develop +# - test + +language: cpp +compiler: gcc + +env: + global: + - BOOST_BRANCH=$([[ "$TRAVIS_BRANCH" = "master" ]] && echo master || echo develop) + - BOOST=boost-local # must be different from graph/boost dir name +addons: + apt: + sources: ubuntu-toolchain-r-test + packages: g++-4.8 + +before_install: + # Clone boost repository + - cd + - mkdir $BOOST && cd $BOOST + - git init . + - git remote add --no-tags -t $BOOST_BRANCH origin https://github.com/boostorg/boost.git + - git fetch --depth=1 + - git checkout $BOOST_BRANCH + - git submodule update --init --merge + - git remote set-branches --add origin $BOOST_BRANCH + - git pull --recurse-submodules + - git submodule update --init + - git checkout $BOOST_BRANCH + - git submodule foreach "git reset --quiet --hard; git clean -fxd" + - git reset --hard; git clean -fxd + - git status + + # replace the content of the library with the currently tested repo + - cd && pwd && ls + - rm -rf $BOOST/libs/graph + - cd $TRAVIS_BUILD_DIR && cd .. + - mv graph $HOME/$BOOST/libs/ + + # build b2 and create headers + - cd && cd $BOOST + - ./bootstrap.sh + - ./b2 headers + +# This part is meant for unit tests +script: + - cd $HOME/$BOOST/libs/graph/test + - ../../../b2 toolset=gcc-4.8 cxxflags=-std=c++11 diff --git a/README.md b/README.md new file mode 100644 index 00000000..7a4dc735 --- /dev/null +++ b/README.md @@ -0,0 +1,44 @@ +Boost Graph Library +=================== + +A generic interface for traversing graphs, using C++ templates. + +The full documentation is available on [boost.org](http://www.boost.org/doc/libs/release/libs/graph/doc/index.html). + +## Support, bugs and feature requests ## + +Bugs and feature requests can be reported through the [Trac issue tracker](https://svn.boost.org/trac/boost/query?component=graph&desc=1&order=id) +(see [open issues](https://svn.boost.org/trac/boost/query?status=!closed&component=graph&desc=1&order=id) and +[closed issues](https://svn.boost.org/trac/boost/query?status=closed&component=graph&col=id&col=summary&col=status&col=owner&col=type&col=milestone&col=version&desc=1&order=id)). [Here](http://lists.boost.org/Archives/boost/2015/04/221780.php) is why Trac is still in use. + +You can submit your changes through a [pull request](https://github.com/boostorg/graph/pulls). One of the maintainers will take a look (remember that it can take some time). + +There is no mailing-list specific to Boost Graph, although you can use the general-purpose Boost [mailing-list](http://lists.boost.org/mailman/listinfo.cgi/boost-users) using the tag [graph]. + + +## Development ## + +Clone the whole boost project, which includes the individual Boost projects as submodules ([see boost+git doc](https://github.com/boostorg/boost/wiki/Getting-Started)): + + git clone https://github.com/boostorg/boost + cd boost + git submodule update --init + +The Boost Graph Library is located in `libs/graph/`. + +Boost Graph Library is mostly made of headers but also contains some compiled components. Here are the build commands: + + ./bootstrap.sh <- compile b2 + ./b2 headers <- just installs headers + ./b2 <- build compiled components + +**Note:** The Boost Graph Library cannot currently be built outside of Boost itself. + +### Running tests ### +First, make sure you are in `libs/graph/test`. +You can either run all the 300+ tests listed in `Jamfile.v2` or run a single test: + + ../../../b2 <- run all tests + ../../../b2 cycle_canceling_test <- single test + +You can also check the [regression tests reports](http://beta.boost.org/development/tests/develop/developer/graph.html). diff --git a/doc/AdjacencyGraph.html b/doc/AdjacencyGraph.html index b72031b1..efe6a891 100644 --- a/doc/AdjacencyGraph.html +++ b/doc/AdjacencyGraph.html @@ -112,7 +112,6 @@ The adjacent_vertices() function must return in constant time. typedef typename boost::graph_traits<G>::adjacency_iterator adjacency_iterator; void constraints() { - BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept<G> )); BOOST_CONCEPT_ASSERT(( MultiPassInputIteratorConcept<adjacency_iterator> )); p = adjacent_vertices(v, g); diff --git a/doc/BidirectionalGraph.html b/doc/BidirectionalGraph.html index e5a92215..e5b551e0 100644 --- a/doc/BidirectionalGraph.html +++ b/doc/BidirectionalGraph.html @@ -149,16 +149,21 @@ undirected graphs). BOOST_CONCEPT_ASSERT(( MultiPassInputIteratorConcept<in_edge_iterator> )); p = in_edges(v, g); + n = in_degree(v, g); + n = degree(v, g); e = *p.first; const_constraints(g); } void const_constraints(const G& g) { p = in_edges(v, g); + n = in_degree(v, g); + n = degree(v, g); e = *p.first; } std::pair<in_edge_iterator, in_edge_iterator> p; typename boost::graph_traits<G>::vertex_descriptor v; typename boost::graph_traits<G>::edge_descriptor e; + typename boost::graph_traits<G>::degree_size_type n; G g; }; diff --git a/doc/adjacency_list.html b/doc/adjacency_list.html index 10cc75f1..3574d501 100644 --- a/doc/adjacency_list.html +++ b/doc/adjacency_list.html @@ -1,7 +1,7 @@ - - - + + + Boost Graph Library: Edge Coloring - -C++ Boost + +C++ Boost
@@ -46,7 +46,7 @@

Computes an edge coloring for the vertices in the graph, using -an algorithm proposed by Mista et al. []. Given edges ordered +an algorithm proposed by Misra et al. []. Given edges ordered e1, e2, ..., en it assignes a colors c1, c2, ..., cn in a way that no vertex connects with 2 edges of the same color. Furthermore @@ -95,4 +95,4 @@ Maciej Piechotka (uzytkownik2@gmail.com - + diff --git a/doc/edmonds_karp_max_flow.html b/doc/edmonds_karp_max_flow.html index 56875369..e40a9339 100644 --- a/doc/edmonds_karp_max_flow.html +++ b/doc/edmonds_karp_max_flow.html @@ -195,7 +195,7 @@ IN: vertex_index_map(VertexIndexMap i_map) Default: get(vertex_index, g) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property. diff --git a/doc/figs/cr.jpg b/doc/figs/cr.jpg old mode 100755 new mode 100644 diff --git a/doc/figs/dominator-tree1.gif b/doc/figs/dominator-tree1.gif old mode 100755 new mode 100644 diff --git a/doc/figs/dominator-tree2.gif b/doc/figs/dominator-tree2.gif old mode 100755 new mode 100644 diff --git a/doc/figs/maximal-match.png b/doc/figs/maximal-match.png old mode 100755 new mode 100644 diff --git a/doc/figs/maximum-match.png b/doc/figs/maximum-match.png old mode 100755 new mode 100644 diff --git a/doc/figs/mcr.jpg b/doc/figs/mcr.jpg old mode 100755 new mode 100644 diff --git a/doc/figs/very_complex_graph.gif b/doc/figs/very_complex_graph.gif old mode 100755 new mode 100644 diff --git a/doc/filtered_graph.html b/doc/filtered_graph.html index 8f5d1c39..75e27784 100644 --- a/doc/filtered_graph.html +++ b/doc/filtered_graph.html @@ -257,7 +257,7 @@ The type used for dealing with the number of vertices in the graph.


-graph_traits<filtered_graph>::edge_size_type +graph_traits<filtered_graph>::edges_size_type

The type used for dealing with the number of edges in the graph. diff --git a/doc/fruchterman_reingold.html b/doc/fruchterman_reingold.html index f0ea6bd9..966badfd 100644 --- a/doc/fruchterman_reingold.html +++ b/doc/fruchterman_reingold.html @@ -198,7 +198,7 @@ IN: vertex_index_map(VertexIndexMap i_map) Default: get(vertex_index, g) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property.
Python: Unsupported parameter. diff --git a/doc/graph_concepts.html b/doc/graph_concepts.html index 9b5b5cd3..64898b24 100644 --- a/doc/graph_concepts.html +++ b/doc/graph_concepts.html @@ -174,7 +174,7 @@ the graph can be visited. boost::graph_traits<G>::degree_size_type The integer type for -vertex degee. +vertex degree. out_edges(v, g) diff --git a/doc/graph_theory_review.html b/doc/graph_theory_review.html index 33a6d2cd..625bd654 100644 --- a/doc/graph_theory_review.html +++ b/doc/graph_theory_review.html @@ -217,7 +217,7 @@ 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 +parallel edge (b,y)). The amount 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 @@ -527,7 +527,7 @@ A flow network is a directed graph G=(V,E) with a 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: +constraints:

f(u,v) <= c(u,v) for all (u,v) in V x V (Capacity constraint)
diff --git a/doc/graph_traits.html b/doc/graph_traits.html index 66b93a2b..c9b30c62 100644 --- a/doc/graph_traits.html +++ b/doc/graph_traits.html @@ -218,7 +218,7 @@ vertices in the graph. -edge_size_type +edges_size_type The unsigned integer type used for representing the number of diff --git a/doc/gursoy_atun_layout.html b/doc/gursoy_atun_layout.html index db61443e..8af8bbea 100644 --- a/doc/gursoy_atun_layout.html +++ b/doc/gursoy_atun_layout.html @@ -171,7 +171,7 @@ IN: VertexIndexMap vertex_index_map Default: get(vertex_index, g) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property. diff --git a/doc/hawick_circuits.html b/doc/hawick_circuits.html index 5fabcf7c..3e6516c6 100644 --- a/doc/hawick_circuits.html +++ b/doc/hawick_circuits.html @@ -1,3 +1,11 @@ + +

C++ Boost

@@ -17,7 +25,7 @@ self-loops and redundant circuits caused by parallel edges are enumerated too. edges are not desired.

The algorithm is described in detail in -http://www.massey.ac.nz/~kahawick/cstn/013/cstn-013.pdf.

+http://complexity.massey.ac.nz/cstn/013/cstn-013.pdf.

Where defined

@@ -54,5 +62,5 @@ edges are not desired.


diff --git a/doc/hawick_circuits.md b/doc/hawick_circuits.md deleted file mode 100644 index 828a71b9..00000000 --- a/doc/hawick_circuits.md +++ /dev/null @@ -1,53 +0,0 @@ - - -![C++ Boost](../../../boost.png) - -# `hawick_circuits` - - template - void hawick_circuits(Graph const& graph, Visitor visitor, VertexIndexMap const& vim = get(vertex_index, graph)); - - template - void hawick_unique_circuits(Graph const& graph, Visitor visitor, VertexIndexMap const& vim = get(vertex_index, graph)); - -Enumerate all the elementary circuits in a directed multigraph. Specifically, -self-loops and redundant circuits caused by parallel edges are enumerated too. -`hawick_unique_circuits` may be used if redundant circuits caused by parallel -edges are not desired. - -The algorithm is described in detail in -. - - -### Where defined - -[`#include `](../../../boost/graph/hawick_circuits.hpp) - - -### Parameters - -__IN:__ `Graph const& graph` - -> The graph on which the algorithm is to be performed. It must be a model of -> the `VertexListGraph` and `AdjacencyGraph` concepts. - -__IN:__ `Visitor visitor` - -> The visitor that will be notified on each circuit found by the algorithm. -> The `visitor.cycle(circuit, graph)` expression must be valid, with `circuit` -> being a `const`-reference to a random access sequence of `vertex_descriptor`s. -> -> For example, if a circuit `u -> v -> w -> u` exists in the graph, the -> visitor will be called with a sequence consisting of `(u, v, w)`. - -__IN:__ `VertexIndexMap const& vim = get(vertex_index, graph)` - -> A model of the `ReadablePropertyMap` concept mapping each `vertex_descriptor` -> to an integer in the range `[0, num_vertices(graph))`. It defaults to using -> the vertex index map provided by the `graph`. - - ------------------------------------------------------------------------------- - diff --git a/doc/index.html b/doc/index.html index d8f92c6d..426edef4 100644 --- a/doc/index.html +++ b/doc/index.html @@ -161,7 +161,7 @@ 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 +built interfacing code for using a variety of graph structures (LEDA graphs, Stanford GraphBase graphs, and even Fortran-style arrays) in BGL graph algorithms. diff --git a/doc/isomorphism.html b/doc/isomorphism.html index 3b86077b..7a19f3b0 100644 --- a/doc/isomorphism.html +++ b/doc/isomorphism.html @@ -147,7 +147,7 @@ map.
Default: get(vertex_index, g1) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property.
Python: Unsupported parameter. @@ -166,7 +166,7 @@ map.
Default: get(vertex_index, g2) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property.
Python: Unsupported parameter. diff --git a/doc/kamada_kawai_spring_layout.html b/doc/kamada_kawai_spring_layout.html index 45386fc7..85ee54a2 100644 --- a/doc/kamada_kawai_spring_layout.html +++ b/doc/kamada_kawai_spring_layout.html @@ -246,7 +246,7 @@ As a mapping from vertices to index values between 0 and Default:get(vertex_index,g). Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property.
Python: Unsupported parameter. diff --git a/doc/kruskal_min_spanning_tree.html b/doc/kruskal_min_spanning_tree.html index 69d2a2a9..ff65133c 100644 --- a/doc/kruskal_min_spanning_tree.html +++ b/doc/kruskal_min_spanning_tree.html @@ -166,7 +166,7 @@ IN: vertex_index_map(VertexIndexMap i_map) Default: get(vertex_index, g) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property.
diff --git a/doc/metric_tsp_approx.html b/doc/metric_tsp_approx.html index b475c9d3..fdc19d85 100644 --- a/doc/metric_tsp_approx.html +++ b/doc/metric_tsp_approx.html @@ -143,7 +143,7 @@ IN: VertexIndexMap indexmap Default: get(vertex_index, g) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property.
diff --git a/doc/profile.htm b/doc/profile.htm old mode 100755 new mode 100644 diff --git a/doc/push_relabel_max_flow.html b/doc/push_relabel_max_flow.html index 5dff0504..d70bad3e 100644 --- a/doc/push_relabel_max_flow.html +++ b/doc/push_relabel_max_flow.html @@ -77,7 +77,7 @@ The time complexity is O(V3).

Where Defined

-boost/graph/preflow_push_max_flow.hpp +boost/graph/push_relabel_max_flow.hpp

@@ -141,7 +141,7 @@ IN: vertex_index_map(VertexIndexMap index_map) Default: get(vertex_index, g) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property.
diff --git a/doc/quick_tour.html b/doc/quick_tour.html index 5156bb7b..7a9fd725 100644 --- a/doc/quick_tour.html +++ b/doc/quick_tour.html @@ -160,6 +160,8 @@ call get(vertex_index, g) returns the actual property map object. { // ... + typedef graph_traits<Graph>::vertex_descriptor Vertex; + // get the property map for vertex indices typedef property_map<Graph, vertex_index_t>::type IndexMap; IndexMap index = get(vertex_index, g); @@ -167,8 +169,10 @@ call get(vertex_index, g) returns the actual property map object. std::cout << "vertices(g) = "; typedef graph_traits<Graph>::vertex_iterator vertex_iter; std::pair<vertex_iter, vertex_iter> vp; - for (vp = vertices(g); vp.first != vp.second; ++vp.first) - std::cout << index[*vp.first] << " "; + for (vp = vertices(g); vp.first != vp.second; ++vp.first) { + Vertex v = *vp.first; + std::cout << index[v] << " "; + } std::cout << std::endl; // ... return 0; diff --git a/doc/r_c_shortest_paths.html b/doc/r_c_shortest_paths.html old mode 100755 new mode 100644 diff --git a/doc/reverse_graph.html b/doc/reverse_graph.html index bb4a10f1..761b7545 100644 --- a/doc/reverse_graph.html +++ b/doc/reverse_graph.html @@ -190,7 +190,7 @@ The type used for dealing with the number of vertices in the graph.


-graph_traits<reverse_graph>::edge_size_type +graph_traits<reverse_graph>::edges_size_type

The type used for dealing with the number of edges in the graph. diff --git a/doc/sloan_ordering.htm b/doc/sloan_ordering.htm old mode 100755 new mode 100644 diff --git a/doc/sloan_start_end_vertices.htm b/doc/sloan_start_end_vertices.htm old mode 100755 new mode 100644 diff --git a/doc/stanford_graph.html b/doc/stanford_graph.html index f418deca..6940364c 100644 --- a/doc/stanford_graph.html +++ b/doc/stanford_graph.html @@ -124,7 +124,7 @@ headerfile <string.h> (if SYSV is #defined) or the headerfile <strings.h> (if SYSV is not #defined).  Some compilers, like gcc/g++, don't care much (gcc "knows" about the "string" functions without -refering to <string.h>), but others, like MSVC on Win32, do (so +referring to <string.h>), but others, like MSVC on Win32, do (so all "Developer Studio Projects" in the "MSVC" subdirectory of the SGB distribution appropriately define SYSV). You should be careful to set (or not) SYSV according to the needs of diff --git a/doc/strong_components.html b/doc/strong_components.html index 64451c34..39c0cc52 100644 --- a/doc/strong_components.html +++ b/doc/strong_components.html @@ -84,7 +84,7 @@ 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 Writable Property -Map. The value type shouch be an integer type, preferably the same +Map. The value type should 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.
@@ -162,7 +162,7 @@ IN: vertex_index_map(VertexIndexMap i_map) Default: get(vertex_index, g) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property.
diff --git a/doc/subgraph.html b/doc/subgraph.html index 90c6019c..4150a38d 100644 --- a/doc/subgraph.html +++ b/doc/subgraph.html @@ -1,17 +1,17 @@ Boost Graph Library: Subgraph - -C++ Boost + +C++ Boost
@@ -71,7 +71,7 @@ create the root graph object. Here we use adjacency_list as the underlying graph implementation. The underlying graph type is required to have vertex_index and edge_index internal properties, so we add an edge index property to the adjacency -list. We do not need to add a vertex index properety because that is +list. We do not need to add a vertex index property because that is built in to the adjacency_list. We will be building the graph and subgraphs in Figure 1, so we will need a total of six vertices. @@ -83,7 +83,7 @@ typedef subgraph< adjacency_list< vecS, vecS, directedS, const int N = 6; Graph G0(N); -enum { A, B, C, D, E, F}; // for conveniently refering to vertices in G0 +enum { A, B, C, D, E, F}; // for conveniently referring to vertices in G0 Next we create two empty subgraph objects, specifying G0 as @@ -91,8 +91,8 @@ their parent.
 Graph& G1 = G0.create_subgraph(), G2 = G0.create_subgraph();
-enum { A1, B1, C2 }; // for conveniently refering to vertices in G1
-enum { A2, B2 };     // for conveniently refering to vertices in G2
+enum { A1, B1, C2 }; // for conveniently referring to vertices in G1
+enum { A2, B2 };     // for conveniently referring to vertices in G2
 
We can add vertices from the root graph to the subgraphs using the @@ -187,7 +187,7 @@ the underlying Graph type.
 graph_traits<subgraph>::vertex_descriptor
 
- The type for the vertex descriptors. + The type for the vertex descriptors. (Required by Graph.)
@@ -195,7 +195,7 @@ graph_traits<subgraph>::vertex_descriptor
 graph_traits<subgraph>::edge_descriptor
 
- The type for the edge descriptors. + The type for the edge descriptors. (Required by Graph.)
@@ -203,7 +203,7 @@ graph_traits<subgraph>::edge_descriptor
 graph_traits<subgraph>::vertex_iterator
 
- The type for the iterators returned by vertices. + The type for the iterators returned by vertices. (Required by VertexListGraph.)
@@ -211,14 +211,14 @@ graph_traits<subgraph>::vertex_iterator
 graph_traits<subgraph>::edge_iterator
 
- The type for the iterators returned by edges. + The type for the iterators returned by edges. (Required by EdgeListGraph.)
 graph_traits<subgraph>::out_edge_iterator
 
- The type for the iterators returned by out_edges. + The type for the iterators returned by out_edges. (Required by IncidenceGraph.)
@@ -226,14 +226,14 @@ graph_traits<subgraph>::out_edge_iterator graph_traits<subgraph>::in_edge_iterator The in_edge_iterator is the - iterator type returned by the in_edges function. + iterator type returned by the in_edges function. (Required by BidirectionalGraph.)
 graph_traits<subgraph>::adjacency_iterator
 
- The type for the iterators returned by adjacent_vertices. + The type for the iterators returned by adjacent_vertices. (Required by AdjacencyGraph.)
@@ -252,7 +252,7 @@ graph_traits<subgraph>::edge_parallel_category parallel edges (edges with the same source and target), which depends on the underlying Graph class. The two tags are allow_parallel_edge_tag and - disallow_parallel_edge_tag. + disallow_parallel_edge_tag. (Required by Graph.)
@@ -388,7 +388,7 @@ subgraph& parent()
 std::pair<children_iterator, children_iterator> children() const
 
-Return an iterator pair for accessing the children subgraphs. +Return an iterator pair for accessing the children subgraphs. @@ -441,7 +441,7 @@ out_edges(vertex_descriptor u_local, const subgraph& g) Returns an iterator range providing access to the out-edges of vertex u in subgraph g. If the graph is undirected, this iterator range provides access to all edge incident on - vertex u. + vertex u. (Required by IncidenceGraph.)
@@ -451,7 +451,7 @@ in_edges(vertex_descriptor v_local, const subgraph& g) Returns an iterator range providing access to the in-edges of vertex - v in subgraph g. + v in subgraph g. (Required by BidirectionalGraph.)
@@ -482,7 +482,7 @@ out_degree(vertex_descriptor u_local, const subgraph& g)
 degree_size_type in_degree(vertex_descriptor u_local, const subgraph& g)
 
- Returns the number of edges entering vertex u in subgraph g. + Returns the number of edges entering vertex u in subgraph g. (Required by BidirectionalGraph.)
@@ -543,7 +543,7 @@ void remove_edge(vertex_descriptor u_local, vertex_descriptor v_local, subgraph& g) Removes the edge (u,v) from the subgraph and from all of the - ancestors of g in the subgraph tree. + ancestors of g in the subgraph tree. (Required by EdgeMutableGraph.)
@@ -551,7 +551,7 @@ void remove_edge(vertex_descriptor u_local, vertex_descriptor v_local, void remove_edge(edge_descriptor e_local, subgraph& g) Removes the edge e from the subgraph and from all of the - ancestors of g in the subgraph tree. + ancestors of g in the subgraph tree. (Required by EdgeMutableGraph.)
@@ -591,7 +591,7 @@ get(PropertyTag, const subgraph& g) descriptor for one subgraph will change the property for the global vertex descriptor, and therefore for all other subgraphs. However, the key type for a subgraph's property map is a subgraph-local - vertex or edge descriptor. + vertex or edge descriptor. (Required by PropertyGraph.)
@@ -605,7 +605,7 @@ get(PropertyTag, const subgraph& g, Key k_local) This returns the property value for the key k_local, which is either a local vertex or local edge descriptor. See the above get function - for more information about the propert maps. + for more information about the property maps. (Required by PropertyGraph.)
@@ -656,11 +656,11 @@ properties into a property that contains an appropriate index. For example:
 struct my_vertex { ... };
-typedef property<vertex_index_t, std::size_t, vertex_prop> vertex_prop;
+typedef property<vertex_index_t, std::size_t, my_vertex> vertex_prop;
 
 struct my_edge { ... };
-typedef property<edge_index_t, std::size_t, vertex_prop> edge_prop;
+typedef property<edge_index_t, std::size_t, my_edge> edge_prop;
 
 typedef adjacency_list<vecS, listS, undirectedS, vertex_prop, edge_prop> Graph;
-typdef subgraph<Graph> Subgraph;
+typedef subgraph<Graph> Subgraph;
 
diff --git a/doc/successive_shortest_path_nonnegative_weights.html b/doc/successive_shortest_path_nonnegative_weights.html index d6d53be2..434eabbb 100644 --- a/doc/successive_shortest_path_nonnegative_weights.html +++ b/doc/successive_shortest_path_nonnegative_weights.html @@ -214,7 +214,7 @@ IN: vertex_index_map(VertexIndexMap i_map) Default: get(vertex_index, g) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property. diff --git a/doc/topological_sort.html b/doc/topological_sort.html index 0f72470f..eba74f87 100644 --- a/doc/topological_sort.html +++ b/doc/topological_sort.html @@ -101,7 +101,7 @@ IN: vertex_index_map(VertexIndexMap i_map) Default: get(vertex_index, g) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property.
diff --git a/doc/transitive_closure.html b/doc/transitive_closure.html index 58c33182..f5310b85 100644 --- a/doc/transitive_closure.html +++ b/doc/transitive_closure.html @@ -97,7 +97,7 @@ IN: vertex_index_map(VertexIndexMap& index_map) Default: get(vertex_index, g) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property.
diff --git a/doc/transpose_graph.html b/doc/transpose_graph.html index 7c7057f3..57ea481b 100644 --- a/doc/transpose_graph.html +++ b/doc/transpose_graph.html @@ -91,7 +91,7 @@ integers from 0 to num_vertices(G).
Default: get(vertex_index, G) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property. diff --git a/doc/undirected_dfs.html b/doc/undirected_dfs.html index 78def89b..c29792d4 100644 --- a/doc/undirected_dfs.html +++ b/doc/undirected_dfs.html @@ -253,7 +253,7 @@ IN: vertex_index_map(VertexIndexMap i_map) Default: get(vertex_index, g) Note: if you use this default, make sure your graph has an internal vertex_index property. For example, - adjacenty_list with VertexList=listS does + adjacency_list with VertexList=listS does not have an internal vertex_index property.
diff --git a/doc/users.html b/doc/users.html index 497b1d0c..65b23306 100644 --- a/doc/users.html +++ b/doc/users.html @@ -33,7 +33,7 @@ or form.

  • BGL interface for language R.
  • CUJ Article about Electronic Design Automation
  • -
  • A BGL-inspired Ruby Graph Library
  • +
  • A BGL-inspired Ruby Graph Library
  • A BGL-inspired C# Graph Library
  • A BGL-inspired Squeak (Smalltalk) Graph Library
  • BGL course at DataSim
  • diff --git a/doc/vf2_sub_graph_iso.html b/doc/vf2_sub_graph_iso.html old mode 100755 new mode 100644 diff --git a/doc/wavefront.htm b/doc/wavefront.htm old mode 100755 new mode 100644 diff --git a/doc/write-graphviz.html b/doc/write-graphviz.html index 9af6e7b7..3899fede 100644 --- a/doc/write-graphviz.html +++ b/doc/write-graphviz.html @@ -70,7 +70,7 @@ write_graphviz_dp(std::ostream& out, const Graph& g,

    This is to write a BGL graph object into an output stream in graphviz dot format -so that users can make use of AT&T graphviz +so that users can make use of graphviz to draw a picture with nice layout.

    The first version with two parameters will write the graph into a diff --git a/example/Jamfile.v2 b/example/Jamfile.v2 index 13cdf75f..4ad34893 100644 --- a/example/Jamfile.v2 +++ b/example/Jamfile.v2 @@ -4,54 +4,215 @@ # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -# exe labeled_graph : labeled_graph.cpp ; -# exe quick_tour_new : quick_tour_new.cpp ; -exe degree_centrality : degree_centrality.cpp ; -exe influence_prestige : influence_prestige.cpp ; -exe closeness_centrality : closeness_centrality.cpp ; -exe scaled_closeness_centrality : scaled_closeness_centrality.cpp ; -exe mean_geodesic : mean_geodesic.cpp ; -exe inclusive_mean_geodesic : inclusive_mean_geodesic.cpp ; -exe eccentricity : eccentricity.cpp ; -exe clustering_coefficient : clustering_coefficient.cpp ; -exe tiernan_print_cycles : tiernan_print_cycles.cpp ; -exe tiernan_girth_circumference : tiernan_girth_circumference.cpp ; -exe bron_kerbosch_print_cliques : bron_kerbosch_print_cliques.cpp ; -exe bron_kerbosch_clique_number : bron_kerbosch_clique_number.cpp ; -exe mcgregor_subgraphs_example : mcgregor_subgraphs_example.cpp ; -exe grid_graph_example : grid_graph_example.cpp ; -exe grid_graph_properties : grid_graph_properties.cpp ; -exe bipartite_example : bipartite_example.cpp ; -exe fr_layout : fr_layout.cpp ; -exe canonical_ordering : canonical_ordering.cpp ; -exe components_on_edgelist : components_on_edgelist.cpp ; -exe boykov_kolmogorov-eg : boykov_kolmogorov-eg.cpp ; -exe ospf-example : ospf-example.cpp ../build//boost_graph ; -# exe cc-internet : cc-internet.cpp ../build//boost_graph ; -exe implicit_graph : implicit_graph.cpp ; -exe astar_maze : astar_maze.cpp ; +exe accum-compile-times : accum-compile-times.cpp ; +exe actor_clustering : actor_clustering.cpp ; +exe adjacency_list : adjacency_list.cpp ; +exe adjacency_list_io : adjacency_list_io.cpp ; +exe adjacency_matrix : adjacency_matrix.cpp ; +exe adj_list_ra_edgelist : adj_list_ra_edgelist.cpp ; exe astar-cities : astar-cities.cpp ; -exe stoer_wagner : stoer_wagner.cpp ; -exe bfs-example : bfs-example.cpp ; +exe astar_maze : astar_maze.cpp ; +exe bellman-example : bellman-example.cpp ; +exe bellman-ford-internet : bellman-ford-internet.cpp ; +exe bfs : bfs.cpp ; exe bfs-example2 : bfs-example2.cpp ; +exe bfs-example : bfs-example.cpp ; +exe bfs-name-printer : bfs-name-printer.cpp ; +exe bfs_neighbor : bfs_neighbor.cpp ; +exe bipartite_example : bipartite_example.cpp ; +exe biconnected_components : biconnected_components.cpp ; +exe boost_web_graph : boost_web_graph.cpp ; +exe boykov_kolmogorov-eg : boykov_kolmogorov-eg.cpp ; +exe bron_kerbosch_clique_number : bron_kerbosch_clique_number.cpp ; +exe bron_kerbosch_print_cliques : bron_kerbosch_print_cliques.cpp ; +#exe bucket_sorter : bucket_sorter.cpp ; +exe canonical_ordering : canonical_ordering.cpp ; +# exe cc-internet : cc-internet.cpp ../build//boost_graph ; +exe city_visitor : city_visitor.cpp ; +exe closeness_centrality : closeness_centrality.cpp ; +exe clustering_coefficient : clustering_coefficient.cpp ; +exe components_on_edgelist : components_on_edgelist.cpp ; + +# TODO: Duplicate? +exe connected_components : connected_components.cpp ; +exe connected-components : connected-components.cpp ; + +exe container_gen : container_gen.cpp ; +exe copy-example : copy-example.cpp ; +# exe csr-example : csr-example.cpp ; +exe cuthill_mckee_ordering : cuthill_mckee_ordering.cpp ; +exe cycle_canceling_example : cycle_canceling_example.cpp ; +exe cycle-file-dep2 : cycle-file-dep2.cpp ; +exe cycle-file-dep : cycle-file-dep.cpp ; +exe cycle_ratio_example : cycle_ratio_example.cpp ; +exe dag_shortest_paths : dag_shortest_paths.cpp ; +exe dave : dave.cpp ; +exe default-constructor2 : default-constructor2.cpp ; +exe default-constructor : default-constructor.cpp ; +exe degree_centrality : degree_centrality.cpp ; +exe dfs : dfs.cpp ; exe dfs-example : dfs-example.cpp ; + +# TODO: Duplicate? +exe dfs_parenthesis : dfs_parenthesis.cpp ; +# exe dfs-parenthesis : dfs-parenthesis.cpp ; + exe dijkstra-example : dijkstra-example.cpp ; exe dijkstra-example-listS : dijkstra-example-listS.cpp ; exe dijkstra-no-color-map-example : dijkstra-no-color-map-example.cpp ; -exe adjacency_list_io : adjacency_list_io.cpp ; -exe undirected_adjacency_list : undirected_adjacency_list.cpp ; exe directed_graph : directed_graph.cpp ; -exe undirected_graph : undirected_graph.cpp ; -exe two_graphs_common_spanning_trees : two_graphs_common_spanning_trees.cpp ; -exe strong_components : strong_components.cpp ../build//boost_graph ; +exe eccentricity : eccentricity.cpp ; +exe edge_basics : edge_basics.cpp ; +exe edge_coloring : edge_coloring.cpp ; + +# TODO: Duplicate? +exe edge_connectivity : edge_connectivity.cpp ; +# exe edge-connectivity : edge-connectivity.cpp ; + +exe edge-function : edge-function.cpp ; + +# TODO: Duplicate? +exe edge_iterator_constructor : edge_iterator_constructor.cpp ; +exe edge-iter-constructor : edge-iter-constructor.cpp ; + +exe edge_property : edge_property.cpp ; +exe edmonds-karp-eg : edmonds-karp-eg.cpp ; +exe exterior_properties : exterior_properties.cpp ; +exe exterior_property_map : exterior_property_map.cpp ; +exe family_tree : family_tree.cpp ; +exe fibonacci_heap : fibonacci_heap.cpp ; +exe file_dependencies : file_dependencies.cpp ; +exe filtered-copy-example : filtered-copy-example.cpp ; +exe filtered_graph : filtered_graph.cpp ; +exe filtered_graph_edge_range : filtered_graph_edge_range.cpp ; +exe filtered_vec_as_graph : filtered_vec_as_graph.cpp ; +exe fr_layout : fr_layout.cpp ; +exe gerdemann : gerdemann.cpp ; + +# This needs SGB headers, via BGL's stanford_graph.h: +# exe girth : girth.cpp ; + +exe graph-assoc-types : graph-assoc-types.cpp ; + +#TODO: +#exe graph_as_tree : graph_as_tree.cpp ; + +exe graph : graph.cpp ; +exe graph_property : graph_property.cpp ; +exe graph-property-iter-eg : graph-property-iter-eg.cpp ; +exe graph-thingie : graph-thingie.cpp /boost/graph//boost_graph ; +exe graphviz : graphviz.cpp /boost/graph//boost_graph ; +exe grid_graph_example : grid_graph_example.cpp ; +exe grid_graph_properties : grid_graph_properties.cpp ; +exe hawick_circuits : hawick_circuits.cpp ; +exe implicit_graph : implicit_graph.cpp ; +exe inclusive_mean_geodesic : inclusive_mean_geodesic.cpp ; +exe incremental_components : incremental_components.cpp ; +exe incremental-components-eg : incremental-components-eg.cpp ; +exe in_edges : in_edges.cpp ; +exe influence_prestige : influence_prestige.cpp ; +exe interior_pmap_bundled : interior_pmap_bundled.cpp ; +exe interior_property_map : interior_property_map.cpp ; +exe isomorphism : isomorphism.cpp ; +exe iteration_macros : iteration_macros.cpp ; +exe iterator-property-map-eg : iterator-property-map-eg.cpp ; +exe johnson-eg : johnson-eg.cpp ; +exe kevin-bacon2 : kevin-bacon2.cpp /boost//serialization ; +exe kevin-bacon : kevin-bacon.cpp ; +exe king_ordering : king_ordering.cpp ; +exe knights_tour : knights_tour.cpp ; +exe kruskal-example : kruskal-example.cpp ; +# exe kruskal-telephone : kruskal-telephone.cpp ; +exe kuratowski_subgraph : kuratowski_subgraph.cpp ; +# exe labeled_graph : last-mod-time.cpp ; +exe last-mod-time : last-mod-time.cpp ; + +# These need LEDA: +# exe leda-concept-check : leda-concept-check.cpp ; +# exe leda-graph-eg : leda-graph-eg.cpp ; + +# exe loops_dfs : loops_dfs.cpp ; +exe make_biconnected_planar : make_biconnected_planar.cpp ; +exe make_maximal_planar : make_maximal_planar.cpp ; +exe matching_example : matching_example.cpp ; +exe max_flow : max_flow.cpp ; +exe mcgregor_subgraphs_example : mcgregor_subgraphs_example.cpp ; +exe mean_geodesic : mean_geodesic.cpp ; + +# This needs SGB headers, via BGL's stanford_graph.h: +# exe miles_span : miles_span.cpp ; + +exe minimum_degree_ordering : minimum_degree_ordering.cpp iohb.c ; + +# This has an error pragma explaining that it is incorrect. +# exe min_max_paths : min_max_paths.cpp ; + +exe modify_graph : modify_graph.cpp ; +exe neighbor_bfs : neighbor_bfs.cpp ; +exe ordered_out_edges : ordered_out_edges.cpp ; +exe ospf-example : ospf-example.cpp ../build//boost_graph ; +exe parallel-compile-time : parallel-compile-time.cpp ; +exe planar_face_traversal : planar_face_traversal.cpp ; +exe prim-example : prim-example.cpp ; +# exe prim-telephone : prim-telephone.cpp ; +exe print-adjacent-vertices : print-adjacent-vertices.cpp ; +exe print-edges : print-edges.cpp ; +exe print-in-edges : print-in-edges.cpp ; +exe print-out-edges : print-out-edges.cpp ; +exe property_iterator : property_iterator.cpp ; +exe property-map-traits-eg : property-map-traits-eg.cpp ; +exe push-relabel-eg : push-relabel-eg.cpp ; +exe put-get-helper-eg : put-get-helper-eg.cpp ; +exe quick_tour : quick_tour.cpp ; +exe r_c_shortest_paths_example : r_c_shortest_paths_example.cpp ; +exe read_graphviz : read_graphviz.cpp ../build//boost_graph ; +exe read_write_dimacs-eg : read_write_dimacs-eg.cpp ; +# exe reachable-loop-head : reachable-loop-head.cpp ; +# exe reachable-loop-tail : reachable-loop-tail.cpp ; +exe remove_edge_if_bidir : remove_edge_if_bidir.cpp ; +exe remove_edge_if_dir : remove_edge_if_dir.cpp ; +exe remove_edge_if_undir : remove_edge_if_undir.cpp ; +exe reverse_graph : reverse_graph.cpp ; + +# This needs SGB headers, via BGL's stanford_graph.h: +# exe roget_components : roget_components.cpp ; + +# exe quick_tour_new : quick_tour_new.cpp ; +exe scaled_closeness_centrality : scaled_closeness_centrality.cpp ; +# exe scc : scc.cpp ; +exe simple_planarity_test : simple_planarity_test.cpp ; +exe sloan_ordering : sloan_ordering.cpp ; +exe stoer_wagner : stoer_wagner.cpp ; exe strong-components : strong-components.cpp ; -exe subgraph : subgraph.cpp ; +exe strong_components : strong_components.cpp ../build//boost_graph ; exe subgraph_properties : subgraph_properties.cpp ; +exe subgraph : subgraph.cpp ; +exe successive_shortest_path_nonnegative_weights_example : successive_shortest_path_nonnegative_weights_example.cpp ; +exe tiernan_girth_circumference : tiernan_girth_circumference.cpp ; +exe tiernan_print_cycles : tiernan_print_cycles.cpp ; +exe topo-sort1 : topo-sort1.cpp ; +exe topo-sort2 : topo-sort2.cpp ; +exe topo_sort : topo_sort.cpp ; +exe topo-sort-file-dep2 : topo-sort-file-dep2.cpp ; +exe topo-sort-file-dep : topo-sort-file-dep.cpp ; + +# This needs LEDA: +# exe topo-sort-with-leda : topo-sort-with-leda.cpp ; + +# This needs SGB headers, via BGL's stanford_graph.h: +# exe topo-sort-with-sgb : topo-sort-with-sgb.cpp ; + +exe transitive_closure : transitive_closure.cpp ; +exe transpose-example : transpose-example.cpp ; +exe two_graphs_common_spanning_trees : two_graphs_common_spanning_trees.cpp ; +exe undirected_adjacency_list : undirected_adjacency_list.cpp ; +exe undirected_dfs : undirected_dfs.cpp ; +exe undirected_graph : undirected_graph.cpp ; +exe vector_as_graph : vector_as_graph.cpp ; +exe vertex_basics : vertex_basics.cpp ; +exe vertex-name-property : vertex-name-property.cpp ; exe vf2_sub_graph_iso_example : vf2_sub_graph_iso_example.cpp ; exe vf2_sub_graph_iso_multi_example : vf2_sub_graph_iso_multi_example.cpp ; -exe sloan_ordering : sloan_ordering.cpp ; -exe hawick_circuits : hawick_circuits.cpp ; -exe edge_coloring : edge_coloring.cpp ; -exe successive_shortest_path_nonnegative_weights_example : successive_shortest_path_nonnegative_weights_example.cpp ; -exe cycle_canceling_example : cycle_canceling_example.cpp ; +exe visitor : visitor.cpp ; +exe write_graphviz : write_graphviz.cpp ; diff --git a/example/accum-compile-times.cpp b/example/accum-compile-times.cpp index 385d86c9..85af0482 100644 --- a/example/accum-compile-times.cpp +++ b/example/accum-compile-times.cpp @@ -72,15 +72,9 @@ main() typedef property_map < file_dep_graph2, vertex_name_t >::type name_map_t; typedef property_map < file_dep_graph2, vertex_compile_cost_t >::type compile_cost_map_t; - typedef property_map ::type - distance_map_t; - typedef property_map ::type - color_map_t; name_map_t name_map = get(vertex_name, g); compile_cost_map_t compile_cost_map = get(vertex_compile_cost, g); - distance_map_t distance_map = get(vertex_distance, g); - color_map_t color_map = get(vertex_color, g); std::ifstream name_in("makefile-target-names.dat"); std::ifstream compile_cost_in("target-compile-costs.dat"); diff --git a/example/adj_list_ra_edgelist.cpp b/example/adj_list_ra_edgelist.cpp index 0c8dc032..d92ecd66 100644 --- a/example/adj_list_ra_edgelist.cpp +++ b/example/adj_list_ra_edgelist.cpp @@ -9,6 +9,7 @@ #include #include +#include int main() @@ -22,8 +23,12 @@ main() E edge_array[] = { E(0,1), E(0,2), E(0,1) }; const std::size_t m = sizeof(edge_array) / sizeof(E); Graph g(edge_array, edge_array + m, n); - for (std::size_t i = 0; i < m; ++i) - std::cout << edges(g).first[i] << " "; + + graph_traits::edge_iterator edge_iterator; + for (std::size_t i = 0; i < m; ++i) { + const graph_traits::edge_iterator e = edges(g).first + i; + std::cout << *e << " "; + } std::cout << std::endl; return 0; diff --git a/example/connected-components.cpp b/example/connected-components.cpp index b07f3db0..15a83ca6 100644 --- a/example/connected-components.cpp +++ b/example/connected-components.cpp @@ -16,7 +16,6 @@ main() { using namespace boost; typedef adjacency_list < vecS, vecS, undirectedS > Graph; - typedef graph_traits < Graph >::vertex_descriptor Vertex; const int N = 6; Graph G(N); diff --git a/example/copy-example.cpp b/example/copy-example.cpp index 41a0178a..572bb369 100644 --- a/example/copy-example.cpp +++ b/example/copy-example.cpp @@ -15,7 +15,6 @@ int main() { using namespace boost; - typedef int weight_t; typedef adjacency_list < vecS, vecS, directedS, property < vertex_name_t, char > > graph_t; diff --git a/example/csr-example.cpp b/example/csr-example.cpp index 6381fc54..b597193a 100644 --- a/example/csr-example.cpp +++ b/example/csr-example.cpp @@ -38,7 +38,7 @@ int main() E(5, 2) }; typedef compressed_sparse_row_graph WebGraph; - WebGraph g(&the_edges[0], &the_edges[0] + sizeof(the_edges)/sizeof(E), 6); + WebGraph g(boost::edges_are_sorted, &the_edges[0], &the_edges[0] + sizeof(the_edges)/sizeof(E), 6); // Set the URLs of each vertex int index = 0; diff --git a/example/dfs.cpp b/example/dfs.cpp index e68ba39a..8d68a09f 100644 --- a/example/dfs.cpp +++ b/example/dfs.cpp @@ -107,7 +107,6 @@ main(int , char* []) add_edge(4, 0, G); add_edge(4, 1, G); - typedef graph_traits::vertex_descriptor Vertex; typedef graph_traits::vertices_size_type size_type; std::vector d(num_vertices(G)); diff --git a/example/dfs_parenthesis.cpp b/example/dfs_parenthesis.cpp index 5bf04c41..6f03401e 100644 --- a/example/dfs_parenthesis.cpp +++ b/example/dfs_parenthesis.cpp @@ -64,9 +64,6 @@ main(int, char*[]) Graph G(edge_array, edge_array + sizeof(edge_array)/sizeof(E), 5); #endif - typedef boost::graph_traits::vertex_descriptor Vertex; - typedef boost::graph_traits::vertices_size_type size_type; - std::cout << "DFS parenthesis:" << std::endl; depth_first_search(G, visitor(make_dfs_visitor(std::make_pair(open_paren(), close_paren())))); diff --git a/example/edge_coloring.cpp b/example/edge_coloring.cpp index 81a8a38d..1a752fd1 100644 --- a/example/edge_coloring.cpp +++ b/example/edge_coloring.cpp @@ -7,6 +7,7 @@ // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= +#include #include #include #include @@ -56,7 +57,7 @@ int main(int, char *[]) Graph G(10); for (size_t i = 0; i < sizeof(edges)/sizeof(edges[0]); i++) - add_edge(edges[i].first, edges[i].second, G).first; + add_edge(edges[i].first, edges[i].second, G); size_t colors = edge_coloring(G, get(edge_bundle, G)); diff --git a/example/edge_iterator_constructor.cpp b/example/edge_iterator_constructor.cpp index 2fb6c3b3..95da715a 100644 --- a/example/edge_iterator_constructor.cpp +++ b/example/edge_iterator_constructor.cpp @@ -80,7 +80,7 @@ bool operator==(const edge_stream_iterator& x, const edge_stream_iterator& y) { return (x.m_stream == y.m_stream && x.m_end_marker == y.m_end_marker) - || x.m_end_marker == false && y.m_end_marker == false; + || (x.m_end_marker == false && y.m_end_marker == false); } bool operator!=(const edge_stream_iterator& x, const edge_stream_iterator& y) diff --git a/example/edge_property.cpp b/example/edge_property.cpp index 3bfe575c..879e7570 100644 --- a/example/edge_property.cpp +++ b/example/edge_property.cpp @@ -141,8 +141,6 @@ int main(int , char* []) add_edge(6, 8, Flow(10, Cap(8)), G); - typedef boost::graph_traits::edge_descriptor Edge; - print_network(G); property_map::type diff --git a/example/family-tree-eg.cpp b/example/family_tree.cpp similarity index 100% rename from example/family-tree-eg.cpp rename to example/family_tree.cpp diff --git a/example/filtered-copy-example.cpp b/example/filtered-copy-example.cpp index d16dee2d..226dfd29 100644 --- a/example/filtered-copy-example.cpp +++ b/example/filtered-copy-example.cpp @@ -29,7 +29,6 @@ int main() { using namespace boost; - typedef int weight_t; typedef adjacency_list < vecS, vecS, bidirectionalS, property < vertex_name_t, char > > graph_t; diff --git a/example/graph-assoc-types.cpp b/example/graph-assoc-types.cpp index 8838cffb..aedeebca 100644 --- a/example/graph-assoc-types.cpp +++ b/example/graph-assoc-types.cpp @@ -28,7 +28,7 @@ template < typename Graph > void generic_bar(Graph & g) { // Declare some vertex and edge descriptor variables - typename graph_traits < Graph >::vertex_descriptor u, v; + typename graph_traits < Graph >::vertex_descriptor u = vertex(0,g), v = vertex(1,g); typename graph_traits < Graph >::edge_descriptor e1, e2; // Set u and e1 to valid descriptors... v = u; // Make v a handle to the same vertex as u. diff --git a/example/graph-thingie.cpp b/example/graph-thingie.cpp index 51032e1a..6b8031dd 100644 --- a/example/graph-thingie.cpp +++ b/example/graph-thingie.cpp @@ -89,6 +89,10 @@ const char* dot = istringstream gvgraph(dot); bool status = read_graphviz(gvgraph,graph,dp,"node_id"); + if (!status) { + cerr << "read_graphviz() failed." << endl; + return -1; + } cout << "graph " << get("name",dp,&graph) << " (" << get("identifier",dp,&graph) << ")\n\n"; diff --git a/example/graph.cpp b/example/graph.cpp index 035b0d71..c73fba7b 100644 --- a/example/graph.cpp +++ b/example/graph.cpp @@ -46,7 +46,6 @@ std::size_t myrand(std::size_t N) { template bool check_edge(Graph& g, std::size_t a, std::size_t b) { - typedef typename Graph::vertex_descriptor Vertex; typename Graph::adjacency_iterator vi, viend, found; boost::tie(vi, viend) = adjacent_vertices(vertex(a,g), g); diff --git a/example/graph_as_tree.cpp b/example/graph_as_tree.cpp index 4201d369..635cd179 100644 --- a/example/graph_as_tree.cpp +++ b/example/graph_as_tree.cpp @@ -10,6 +10,7 @@ #include #include #include +#include class tree_printer { public: diff --git a/example/implicit_graph.cpp b/example/implicit_graph.cpp index 9b42e4d6..0d788735 100644 --- a/example/implicit_graph.cpp +++ b/example/implicit_graph.cpp @@ -381,7 +381,7 @@ edges_size_type num_edges(const ring_graph& g) { std::pair edge(vertex_descriptor u, vertex_descriptor v, const ring_graph& g) { if ((u == v + 1 || v == u + 1) && - u >= 0 && u < num_vertices(g) && v >= 0 && v < num_vertices(g)) + u > 0 && u < num_vertices(g) && v > 0 && v < num_vertices(g)) return std::pair(edge_descriptor(u, v), true); else return std::pair(edge_descriptor(), false); diff --git a/example/incremental-components-eg.cpp b/example/incremental-components-eg.cpp index 2ee63e4d..7faf4418 100644 --- a/example/incremental-components-eg.cpp +++ b/example/incremental-components-eg.cpp @@ -22,7 +22,7 @@ int main(int argc, char* argv[]) { typedef adjacency_list Graph; typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; + //typedef graph_traits::edge_descriptor Edge; typedef graph_traits::vertices_size_type VertexIndex; // Create a graph diff --git a/example/iohb.c b/example/iohb.c index d0001621..eac5abec 100644 --- a/example/iohb.c +++ b/example/iohb.c @@ -227,7 +227,7 @@ Fri Aug 15 16:29:47 EDT 1997 char* substr(const char* S, const int pos, const int len); void upcase(char* S); -void IOHBTerminate(char* message); +void IOHBTerminate(const char* message); int readHB_info(const char* filename, int* M, int* N, int* nz, char** Type, int* Nrhs) @@ -1340,7 +1340,7 @@ int writeHB_mat_char(const char* filename, int M, int N, int Ptrperline, Ptrwidth, Indperline, Indwidth; int Rhsperline, Rhswidth, Rhsprec; int Rhsflag; - int Valperline, Valwidth, Valprec; + int Valperline = 1, Valwidth, Valprec; int Valflag; /* Indicates 'E','D', or 'F' float format */ char pformat[16],iformat[16],vformat[19],rformat[19]; @@ -1602,9 +1602,9 @@ void upcase(char* S) S[i] = toupper(S[i]); } -void IOHBTerminate(char* message) +void IOHBTerminate(const char* message) { - fprintf(stderr,message); + fprintf(stderr,"%s",message); exit(1); } diff --git a/example/iohb.h b/example/iohb.h index 7c1ec21f..a986eb8b 100644 --- a/example/iohb.h +++ b/example/iohb.h @@ -62,7 +62,7 @@ int ParseIfmt(char* fmt, int* perline, int* width); int ParseRfmt(char* fmt, int* perline, int* width, int* prec, int* flag); -void IOHBTerminate(char* message); +void IOHBTerminate(const char* message); #ifdef __cplusplus } #endif diff --git a/example/iteration_macros.cpp b/example/iteration_macros.cpp index 49d5468c..27451f96 100644 --- a/example/iteration_macros.cpp +++ b/example/iteration_macros.cpp @@ -10,6 +10,7 @@ #include #include +#include enum family { Jeanie, Debbie, Rick, John, Amanda, Margaret, Benjamin, N }; @@ -41,7 +42,7 @@ int main() else std::cout << " is the parent of "; - BGL_FORALL_ADJACENT(i, j, g, adjacency_list<>) + BGL_FORALL_ADJ(i, j, g, adjacency_list<>) std::cout << name[get(index_map, j)] << ", "; std::cout << std::endl; } diff --git a/example/kevin-bacon2.cpp b/example/kevin-bacon2.cpp index 79fb9a58..2cd17838 100644 --- a/example/kevin-bacon2.cpp +++ b/example/kevin-bacon2.cpp @@ -16,6 +16,7 @@ #include #include #include +#include struct vertex_properties { std::string name; diff --git a/example/king_ordering.cpp b/example/king_ordering.cpp index 60a856a9..2b081fa2 100644 --- a/example/king_ordering.cpp +++ b/example/king_ordering.cpp @@ -76,7 +76,7 @@ int main(int , char* []) Vertex s = vertex(6, G); //king_ordering king_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), - get(vertex_degree, G)); + get(vertex_degree, G), get(vertex_index, G)); cout << "King ordering starting at: " << s << endl; cout << " "; for (std::vector::const_iterator i = inv_perm.begin(); @@ -94,7 +94,7 @@ int main(int , char* []) Vertex s = vertex(0, G); //king_ordering king_ordering(G, s, inv_perm.rbegin(), get(vertex_color, G), - get(vertex_degree, G)); + get(vertex_degree, G), get(vertex_index, G)); cout << "King ordering starting at: " << s << endl; cout << " "; for (std::vector::const_iterator i=inv_perm.begin(); @@ -112,7 +112,7 @@ int main(int , char* []) { //king_ordering king_ordering(G, inv_perm.rbegin(), get(vertex_color, G), - make_degree_map(G)); + make_degree_map(G), get(vertex_index, G)); cout << "King ordering:" << endl; cout << " "; diff --git a/example/knights-tour.cpp b/example/knights_tour.cpp similarity index 100% rename from example/knights-tour.cpp rename to example/knights_tour.cpp diff --git a/example/kruskal-example.cpp b/example/kruskal-example.cpp index ca27eb74..64297768 100644 --- a/example/kruskal-example.cpp +++ b/example/kruskal-example.cpp @@ -17,7 +17,6 @@ main() typedef adjacency_list < vecS, vecS, undirectedS, no_property, property < edge_weight_t, int > > Graph; typedef graph_traits < Graph >::edge_descriptor Edge; - typedef graph_traits < Graph >::vertex_descriptor Vertex; typedef std::pair E; const int num_nodes = 5; diff --git a/example/loops_dfs.cpp b/example/loops_dfs.cpp index 9536701b..4bc66004 100644 --- a/example/loops_dfs.cpp +++ b/example/loops_dfs.cpp @@ -50,7 +50,6 @@ find_loops(typename graph_traits < Graph >::vertex_descriptor entry, { BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); typedef typename graph_traits < Graph >::edge_descriptor Edge; - typedef typename graph_traits < Graph >::vertex_descriptor Vertex; std::vector < Edge > back_edges; std::vector < default_color_type > color_map(num_vertices(g)); depth_first_visit(g, entry, @@ -58,7 +57,7 @@ find_loops(typename graph_traits < Graph >::vertex_descriptor entry, make_iterator_property_map(color_map.begin(), get(vertex_index, g), color_map[0])); - for (std::vector < Edge >::size_type i = 0; i < back_edges.size(); ++i) { + for (typename std::vector < Edge >::size_type i = 0; i < back_edges.size(); ++i) { typename Loops::value_type x; loops.push_back(x); compute_loop_extent(back_edges[i], g, loops.back()); diff --git a/example/minimum_degree_ordering.cpp b/example/minimum_degree_ordering.cpp index 049895cc..a7b1963a 100644 --- a/example/minimum_degree_ordering.cpp +++ b/example/minimum_degree_ordering.cpp @@ -99,13 +99,10 @@ int main(int argc, char* argv[]) if ( argc >= 4 ) delta = atoi(argv[3]); - typedef double Type; - harwell_boeing hbs(argv[1]); //must be BGL directed graph now typedef adjacency_list Graph; - typedef graph_traits::vertex_descriptor Vertex; int n = hbs.nrows(); diff --git a/example/prim-example.cpp b/example/prim-example.cpp index ba44aa9b..b36740bf 100644 --- a/example/prim-example.cpp +++ b/example/prim-example.cpp @@ -32,7 +32,6 @@ main() } #else Graph g(edges, edges + sizeof(edges) / sizeof(E), weights, num_nodes); - property_map::type weightmap = get(edge_weight, g); #endif std::vector < graph_traits < Graph >::vertex_descriptor > p(num_vertices(g)); diff --git a/example/print-in-edges.cpp b/example/print-in-edges.cpp index f558d4e9..3a889f06 100644 --- a/example/print-in-edges.cpp +++ b/example/print-in-edges.cpp @@ -102,7 +102,6 @@ main() graph_traits < graph_type >::vertex_iterator i, end; boost::tie(i, end) = vertices(g); - typedef property_map < graph_type, vertex_name_t >::type name_map_t; i = std::find_if(i, end, name_equals("libzigzag.a", get(vertex_name, g))); output_in_edges(std::cout, g, *i, get(vertex_name, g)); assert(num_vertices(g) == 15); diff --git a/example/r_c_shortest_paths_example.cpp b/example/r_c_shortest_paths_example.cpp old mode 100755 new mode 100644 index 5024c459..518b90c6 --- a/example/r_c_shortest_paths_example.cpp +++ b/example/r_c_shortest_paths_example.cpp @@ -200,7 +200,6 @@ public: // example graph structure and cost from // http://www.boost.org/libs/graph/example/dijkstra-example.cpp -const int num_nodes = 5; enum nodes { A, B, C, D, E }; char name[] = "ABCDE"; diff --git a/example/read_graphviz.cpp b/example/read_graphviz.cpp index a58ae539..8750e9dc 100644 --- a/example/read_graphviz.cpp +++ b/example/read_graphviz.cpp @@ -57,5 +57,5 @@ int main() { bool status = read_graphviz(gvgraph,graph,dp,"node_id"); - return 0; + return status ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/example/reverse-graph-eg.cpp b/example/reverse_graph.cpp similarity index 100% rename from example/reverse-graph-eg.cpp rename to example/reverse_graph.cpp diff --git a/example/roget_components.cpp b/example/roget_components.cpp index 8a34f22e..7a11353f 100644 --- a/example/roget_components.cpp +++ b/example/roget_components.cpp @@ -7,7 +7,8 @@ // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= -#include +#include +#include #include #include #include diff --git a/example/sloan_ordering.cpp b/example/sloan_ordering.cpp old mode 100755 new mode 100644 diff --git a/example/topo-sort-with-sgb.cpp b/example/topo-sort-with-sgb.cpp index 9b0ea8e5..b7d9ae66 100644 --- a/example/topo-sort-with-sgb.cpp +++ b/example/topo-sort-with-sgb.cpp @@ -8,8 +8,8 @@ #include #include #include -#include #include +#include int main() diff --git a/example/transpose-example.cpp b/example/transpose-example.cpp index 252901bb..7378dd19 100644 --- a/example/transpose-example.cpp +++ b/example/transpose-example.cpp @@ -15,7 +15,6 @@ int main() { using namespace boost; - typedef int weight_t; typedef adjacency_list < vecS, vecS, bidirectionalS, property < vertex_name_t, char > > graph_t; diff --git a/example/vector-as-graph.cpp b/example/vector_as_graph.cpp similarity index 100% rename from example/vector-as-graph.cpp rename to example/vector_as_graph.cpp diff --git a/example/vf2_sub_graph_iso_example.cpp b/example/vf2_sub_graph_iso_example.cpp old mode 100755 new mode 100644 diff --git a/example/vf2_sub_graph_iso_multi_example.cpp b/example/vf2_sub_graph_iso_multi_example.cpp old mode 100755 new mode 100644 diff --git a/example/visitor.cpp b/example/visitor.cpp index 700932d8..cd5b4f5a 100644 --- a/example/visitor.cpp +++ b/example/visitor.cpp @@ -84,7 +84,6 @@ main(int, char*[]) Graph G(edges, edges + sizeof(edges)/sizeof(E), 5); #endif - typedef boost::graph_traits::vertex_descriptor Vertex; typedef boost::graph_traits::vertices_size_type size_type; std::vector d(num_vertices(G)); diff --git a/include/boost/graph/adjacency_iterator.hpp b/include/boost/graph/adjacency_iterator.hpp index d5006064..c134fe5a 100644 --- a/include/boost/graph/adjacency_iterator.hpp +++ b/include/boost/graph/adjacency_iterator.hpp @@ -10,6 +10,7 @@ #ifndef BOOST_ADJACENCY_ITERATOR_HPP #define BOOST_ADJACENCY_ITERATOR_HPP +#include #include #include diff --git a/include/boost/graph/adjacency_list.hpp b/include/boost/graph/adjacency_list.hpp index d7fbc06d..da80063d 100644 --- a/include/boost/graph/adjacency_list.hpp +++ b/include/boost/graph/adjacency_list.hpp @@ -20,14 +20,6 @@ #include -#if !defined BOOST_NO_SLIST -# ifdef BOOST_SLIST_HEADER -# include BOOST_SLIST_HEADER -# else -# include -# endif -#endif - #include #include @@ -52,10 +44,6 @@ namespace boost { // to map the selectors to the container type used to implement the // graph. -#if !defined BOOST_NO_SLIST - struct slistS {}; -#endif - struct vecS { }; struct listS { }; struct setS { }; @@ -74,12 +62,7 @@ namespace boost { struct container_gen { typedef std::list type; }; -#if !defined BOOST_NO_SLIST - template - struct container_gen { - typedef BOOST_STD_EXTENSION_NAMESPACE::slist type; - }; -#endif + template struct container_gen { typedef std::vector type; @@ -136,12 +119,6 @@ namespace boost { struct parallel_edge_traits { typedef allow_parallel_edge_tag type; }; -#if !defined BOOST_NO_SLIST - template <> - struct parallel_edge_traits { - typedef allow_parallel_edge_tag type; }; -#endif - template <> struct parallel_edge_traits { typedef disallow_parallel_edge_tag type; }; diff --git a/include/boost/graph/adjacency_matrix.hpp b/include/boost/graph/adjacency_matrix.hpp index b1078d97..ade7351f 100644 --- a/include/boost/graph/adjacency_matrix.hpp +++ b/include/boost/graph/adjacency_matrix.hpp @@ -443,7 +443,7 @@ namespace boost { // graph type. Instead, use directedS, which also provides the // functionality required for a Bidirectional Graph (in_edges, // in_degree, etc.). - BOOST_STATIC_ASSERT(type_traits::ice_not<(is_same::value)>::value); + BOOST_STATIC_ASSERT(!(is_same::value)); typedef typename mpl::if_::type diff --git a/include/boost/graph/astar_search.hpp b/include/boost/graph/astar_search.hpp index 435ccf03..f9f86c14 100644 --- a/include/boost/graph/astar_search.hpp +++ b/include/boost/graph/astar_search.hpp @@ -46,11 +46,12 @@ namespace boost { template - class astar_heuristic : public std::unary_function< - typename graph_traits::vertex_descriptor, CostType> + class astar_heuristic { public: typedef typename graph_traits::vertex_descriptor Vertex; + typedef Vertex argument_type; + typedef CostType result_type; astar_heuristic() {} CostType operator()(Vertex u) { return static_cast(0); } }; @@ -325,7 +326,7 @@ namespace boost { bool decreased = relax(e, g, weight, predecessor, distance, combine, compare); - Distance w_d = combine(get(distance, v), e_weight); + combine(get(distance, v), e_weight); if (decreased) { vis.edge_relaxed(e, g); Distance w_rank = combine(get(distance, w), h(w)); diff --git a/include/boost/graph/bc_clustering.hpp b/include/boost/graph/bc_clustering.hpp index 6f4bbf40..beba4d8e 100644 --- a/include/boost/graph/bc_clustering.hpp +++ b/include/boost/graph/bc_clustering.hpp @@ -114,8 +114,6 @@ betweenness_centrality_clustering(MutableGraph& g, Done done, centrality_type; typedef typename graph_traits::edge_iterator edge_iterator; typedef typename graph_traits::edge_descriptor edge_descriptor; - typedef typename graph_traits::vertices_size_type - vertices_size_type; if (has_no_edges(g)) return; diff --git a/include/boost/graph/buffer_concepts.hpp b/include/boost/graph/buffer_concepts.hpp index 2bad8af3..233a7206 100644 --- a/include/boost/graph/buffer_concepts.hpp +++ b/include/boost/graph/buffer_concepts.hpp @@ -6,13 +6,13 @@ #ifndef BOOST_GRAPH_BUFFER_CONCEPTS_HPP #define BOOST_GRAPH_BUFFER_CONCEPTS_HPP 1 #include -#include #include #include #include #include #include +#include namespace boost { BOOST_concept(Buffer, (B)) @@ -87,5 +87,6 @@ namespace boost { }; } // end `namespace boost` +#include #endif // !BOOST_GRAPH_BUFFER_CONCEPTS_HPP diff --git a/include/boost/graph/copy.hpp b/include/boost/graph/copy.hpp index 21bb0fb0..6246ebce 100644 --- a/include/boost/graph/copy.hpp +++ b/include/boost/graph/copy.hpp @@ -248,8 +248,8 @@ namespace boost { template struct choose_graph_copy { - typedef typename Graph::traversal_category Trv; - typedef typename Graph::directed_category Dr; + typedef typename graph_traits::traversal_category Trv; + typedef typename graph_traits::directed_category Dr; enum { algo = (is_convertible::value && is_convertible::value) diff --git a/include/boost/graph/depth_first_search.hpp b/include/boost/graph/depth_first_search.hpp index b002d367..cf60e1ac 100644 --- a/include/boost/graph/depth_first_search.hpp +++ b/include/boost/graph/depth_first_search.hpp @@ -64,19 +64,27 @@ namespace boost { template struct do_call_finish_edge { template - static void call_finish_edge(Vis& vis, const E& e, const G& g) { + static void call_finish_edge(Vis& vis, E e, const G& g) { vis.finish_edge(e, g); } }; template <> struct do_call_finish_edge { template - static void call_finish_edge(Vis&, const E&, const G&) {} + static void call_finish_edge(Vis&, E, const G&) {} }; template - void call_finish_edge(Vis& vis, const E& e, const G& g) { // Only call if method exists + void call_finish_edge(Vis& vis, E e, const G& g) { // Only call if method exists +#if ((defined(__GNUC__) && (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))) || \ + defined(__clang__) || \ + (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1200))) + do_call_finish_edge< + has_member_function_finish_edge >::value>::call_finish_edge(vis, e, g); +#else do_call_finish_edge::value>::call_finish_edge(vis, e, g); +#endif } @@ -137,6 +145,11 @@ namespace boost { src_e = back.second.first; boost::tie(ei, ei_end) = back.second.second; stack.pop_back(); + // finish_edge has to be called here, not after the + // loop. Think of the pop as the return from a recursive call. + if (src_e) { + call_finish_edge(vis, src_e.get(), g); + } while (ei != ei_end) { Vertex v = target(*ei, g); vis.examine_edge(*ei, g); @@ -164,7 +177,6 @@ namespace boost { } put(color, u, Color::black()); vis.finish_vertex(u, g); - if (src_e) call_finish_edge(vis, src_e.get(), g); } } diff --git a/include/boost/graph/detail/adjacency_list.hpp b/include/boost/graph/detail/adjacency_list.hpp index 9e6b623e..6fb497d7 100644 --- a/include/boost/graph/detail/adjacency_list.hpp +++ b/include/boost/graph/detail/adjacency_list.hpp @@ -41,6 +41,7 @@ #ifdef BOOST_NO_CXX11_RVALUE_REFERENCES #define BOOST_GRAPH_MOVE_IF_POSSIBLE(x) (x) #else +#include #define BOOST_GRAPH_MOVE_IF_POSSIBLE(x) (std::move((x))) #endif @@ -236,12 +237,6 @@ namespace boost { inline stored_edge() { } inline stored_edge(Vertex target, const no_property& = no_property()) : m_target(target) { } - // Need to write this explicitly so stored_edge_property can - // invoke Base::operator= (at least, for SGI MIPSPro compiler) - inline stored_edge& operator=(const stored_edge& x) { - m_target = x.m_target; - return *this; - } inline Vertex& get_target() const { return m_target; } inline const no_property& get_property() const { return s_prop; } inline bool operator==(const stored_edge& x) const @@ -257,7 +252,7 @@ namespace boost { template no_property stored_edge::s_prop; -#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) +#if defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || defined(BOOST_NO_CXX11_SMART_PTR) template class stored_edge_property : public stored_edge { typedef stored_edge_property self; @@ -269,12 +264,24 @@ namespace boost { const Property& p = Property()) : stored_edge(target), m_property(new Property(p)) { } stored_edge_property(const self& x) - : Base(x), m_property(const_cast(x).m_property) { } + : Base(static_cast< Base const& >(x)), m_property(const_cast(x).m_property) { } self& operator=(const self& x) { - Base::operator=(x); + // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla). + static_cast(*this) = static_cast< Base const& >(x); m_property = const_cast(x).m_property; return *this; } +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + // NOTE Don't rely on default operators, their behavior is broken on several compilers (GCC 4.6). + stored_edge_property(self&& x) + : Base(static_cast< Base&& >(x)), m_property(std::move(x.m_property)) { } + self& operator=(self&& x) { + // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla). + static_cast(*this) = static_cast< Base&& >(x); + m_property = std::move(x.m_property); + return *this; + } +#endif inline Property& get_property() { return *m_property; } inline const Property& get_property() const { return *m_property; } protected: @@ -282,7 +289,11 @@ namespace boost { // invalidation for add_edge() with EdgeList=vecS. Instead we // hold a pointer to the property. std::auto_ptr is not // a perfect fit for the job, but it is darn close. +#ifdef BOOST_NO_AUTO_PTR + std::unique_ptr m_property; +#else std::auto_ptr m_property; +#endif }; #else template @@ -295,8 +306,22 @@ namespace boost { inline stored_edge_property(Vertex target, const Property& p = Property()) : stored_edge(target), m_property(new Property(p)) { } - stored_edge_property(self&& x) = default; - self& operator=(self&& x) = default; + stored_edge_property(self&& x) : Base(static_cast< Base&& >(x)), + m_property(std::move(x.m_property)) { } + stored_edge_property(self const& x) : Base(static_cast< Base const& >(x)), + m_property(std::move(const_cast(x).m_property)) { } + self& operator=(self&& x) { + // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla). + static_cast(*this) = static_cast< Base&& >(x); + m_property = std::move(x.m_property); + return *this; + } + self& operator=(self const& x) { + // NOTE: avoid 'Base::operator=(x);' broken on SGI MIPSpro (bug 55771 of Mozilla). + static_cast(*this) = static_cast< Base const& >(x); + m_property = std::move(const_cast(x).m_property); + return *this; + } inline Property& get_property() { return *m_property; } inline const Property& get_property() const { return *m_property; } protected: diff --git a/include/boost/graph/detail/array_binary_tree.hpp b/include/boost/graph/detail/array_binary_tree.hpp index 78755556..fd403d1f 100644 --- a/include/boost/graph/detail/array_binary_tree.hpp +++ b/include/boost/graph/detail/array_binary_tree.hpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace boost { @@ -63,6 +64,9 @@ public: inline iterator& operator++() { ++i; return *this; } inline iterator operator++(int) { iterator t = *this; ++(*this); return t; } + inline iterator& operator--() { --i; return *this; } + inline iterator operator--(int) + { iterator t = *this; --(*this); return t; } inline bool operator==(const iterator& x) const { return i == x.i; } inline bool operator!=(const iterator& x) const { return !(*this == x); } diff --git a/include/boost/graph/detail/compressed_sparse_row_struct.hpp b/include/boost/graph/detail/compressed_sparse_row_struct.hpp index 6e7b60d7..44c64e11 100644 --- a/include/boost/graph/detail/compressed_sparse_row_struct.hpp +++ b/include/boost/graph/detail/compressed_sparse_row_struct.hpp @@ -459,7 +459,7 @@ namespace detail { edge_descriptor m_edge; - friend class iterator_core_access; + friend class boost::iterator_core_access; }; template @@ -547,7 +547,7 @@ namespace detail { EdgeIndex m_index_in_backward_graph; const CSRGraph* m_graph; - friend class iterator_core_access; + friend class boost::iterator_core_access; }; template diff --git a/include/boost/graph/detail/edge.hpp b/include/boost/graph/detail/edge.hpp index badf28d4..3aba9f8d 100644 --- a/include/boost/graph/detail/edge.hpp +++ b/include/boost/graph/detail/edge.hpp @@ -13,6 +13,8 @@ #include +#include + namespace boost { namespace detail { diff --git a/include/boost/graph/detail/geodesic.hpp b/include/boost/graph/detail/geodesic.hpp index adcb17f0..57352b1a 100644 --- a/include/boost/graph/detail/geodesic.hpp +++ b/include/boost/graph/detail/geodesic.hpp @@ -82,8 +82,11 @@ namespace detail { // Similar to std::plus, but maximizes parameters // rather than adding them. template - struct maximize : public std::binary_function + struct maximize { + typedef T result_type; + typedef T first_argument_type; + typedef T second_argument_type; T operator ()(T x, T y) const { BOOST_USING_STD_MAX(); return max BOOST_PREVENT_MACRO_SUBSTITUTION (x, y); } }; @@ -93,11 +96,10 @@ namespace detail { // types, but should be specialized for those types that have // discrete notions of reciprocals. template - struct reciprocal : public std::unary_function + struct reciprocal { - typedef std::unary_function function_type; - typedef typename function_type::result_type result_type; - typedef typename function_type::argument_type argument_type; + typedef T result_type; + typedef T argument_type; T operator ()(T t) { return T(1) / t; } }; diff --git a/include/boost/graph/detail/list_base.hpp b/include/boost/graph/detail/list_base.hpp index 88d83165..60332406 100644 --- a/include/boost/graph/detail/list_base.hpp +++ b/include/boost/graph/detail/list_base.hpp @@ -58,10 +58,10 @@ namespace boost { template inline Node - slist_previous(Node head, Node x, Node nil, + slist_previous(Node head, Node x, Node empty, Next next) { - while (head != nil && next(head) != x) + while (head != empty && next(head) != x) head = next(head); return head; } @@ -82,12 +82,12 @@ namespace boost { template inline Node - slist_reverse(Node node, Node nil, + slist_reverse(Node node, Node empty, Next next) { Node result = node; node = next(node); - next(result) = nil; + next(result) = empty; while(node) { Node next = next(node); next(node) = result; @@ -99,11 +99,11 @@ namespace boost { template inline std::size_t - slist_size(Node head, Node nil, + slist_size(Node head, Node empty, Next next) { std::size_t s = 0; - for ( ; head != nil; head = next(head)) + for ( ; head != empty; head = next(head)) ++s; return s; } diff --git a/include/boost/graph/detail/read_graphviz_new.hpp b/include/boost/graph/detail/read_graphviz_new.hpp index 7c7986dc..81221c0b 100644 --- a/include/boost/graph/detail/read_graphviz_new.hpp +++ b/include/boost/graph/detail/read_graphviz_new.hpp @@ -18,7 +18,7 @@ // and page 34 or http://www.graphviz.org/pdf/dotguide.pdf // // See documentation for this code at: -// http://www.boost.org/libs/graph/doc/read-graphviz.html +// http://www.boost.org/libs/graph/doc/read_graphviz.html // // Author: Jeremiah Willcock diff --git a/include/boost/graph/detail/read_graphviz_spirit.hpp b/include/boost/graph/detail/read_graphviz_spirit.hpp index 99464698..2ba09cc0 100644 --- a/include/boost/graph/detail/read_graphviz_spirit.hpp +++ b/include/boost/graph/detail/read_graphviz_spirit.hpp @@ -14,7 +14,7 @@ // http://www.graphviz.org/cvs/doc/info/lang.html // // See documentation for this code at: -// http://www.boost.org/libs/graph/doc/read-graphviz.html +// http://www.boost.org/libs/graph/doc/read_graphviz.html // // Author: Ronald Garcia diff --git a/include/boost/graph/directed_graph.hpp b/include/boost/graph/directed_graph.hpp index 585308d1..fdbd3008 100644 --- a/include/boost/graph/directed_graph.hpp +++ b/include/boost/graph/directed_graph.hpp @@ -92,7 +92,7 @@ public: { } directed_graph(directed_graph const& x) - : m_graph(x), m_num_vertices(x.m_num_vertices), m_num_edges(x.m_num_edges) + : m_graph(x.m_graph), m_num_vertices(x.m_num_vertices), m_num_edges(x.m_num_edges) , m_max_vertex_index(x.m_max_vertex_index), m_max_edge_index(x.m_max_edge_index) { } @@ -172,7 +172,7 @@ public: { return m_num_edges; } private: - // A helper fucntion for managing edge index attributes. + // A helper function for managing edge index attributes. std::pair const& make_index(std::pair const& x) { @@ -307,7 +307,7 @@ public: void swap(directed_graph& g) { - m_graph.swap(g); + m_graph.swap(g.m_graph); std::swap(m_num_vertices, g.m_num_vertices); std::swap(m_max_vertex_index, g.m_max_vertex_index); std::swap(m_num_edges, g.m_num_edges); diff --git a/include/boost/graph/dominator_tree.hpp b/include/boost/graph/dominator_tree.hpp index 9371eee0..e4a7eef5 100644 --- a/include/boost/graph/dominator_tree.hpp +++ b/include/boost/graph/dominator_tree.hpp @@ -70,29 +70,31 @@ namespace boost { /** * @param g [in] the target graph of the dominator tree * @param entry [in] the entry node of g + * @param indexMap [in] the vertex index map for g * @param domTreePredMap [out] the immediate dominator map * (parent map in dominator tree) */ dominator_visitor(const Graph& g, const Vertex& entry, + const IndexMap& indexMap, DomTreePredMap domTreePredMap) : semi_(num_vertices(g)), ancestor_(num_vertices(g), graph_traits::null_vertex()), samedom_(ancestor_), best_(semi_), semiMap_(make_iterator_property_map(semi_.begin(), - get(vertex_index, g))), + indexMap)), ancestorMap_(make_iterator_property_map(ancestor_.begin(), - get(vertex_index, g))), + indexMap)), bestMap_(make_iterator_property_map(best_.begin(), - get(vertex_index, g))), + indexMap)), buckets_(num_vertices(g)), bucketMap_(make_iterator_property_map(buckets_.begin(), - get(vertex_index, g))), + indexMap)), entry_(entry), domTreePredMap_(domTreePredMap), numOfVertices_(num_vertices(g)), samedomMap(make_iterator_property_map(samedom_.begin(), - get(vertex_index, g))) + indexMap)) { } @@ -237,7 +239,7 @@ namespace boost { lengauer_tarjan_dominator_tree_without_dfs (const Graph& g, const typename graph_traits::vertex_descriptor& entry, - const IndexMap& /*indexMap*/, + const IndexMap& indexMap, TimeMap dfnumMap, PredMap parentMap, VertexVector& verticesByDFNum, DomTreePredMap domTreePredMap) { @@ -252,7 +254,7 @@ namespace boost { // 1. Visit each vertex in reverse post order and calculate sdom. detail::dominator_visitor - visitor(g, entry, domTreePredMap); + visitor(g, entry, indexMap, domTreePredMap); VerticesSizeType i; for (i = 0; i < numOfVertices; ++i) diff --git a/include/boost/graph/filtered_graph.hpp b/include/boost/graph/filtered_graph.hpp index 74fea461..5426eac6 100644 --- a/include/boost/graph/filtered_graph.hpp +++ b/include/boost/graph/filtered_graph.hpp @@ -409,6 +409,26 @@ namespace boost { return n; } + template + typename enable_if::type, + typename filtered_graph::degree_size_type + >::type + degree(typename filtered_graph::vertex_descriptor u, + const filtered_graph& g) + { + return out_degree(u, g) + in_degree(u, g); + } + + template + typename disable_if::type, + typename filtered_graph::degree_size_type + >::type + degree(typename filtered_graph::vertex_descriptor u, + const filtered_graph& g) + { + return out_degree(u, g); + } + template std::pair::edge_descriptor, bool> edge(typename filtered_graph::vertex_descriptor u, diff --git a/include/boost/graph/find_flow_cost.hpp b/include/boost/graph/find_flow_cost.hpp index e4d6f404..1d49cddd 100644 --- a/include/boost/graph/find_flow_cost.hpp +++ b/include/boost/graph/find_flow_cost.hpp @@ -14,9 +14,9 @@ namespace boost { template -typename property_traits::type>::value_type +typename property_traits::value_type find_flow_cost(const Graph & g, Capacity capacity, ResidualCapacity residual_capacity, Weight weight) { - typedef typename property_traits::const_type>::value_type Cost; + typedef typename property_traits::value_type Cost; Cost cost = 0; BGL_FORALL_EDGES_T(e, g, Graph) { @@ -28,7 +28,7 @@ find_flow_cost(const Graph & g, Capacity capacity, ResidualCapacity residual_cap } template -typename property_traits::type>::value_type +typename detail::edge_weight_value::type find_flow_cost(const Graph & g, const bgl_named_params& params) { return find_flow_cost(g, diff --git a/include/boost/graph/graph_concepts.hpp b/include/boost/graph/graph_concepts.hpp index 875f8184..3b873a82 100644 --- a/include/boost/graph/graph_concepts.hpp +++ b/include/boost/graph/graph_concepts.hpp @@ -128,12 +128,14 @@ typename T::ThereReallyIsNoMemberByThisNameInT vertices(T const&); p = in_edges(v, g); n = in_degree(v, g); + n = degree(v, g); e = *p.first; const_constraints(g); } void const_constraints(const G& cg) { p = in_edges(v, cg); n = in_degree(v, cg); + n = degree(v, cg); e = *p.first; } std::pair p; diff --git a/include/boost/graph/graph_utility.hpp b/include/boost/graph/graph_utility.hpp index f1f120e3..b7278b6b 100644 --- a/include/boost/graph/graph_utility.hpp +++ b/include/boost/graph/graph_utility.hpp @@ -18,14 +18,6 @@ #include #include -#if !defined BOOST_NO_SLIST -# ifdef BOOST_SLIST_HEADER -# include BOOST_SLIST_HEADER -# else -# include -# endif -#endif - #include #include #include @@ -154,84 +146,84 @@ namespace boost { // -JGS template - void print_in_edges(const IncidenceGraph& G, Name name) + void print_in_edges(const IncidenceGraph& G, Name name, std::ostream& os = std::cout) { typename graph_traits::vertex_iterator ui,ui_end; for (boost::tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) { - std::cout << get(name,*ui) << " <-- "; + os << get(name,*ui) << " <-- "; typename graph_traits ::in_edge_iterator ei, ei_end; for(boost::tie(ei,ei_end) = in_edges(*ui,G); ei != ei_end; ++ei) - std::cout << get(name,source(*ei,G)) << " "; - std::cout << std::endl; + os << get(name,source(*ei,G)) << " "; + os << '\n'; } } template - void print_graph_dispatch(const IncidenceGraph& G, Name name, directed_tag) + void print_graph_dispatch(const IncidenceGraph& G, Name name, directed_tag, std::ostream& os = std::cout) { typename graph_traits::vertex_iterator ui,ui_end; for (boost::tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) { - std::cout << get(name,*ui) << " --> "; + os << get(name,*ui) << " --> "; typename graph_traits ::out_edge_iterator ei, ei_end; for(boost::tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei) - std::cout << get(name,target(*ei,G)) << " "; - std::cout << std::endl; + os << get(name,target(*ei,G)) << " "; + os << '\n'; } } template - void print_graph_dispatch(const IncidenceGraph& G, Name name, undirected_tag) + void print_graph_dispatch(const IncidenceGraph& G, Name name, undirected_tag, std::ostream& os = std::cout) { typename graph_traits::vertex_iterator ui,ui_end; for (boost::tie(ui,ui_end) = vertices(G); ui != ui_end; ++ui) { - std::cout << get(name,*ui) << " <--> "; + os << get(name,*ui) << " <--> "; typename graph_traits ::out_edge_iterator ei, ei_end; for(boost::tie(ei,ei_end) = out_edges(*ui,G); ei != ei_end; ++ei) - std::cout << get(name,target(*ei,G)) << " "; - std::cout << std::endl; + os << get(name,target(*ei,G)) << " "; + os << '\n'; } } template - void print_graph(const IncidenceGraph& G, Name name) + void print_graph(const IncidenceGraph& G, Name name, std::ostream& os = std::cout) { typedef typename graph_traits ::directed_category Cat; - print_graph_dispatch(G, name, Cat()); + print_graph_dispatch(G, name, Cat(), os); } template - void print_graph(const IncidenceGraph& G) { - print_graph(G, get(vertex_index, G)); + void print_graph(const IncidenceGraph& G, std::ostream& os = std::cout) { + print_graph(G, get(vertex_index, G), os); } template - void print_edges(const EdgeListGraph& G, Name name) + void print_edges(const EdgeListGraph& G, Name name, std::ostream& os = std::cout) { typename graph_traits::edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = edges(G); ei != ei_end; ++ei) - std::cout << "(" << get(name, source(*ei, G)) + os << "(" << get(name, source(*ei, G)) << "," << get(name, target(*ei, G)) << ") "; - std::cout << std::endl; + os << '\n'; } template - void print_edges2(const EdgeListGraph& G, VertexName vname, EdgeName ename) + void print_edges2(const EdgeListGraph& G, VertexName vname, EdgeName ename, std::ostream& os = std::cout) { typename graph_traits::edge_iterator ei, ei_end; for (boost::tie(ei, ei_end) = edges(G); ei != ei_end; ++ei) - std::cout << get(ename, *ei) << "(" << get(vname, source(*ei, G)) + os << get(ename, *ei) << "(" << get(vname, source(*ei, G)) << "," << get(vname, target(*ei, G)) << ") "; - std::cout << std::endl; + os << '\n'; } template - void print_vertices(const VertexListGraph& G, Name name) + void print_vertices(const VertexListGraph& G, Name name, std::ostream& os = std::cout) { typename graph_traits::vertex_iterator vi,vi_end; for (boost::tie(vi,vi_end) = vertices(G); vi != vi_end; ++vi) - std::cout << get(name,*vi) << " "; - std::cout << std::endl; + os << get(name,*vi) << " "; + os << '\n'; } template diff --git a/include/boost/graph/graphml.hpp b/include/boost/graph/graphml.hpp index be73def3..a7faa647 100644 --- a/include/boost/graph/graphml.hpp +++ b/include/boost/graph/graphml.hpp @@ -97,8 +97,8 @@ class mutate_graph_impl : public mutate_graph bool type_found = false; try { - mpl::for_each(put_property - (name, m_dp, m_g, value, value_type, m_type_names, type_found)); + mpl::for_each(put_property + (name, m_dp, &m_g, value, value_type, m_type_names, type_found)); } catch (bad_lexical_cast) { diff --git a/include/boost/graph/gursoy_atun_layout.hpp b/include/boost/graph/gursoy_atun_layout.hpp index 9f050e1b..d843db7a 100644 --- a/include/boost/graph/gursoy_atun_layout.hpp +++ b/include/boost/graph/gursoy_atun_layout.hpp @@ -10,10 +10,11 @@ #ifndef BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP #define BOOST_GRAPH_GURSOY_ATUN_LAYOUT_HPP -// Gursoy-Atun graph layout, based on: +// Gürsoy-Atun graph layout, based on: // "Neighbourhood Preserving Load Balancing: A Self-Organizing Approach" -// in EuroPar 2000, p. 234 of LNCS 1900 -// http://springerlink.metapress.com/link.asp?id=pcu07ew5rhexp9yt +// in 6th International Euro-Par Conference Munich, Germany, August 29 – September 1, 2000 Proceedings, +// pp 234-241 +// http://dx.doi.org/10.1007/3-540-44520-X_32 #include #include diff --git a/include/boost/graph/kamada_kawai_spring_layout.hpp b/include/boost/graph/kamada_kawai_spring_layout.hpp index 63355c94..b10ebe3d 100644 --- a/include/boost/graph/kamada_kawai_spring_layout.hpp +++ b/include/boost/graph/kamada_kawai_spring_layout.hpp @@ -106,7 +106,7 @@ namespace boost { template <> struct linear_solver<3> { template - static Vec solve(double mat[2][2], Vec rhs) { + static Vec solve(double mat[3][3], Vec rhs) { double denom = mat[0][0] * (mat[1][1] * mat[2][2] - mat[2][1] * mat[1][2]) - mat[1][0] * (mat[0][1] * mat[2][2] - mat[2][1] * mat[0][2]) + mat[2][0] * (mat[0][1] * mat[1][2] - mat[1][1] * mat[0][2]); diff --git a/include/boost/graph/labeled_graph.hpp b/include/boost/graph/labeled_graph.hpp index 5b688b02..59df0feb 100644 --- a/include/boost/graph/labeled_graph.hpp +++ b/include/boost/graph/labeled_graph.hpp @@ -132,7 +132,7 @@ namespace graph_detail { // Note that insertion always succeeds so we can add the vertex first // and then the mapping to the label. typedef typename graph_traits::vertex_descriptor Vertex; - Vertex v = add_vertex(g); + Vertex v = add_vertex(p, g); c.insert(std::make_pair(l, v)); return std::make_pair(v, true); } @@ -319,14 +319,15 @@ public: labeled_graph(vertices_size_type n, LabelIter l, graph_property_type const& gp = graph_property_type()) : _graph(gp) - { while(n-- >= 0) add_vertex(*l++); } + { while(n-- > 0) add_vertex(*l++); } // Construct the graph over n vertices each of which has a label in the // range [l, l + n) and a property in the range [p, p + n). template labeled_graph(vertices_size_type n, LabelIter l, PropIter p, graph_property_type const& gp = graph_property_type()) - { while(n-- >= 0) add_vertex(*l++, *p++); } + : _graph(gp) + { while(n-- > 0) add_vertex(*l++, *p++); } labeled_graph& operator=(labeled_graph const& x) { _graph = x._graph; diff --git a/include/boost/graph/metis.hpp b/include/boost/graph/metis.hpp index f16cac26..2ec2fc3e 100644 --- a/include/boost/graph/metis.hpp +++ b/include/boost/graph/metis.hpp @@ -161,7 +161,6 @@ class metis_distribution iterator end() { return vertices.end(); } private: - std::istream& in; process_id_type my_id; std::vector vertices; }; @@ -300,7 +299,7 @@ void metis_reader::start() } metis_distribution::metis_distribution(std::istream& in, process_id_type my_id) - : in(in), my_id(my_id), + : my_id(my_id), vertices(std::istream_iterator(in), std::istream_iterator()) { diff --git a/include/boost/graph/metric_tsp_approx.hpp b/include/boost/graph/metric_tsp_approx.hpp index c8e7dba5..31026258 100644 --- a/include/boost/graph/metric_tsp_approx.hpp +++ b/include/boost/graph/metric_tsp_approx.hpp @@ -53,13 +53,13 @@ namespace boost Visitor vis(vis_); // require copy construction Graph g(1); Vertex v(*vertices(g).first); - vis_.visit_vertex(v, g); // require visit_vertex + vis.visit_vertex(v, g); // require visit_vertex } }; // Tree visitor that keeps track of a preorder traversal of a tree // TODO: Consider migrating this to the graph_as_tree header. - // TODO: Parameterize the underlying stores o it doesn't have to be a vector. + // TODO: Parameterize the underlying stores so it doesn't have to be a vector. template class PreorderTraverser { private: @@ -266,7 +266,7 @@ namespace boost { return graph_traits::null_vertex(); } public: - tsp_tour_len_visitor(Graph const&, OutIter iter, Length& l, WeightMap map) + tsp_tour_len_visitor(Graph const&, OutIter iter, Length& l, WeightMap& map) : iter_(iter), tourlen_(l), wmap_(map), previous_(null()) { } diff --git a/include/boost/graph/named_function_params.hpp b/include/boost/graph/named_function_params.hpp index 26d3d5e4..4842dc95 100644 --- a/include/boost/graph/named_function_params.hpp +++ b/include/boost/graph/named_function_params.hpp @@ -228,6 +228,7 @@ BOOST_BGL_DECLARE_NAMED_PARAMS }; struct param_not_found {}; + static param_not_found g_param_not_found; template struct get_param_type: @@ -237,7 +238,7 @@ BOOST_BGL_DECLARE_NAMED_PARAMS inline const typename lookup_named_param_def::type& get_param(const Args& p, Tag) { - return lookup_named_param_def::get(p, param_not_found()); + return lookup_named_param_def::get(p, g_param_not_found); } template @@ -323,9 +324,17 @@ BOOST_BGL_DECLARE_NAMED_PARAMS struct edge_capacity_value { typedef bgl_named_params Params; - typedef typename detail::choose_impl_result::type, edge_capacity_t>::type CapacityEdgeMap; + typedef typename detail::choose_impl_result::type, edge_capacity_t>::type CapacityEdgeMap; typedef typename property_traits::value_type type; }; + // used in the max-flow algorithms + template + struct edge_weight_value + { + typedef bgl_named_params Params; + typedef typename detail::choose_impl_result::type, edge_weight_t>::type WeightMap; + typedef typename property_traits::value_type type; + }; } diff --git a/include/boost/graph/planar_canonical_ordering.hpp b/include/boost/graph/planar_canonical_ordering.hpp index d470ee59..465b32df 100644 --- a/include/boost/graph/planar_canonical_ordering.hpp +++ b/include/boost/graph/planar_canonical_ordering.hpp @@ -63,7 +63,7 @@ namespace boost std::list ready_to_be_processed; vertex_t first_vertex = *vertices(g).first; - vertex_t second_vertex; + vertex_t second_vertex = first_vertex; adjacency_iterator_t ai, ai_end; for(boost::tie(ai,ai_end) = adjacent_vertices(first_vertex,g); ai != ai_end; ++ai) { diff --git a/include/boost/graph/planar_detail/boyer_myrvold_impl.hpp b/include/boost/graph/planar_detail/boyer_myrvold_impl.hpp index 41ba2bc5..45a552aa 100644 --- a/include/boost/graph/planar_detail/boyer_myrvold_impl.hpp +++ b/include/boost/graph/planar_detail/boyer_myrvold_impl.hpp @@ -34,26 +34,26 @@ namespace boost typename DFSParentEdgeMap, typename SizeType> struct planar_dfs_visitor : public dfs_visitor<> { - planar_dfs_visitor(LowPointMap lpm, DFSParentMap dfs_p, + planar_dfs_visitor(LowPointMap lpm, DFSParentMap dfs_p, DFSNumberMap dfs_n, LeastAncestorMap lam, - DFSParentEdgeMap dfs_edge) + DFSParentEdgeMap dfs_edge) : low(lpm), parent(dfs_p), df_number(dfs_n), least_ancestor(lam), df_edge(dfs_edge), - count(0) + count(0) {} - - + + template void start_vertex(const Vertex& u, Graph&) { put(parent, u, u); put(least_ancestor, u, count); } - - + + template void discover_vertex(const Vertex& u, Graph&) { @@ -61,7 +61,7 @@ namespace boost put(df_number, u, count); ++count; } - + template void tree_edge(const Edge& e, Graph& g) { @@ -73,13 +73,13 @@ namespace boost put(df_edge, t, e); put(least_ancestor, t, get(df_number, s)); } - + template void back_edge(const Edge& e, Graph& g) { typedef typename graph_traits::vertex_descriptor vertex_t; typedef typename graph_traits::vertices_size_type v_size_t; - + vertex_t s(source(e,g)); vertex_t t(target(e,g)); BOOST_USING_STD_MIN(); @@ -89,20 +89,20 @@ namespace boost v_size_t t_df_number = get(df_number, t); v_size_t s_least_ancestor_df_number = get(least_ancestor, s); - put(low, s, + put(low, s, min BOOST_PREVENT_MACRO_SUBSTITUTION(s_low_df_number, t_df_number) ); - - put(least_ancestor, s, - min BOOST_PREVENT_MACRO_SUBSTITUTION(s_least_ancestor_df_number, + + put(least_ancestor, s, + min BOOST_PREVENT_MACRO_SUBSTITUTION(s_least_ancestor_df_number, t_df_number ) ); } } - + template void finish_vertex(const Vertex& u, Graph&) { @@ -115,21 +115,21 @@ namespace boost if (u_parent != u) { - put(low, u_parent, - min BOOST_PREVENT_MACRO_SUBSTITUTION(u_lowpoint, + put(low, u_parent, + min BOOST_PREVENT_MACRO_SUBSTITUTION(u_lowpoint, u_parent_lowpoint ) ); } } - + LowPointMap low; DFSParentMap parent; DFSNumberMap df_number; LeastAncestorMap least_ancestor; DFSParentEdgeMap df_edge; SizeType count; - + }; @@ -150,7 +150,7 @@ namespace boost typedef typename graph_traits::edge_descriptor edge_t; typedef typename graph_traits::vertex_iterator vertex_iterator_t; typedef typename graph_traits::edge_iterator edge_iterator_t; - typedef typename graph_traits::out_edge_iterator + typedef typename graph_traits::out_edge_iterator out_edge_iterator_t; typedef graph::detail::face_handle face_handle_t; @@ -173,16 +173,16 @@ namespace boost typedef typename map_vertex_to_::type vertex_to_v_size_map_t; typedef typename map_vertex_to_::type vertex_to_vertex_map_t; typedef typename map_vertex_to_::type vertex_to_edge_map_t; - typedef typename map_vertex_to_::type + typedef typename map_vertex_to_::type vertex_to_vertex_list_ptr_map_t; - typedef typename map_vertex_to_< edge_vector_t >::type + typedef typename map_vertex_to_< edge_vector_t >::type vertex_to_edge_vector_map_t; typedef typename map_vertex_to_::type vertex_to_bool_map_t; - typedef typename map_vertex_to_::type + typedef typename map_vertex_to_::type vertex_to_face_handle_map_t; - typedef typename map_vertex_to_::type + typedef typename map_vertex_to_::type vertex_to_face_handle_list_ptr_map_t; - typedef typename map_vertex_to_::type + typedef typename map_vertex_to_::type vertex_to_separated_node_map_t; template struct face_vertex_iterator { - typedef face_iterator type; @@ -216,7 +216,7 @@ namespace boost public: - + boyer_myrvold_impl(const Graph& arg_g, VertexIndexMap arg_vm): g(arg_g), @@ -237,7 +237,7 @@ namespace boost flipped_vector(num_vertices(g), false), backedges_vector(num_vertices(g)), dfs_parent_edge_vector(num_vertices(g)), - + vertices_by_dfs_num(num_vertices(g)), low_point(low_point_vector.begin(), vm), @@ -271,72 +271,72 @@ namespace boost // Sort vertices by their lowpoint - need this later in the constructor vertex_vector_t vertices_by_lowpoint(num_vertices(g)); - std::copy( vertices(g).first, vertices(g).second, + std::copy( vertices(g).first, vertices(g).second, vertices_by_lowpoint.begin() ); - bucket_sort(vertices_by_lowpoint.begin(), - vertices_by_lowpoint.end(), + bucket_sort(vertices_by_lowpoint.begin(), + vertices_by_lowpoint.end(), low_point, num_vertices(g) ); - // Sort vertices by their dfs number - need this to iterate by reverse + // Sort vertices by their dfs number - need this to iterate by reverse // DFS number in the main loop. - std::copy( vertices(g).first, vertices(g).second, + std::copy( vertices(g).first, vertices(g).second, vertices_by_dfs_num.begin() ); - bucket_sort(vertices_by_dfs_num.begin(), - vertices_by_dfs_num.end(), + bucket_sort(vertices_by_dfs_num.begin(), + vertices_by_dfs_num.end(), dfs_number, num_vertices(g) ); - // Initialize face handles. A face handle is an abstraction that serves - // two uses in our implementation - it allows us to efficiently move - // along the outer face of embedded bicomps in a partially embedded - // graph, and it provides storage for the planar embedding. Face - // handles are implemented by a sequence of edges and are associated - // with a particular vertex - the sequence of edges represents the - // current embedding of edges around that vertex, and the first and - // last edges in the sequence represent the pair of edges on the outer - // face that are adjacent to the associated vertex. This lets us embed - // edges in the graph by just pushing them on the front or back of the + // Initialize face handles. A face handle is an abstraction that serves + // two uses in our implementation - it allows us to efficiently move + // along the outer face of embedded bicomps in a partially embedded + // graph, and it provides storage for the planar embedding. Face + // handles are implemented by a sequence of edges and are associated + // with a particular vertex - the sequence of edges represents the + // current embedding of edges around that vertex, and the first and + // last edges in the sequence represent the pair of edges on the outer + // face that are adjacent to the associated vertex. This lets us embed + // edges in the graph by just pushing them on the front or back of the // sequence of edges held by the face handles. - // + // // Our algorithm starts with a DFS tree of edges (where every vertex is - // an articulation point and every edge is a singleton bicomp) and - // repeatedly merges bicomps by embedding additional edges. Note that - // any bicomp at any point in the algorithm can be associated with a + // an articulation point and every edge is a singleton bicomp) and + // repeatedly merges bicomps by embedding additional edges. Note that + // any bicomp at any point in the algorithm can be associated with a // unique edge connecting the vertex of that bicomp with the lowest DFS - // number (which we refer to as the "root" of the bicomp) with its DFS + // number (which we refer to as the "root" of the bicomp) with its DFS // child in the bicomp: the existence of two such edges would contradict - // the properties of a DFS tree. We refer to the DFS child of the root - // of a bicomp as the "canonical DFS child" of the bicomp. Note that a + // the properties of a DFS tree. We refer to the DFS child of the root + // of a bicomp as the "canonical DFS child" of the bicomp. Note that a // vertex can be the root of more than one bicomp. // - // We move around the external faces of a bicomp using a few property + // We move around the external faces of a bicomp using a few property // maps, which we'll initialize presently: // - // - face_handles: maps a vertex to a face handle that can be used to - // move "up" a bicomp. For a vertex that isn't an articulation point, - // this holds the face handles that can be used to move around that + // - face_handles: maps a vertex to a face handle that can be used to + // move "up" a bicomp. For a vertex that isn't an articulation point, + // this holds the face handles that can be used to move around that // vertex's unique bicomp. For a vertex that is an articulation point, - // this holds the face handles associated with the unique bicomp that - // the vertex is NOT the root of. These handles can therefore be used - // to move from any point on the outer face of the tree of bicomps + // this holds the face handles associated with the unique bicomp that + // the vertex is NOT the root of. These handles can therefore be used + // to move from any point on the outer face of the tree of bicomps // around the current outer face towards the root of the DFS tree. // - // - dfs_child_handles: these are used to hold face handles for + // - dfs_child_handles: these are used to hold face handles for // vertices that are articulation points - dfs_child_handles[v] holds // the face handles corresponding to vertex u in the bicomp with root // u and canonical DFS child v. // // - canonical_dfs_child: this property map allows one to determine the // canonical DFS child of a bicomp while traversing the outer face. - // This property map is only valid when applied to one of the two + // This property map is only valid when applied to one of the two // vertices adjacent to the root of the bicomp on the outer face. To // be more precise, if v is the canonical DFS child of a bicomp, - // canonical_dfs_child[dfs_child_handles[v].first_vertex()] == v and + // canonical_dfs_child[dfs_child_handles[v].first_vertex()] == v and // canonical_dfs_child[dfs_child_handles[v].second_vertex()] == v. // // - pertinent_roots: given a vertex v, pertinent_roots[v] contains a @@ -365,19 +365,19 @@ namespace boost } canonical_dfs_child[v] = v; - pertinent_roots[v] = face_handle_list_ptr_t(new face_handle_list_t); + pertinent_roots[v] = face_handle_list_ptr_t(new face_handle_list_t); separated_dfs_child_list[v] = vertex_list_ptr_t(new vertex_list_t); } // We need to create a list of not-yet-merged depth-first children for - // each vertex that will be updated as bicomps get merged. We sort each - // list by ascending lowpoint, which allows the externally_active - // function to run in constant time, and we keep a pointer to each - // vertex's representation in its parent's list, which allows merging + // each vertex that will be updated as bicomps get merged. We sort each + // list by ascending lowpoint, which allows the externally_active + // function to run in constant time, and we keep a pointer to each + // vertex's representation in its parent's list, which allows merging //in constant time. - for(typename vertex_vector_t::iterator itr = + for(typename vertex_vector_t::iterator itr = vertices_by_lowpoint.begin(); itr != vertices_by_lowpoint.end(); ++itr) { @@ -389,7 +389,7 @@ namespace boost separated_dfs_child_list[parent]->insert (separated_dfs_child_list[parent]->end(), v); } - } + } // The merge stack holds path information during a walkdown iteration merge_stack.reserve(num_vertices(g)); @@ -404,11 +404,11 @@ namespace boost bool is_planar() { - // This is the main algorithm: starting with a DFS tree of embedded - // edges (which, since it's a tree, is planar), iterate through all + // This is the main algorithm: starting with a DFS tree of embedded + // edges (which, since it's a tree, is planar), iterate through all // vertices by reverse DFS number, attempting to embed all backedges // connecting the current vertex to vertices with higher DFS numbers. - // + // // The walkup is a procedure that examines all such backedges and sets // up the required data structures so that they can be searched by the // walkdown in linear time. The walkdown does the actual work of @@ -434,7 +434,7 @@ namespace boost store_old_face_handles(StoreOldHandlesPolicy()); vertex_t v(*vi); - + walkup(v); if (!walkdown(v)) @@ -445,7 +445,7 @@ namespace boost clean_up_embedding(StoreEmbeddingPolicy()); return true; - + } @@ -462,14 +462,14 @@ namespace boost void walkup(vertex_t v) { - // The point of the walkup is to follow all backedges from v to + // The point of the walkup is to follow all backedges from v to // vertices with higher DFS numbers, and update pertinent_roots // for the bicomp roots on the path from backedge endpoints up // to v. This will set the stage for the walkdown to efficiently // traverse the graph of bicomps down from v. typedef typename face_vertex_iterator::type walkup_iterator_t; - + out_edge_iterator_t oi, oi_end; for(boost::tie(oi,oi_end) = out_edges(v,g); oi != oi_end; ++oi) { @@ -491,7 +491,7 @@ namespace boost backedges[w].push_back(e); - v_size_t timestamp = dfs_number[v]; + v_size_t timestamp = dfs_number[v]; backedge_flag[w] = timestamp; walkup_iterator_t walkup_itr(w, face_handles); @@ -500,11 +500,11 @@ namespace boost while (true) { - + // Move to the root of the current bicomp or the first visited // vertex on the bicomp by going up each side in parallel - - while(walkup_itr != walkup_end && + + while(walkup_itr != walkup_end && visited[*walkup_itr] != timestamp ) { @@ -515,20 +515,20 @@ namespace boost // If we've found the root of a bicomp through a path we haven't // seen before, update pertinent_roots with a handle to the - // current bicomp. Otherwise, we've just seen a path we've been + // current bicomp. Otherwise, we've just seen a path we've been // up before, so break out of the main while loop. - + if (walkup_itr == walkup_end) { vertex_t dfs_child = canonical_dfs_child[lead_vertex]; vertex_t parent = dfs_parent[dfs_child]; - visited[dfs_child_handles[dfs_child].first_vertex()] + visited[dfs_child_handles[dfs_child].first_vertex()] = timestamp; - visited[dfs_child_handles[dfs_child].second_vertex()] + visited[dfs_child_handles[dfs_child].second_vertex()] = timestamp; - if (low_point[dfs_child] < dfs_number[v] || + if (low_point[dfs_child] < dfs_number[v] || least_ancestor[dfs_child] < dfs_number[v] ) { @@ -553,10 +553,10 @@ namespace boost break; } - } - + } + } - + @@ -577,19 +577,19 @@ namespace boost while (!pertinent_roots[v]->empty()) { - + face_handle_t root_face_handle = pertinent_roots[v]->front(); face_handle_t curr_face_handle = root_face_handle; - pertinent_roots[v]->pop_front(); + pertinent_roots[v]->pop_front(); merge_stack.clear(); while(true) { - typename face_vertex_iterator<>::type + typename face_vertex_iterator<>::type first_face_itr, second_face_itr, face_end; - vertex_t first_side_vertex + vertex_t first_side_vertex = graph_traits::null_vertex(); vertex_t second_side_vertex; vertex_t first_tail, second_tail; @@ -603,7 +603,7 @@ namespace boost for(; first_face_itr != face_end; ++first_face_itr) { vertex_t face_vertex(*first_face_itr); - if (pertinent(face_vertex, v) || + if (pertinent(face_vertex, v) || externally_active(face_vertex, v) ) { @@ -614,7 +614,7 @@ namespace boost first_tail = face_vertex; } - if (first_side_vertex == graph_traits::null_vertex() || + if (first_side_vertex == graph_traits::null_vertex() || first_side_vertex == curr_face_handle.get_anchor() ) break; @@ -622,7 +622,7 @@ namespace boost for(;second_face_itr != face_end; ++second_face_itr) { vertex_t face_vertex(*second_face_itr); - if (pertinent(face_vertex, v) || + if (pertinent(face_vertex, v) || externally_active(face_vertex, v) ) { @@ -654,14 +654,14 @@ namespace boost chosen = second_side_vertex; chose_first_upper_path = false; } - else + else { - // If there's a pertinent vertex on the lower face - // between the first_face_itr and the second_face_itr, + // If there's a pertinent vertex on the lower face + // between the first_face_itr and the second_face_itr, // this graph isn't planar. - for(; - *first_face_itr != second_side_vertex; + for(; + *first_face_itr != second_side_vertex; ++first_face_itr ) { @@ -675,85 +675,85 @@ namespace boost return false; } } - - // Otherwise, the fact that we didn't find a pertinent - // vertex on this face is fine - we should set the - // short-circuit edges and break out of this loop to + + // Otherwise, the fact that we didn't find a pertinent + // vertex on this face is fine - we should set the + // short-circuit edges and break out of this loop to // start looking at a different pertinent root. - + if (first_side_vertex == second_side_vertex) { if (first_tail != v) { - vertex_t first + vertex_t first = face_handles[first_tail].first_vertex(); - vertex_t second + vertex_t second = face_handles[first_tail].second_vertex(); - boost::tie(first_side_vertex, first_tail) - = make_tuple(first_tail, - first == first_side_vertex ? + boost::tie(first_side_vertex, first_tail) + = make_tuple(first_tail, + first == first_side_vertex ? second : first ); } else if (second_tail != v) { - vertex_t first + vertex_t first = face_handles[second_tail].first_vertex(); - vertex_t second + vertex_t second = face_handles[second_tail].second_vertex(); - boost::tie(second_side_vertex, second_tail) + boost::tie(second_side_vertex, second_tail) = make_tuple(second_tail, - first == second_side_vertex ? + first == second_side_vertex ? second : first); } else break; } - - canonical_dfs_child[first_side_vertex] + + canonical_dfs_child[first_side_vertex] = canonical_dfs_child[root_face_handle.first_vertex()]; - canonical_dfs_child[second_side_vertex] + canonical_dfs_child[second_side_vertex] = canonical_dfs_child[root_face_handle.second_vertex()]; root_face_handle.set_first_vertex(first_side_vertex); root_face_handle.set_second_vertex(second_side_vertex); - if (face_handles[first_side_vertex].first_vertex() == + if (face_handles[first_side_vertex].first_vertex() == first_tail ) face_handles[first_side_vertex].set_first_vertex(v); else face_handles[first_side_vertex].set_second_vertex(v); - if (face_handles[second_side_vertex].first_vertex() == + if (face_handles[second_side_vertex].first_vertex() == second_tail ) face_handles[second_side_vertex].set_first_vertex(v); else face_handles[second_side_vertex].set_second_vertex(v); - + break; - + } - // When we unwind the stack, we need to know which direction + // When we unwind the stack, we need to know which direction // we came down from on the top face handle - - bool chose_first_lower_path = - (chose_first_upper_path && - face_handles[chosen].first_vertex() == first_tail) + + bool chose_first_lower_path = + (chose_first_upper_path && + face_handles[chosen].first_vertex() == first_tail) || - (!chose_first_upper_path && + (!chose_first_upper_path && face_handles[chosen].first_vertex() == second_tail); //If there's a backedge at the chosen vertex, embed it now if (backedge_flag[chosen] == dfs_number[v]) { w = chosen; - + backedge_flag[chosen] = num_vertices(g) + 1; add_to_merge_points(chosen, StoreOldHandlesPolicy()); - + typename edge_vector_t::iterator ei, ei_end; ei_end = backedges[chosen].end(); for(ei = backedges[chosen].begin(); ei != ei_end; ++ei) @@ -778,11 +778,10 @@ namespace boost } //Unwind the merge stack to the root, merging all bicomps - + bool bottom_path_follows_first; bool top_path_follows_first; bool next_bottom_follows_first = chose_first_upper_path; - face_handle_t top_handle, bottom_handle; vertex_t merge_point = chosen; @@ -790,8 +789,8 @@ namespace boost { bottom_path_follows_first = next_bottom_follows_first; - boost::tie(merge_point, - next_bottom_follows_first, + boost::tie(merge_point, + next_bottom_follows_first, top_path_follows_first ) = merge_stack.back(); merge_stack.pop_back(); @@ -799,7 +798,7 @@ namespace boost face_handle_t top_handle(face_handles[merge_point]); face_handle_t bottom_handle (*pertinent_roots[merge_point]->begin()); - + vertex_t bottom_dfs_child = canonical_dfs_child [pertinent_roots[merge_point]->begin()->first_vertex()]; @@ -810,23 +809,23 @@ namespace boost pertinent_roots[merge_point]->pop_front(); - add_to_merge_points(top_handle.get_anchor(), + add_to_merge_points(top_handle.get_anchor(), StoreOldHandlesPolicy() ); - + if (top_path_follows_first && bottom_path_follows_first) { bottom_handle.flip(); top_handle.glue_first_to_second(bottom_handle); - } - else if (!top_path_follows_first && + } + else if (!top_path_follows_first && bottom_path_follows_first ) { flipped[bottom_dfs_child] = true; top_handle.glue_second_to_first(bottom_handle); } - else if (top_path_follows_first && + else if (top_path_follows_first && !bottom_path_follows_first ) { @@ -842,17 +841,17 @@ namespace boost } //Finally, embed all edges (v,w) at their upper end points - canonical_dfs_child[w] + canonical_dfs_child[w] = canonical_dfs_child[root_face_handle.first_vertex()]; - - add_to_merge_points(root_face_handle.get_anchor(), + + add_to_merge_points(root_face_handle.get_anchor(), StoreOldHandlesPolicy() ); - + typename edge_vector_t::iterator ei, ei_end; ei_end = backedges[chosen].end(); for(ei = backedges[chosen].begin(); ei != ei_end; ++ei) - { + { if (next_bottom_follows_first) root_face_handle.push_first(*ei, g); else @@ -863,7 +862,7 @@ namespace boost curr_face_handle = root_face_handle; }//while(true) - + }//while(!pertinent_roots[v]->empty()) return true; @@ -879,14 +878,14 @@ namespace boost void store_old_face_handles(graph::detail::store_old_handles) { - for(typename std::vector::iterator mp_itr + for(typename std::vector::iterator mp_itr = current_merge_points.begin(); mp_itr != current_merge_points.end(); ++mp_itr) { face_handles[*mp_itr].store_old_face_handles(); } current_merge_points.clear(); - } + } void add_to_merge_points(vertex_t, graph::detail::no_old_handles) {} @@ -896,7 +895,7 @@ namespace boost current_merge_points.push_back(v); } - + void add_to_embedded_edges(edge_t, graph::detail::no_old_handles) {} void add_to_embedded_edges(edge_t e, graph::detail::store_old_handles) @@ -924,7 +923,7 @@ namespace boost { typename vertex_list_t::iterator yi, yi_end; yi_end = separated_dfs_child_list[*xi]->end(); - for(yi = separated_dfs_child_list[*xi]->begin(); + for(yi = separated_dfs_child_list[*xi]->begin(); yi != yi_end; ++yi ) { @@ -933,7 +932,7 @@ namespace boost (dfs_child_handles[*yi]); } } - } + } // Up until this point, we've flipped bicomps lazily by setting // flipped[v] to true if the bicomp rooted at v was flipped (the @@ -944,7 +943,7 @@ namespace boost typedef typename vertex_vector_t::iterator vertex_vector_itr_t; vertex_vector_itr_t vi_end = vertices_by_dfs_num.end(); - for(vertex_vector_itr_t vi = vertices_by_dfs_num.begin(); + for(vertex_vector_itr_t vi = vertices_by_dfs_num.begin(); vi != vi_end; ++vi ) { @@ -968,7 +967,7 @@ namespace boost // If there are any self-loops in the graph, they were flagged // during the walkup, and we should add them to the embedding now. - // Adding a self loop anywhere in the embedding could never + // Adding a self loop anywhere in the embedding could never // invalidate the embedding, but they would complicate the traversal // if they were added during the walkup/walkdown. @@ -979,13 +978,13 @@ namespace boost edge_t e(*ei); face_handles[source(e,g)].push_second(e,g); } - + } - + bool pertinent(vertex_t w, vertex_t v) { // w is pertinent with respect to v if there is a backedge (v,w) or if @@ -993,38 +992,38 @@ namespace boost return backedge_flag[w] == dfs_number[v] || !pertinent_roots[w]->empty(); } - + bool externally_active(vertex_t w, vertex_t v) { // Let a be any proper depth-first search ancestor of v. w is externally - // active with respect to v if there exists a backedge (a,w) or a + // active with respect to v if there exists a backedge (a,w) or a // backedge (a,w_0) for some w_0 in a descendent bicomp of w. v_size_t dfs_number_of_v = dfs_number[v]; return (least_ancestor[w] < dfs_number_of_v) || (!separated_dfs_child_list[w]->empty() && - low_point[separated_dfs_child_list[w]->front()] < dfs_number_of_v); + low_point[separated_dfs_child_list[w]->front()] < dfs_number_of_v); } - - + + bool internally_active(vertex_t w, vertex_t v) { return pertinent(w,v) && !externally_active(w,v); - } - + } + void remove_vertex_from_separated_dfs_child_list(vertex_t v) { - typename vertex_list_t::iterator to_delete + typename vertex_list_t::iterator to_delete = separated_node_in_parent_list[v]; - garbage.splice(garbage.end(), - *separated_dfs_child_list[dfs_parent[v]], - to_delete, + garbage.splice(garbage.end(), + *separated_dfs_child_list[dfs_parent[v]], + to_delete, boost::next(to_delete) ); } @@ -1032,9 +1031,9 @@ namespace boost - + // End of the implementation of the basic Boyer-Myrvold Algorithm. The rest - // of the code below implements the isolation of a Kuratowski subgraph in + // of the code below implements the isolation of a Kuratowski subgraph in // the case that the input graph is not planar. This is by far the most // complicated part of the implementation. @@ -1047,7 +1046,7 @@ namespace boost template - vertex_t kuratowski_walkup(vertex_t v, + vertex_t kuratowski_walkup(vertex_t v, EdgeToBoolPropertyMap forbidden_edge, EdgeToBoolPropertyMap goal_edge, EdgeToBoolPropertyMap is_embedded, @@ -1057,19 +1056,19 @@ namespace boost vertex_t current_endpoint; bool seen_goal_edge = false; out_edge_iterator_t oi, oi_end; - + for(boost::tie(oi,oi_end) = out_edges(v,g); oi != oi_end; ++oi) forbidden_edge[*oi] = true; - + for(boost::tie(oi,oi_end) = out_edges(v,g); oi != oi_end; ++oi) { path_edges.clear(); - + edge_t e(*oi); - current_endpoint = target(*oi,g) == v ? + current_endpoint = target(*oi,g) == v ? source(*oi,g) : target(*oi,g); - - if (dfs_number[current_endpoint] < dfs_number[v] || + + if (dfs_number[current_endpoint] < dfs_number[v] || is_embedded[e] || v == current_endpoint //self-loop ) @@ -1077,7 +1076,7 @@ namespace boost //Not a backedge continue; } - + path_edges.push_back(e); if (goal_edge[e]) { @@ -1085,30 +1084,30 @@ namespace boost } typedef typename face_edge_iterator<>::type walkup_itr_t; - - walkup_itr_t + + walkup_itr_t walkup_itr(current_endpoint, face_handles, first_side()); walkup_itr_t walkup_end; - + seen_goal_edge = false; - + while (true) - { - + { + if (walkup_itr != walkup_end && forbidden_edge[*walkup_itr]) break; - - while(walkup_itr != walkup_end && - !goal_edge[*walkup_itr] && + + while(walkup_itr != walkup_end && + !goal_edge[*walkup_itr] && !forbidden_edge[*walkup_itr] ) { edge_t f(*walkup_itr); forbidden_edge[f] = true; path_edges.push_back(f); - current_endpoint = - source(f, g) == current_endpoint ? - target(f, g) : + current_endpoint = + source(f, g) == current_endpoint ? + target(f, g) : source(f,g); ++walkup_itr; } @@ -1120,14 +1119,14 @@ namespace boost break; } - walkup_itr + walkup_itr = walkup_itr_t(current_endpoint, face_handles, first_side()); - + } - + if (seen_goal_edge) break; - + } if (seen_goal_edge) @@ -1157,9 +1156,9 @@ namespace boost // | there exists some bicomp containing three vertices // ----- x,y, and z as shown such that x and y are externally // | | active with respect to v (which means that there are - // x y two vertices x_0 and y_0 such that (1) both x_0 and - // | | y_0 are proper depth-first search ancestors of v and - // --z-- (2) there are two disjoint paths, one connecting x + // x y two vertices x_0 and y_0 such that (1) both x_0 and + // | | y_0 are proper depth-first search ancestors of v and + // --z-- (2) there are two disjoint paths, one connecting x // and x_0 and one connecting y and y_0, both consisting // fig. 1 entirely of unembedded edges). Furthermore, there // exists a vertex z_0 such that z is a depth-first @@ -1175,10 +1174,10 @@ namespace boost // properties of the Boyer-Myrvold algorithm to show the existence of an // "x-y path" connecting some vertex on the "left side" of the x,y,z // bicomp with some vertex on the "right side" of the bicomp (where the - // left and right are split by a line drawn through v and z.If either of - // the endpoints of the x-y path is above x or y on the bicomp, a K_3_3 - // can be isolated - this is a case C. Otherwise, both endpoints are at - // or below x and y on the bicomp. If there is a vertex alpha on the x-y + // left and right are split by a line drawn through v and z.If either of + // the endpoints of the x-y path is above x or y on the bicomp, a K_3_3 + // can be isolated - this is a case C. Otherwise, both endpoints are at + // or below x and y on the bicomp. If there is a vertex alpha on the x-y // path such that alpha is not x or y and there's a path from alpha to v // that's disjoint from any of the edges on the bicomp and the x-y path, // a K_3_3 can be isolated - this is a case D. Otherwise, properties of @@ -1192,8 +1191,8 @@ namespace boost out_edge_iterator_t oei, oei_end; typename std::vector::iterator xi, xi_end; - // Clear the short-circuit edges - these are needed for the planar - // testing/embedding algorithm to run in linear time, but they'll + // Clear the short-circuit edges - these are needed for the planar + // testing/embedding algorithm to run in linear time, but they'll // complicate the kuratowski subgraph isolation for(boost::tie(vi,vi_end) = vertices(g); vi != vi_end; ++vi) { @@ -1217,12 +1216,12 @@ namespace boost typename std::vector::iterator embedded_itr, embedded_end; embedded_end = embedded_edges.end(); - for(embedded_itr = embedded_edges.begin(); + for(embedded_itr = embedded_edges.begin(); embedded_itr != embedded_end; ++embedded_itr ) is_embedded[*embedded_itr] = true; - // upper_face_vertex is true for x,y, and all vertices above x and y in + // upper_face_vertex is true for x,y, and all vertices above x and y in // the bicomp std::vector upper_face_vertex_vector(num_vertices(g), false); vertex_to_bool_map_t upper_face_vertex @@ -1234,7 +1233,7 @@ namespace boost // These next few variable declarations are all things that we need // to find. - vertex_t z; + vertex_t z = graph_traits::null_vertex(); vertex_t bicomp_root; vertex_t w = graph_traits::null_vertex(); face_handle_t w_handle; @@ -1256,13 +1255,13 @@ namespace boost //backedge from V, then goes up until it hits either X or Y //(but doesn't find X or Y as the root of a bicomp) - typename face_vertex_iterator<>::type + typename face_vertex_iterator<>::type x_upper_itr(x, face_handles, first_side()); - typename face_vertex_iterator<>::type + typename face_vertex_iterator<>::type x_lower_itr(x, face_handles, second_side()); typename face_vertex_iterator<>::type face_itr, face_end; - // Don't know which path from x is the upper or lower path - + // Don't know which path from x is the upper or lower path - // we'll find out here for(face_itr = x_upper_itr; face_itr != face_end; ++face_itr) { @@ -1284,9 +1283,9 @@ namespace boost upper_face_vertex[current_vertex] = true; } - v_dfchild_handle + v_dfchild_handle = dfs_child_handles[canonical_dfs_child[previous_vertex]]; - + for(face_itr = x_lower_itr; *face_itr != y; ++face_itr) { vertex_t current_vertex(*face_itr); @@ -1297,7 +1296,7 @@ namespace boost if (w == graph_traits::null_vertex()) //haven't found a w yet { roots_end = pertinent_roots[current_vertex]->end(); - for(roots_itr = pertinent_roots[current_vertex]->begin(); + for(roots_itr = pertinent_roots[current_vertex]->begin(); roots_itr != roots_end; ++roots_itr ) { @@ -1327,7 +1326,7 @@ namespace boost edge_to_bool_map_t outer_face_edge(outer_face_edge_vector.begin(), em); walkup_itr_t walkup_end; - for(walkup_itr_t walkup_itr(x, face_handles, first_side()); + for(walkup_itr_t walkup_itr(x, face_handles, first_side()); walkup_itr != walkup_end; ++walkup_itr ) { @@ -1335,7 +1334,7 @@ namespace boost is_in_subgraph[*walkup_itr] = true; } - for(walkup_itr_t walkup_itr(x, face_handles, second_side()); + for(walkup_itr_t walkup_itr(x, face_handles, second_side()); walkup_itr != walkup_end; ++walkup_itr ) { @@ -1355,53 +1354,53 @@ namespace boost for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { edge_t e(*ei); - goal_edge[e] + goal_edge[e] = !outer_face_edge[e] && (source(e,g) == x || target(e,g) == x); forbidden_edge[*ei] = outer_face_edge[*ei]; } vertex_t x_ancestor = v; vertex_t x_endpoint = graph_traits::null_vertex(); - + while(x_endpoint == graph_traits::null_vertex()) - { + { x_ancestor = dfs_parent[x_ancestor]; - x_endpoint = kuratowski_walkup(x_ancestor, - forbidden_edge, + x_endpoint = kuratowski_walkup(x_ancestor, + forbidden_edge, goal_edge, is_embedded, x_external_path ); - - } + + } for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { edge_t e(*ei); - goal_edge[e] + goal_edge[e] = !outer_face_edge[e] && (source(e,g) == y || target(e,g) == y); forbidden_edge[*ei] = outer_face_edge[*ei]; } vertex_t y_ancestor = v; vertex_t y_endpoint = graph_traits::null_vertex(); - + while(y_endpoint == graph_traits::null_vertex()) - { + { y_ancestor = dfs_parent[y_ancestor]; - y_endpoint = kuratowski_walkup(y_ancestor, - forbidden_edge, + y_endpoint = kuratowski_walkup(y_ancestor, + forbidden_edge, goal_edge, is_embedded, y_external_path ); - - } - + + } + vertex_t parent, child; - + //If v isn't on the same bicomp as x and y, it's a case A if (bicomp_root != v) { @@ -1412,13 +1411,13 @@ namespace boost for(boost::tie(oei,oei_end) = out_edges(*vi,g); oei != oei_end; ++oei) if(!outer_face_edge[*oei]) goal_edge[*oei] = true; - + for(boost::tie(ei,ei_end) = edges(g); ei != ei_end; ++ei) forbidden_edge[*ei] = outer_face_edge[*ei]; - + z = kuratowski_walkup (v, forbidden_edge, goal_edge, is_embedded, z_v_path); - + } else if (w != graph_traits::null_vertex()) { @@ -1430,17 +1429,17 @@ namespace boost goal_edge[e] = false; forbidden_edge[e] = outer_face_edge[e]; } - + goal_edge[w_handle.first_edge()] = true; goal_edge[w_handle.second_edge()] = true; z = kuratowski_walkup(v, - forbidden_edge, + forbidden_edge, goal_edge, is_embedded, z_v_path ); - + for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { @@ -1453,41 +1452,41 @@ namespace boost { goal_edge[*pi] = true; } - + w_ancestor = v; vertex_t w_endpoint = graph_traits::null_vertex(); - + while(w_endpoint == graph_traits::null_vertex()) - { + { w_ancestor = dfs_parent[w_ancestor]; - w_endpoint = kuratowski_walkup(w_ancestor, - forbidden_edge, + w_endpoint = kuratowski_walkup(w_ancestor, + forbidden_edge, goal_edge, is_embedded, w_path ); - - } - - // We really want both the w walkup and the z walkup to finish on - // exactly the same edge, but for convenience (since we don't have - // control over which side of a bicomp a walkup moves up) we've - // defined the walkup to either end at w_handle.first_edge() or - // w_handle.second_edge(). If both walkups ended at different edges, - // we'll do a little surgery on the w walkup path to make it follow + + } + + // We really want both the w walkup and the z walkup to finish on + // exactly the same edge, but for convenience (since we don't have + // control over which side of a bicomp a walkup moves up) we've + // defined the walkup to either end at w_handle.first_edge() or + // w_handle.second_edge(). If both walkups ended at different edges, + // we'll do a little surgery on the w walkup path to make it follow // the other side of the final bicomp. - if ((w_path.back() == w_handle.first_edge() && - z_v_path.back() == w_handle.second_edge()) + if ((w_path.back() == w_handle.first_edge() && + z_v_path.back() == w_handle.second_edge()) || - (w_path.back() == w_handle.second_edge() && + (w_path.back() == w_handle.second_edge() && z_v_path.back() == w_handle.first_edge()) ) { walkup_itr_t wi, wi_end; edge_t final_edge = w_path.back(); - vertex_t anchor - = source(final_edge, g) == w_handle.get_anchor() ? + vertex_t anchor + = source(final_edge, g) == w_handle.get_anchor() ? target(final_edge, g) : source(final_edge, g); if (face_handles[anchor].first_edge() == final_edge) wi = walkup_itr_t(anchor, face_handles, second_side()); @@ -1506,9 +1505,9 @@ namespace boost } } - + } - else + else { //We need to find a valid z, since the x-y path re-defines the lower @@ -1519,7 +1518,7 @@ namespace boost // The z we've used so far is just an externally active vertex on the // lower face path, but may not be the z we need for a case C, D, or - // E subgraph. the z we need now is any externally active vertex on + // E subgraph. the z we need now is any externally active vertex on // the lower face path with both old_face_handles edges on the outer // face. Since we know an x-y path exists, such a z must also exist. @@ -1530,7 +1529,7 @@ namespace boost for(face_itr = x_lower_itr; *face_itr != y; ++face_itr) { vertex_t possible_z(*face_itr); - if (pertinent(possible_z,v) && + if (pertinent(possible_z,v) && outer_face_edge[face_handles[possible_z].old_first_edge()] && outer_face_edge[face_handles[possible_z].old_second_edge()] ) @@ -1544,14 +1543,14 @@ namespace boost if (externally_active(z,v)) w = z; - + typedef typename face_edge_iterator - ::type old_face_iterator_t; + ::type old_face_iterator_t; - old_face_iterator_t + old_face_iterator_t first_old_face_itr(z, face_handles, first_side()); - old_face_iterator_t + old_face_iterator_t second_old_face_itr(z, face_handles, second_side()); old_face_iterator_t old_face_itr, old_face_end; @@ -1563,10 +1562,10 @@ namespace boost vertex_to_bool_map_t x_y_path_vertex (x_y_path_vertex_vector.begin(), vm); - typename std::vector::iterator + typename std::vector::iterator of_itr, of_itr_end; - of_itr_end = old_face_iterators.end(); - for(of_itr = old_face_iterators.begin(); + of_itr_end = old_face_iterators.end(); + for(of_itr = old_face_iterators.begin(); of_itr != of_itr_end; ++of_itr ) { @@ -1580,13 +1579,13 @@ namespace boost { edge_t e(*old_face_itr); previous_vertex = current_vertex; - current_vertex = source(e,g) == current_vertex ? + current_vertex = source(e,g) == current_vertex ? target(e,g) : source(e,g); - + if (current_vertex == x || current_vertex == y) seen_x_or_y = true; - if (w == graph_traits::null_vertex() && + if (w == graph_traits::null_vertex() && externally_active(current_vertex,v) && outer_face_edge[e] && outer_face_edge[*boost::next(old_face_itr)] && @@ -1595,10 +1594,10 @@ namespace boost { w = current_vertex; } - + if (!outer_face_edge[e]) { - if (!upper_face_vertex[current_vertex] && + if (!upper_face_vertex[current_vertex] && !lower_face_vertex[current_vertex] ) { @@ -1606,22 +1605,22 @@ namespace boost } is_in_subgraph[e] = true; - if (upper_face_vertex[source(e,g)] || + if (upper_face_vertex[source(e,g)] || lower_face_vertex[source(e,g)] ) { - if (first_x_y_path_endpoint == + if (first_x_y_path_endpoint == graph_traits::null_vertex() ) first_x_y_path_endpoint = source(e,g); else second_x_y_path_endpoint = source(e,g); } - if (upper_face_vertex[target(e,g)] || + if (upper_face_vertex[target(e,g)] || lower_face_vertex[target(e,g)] ) { - if (first_x_y_path_endpoint == + if (first_x_y_path_endpoint == graph_traits::null_vertex() ) first_x_y_path_endpoint = target(e,g); @@ -1635,35 +1634,35 @@ namespace boost { chosen_case = detail::BM_CASE_C; } - + } } - // Look for a case D - one of v's embedded edges will connect to the + // Look for a case D - one of v's embedded edges will connect to the // x-y path along an inner face path. //First, get a list of all of v's embedded child edges out_edge_iterator_t v_edge_itr, v_edge_end; - for(boost::tie(v_edge_itr,v_edge_end) = out_edges(v,g); + for(boost::tie(v_edge_itr,v_edge_end) = out_edges(v,g); v_edge_itr != v_edge_end; ++v_edge_itr ) { edge_t embedded_edge(*v_edge_itr); - - if (!is_embedded[embedded_edge] || + + if (!is_embedded[embedded_edge] || embedded_edge == dfs_parent_edge[v] ) continue; case_d_edges.push_back(embedded_edge); - vertex_t current_vertex - = source(embedded_edge,g) == v ? + vertex_t current_vertex + = source(embedded_edge,g) == v ? target(embedded_edge,g) : source(embedded_edge,g); - typename face_edge_iterator<>::type + typename face_edge_iterator<>::type internal_face_itr, internal_face_end; if (face_handles[current_vertex].first_vertex() == v) { @@ -1677,13 +1676,13 @@ namespace boost } while(internal_face_itr != internal_face_end && - !outer_face_edge[*internal_face_itr] && + !outer_face_edge[*internal_face_itr] && !x_y_path_vertex[current_vertex] ) { edge_t e(*internal_face_itr); case_d_edges.push_back(e); - current_vertex = + current_vertex = source(e,g) == current_vertex ? target(e,g) : source(e,g); ++internal_face_itr; } @@ -1699,7 +1698,7 @@ namespace boost } } - + } @@ -1714,25 +1713,25 @@ namespace boost for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { edge_t e(*ei); - goal_edge[e] = !outer_face_edge[e] && + goal_edge[e] = !outer_face_edge[e] && (source(e,g) == z || target(e,g) == z); forbidden_edge[e] = outer_face_edge[e]; } kuratowski_walkup(v, - forbidden_edge, + forbidden_edge, goal_edge, is_embedded, z_v_path ); - + if (chosen_case == detail::BM_CASE_E) { for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) { forbidden_edge[*ei] = outer_face_edge[*ei]; - goal_edge[*ei] = !outer_face_edge[*ei] && + goal_edge[*ei] = !outer_face_edge[*ei] && (source(*ei,g) == w || target(*ei,g) == w); } @@ -1748,22 +1747,22 @@ namespace boost { goal_edge[*pi] = true; } - + w_ancestor = v; vertex_t w_endpoint = graph_traits::null_vertex(); - + while(w_endpoint == graph_traits::null_vertex()) - { + { w_ancestor = dfs_parent[w_ancestor]; - w_endpoint = kuratowski_walkup(w_ancestor, - forbidden_edge, + w_endpoint = kuratowski_walkup(w_ancestor, + forbidden_edge, goal_edge, is_embedded, w_path ); - - } - + + } + } @@ -1794,7 +1793,7 @@ namespace boost xi_end = w_path.end(); for(xi = w_path.begin(); xi != xi_end; ++xi) is_in_subgraph[*xi] = true; - + child = bicomp_root; parent = dfs_parent[child]; while(child != parent) @@ -1806,10 +1805,10 @@ namespace boost - // At this point, we've already isolated the Kuratowski subgraph and - // collected all of the edges that compose it in the is_in_subgraph - // property map. But we want the verification of such a subgraph to be - // a deterministic process, and we can simplify the function + // At this point, we've already isolated the Kuratowski subgraph and + // collected all of the edges that compose it in the is_in_subgraph + // property map. But we want the verification of such a subgraph to be + // a deterministic process, and we can simplify the function // is_kuratowski_subgraph by cleaning up some edges here. if (chosen_case == detail::BM_CASE_B) @@ -1821,13 +1820,13 @@ namespace boost // In a case C subgraph, at least one of the x-y path endpoints // (call it alpha) is above either x or y on the outer face. The // other endpoint may be attached at x or y OR above OR below. In - // any of these three cases, we can form a K_3_3 by removing the - // edge attached to v on the outer face that is NOT on the path to + // any of these three cases, we can form a K_3_3 by removing the + // edge attached to v on the outer face that is NOT on the path to // alpha. - typename face_vertex_iterator::type + typename face_vertex_iterator::type face_itr, face_end; - if (face_handles[v_dfchild_handle.first_vertex()].first_edge() == + if (face_handles[v_dfchild_handle.first_vertex()].first_edge() == v_dfchild_handle.first_edge() ) { @@ -1857,13 +1856,13 @@ namespace boost break; } } - + } else if (chosen_case == detail::BM_CASE_D) { // Need to remove both of the edges adjacent to v on the outer face. // remove the connecting edges from v to bicomp, then - // is_kuratowski_subgraph will shrink vertices of degree 1 + // is_kuratowski_subgraph will shrink vertices of degree 1 // automatically... is_in_subgraph[v_dfchild_handle.first_edge()] = false; @@ -1872,8 +1871,8 @@ namespace boost } else if (chosen_case == detail::BM_CASE_E) { - // Similarly to case C, if the endpoints of the x-y path are both - // below x and y, we should remove an edge to allow the subgraph to + // Similarly to case C, if the endpoints of the x-y path are both + // below x and y, we should remove an edge to allow the subgraph to // contract to a K_3_3. @@ -1881,7 +1880,7 @@ namespace boost (second_x_y_path_endpoint != x && second_x_y_path_endpoint != y) ) { - is_in_subgraph[dfs_parent_edge[v]] = false; + is_in_subgraph[dfs_parent_edge[v]] = false; vertex_t deletion_endpoint, other_endpoint; if (lower_face_vertex[first_x_y_path_endpoint]) @@ -1890,13 +1889,13 @@ namespace boost other_endpoint = first_x_y_path_endpoint; } else - { + { deletion_endpoint = first_x_y_path_endpoint; other_endpoint = second_x_y_path_endpoint; } typename face_edge_iterator<>::type face_itr, face_end; - + bool found_other_endpoint = false; for(face_itr = typename face_edge_iterator<>::type (deletion_endpoint, face_handles, first_side()); @@ -1904,7 +1903,7 @@ namespace boost ) { edge_t e(*face_itr); - if (source(e,g) == other_endpoint || + if (source(e,g) == other_endpoint || target(e,g) == other_endpoint ) { @@ -1915,7 +1914,7 @@ namespace boost if (found_other_endpoint) { - is_in_subgraph[face_handles[deletion_endpoint].first_edge()] + is_in_subgraph[face_handles[deletion_endpoint].first_edge()] = false; } else @@ -1924,14 +1923,14 @@ namespace boost = false; } } - + } for(boost::tie(ei, ei_end) = edges(g); ei != ei_end; ++ei) if (is_in_subgraph[*ei]) *o_itr = *ei; - + } @@ -1957,14 +1956,14 @@ namespace boost vertex_t kuratowski_v; vertex_t kuratowski_x; vertex_t kuratowski_y; - - vertex_list_t garbage; // we delete items from linked lists by + + vertex_list_t garbage; // we delete items from linked lists by // splicing them into garbage //only need these two for kuratowski subgraph isolation std::vector current_merge_points; std::vector embedded_edges; - + //property map storage std::vector low_point_vector; std::vector dfs_parent_vector; @@ -1976,7 +1975,7 @@ namespace boost std::vector< face_handle_t > face_handles_vector; std::vector< face_handle_t > dfs_child_handles_vector; std::vector< vertex_list_ptr_t > separated_dfs_child_list_vector; - std::vector< typename vertex_list_t::iterator > + std::vector< typename vertex_list_t::iterator > separated_node_in_parent_list_vector; std::vector canonical_dfs_child_vector; std::vector flipped_vector; @@ -1993,20 +1992,20 @@ namespace boost vertex_to_face_handle_list_ptr_map_t pertinent_roots; vertex_to_v_size_map_t backedge_flag; vertex_to_v_size_map_t visited; - vertex_to_face_handle_map_t face_handles; + vertex_to_face_handle_map_t face_handles; vertex_to_face_handle_map_t dfs_child_handles; vertex_to_vertex_list_ptr_map_t separated_dfs_child_list; vertex_to_separated_node_map_t separated_node_in_parent_list; - vertex_to_vertex_map_t canonical_dfs_child; + vertex_to_vertex_map_t canonical_dfs_child; vertex_to_bool_map_t flipped; vertex_to_edge_vector_map_t backedges; vertex_to_edge_map_t dfs_parent_edge; //only need for kuratowski merge_stack_t merge_stack; - + }; - - + + } //namespace boost #endif //__BOYER_MYRVOLD_IMPL_HPP__ diff --git a/include/boost/graph/properties.hpp b/include/boost/graph/properties.hpp index ca6a4e9b..660102b4 100644 --- a/include/boost/graph/properties.hpp +++ b/include/boost/graph/properties.hpp @@ -324,13 +324,6 @@ namespace boost { } -#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) && !defined (BOOST_GRAPH_NO_BUNDLED_PROPERTIES) -// This compiler cannot define a partial specialization based on a -// pointer-to-member type, as seen in boost/graph/subgraph.hpp line 985 (as of -// trunk r53912) -# define BOOST_GRAPH_NO_BUNDLED_PROPERTIES -#endif - // NOTE: These functions are declared, but never defined since they need to // be overloaded by graph implementations. However, we need them to be // declared for the functions below. diff --git a/include/boost/graph/r_c_shortest_paths.hpp b/include/boost/graph/r_c_shortest_paths.hpp index afa50cf0..7e490fc7 100644 --- a/include/boost/graph/r_c_shortest_paths.hpp +++ b/include/boost/graph/r_c_shortest_paths.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include diff --git a/include/boost/graph/random.hpp b/include/boost/graph/random.hpp index f0153b2c..8b3d3c50 100644 --- a/include/boost/graph/random.hpp +++ b/include/boost/graph/random.hpp @@ -103,6 +103,7 @@ namespace boost { } } BOOST_ASSERT (false); // Should not get here + return typename graph_traits::edge_descriptor(); } namespace detail { diff --git a/include/boost/graph/reverse_graph.hpp b/include/boost/graph/reverse_graph.hpp index 24eb1c7c..56ffe72d 100644 --- a/include/boost/graph/reverse_graph.hpp +++ b/include/boost/graph/reverse_graph.hpp @@ -322,6 +322,13 @@ target(const detail::reverse_graph_edge_descriptor& e, const reverse_graph return source(e.underlying_descx, g.m_g); } +template +inline typename graph_traits::degree_size_type +degree(const typename graph_traits::vertex_descriptor u, + const reverse_graph& g) +{ + return degree(u, g.m_g); +} namespace detail { diff --git a/include/boost/graph/stanford_graph.hpp b/include/boost/graph/stanford_graph.hpp index b2d3987d..01431737 100644 --- a/include/boost/graph/stanford_graph.hpp +++ b/include/boost/graph/stanford_graph.hpp @@ -46,6 +46,8 @@ extern "C" { #include /* graphs based on literature */ #include /* graphs based on economic data */ #include /* graphs based on football scores */ +#undef ap /* avoid name clash with BGL parameter */ + // ap ==> Vertex::u.I #include /* graphs based on logic circuits */ #undef val /* avoid name clash with g++ headerfile stl_tempbuf.h */ // val ==> Vertex::x.I @@ -92,6 +94,9 @@ namespace boost { typedef directed_tag directed_category; typedef sgb_traversal_tag traversal_category; typedef allow_parallel_edge_tag edge_parallel_category; + /** Return a null descriptor */ + static vertex_descriptor null_vertex() + { return NULL; } }; template <> struct graph_traits { typedef Vertex* vertex_descriptor; @@ -107,6 +112,9 @@ namespace boost { typedef directed_tag directed_category; typedef sgb_traversal_tag traversal_category; typedef allow_parallel_edge_tag edge_parallel_category; + /** Return a null descriptor */ + static vertex_descriptor null_vertex() + { return NULL; } }; } diff --git a/include/boost/graph/strong_components.hpp b/include/boost/graph/strong_components.hpp index 61345bdc..f1bd56d6 100644 --- a/include/boost/graph/strong_components.hpp +++ b/include/boost/graph/strong_components.hpp @@ -64,6 +64,7 @@ namespace boost { do { w = s.top(); s.pop(); put(comp, w, c); + put(root, w, v); } while (w != v); ++c; } diff --git a/include/boost/graph/transitive_closure.hpp b/include/boost/graph/transitive_closure.hpp index 4f81349b..ac1f0ae3 100644 --- a/include/boost/graph/transitive_closure.hpp +++ b/include/boost/graph/transitive_closure.hpp @@ -41,8 +41,9 @@ namespace boost { template < typename TheContainer, typename ST = std::size_t, typename VT = typename TheContainer::value_type > - struct subscript_t:public std::unary_function < ST, VT > + struct subscript_t { + typedef ST argument_type; typedef VT& result_type; subscript_t(TheContainer & c):container(&c) diff --git a/include/boost/graph/tree_traits.hpp b/include/boost/graph/tree_traits.hpp index 0843628c..a04c750f 100644 --- a/include/boost/graph/tree_traits.hpp +++ b/include/boost/graph/tree_traits.hpp @@ -6,6 +6,8 @@ #ifndef BOOST_TREE_STRUCTURE_HPP #define BOOST_TREE_STRUCTURE_HPP +#include //For boost::tie() + namespace boost { template diff --git a/include/boost/graph/undirected_graph.hpp b/include/boost/graph/undirected_graph.hpp index 5c000dc2..1db21a64 100644 --- a/include/boost/graph/undirected_graph.hpp +++ b/include/boost/graph/undirected_graph.hpp @@ -294,7 +294,7 @@ public: } void swap(undirected_graph& g) { - m_graph.swap(g); + m_graph.swap(g.m_graph); std::swap(m_num_vertices, g.m_num_vertices); std::swap(m_max_vertex_index, g.m_max_vertex_index); std::swap(m_num_edges, g.m_num_edges); diff --git a/include/boost/graph/vf2_sub_graph_iso.hpp b/include/boost/graph/vf2_sub_graph_iso.hpp index f86b6ee2..564b00f3 100644 --- a/include/boost/graph/vf2_sub_graph_iso.hpp +++ b/include/boost/graph/vf2_sub_graph_iso.hpp @@ -113,16 +113,13 @@ namespace boost { IndexMapThis index_map_this, IndexMapOther index_map_other) : graph_this_(graph_this), graph_other_(graph_other), index_map_this_(index_map_this), index_map_other_(index_map_other), + core_vec_(num_vertices(graph_this_), graph_traits::null_vertex()), + core_(core_vec_.begin(), index_map_this_), + in_vec_(num_vertices(graph_this_), 0), + out_vec_(num_vertices(graph_this_), 0), + in_(in_vec_.begin(), index_map_this_), + out_(out_vec_.begin(), index_map_this_), term_in_count_(0), term_out_count_(0), term_both_count_(0), core_count_(0) { - - core_vec_.resize(num_vertices(graph_this_), graph_traits::null_vertex()); - core_ = make_iterator_property_map(core_vec_.begin(), index_map_this_); - - in_vec_.resize(num_vertices(graph_this_), 0); - in_ = make_iterator_property_map(in_vec_.begin(), index_map_this_); - - out_vec_.resize(num_vertices(graph_this_), 0); - out_ = make_iterator_property_map(out_vec_.begin(), index_map_this_); } // Adds a vertex pair to the state of graph graph_this diff --git a/include/boost/pending/container_traits.hpp b/include/boost/pending/container_traits.hpp index a58b5245..13800a30 100644 --- a/include/boost/pending/container_traits.hpp +++ b/include/boost/pending/container_traits.hpp @@ -23,14 +23,6 @@ #include #include -#if !defined BOOST_NO_SLIST -# ifdef BOOST_SLIST_HEADER -# include BOOST_SLIST_HEADER -# else -# include -# endif -#endif - #ifndef BOOST_NO_CXX11_HDR_UNORDERED_SET #include #endif @@ -149,27 +141,6 @@ namespace boost { namespace graph_detail { typedef stable_tag iterator_stability; }; - - // std::slist -#ifndef BOOST_NO_SLIST - template - struct container_traits > { - typedef front_insertion_sequence_tag category; - typedef stable_tag iterator_stability; - }; - template - front_insertion_sequence_tag container_category( - const BOOST_STD_EXTENSION_NAMESPACE::slist& - ) - { return front_insertion_sequence_tag(); } - - template - stable_tag iterator_stability( - const BOOST_STD_EXTENSION_NAMESPACE::slist&) - { return stable_tag(); } -#endif - - // std::set struct set_tag : virtual public sorted_associative_container_tag, diff --git a/include/boost/pending/relaxed_heap.hpp b/include/boost/pending/relaxed_heap.hpp index 13f7af4c..8be44847 100644 --- a/include/boost/pending/relaxed_heap.hpp +++ b/include/boost/pending/relaxed_heap.hpp @@ -191,7 +191,9 @@ public: return !smallest_value || (smallest_value->kind == largest_key); } - bool contains(const value_type& x) const { return groups[get(id, x)]; } + bool contains(const value_type& x) const { + return static_cast(groups[get(id, x)]); + } void pop() { diff --git a/meta/libraries.json b/meta/libraries.json new file mode 100644 index 00000000..c6946d1d --- /dev/null +++ b/meta/libraries.json @@ -0,0 +1,16 @@ +{ + "key": "graph", + "name": "Graph", + "authors": [ + "Jeremy Siek and a University of Notre Dame team." + ], + "description": "The BGL graph interface and graph components are generic, in the same sense as the Standard Template Library (STL).", + "category": [ + "Algorithms", + "Containers", + "Iterators" + ], + "maintainers": [ + "K. Noel Belcourt " + ] +} diff --git a/quickbook/Jamfile.v2 b/quickbook/Jamfile.v2 deleted file mode 100644 index 804366ab..00000000 --- a/quickbook/Jamfile.v2 +++ /dev/null @@ -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 - : - boost.root=../../../.. - - # ToC and chunking - chunk.section.depth=5 - chunk.first.sections=1 - toc.section.depth=5 - toc.max.depth=3 - generate.section.toc.level=5 - - # Misc options - navig.graphics=1 - annotation.support=1 - - ; diff --git a/quickbook/bibliography.qbk b/quickbook/bibliography.qbk deleted file mode 100644 index 99cdd913..00000000 --- a/quickbook/bibliography.qbk +++ /dev/null @@ -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] \ No newline at end of file diff --git a/quickbook/boost_concepts.qbk b/quickbook/boost_concepts.qbk deleted file mode 100644 index 34845dd5..00000000 --- a/quickbook/boost_concepts.qbk +++ /dev/null @@ -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]]] diff --git a/quickbook/boost_reference.qbk b/quickbook/boost_reference.qbk deleted file mode 100644 index 40f98137..00000000 --- a/quickbook/boost_reference.qbk +++ /dev/null @@ -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] diff --git a/quickbook/concepts/a_star_visitor.qbk b/quickbook/concepts/a_star_visitor.qbk deleted file mode 100644 index c0f48917..00000000 --- a/quickbook/concepts/a_star_visitor.qbk +++ /dev/null @@ -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::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::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::directed_category`] - [ - This type shall be convertible to `directed_tag` or `undirected_tag`. - ] - ] - [ - [`graph_traits::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::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::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] diff --git a/quickbook/concepts/adjacency_graph.qbk b/quickbook/concepts/adjacency_graph.qbk deleted file mode 100644 index da1e2e3e..00000000 --- a/quickbook/concepts/adjacency_graph.qbk +++ /dev/null @@ -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::traversal_category`] - [ - This tag type must be convertible to `adjacency_graph_tag`. - ] - ] - [ - [`graph_traits::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` - ] - ] -] - -[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] diff --git a/quickbook/concepts/adjacency_matrix.qbk b/quickbook/concepts/adjacency_matrix.qbk deleted file mode 100644 index 27b740ce..00000000 --- a/quickbook/concepts/adjacency_matrix.qbk +++ /dev/null @@ -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::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` - ] - ] -] - -[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] diff --git a/quickbook/concepts/bellman_ford_visitor.qbk b/quickbook/concepts/bellman_ford_visitor.qbk deleted file mode 100644 index e929e191..00000000 --- a/quickbook/concepts/bellman_ford_visitor.qbk +++ /dev/null @@ -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] diff --git a/quickbook/concepts/bfs_visitor.qbk b/quickbook/concepts/bfs_visitor.qbk deleted file mode 100644 index e8621518..00000000 --- a/quickbook/concepts/bfs_visitor.qbk +++ /dev/null @@ -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] diff --git a/quickbook/concepts/bidirectional_graph.qbk b/quickbook/concepts/bidirectional_graph.qbk deleted file mode 100644 index 57b68cf1..00000000 --- a/quickbook/concepts/bidirectional_graph.qbk +++ /dev/null @@ -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::traversal_category`] - [ - This tag type must be convertible to `bidirectional_graph_tag`. - ] - ] - [ - [`graph_traits::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_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] diff --git a/quickbook/concepts/clique_visitor.qbk b/quickbook/concepts/clique_visitor.qbk deleted file mode 100644 index e85e203e..00000000 --- a/quickbook/concepts/clique_visitor.qbk +++ /dev/null @@ -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] diff --git a/quickbook/concepts/concepts.qbk b/quickbook/concepts/concepts.qbk deleted file mode 100644 index d23f3ad6..00000000 --- a/quickbook/concepts/concepts.qbk +++ /dev/null @@ -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::vertex_descriptor`]] - [[e] [An object of type `graph_traits::edge_descriptor`]] - [[vi] [An object of type `graph_traits::vertex_iterator`]] - [[ei] [An object of type `graph_traits::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] diff --git a/quickbook/concepts/cycle_visitor.qbk b/quickbook/concepts/cycle_visitor.qbk deleted file mode 100644 index 5855179a..00000000 --- a/quickbook/concepts/cycle_visitor.qbk +++ /dev/null @@ -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] diff --git a/quickbook/concepts/degree_measure.qbk b/quickbook/concepts/degree_measure.qbk deleted file mode 100644 index 0a4092b3..00000000 --- a/quickbook/concepts/degree_measure.qbk +++ /dev/null @@ -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::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::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 - { - typename Graph; - typename Vertex; - typename M::degree_type; - - degree_type M::operator(Vertex v, const Graph& g) - }; - -[endsect] diff --git a/quickbook/concepts/descriptor.qbk b/quickbook/concepts/descriptor.qbk deleted file mode 100644 index 085b3dcc..00000000 --- a/quickbook/concepts/descriptor.qbk +++ /dev/null @@ -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] diff --git a/quickbook/concepts/dfs_visitor.qbk b/quickbook/concepts/dfs_visitor.qbk deleted file mode 100644 index aba95698..00000000 --- a/quickbook/concepts/dfs_visitor.qbk +++ /dev/null @@ -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] diff --git a/quickbook/concepts/dijkstra_visitor.qbk b/quickbook/concepts/dijkstra_visitor.qbk deleted file mode 100644 index 2ccf4251..00000000 --- a/quickbook/concepts/dijkstra_visitor.qbk +++ /dev/null @@ -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] diff --git a/quickbook/concepts/distance_measure.qbk b/quickbook/concepts/distance_measure.qbk deleted file mode 100644 index e7c9e85e..00000000 --- a/quickbook/concepts/distance_measure.qbk +++ /dev/null @@ -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 - { - typename Graph; - typename M::distance_type; - typename M::result_type; - - result_type M::operator(distance_type, const Graph&); - }; - -[endsect] diff --git a/quickbook/concepts/edge_index_graph.qbk b/quickbook/concepts/edge_index_graph.qbk deleted file mode 100644 index 20c5b9d2..00000000 --- a/quickbook/concepts/edge_index_graph.qbk +++ /dev/null @@ -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`.] - ] -] - -[heading Associated Types] -[table - [[Name] [Expression] [Result Type] [Description]] - [ - [Edge Index Type] - [`property_traits::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] diff --git a/quickbook/concepts/edge_list_graph.qbk b/quickbook/concepts/edge_list_graph.qbk deleted file mode 100644 index a4bfdff5..00000000 --- a/quickbook/concepts/edge_list_graph.qbk +++ /dev/null @@ -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::traversal_category`] - [ - This tag type must be convertible to `edge_list_graph_tag`. - ] - ] - [ - [`graph_traits::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::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` - ] - ] - [ - [`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] diff --git a/quickbook/concepts/event_visitor.qbk b/quickbook/concepts/event_visitor.qbk deleted file mode 100644 index d57f9b36..00000000 --- a/quickbook/concepts/event_visitor.qbk +++ /dev/null @@ -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] diff --git a/quickbook/concepts/event_visitor_list.qbk b/quickbook/concepts/event_visitor_list.qbk deleted file mode 100644 index 746a6bf2..00000000 --- a/quickbook/concepts/event_visitor_list.qbk +++ /dev/null @@ -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 - { - typedef on_discover_vertex event_filter; - - template - void operator ()(Vertex v, Graph& G) - { - cout << "(" << v; - } - }; - - - struct close_paren : public base_visitor - { - typedef on_discover_vertex event_filter; - - template - 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] diff --git a/quickbook/concepts/graph.qbk b/quickbook/concepts/graph.qbk deleted file mode 100644 index 9df4c853..00000000 --- a/quickbook/concepts/graph.qbk +++ /dev/null @@ -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::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::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::directed_category`] - [ - This type shall be convertible to `directed_tag` or `undirected_tag`. - ] - ] - [ - [`graph_traits::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::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::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] diff --git a/quickbook/concepts/graphs.qbk b/quickbook/concepts/graphs.qbk deleted file mode 100644 index 843672d2..00000000 --- a/quickbook/concepts/graphs.qbk +++ /dev/null @@ -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::vertex_descriptor`] [The type for vertex representative objects.]] - [[`graph_traits::edge_descriptor`] [The type for edge representative objects.]] - [[`graph_traits::directed_category`] [Graph is directed or undirected?]] - [[`graph_traits::edge_parallel_category`] [Graph allows parallel edges?]] - [[`graph_traits::traversal_category`] [The ways in which the vertices and edges can be traversed.]] - [[[*[IncidenceGraph]]]] - [[`graph_traits::degree_size_type`] [The integer type for vertex degree.]] - [[`graph_traits::out_edge_iterator`] [Type for iterating over out edges.]] - [[`out_edges(v,g)`] [`std::pair`]] - [[`out_degree(v,g)`] [`degree_size_type`]] - [[`source(e,g)`] [`vertex_descriptor`]] - [[`target(e,g)`] [`vertex_descriptor`]] - [[[*[BidirectionalGraph]]]] - [[`graph_traits::in_edge_iterator`] [Type for iterating over in edges.]] - [[`in_edges(v,g)`] [`std::pair`]] - [[`in_degree(v,g)`] [`degree_size_type`]] - [[`degree(v,g)`] [`degree_size_type`]] - [[[*[AdjacencyGraph]]]] - [[`graph_traits::adjacency_iterator`] [Type for iterating over adjacent vertices.]] - [[`adjacent_vertices(v,g)`] [`std::pair`]] - [[[*[VertexListGraph]]]] - [[`graph_traits::vertex_iterator`] [Type for iterating over vertices.]] - [[`graph_traits::vertices_size_type`] [Unsigned integer type for the number of vertices.]] - [[`vertices(g)`] [`std::pair`]] - [[`num_vertices(g)`] [`vertices_size_type`]] - [[[*[EdgeListGraph]]]] - [[`graph_traits::edge_iterator`] [Type for iterating over edges.]] - [[`graph_traits::edges_size_type`] [Unsigned integer type for the number of edges.]] - [[`edges(g)`] [`std::pair`]] - [[`num_edges(g)`] [`edges_size_type`]] - [[`source(e,g)`] [`vertex_descriptor`]] - [[`target(e,g)`] [`vertex_descriptor`]] - [[[*[AdjacencyMatrix]]]] - [[`edge(u,v,g)`] [`std::pair`]] - [[[*[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`]] - [[`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::type`] [Type for a mutable property map.]] - [[`property_map::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`]] -] - -[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::out_edge_iterator e, e_end; - boost::graph_traits::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::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::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::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::vertex_descriptor u, v; - u = vertex(0, graph); - v = vertex(1, graph); - add_edge(graph, u, v, Weight(3.1)); - boost::graph_traits::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::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] diff --git a/quickbook/concepts/incidence_graph.qbk b/quickbook/concepts/incidence_graph.qbk deleted file mode 100644 index fd029749..00000000 --- a/quickbook/concepts/incidence_graph.qbk +++ /dev/null @@ -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::traversal_category`] - [ - This tag type must be convertible to `incidence_graph_tag`. - ] - ] - [ - [`graph_traits::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::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_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] diff --git a/quickbook/concepts/mutable_graph.qbk b/quickbook/concepts/mutable_graph.qbk deleted file mode 100644 index 900d9ca3..00000000 --- a/quickbook/concepts/mutable_graph.qbk +++ /dev/null @@ -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] diff --git a/quickbook/concepts/mutable_property_graph.qbk b/quickbook/concepts/mutable_property_graph.qbk deleted file mode 100644 index 74f3ee12..00000000 --- a/quickbook/concepts/mutable_property_graph.qbk +++ /dev/null @@ -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::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::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::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] diff --git a/quickbook/concepts/numeric_value.qbk b/quickbook/concepts/numeric_value.qbk deleted file mode 100644 index 33422eaa..00000000 --- a/quickbook/concepts/numeric_value.qbk +++ /dev/null @@ -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() and infinity()? - /] - -[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::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::zero()`] - [`numeric_value::value_type`] - [ - Returns the zero-value of the numeric type. - ] - ] - [ - [Infinite Value] - [`numeric_value::infinity()`] - [`numeric_value::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::max()`. - ] - ] -] - -[endsect] diff --git a/quickbook/concepts/property_graph.qbk b/quickbook/concepts/property_graph.qbk deleted file mode 100644 index f8148ceb..00000000 --- a/quickbook/concepts/property_graph.qbk +++ /dev/null @@ -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::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::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::type` if `g` is mutable and - `property_map::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::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] diff --git a/quickbook/concepts/utility.qbk b/quickbook/concepts/utility.qbk deleted file mode 100644 index 3aa133e3..00000000 --- a/quickbook/concepts/utility.qbk +++ /dev/null @@ -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] diff --git a/quickbook/concepts/vertex_index_graph.qbk b/quickbook/concepts/vertex_index_graph.qbk deleted file mode 100644 index 86f16a88..00000000 --- a/quickbook/concepts/vertex_index_graph.qbk +++ /dev/null @@ -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`.] - ] -] - -[heading Associated Types] -[table - [[Name] [Expression] [Result Type] [Description]] - [ - [Vertex Index Type] - [`property_traits::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] diff --git a/quickbook/concepts/vertex_list_graph.qbk b/quickbook/concepts/vertex_list_graph.qbk deleted file mode 100644 index 82704272..00000000 --- a/quickbook/concepts/vertex_list_graph.qbk +++ /dev/null @@ -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::traversal_category`] - [ - This tag type must be convertible to `vertex_list_graph_tag`. - ] - ] - [ - [`graph_traits::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::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` - ] - ] - [ - [`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] diff --git a/quickbook/concepts/visitor.qbk b/quickbook/concepts/visitor.qbk deleted file mode 100644 index 4f4569e8..00000000 --- a/quickbook/concepts/visitor.qbk +++ /dev/null @@ -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] diff --git a/quickbook/concepts/visitors.qbk b/quickbook/concepts/visitors.qbk deleted file mode 100644 index 16ac9431..00000000 --- a/quickbook/concepts/visitors.qbk +++ /dev/null @@ -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] \ No newline at end of file diff --git a/quickbook/graph.qbk b/quickbook/graph.qbk deleted file mode 100644 index 1f7680fa..00000000 --- a/quickbook/graph.qbk +++ /dev/null @@ -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]''''''[x]''''''] -[template sub[x]''''''[x]''''''] - -[template delta[]'''δ'''] [/ d Greek small letter delta] - -[template figure[path caption] -''' - - - - - - '''[caption]''' - - -''' -] - -[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] /] diff --git a/quickbook/guide/adjacency_list.qbk b/quickbook/guide/adjacency_list.qbk deleted file mode 100644 index 0514f436..00000000 --- a/quickbook/guide/adjacency_list.qbk +++ /dev/null @@ -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 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 > VertexProperty; - typedef property EdgeProperty; - - // specify the graph has having the above properties - typedef adjacency_list 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 Cap; - typedef property EdgeProperty; - typedef adjacency_list Graph; - -Just as before, the property maps for these properties can be obtained from the graph via the get(Property, g) function. - - property_map::type capacity = get(capacity_t(), G); - property_map::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 FirstNameProperty; - typedef adjacency_list MyGraphType; - - typedef pair 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::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 - void who_owes_who(EdgeIter first, EdgeIter last, const Graph& G) - { - // Access the propety acessor type for this graph - typedef typename property_map::const_type NameMap; - typedef typename boost::property_traits::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 - struct container_gen { }; - - template - struct container_gen { - typedef std::list 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 - struct container_gen { - typedef custom_container 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 - struct list_with_allocatorS { }; - - namespace boost { - template - struct container_gen, ValueType> - { - typedef typename Alloc::template rebind::other Allocator; - typedef std::list type; - }; - } - - // now you can define a graph using std::list and a specific allocator - typedef adjacency_list< list_with_allocatorS< std::allocator >, 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 - std::pair::iterator, bool> - push(custom_container& 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 - void erase(custom_container& 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 { - typedef allow_parallel_edge_tag type; - }; - -[endsect] \ No newline at end of file diff --git a/quickbook/guide/directed_graph.qbk b/quickbook/guide/directed_graph.qbk deleted file mode 100644 index 5e052971..00000000 --- a/quickbook/guide/directed_graph.qbk +++ /dev/null @@ -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 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::type TargetIndexMap; - typedef std::map 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 separator; - typedef tokenizer 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 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 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 - 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] \ No newline at end of file diff --git a/quickbook/guide/guide.qbk b/quickbook/guide/guide.qbk deleted file mode 100644 index 42a4d730..00000000 --- a/quickbook/guide/guide.qbk +++ /dev/null @@ -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] \ No newline at end of file diff --git a/quickbook/guide/theory.qbk b/quickbook/guide/theory.qbk deleted file mode 100644 index b9569732..00000000 --- a/quickbook/guide/theory.qbk +++ /dev/null @@ -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 - 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] \ No newline at end of file diff --git a/quickbook/guide/tour.qbk b/quickbook/guide/tour.qbk deleted file mode 100644 index 9e00ed73..00000000 --- a/quickbook/guide/tour.qbk +++ /dev/null @@ -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 // for std::cout - #include // for std::pair - #include // for std::for_each - #include - - using namespace std; - using namespace boost; - - int main(int, char*[]) - { - // create a typedef for the Graph type - typedef adjacency_list 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 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::type IndexMap; - IndexMap index = get(vertex_index, g); - - cout << "vertices(g) = "; - typedef graph_traits::vertex_iterator vertex_iter; - pair 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::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(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 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` -type) is dependent on a template parameter (the `Graph` type). Here is how we define the functor's -apply method: - - template struct exercise_vertex { - // ... continued from above - - typedef typename graph_traits::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 - struct exercise_vertex { - //... continued from above - - void operator()(const Vertex& v) const - { - typedef graph_traits GraphTraits; - typedef typename property_map::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 struct exercise_vertex { - // ... continued from above - - void operator()(const Vertex& v) const - { - // ... - cout << "in-edges: "; - typedef typename graph_traits 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 struct exercise_vertex { - // ... continued from above - - void operator()(Vertex v) const - { - //... - cout << "adjacent vertices: "; - typename graph_traits::adjacency_iterator ai; - typename graph_traits::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 // edges have integer edge weight - > Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef std::pair 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 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::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 record_predecessors : public dijkstra_visitor<> - { - public: - record_predecessors(PredecessorMap p) - : m_predecessor(p) - { } - - template - 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 - record_predecessors - make_predecessor_recorder(PredecessorMap p) { - return record_predecessors(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 p(num_vertices(G), graph_traits::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::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] diff --git a/quickbook/guide/undirected_graph.qbk b/quickbook/guide/undirected_graph.qbk deleted file mode 100644 index 6d43128e..00000000 --- a/quickbook/guide/undirected_graph.qbk +++ /dev/null @@ -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 - #include - #include - #include - - struct Actor; - struct Movie; - - typedef boost::undirected_graph 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`. -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::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 - - // the very important actor-to-vertex mapping - typedef std::map 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 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 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::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] \ No newline at end of file diff --git a/quickbook/history.qbk b/quickbook/history.qbk deleted file mode 100644 index d9295e40..00000000 --- a/quickbook/history.qbk +++ /dev/null @@ -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] diff --git a/quickbook/images/eq/Makefile b/quickbook/images/eq/Makefile deleted file mode 100644 index ad9862da..00000000 --- a/quickbook/images/eq/Makefile +++ /dev/null @@ -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) \ No newline at end of file diff --git a/quickbook/images/eq/betweenness.tex b/quickbook/images/eq/betweenness.tex deleted file mode 100644 index d02c5fae..00000000 --- a/quickbook/images/eq/betweenness.tex +++ /dev/null @@ -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} \ No newline at end of file diff --git a/quickbook/images/eq/central_point_dominance.tex b/quickbook/images/eq/central_point_dominance.tex deleted file mode 100644 index 4bf2a95c..00000000 --- a/quickbook/images/eq/central_point_dominance.tex +++ /dev/null @@ -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} \ No newline at end of file diff --git a/quickbook/images/eq/closeness.tex b/quickbook/images/eq/closeness.tex deleted file mode 100644 index 0654bfca..00000000 --- a/quickbook/images/eq/closeness.tex +++ /dev/null @@ -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} \ No newline at end of file diff --git a/quickbook/images/eq/clustering_coef.tex b/quickbook/images/eq/clustering_coef.tex deleted file mode 100644 index a6202c89..00000000 --- a/quickbook/images/eq/clustering_coef.tex +++ /dev/null @@ -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} \ No newline at end of file diff --git a/quickbook/images/eq/mean_geodesic.tex b/quickbook/images/eq/mean_geodesic.tex deleted file mode 100644 index 1a218624..00000000 --- a/quickbook/images/eq/mean_geodesic.tex +++ /dev/null @@ -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} \ No newline at end of file diff --git a/quickbook/images/eq/num_paths_directed.tex b/quickbook/images/eq/num_paths_directed.tex deleted file mode 100644 index d31a328b..00000000 --- a/quickbook/images/eq/num_paths_directed.tex +++ /dev/null @@ -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} \ No newline at end of file diff --git a/quickbook/images/eq/num_paths_undirected.tex b/quickbook/images/eq/num_paths_undirected.tex deleted file mode 100644 index 21f077c0..00000000 --- a/quickbook/images/eq/num_paths_undirected.tex +++ /dev/null @@ -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} \ No newline at end of file diff --git a/quickbook/images/eq/num_triangles.tex b/quickbook/images/eq/num_triangles.tex deleted file mode 100644 index 5e791de3..00000000 --- a/quickbook/images/eq/num_triangles.tex +++ /dev/null @@ -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} \ No newline at end of file diff --git a/quickbook/images/eq/relative_betweenness.tex b/quickbook/images/eq/relative_betweenness.tex deleted file mode 100644 index d7537ed7..00000000 --- a/quickbook/images/eq/relative_betweenness.tex +++ /dev/null @@ -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} \ No newline at end of file diff --git a/quickbook/images/eq/scaled_closeness.tex b/quickbook/images/eq/scaled_closeness.tex deleted file mode 100644 index 53b90770..00000000 --- a/quickbook/images/eq/scaled_closeness.tex +++ /dev/null @@ -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} \ No newline at end of file diff --git a/quickbook/images/eq/small_world.tex b/quickbook/images/eq/small_world.tex deleted file mode 100644 index 9c79f465..00000000 --- a/quickbook/images/eq/small_world.tex +++ /dev/null @@ -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} \ No newline at end of file diff --git a/quickbook/images/reference/Makefile b/quickbook/images/reference/Makefile deleted file mode 100644 index 9dc80fd6..00000000 --- a/quickbook/images/reference/Makefile +++ /dev/null @@ -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) diff --git a/quickbook/images/reference/comm_network.neato b/quickbook/images/reference/comm_network.neato deleted file mode 100644 index d3996f33..00000000 --- a/quickbook/images/reference/comm_network.neato +++ /dev/null @@ -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; -}; \ No newline at end of file diff --git a/quickbook/images/reference/connected_components_after.dot b/quickbook/images/reference/connected_components_after.dot deleted file mode 100644 index a16bdf14..00000000 --- a/quickbook/images/reference/connected_components_after.dot +++ /dev/null @@ -1,12 +0,0 @@ - - -graph G { - subgraph cluster_0 { - 0 -- 1 -- 2 -- 0; - label = "Component 0"; - } - subgraph cluster_1 { - 3 -- 4; - label = "Component 1"; - } -} \ No newline at end of file diff --git a/quickbook/images/reference/connected_components_before.dot b/quickbook/images/reference/connected_components_before.dot deleted file mode 100644 index 9271e3b7..00000000 --- a/quickbook/images/reference/connected_components_before.dot +++ /dev/null @@ -1,5 +0,0 @@ - -graph G { - 0 -- 1 -- 2 -- 0; - 3 -- 4; -} diff --git a/quickbook/images/reference/distribution_directed.circo b/quickbook/images/reference/distribution_directed.circo deleted file mode 100644 index 43f7eb98..00000000 --- a/quickbook/images/reference/distribution_directed.circo +++ /dev/null @@ -1,11 +0,0 @@ - -digraph G { - 0 -> 1; - 1 -> 2; - 2 -> 3; - 3 -> 5; - 5 -> 4; - 4 -> 1; - 4 -> 3; - 5 -> 2; -} \ No newline at end of file diff --git a/quickbook/images/reference/distribution_undirected.circo b/quickbook/images/reference/distribution_undirected.circo deleted file mode 100644 index 5a438ed0..00000000 --- a/quickbook/images/reference/distribution_undirected.circo +++ /dev/null @@ -1,11 +0,0 @@ - -graph G { - 0 -- 1; - 1 -- 2; - 2 -- 3; - 3 -- 5; - 5 -- 4; - 4 -- 1; - 4 -- 3; - 2 -- 5 -} \ No newline at end of file diff --git a/quickbook/images/reference/geodesic.dot b/quickbook/images/reference/geodesic.dot deleted file mode 100644 index 854b632a..00000000 --- a/quickbook/images/reference/geodesic.dot +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/quickbook/images/reference/info_network.dot b/quickbook/images/reference/info_network.dot deleted file mode 100644 index 4dad74b7..00000000 --- a/quickbook/images/reference/info_network.dot +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/quickbook/images/reference/prism_3_2.circo b/quickbook/images/reference/prism_3_2.circo deleted file mode 100644 index cbf99ea9..00000000 --- a/quickbook/images/reference/prism_3_2.circo +++ /dev/null @@ -1,7 +0,0 @@ -digraph { - 0 -> 1 -> 2 -> 0; - 3 -> 4 -> 5 -> 3; - 0 -> 3 -> 0; - 1 -> 4 -> 1; - 2 -> 5 -> 2; -} \ No newline at end of file diff --git a/quickbook/images/reference/social_network.fdp b/quickbook/images/reference/social_network.fdp deleted file mode 100644 index 15902b42..00000000 --- a/quickbook/images/reference/social_network.fdp +++ /dev/null @@ -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; -}; \ No newline at end of file diff --git a/quickbook/images/reference/triangle.circo b/quickbook/images/reference/triangle.circo deleted file mode 100644 index 72245147..00000000 --- a/quickbook/images/reference/triangle.circo +++ /dev/null @@ -1,3 +0,0 @@ -graph { - 0 -- 1 -- 2 -- 0; -} \ No newline at end of file diff --git a/quickbook/introduction.qbk b/quickbook/introduction.qbk deleted file mode 100644 index defcee5a..00000000 --- a/quickbook/introduction.qbk +++ /dev/null @@ -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`. 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` 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] \ No newline at end of file diff --git a/quickbook/reference/adjacency_list.qbk b/quickbook/reference/adjacency_list.qbk deleted file mode 100644 index e555d863..00000000 --- a/quickbook/reference/adjacency_list.qbk +++ /dev/null @@ -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::vertex_descriptor`] - [The type of vertex descriptors associated with the `adjacency_list`.] - ] - [ - [`graph_traits::edge_descriptor`] - [The type of edge descriptors associated with the `adjacency_list`.] - ] - [ - [`graph_traits::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::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::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::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::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::directed_category`] - [ - Provides inforamtion about whether the graph is undirected (`undirected_tag`), - directed (`directed_tag`), or bidirectional (`bidirectional_tag`). - ] - ] - [ - [`graph_traits::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::vertices_size_type`] - [The type used for dealing with the number of vertices in the graph. ] - ] - [ - [`graph_traits::edge_size_type`] - [The type used for dealing with the number of edges in the graph. ] - ] - [ - [`graph_traits::degree_size_type`] - [The type used for dealing with the number of edges incident to a vertex in the graph. ] - ] - [ - [ - `property_map::type` - - `property_map::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::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 - 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 - 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(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 - vertices(const adjacency_list& g) - `` - ] - [Returns an iterator range to the vertex set of `g`.] - ] - [ - [ - `` - pair - edges(const adjacency_list& g) - `` - ] - [Returns an iterator range to the edge set of `g`.] - ] - [ - [ - `` - pair - 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_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 - 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 - add_edge(vertex_descriptor u, vertex_descriptor v, - adjacency_list& g) - `` - ] - [] - ] - [ - [ - `` - pair - 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_map::type - get(Property, adjaceny_list& g); - `` - ] - [] - ] - [ - [ - `` - template - typename property_map::const_type - get(Property, adjaceny_list const& g); - `` - ] - [] - ] - [ - [ - `` - template - typename property_traits< - property_map::const_type - >::value_type - get(Property, adjaceny_list const& g, X x); - `` - ] - [] - ] - [ - [ - `` - template - void put(Property, X, adjaceny_list const& g, - X x, const Value&); - `` - ] - [] - ] - [ - [ - `` - template - typename graph_property::type - void get_property(adjaceny_list const& g, Property); - `` - ] - [] - ] - [ - [ - `` - template - 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 Graph; // VertexList = vecS - Graph G(N); - - // Fill in the graph... - - // Attempt to remove all the vertices. Wrong! - graph_traits::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::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 Graph; // VertexList = listS - Graph G(N); - - // Fill in the graph... - - // Attempt to remove all the vertices. Wrong! - graph_traits::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::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 parent(num_vertices(G)); - std::vector 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] \ No newline at end of file diff --git a/quickbook/reference/adjacency_matrix.qbk b/quickbook/reference/adjacency_matrix.qbk deleted file mode 100644 index aa7849fa..00000000 --- a/quickbook/reference/adjacency_matrix.qbk +++ /dev/null @@ -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 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::vertex_descriptor`] - [The type of the graph's vertex descriptors.] - ] - [ - [`graph_traits::edge_descriptor`] - [The type of the graph's edge descriptors.] - ] - [ - [`graph_traits::vertex_iterator`] - [ - The type for iterators returned by `vertices()`, modeling the - [SgiRandomAccessIterator] concept. - ] - ] - [ - [`graph_traits::edge_iterator`] - [ - The type for iterators returned by `edges()`, modeling the - [SgiForwardIterator] concept. - ] - ] - [ - [`graph_traits::out_edge_iterator`] - [ - The type for iterators returned by `out_edges()`, modeling the - [SgiForwardIterator] concept. - ] - ] - [ - [`graph_traits::in_edge_iterator`] - [ - The type for iterators returned by `in_edges()`, modeling the - [SgiForwardIterator] concept. - ] - ] - [ - [`graph_traits::adjacency_iterator`] - [ - The type for iterators returned by `adjacent_vertices()`, modeling the - [SgiForwardIterator] concept. - ] - ] - [ - [`graph_traits::directed_category`] - [ - Provides inforamtion about whether the graph is undirected (`undirected_tag`), - or directed (`directed_tag`). - ] - ] - [ - [`graph_traits::edge_parallel_category`] - [ - Adjacency matrices do not allow the insertion of parallel edges so - this type is always `disallow_parallel_edges`. - ] - ] - [ - [`graph_traits::vertices_size_type`] - [The type used for dealing with the number of vertices in the graph. ] - ] - [ - [`graph_traits::edge_size_type`] - [The type used for dealing with the number of edges in the graph. ] - ] - [ - [`graph_traits::degree_size_type`] - [The type used for dealing with the number of edges incident to a vertex in the graph.] - ] - [ - [ - `property_map::type` - - `property_map::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::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 - 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 - 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(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 vertices(const adjacency_matrix& g)`] - [Returns an iterator range to the vertex set of `g`.] - ] - [ - [`pair edges(const adjacency_matrix& g)`] - [Returns an iterator range to the edge set of `g`.] - ] - [ - [`pair 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_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 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 add_edge(vertex_descriptor u, vertex_descriptor v, adjacency_matrix& g)`] - [] - ] - [ - [`pair 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_map::type - get(Property, adjaceny_matrix& g); - `` - ] - [] - ] - [ - [ - `` - template - typename property_map::const_type - get(Property, adjaceny_matrix const& g); - `` - ] - [] - ] - [ - [ - `` - template - typename property_traits< - property_map::const_type - >::value_type - get(Property, adjaceny_matrix const& g, X x); - `` - ] - [] - ] - [ - [ - `` - template - void put(Property, X, adjaceny_matrix const& g, X x, const Value&); - `` - ] - [] - ] - [ - [ - `` - template - void get_property(adjaceny_matrix const& g, Property); - `` - ] - [] - ] - [ - [ - `` - template - 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] - diff --git a/quickbook/reference/betweenness_centrality.qbk b/quickbook/reference/betweenness_centrality.qbk deleted file mode 100644 index 3c65610a..00000000 --- a/quickbook/reference/betweenness_centrality.qbk +++ /dev/null @@ -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 - void - brandes_betweenness_centrality(const Graph& g, CentralityMap cm) - - template - void - brandes_betweenness_centrality(const Graph& g, - CentralityMap cm, - EdgeCentralityMap ecm) - - // Named Parameter Interface - template - 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 - 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 - 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] diff --git a/quickbook/reference/breadth_first_search.qbk b/quickbook/reference/breadth_first_search.qbk deleted file mode 100644 index 9facc789..00000000 --- a/quickbook/reference/breadth_first_search.qbk +++ /dev/null @@ -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 - void - breadth_first_search(Graph& g, - typename graph_traits::vertex_descriptor s, - bgl_named_params& params = ``/defaults/``) - - template - void - breadth_first_search(Graph& g, - typename graph_traits::vertex_descriptor s, - Buffer& q, - Visitor vis, - bgl_named_params& 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`. - ] - ] - [ - [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] \ No newline at end of file diff --git a/quickbook/reference/bron_kerbosch_all_cliques.qbk b/quickbook/reference/bron_kerbosch_all_cliques.qbk deleted file mode 100644 index 785954b9..00000000 --- a/quickbook/reference/bron_kerbosch_all_cliques.qbk +++ /dev/null @@ -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 - - template - 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 - - template - 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] \ No newline at end of file diff --git a/quickbook/reference/closeness_centrality.qbk b/quickbook/reference/closeness_centrality.qbk deleted file mode 100644 index b81d360a..00000000 --- a/quickbook/reference/closeness_centrality.qbk +++ /dev/null @@ -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 - - template - float closeness_centrality(const Graph& g, DistanceMap dm) - - template - ResultType closeness_centrality(const Graph& g, DistanceMap dm) - - template - 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 - - template - void all_closeness_centralities(const Graph& g, DistanceMatrixMap dm, ClosenessMap cm) - - template - 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 ...` to -`typedef directed_graph ...`. - -[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] diff --git a/quickbook/reference/clustering_coefficient.qbk b/quickbook/reference/clustering_coefficient.qbk deleted file mode 100644 index a892b254..00000000 --- a/quickbook/reference/clustering_coefficient.qbk +++ /dev/null @@ -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 - - template - float clustering_coefficient(const Graph& g, Vertex v) - - template - 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 - - template - typename property_traits::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] diff --git a/quickbook/reference/connected_components.qbk b/quickbook/reference/connected_components.qbk deleted file mode 100644 index 30ec9410..00000000 --- a/quickbook/reference/connected_components.qbk +++ /dev/null @@ -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 - typename property_traits::value_type - connected_components(const Graph &g, ComponentMap c, - const bgl_named_params& 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] \ No newline at end of file diff --git a/quickbook/reference/degree_centrality.qbk b/quickbook/reference/degree_centrality.qbk deleted file mode 100644 index 4595e90b..00000000 --- a/quickbook/reference/degree_centrality.qbk +++ /dev/null @@ -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 - - template - typename graph_traits::degree_size_type - degree_centrality(const Graph& g, Vertex v); - - template - 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_traits::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_traits::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 - - template - void all_degree_centralities(const Graph& g, CentralityMap cent); - - template - 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 - - template - 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 - - template - 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 struct influence_measure; - template struct prestige_measure; - - template - influence_measure measure_influence(const Graph&); - - template - prestige_measure 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] \ No newline at end of file diff --git a/quickbook/reference/depth_first_search.qbk b/quickbook/reference/depth_first_search.qbk deleted file mode 100644 index 39b3a022..00000000 --- a/quickbook/reference/depth_first_search.qbk +++ /dev/null @@ -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 - void - depth_first_search(Graph& g, - bgl_named_params& params = ``/defaults/``) - - template - void - depth_first_search(Graph& g, - Visitor vis, - ColorMap color, - typename graph_traits::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`. - ] - ] - [ - [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] \ No newline at end of file diff --git a/quickbook/reference/directed_graph.qbk b/quickbook/reference/directed_graph.qbk deleted file mode 100644 index 14597e97..00000000 --- a/quickbook/reference/directed_graph.qbk +++ /dev/null @@ -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` 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::vertex_descriptor`] - ] - [ - [`edge_descriptor`] - [`directed_graph::edge_descriptor`] - ] - [ - [`vertex_iterator`] - [`directed_graph::vertex_iterator`] - ] - [ - [`edge_iterator`] - [`directed_graph::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::vertex_descriptor`] - [ - The type for the vertex descriptors associated with the graph. The `vertex_descriptor` - models the [Descriptor] and [NoConcept Hashable] concepts. - ] - ] - [ - [`graph_traits::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::vertex_iterator`] - [ - The type for iterators returned by `vertices()`. Verex iterators are - models of the [SgiBidirectionalIterator] concept. - ] - ] - [ - [`graph_traits::edge_iterator`] - [ - The type for iterators returned by `edges()`. Edge iterators are - models of the [SgiBidirectionalIterator] concept. - ] - ] - [ - [`graph_traits::out_edge_iterator`] - [ - The type for iterators returned by `out_edges()`. Out-edge iterators - are models of the [SgiBidirectionalIterator] concept. - ] - ] - [ - [`graph_traits::in_edge_iterator`] - [ - The type for iterators returned by `in_edges()`. In-edge iterators - are models of the [SgiBidirectionalIterator] concept. - ] - ] - [ - [`graph_traits::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::vertices_size_type`] - [The type used for dealing with the number of vertices in the graph.] - ] - [ - [`graph_traits::edge_size_type`] - [The type used for dealing with the number of edges in the graph.] - ] - [ - [`graph_traits::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::type` - - `property_map::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::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_category`] - [ - This is always `bidirectional_tag`, indicating that the graph supports in- and - out-edge operations. - ] - ] - [ - [`graph_traits::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 -vertices(const directed_graph& g) -`` - ] - [Returns an iterator range providing access to the vertex list of `g`.] - ] - [ - [ -`` -std::pair -edges(const directed_graph& g) -`` - ] - [Returns an iterator range providing access to the edge list of `g`.] - ] - [ - [ -`` -std::pair -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_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 -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(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 -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 -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 -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 -property_map::type -get(Property, directed_graph& g) -`` - -`` -template -property_map::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 -typename - property_traits< - property_map::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 -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 -typename graph_property::type& -get_property(directed_graph& g, GraphProperty) -`` - -`` -template -const typename graph_property::type& -get_property(const directed_graph& g, GraphProperty) -`` - ] - [ - Returns the graph property specified by the type `GraphProperty` for - the graph `g`. - ] - ] - [ - [ -`` -template -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] \ No newline at end of file diff --git a/quickbook/reference/distance_recorder.qbk b/quickbook/reference/distance_recorder.qbk deleted file mode 100644 index 1d38bc30..00000000 --- a/quickbook/reference/distance_recorder.qbk +++ /dev/null @@ -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 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 -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 -distance_recorder -record_distances(DistanceMap pa, EventTag) -`` - ] - [ - A convenience function for creating [distance_recorder] instances. - ] - ] -] - -[endsect] diff --git a/quickbook/reference/eccentricity.qbk b/quickbook/reference/eccentricity.qbk deleted file mode 100644 index fe21706b..00000000 --- a/quickbook/reference/eccentricity.qbk +++ /dev/null @@ -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 - - template - typename property_traits::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 - - template - std::pair::value_type, - typename property_traits::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 - - template - inline typename property_traits::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 - - template - inline typename property_traits::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 - - template - std::pair::value_type, - typename property_traits::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] \ No newline at end of file diff --git a/quickbook/reference/edge_list.qbk b/quickbook/reference/edge_list.qbk deleted file mode 100644 index af1fda63..00000000 --- a/quickbook/reference/edge_list.qbk +++ /dev/null @@ -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::value_type, - typename DiffereneType = typename iterator_traits::difference_type - typename Category = typename iterator_traits::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 - -[heading Template Parameters] -[table - [[Parameter] [Description] [Default]] - [ - [`EdgeIter`] - [ - Must be a model of [SgiInputIterator], and its `value_type` must be - `pair`. - ] - [ ] - ] - [ - [`ValueType`] - [The `value_type` of `EdgeIter`.] - [`iterator_traits::value_type`] - ] - [ - [`DifferenceType`] - [The `difference_type` of `EdgeIter`.] - [`iterator_traits::difference_type`] - ] - [ - [`Category`] - [The `iterator_category` of `EdgeIter`.] - [`iterator_traits::iterator_category`] - ] -] - -[heading Model Of] -[EdgeListGraph] - -[heading Associated Types] -[table - [[Type] [Description]] - [ - [`graph_traits::vertex_descriptor`] - [The type of vertex descriptors associated with the `edge_list`.] - ] - [ - [`graph_traits::edge_descriptor`] - [The type of edge descriptors associated with the `edge_list`.] - ] - [ - [`graph_traits::edge_size_type`] - [The type used for dealing with the number of edges in the graph.] - ] - [ - [`graph_traits::edge_iterator`] - [The type used for iterating over edges in the graph. The same as `EdgeIter`.] - ] -] - -[/ - -

    Member Functions

    - -
    - - -edge_list(EdgeIterator first, EdgeIterator last) - -

    -Creates a graph object with `n` vertices and with the -edges specified in the edge list given by the range \first,last). - -
    - -

    Non-Member Functions

    - -
    - - -std::pair<edge_iterator, edge_iterator>
    -edges(const edge_list& g) -
    -

    -Returns an iterator-range providing access to the edge set of graph `g`. - -
    - - -vertex_descriptor
    -source(edge_descriptor e, const edge_list& g) -
    -

    -Returns the source vertex of edge `e`. - -
    - - -vertex_descriptor
    -target(edge_descriptor e, const edge_list& g) -
    -

    -Returns the target vertex of edge `e`. - -
    -] - -[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 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 Graph; - Graph g(edges, edges + sizeof(edges) / sizeof(E)); - - std::vector distance(N, std::numeric_limits::max()); - std::vector 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] \ No newline at end of file diff --git a/quickbook/reference/exterior_vertex_property.qbk b/quickbook/reference/exterior_vertex_property.qbk deleted file mode 100644 index d6783ed8..00000000 --- a/quickbook/reference/exterior_vertex_property.qbk +++ /dev/null @@ -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 - 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::value_type`] - [ - This is the same as the template parameter `Value`. - ] - ] - [ - [`P::key_type`] - [ - This is the same as `graph_traits::vertex_descriptor`. - ] - ] - [ - [`P::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::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 - void - do_shortest_paths(const Graph& g, Weight w = ()) - { - typedef exterior_vertex_property 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] \ No newline at end of file diff --git a/quickbook/reference/mean_geodesic.qbk b/quickbook/reference/mean_geodesic.qbk deleted file mode 100644 index ca0b5c83..00000000 --- a/quickbook/reference/mean_geodesic.qbk +++ /dev/null @@ -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 - - template - float mean_geodesic(const Graph& g, DistanceMap dm) - - template - ResultType mean_geodesic(const Graph& g, DistanceMap dm) - - template - 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 - - template - typename property_traits::value_type - all_mean_geodesics(const Graph& g, DistanceMatrixMap dm, GeodesicMap gm) - - template - typename property_traits::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 - - template - typename Measure::result_type - small_world_distance(const Graph& g, GeodesicMap gm, Measure m) - - template - typename property_traits::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 ...` to -`typedef directed_graph ...`. - -[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] \ No newline at end of file diff --git a/quickbook/reference/predecessor_recorder.qbk b/quickbook/reference/predecessor_recorder.qbk deleted file mode 100644 index 056f197b..00000000 --- a/quickbook/reference/predecessor_recorder.qbk +++ /dev/null @@ -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 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 -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 -predecessor_recorder -record_predecessors(PredecessorMap pa, EventTag) -`` - ] - [ - A convenience function for creating [predecessor_recorder] instances. - ] - ] -] - -[endsect] diff --git a/quickbook/reference/property_writer.qbk b/quickbook/reference/property_writer.qbk deleted file mode 100644 index 349f9908..00000000 --- a/quickbook/reference/property_writer.qbk +++ /dev/null @@ -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 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 -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 -time_stamper -stamp_times(Property pa, OutputIterator out, EventTag) -`` - ] - [ - A convenience function for creating [property_writer] instances. - ] - ] -] - -[endsect] diff --git a/quickbook/reference/reference.qbk b/quickbook/reference/reference.qbk deleted file mode 100644 index 0a53ec5b..00000000 --- a/quickbook/reference/reference.qbk +++ /dev/null @@ -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] \ No newline at end of file diff --git a/quickbook/reference/strong_components.qbk b/quickbook/reference/strong_components.qbk deleted file mode 100644 index 55f23543..00000000 --- a/quickbook/reference/strong_components.qbk +++ /dev/null @@ -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 - typename property_traits::value_type - strong_components(const Graph &g, ComponentMap c, - const bgl_named_params& 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] \ No newline at end of file diff --git a/quickbook/reference/tiernan_all_cycles.qbk b/quickbook/reference/tiernan_all_cycles.qbk deleted file mode 100644 index f83c04d7..00000000 --- a/quickbook/reference/tiernan_all_cycles.qbk +++ /dev/null @@ -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 - - template - void tiernan_all_cycles(const Graph& g, Visitor vis) - - template - void tiernan_all_cycles(const Graph& g, Visitor vis, std::size_t max) - - template - 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::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 - - template - 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 - - template - 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 - - template - std::pair - 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] \ No newline at end of file diff --git a/quickbook/reference/time_stamper.qbk b/quickbook/reference/time_stamper.qbk deleted file mode 100644 index 1895a544..00000000 --- a/quickbook/reference/time_stamper.qbk +++ /dev/null @@ -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 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 -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 -time_stamper -stamp_times(TimeMap pa, TimeT& t, EventTag) -`` - ] - [ - A convenience function for creating [time_stamper] instances. - ] - ] -] - -[endsect] diff --git a/quickbook/reference/undirected_graph.qbk b/quickbook/reference/undirected_graph.qbk deleted file mode 100644 index b9cc6082..00000000 --- a/quickbook/reference/undirected_graph.qbk +++ /dev/null @@ -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 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` 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::vertex_descriptor`] - ] - [ - [`edge_descriptor`] - [`undirected_graph::edge_descriptor`] - ] - [ - [`vertex_iterator`] - [`undirected_graph::vertex_iterator`] - ] - [ - [`edge_iterator`] - [`undirected_graph::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::vertex_descriptor`] - [ - The type for the vertex descriptors associated with the graph. The `vertex_descriptor` - models the [Descriptor] and [NoConcept Hashable] concepts. - ] - ] - [ - [`graph_traits::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::vertex_iterator`] - [ - The type for iterators returned by `vertices()`. Verex iterators are - models of the [SgiBidirectionalIterator] concept. - ] - ] - [ - [`graph_traits::edge_iterator`] - [ - The type for iterators returned by `edges()`. Edge iterators are - models of the [SgiBidirectionalIterator] concept. - ] - ] - [ - [`graph_traits::out_edge_iterator`] - [ - The type for iterators returned by `out_edges()`. Out-edge iterators - are models of the [SgiBidirectionalIterator] concept. - ] - ] - [ - [`graph_traits::in_edge_iterator`] - [ - The type for iterators returned by `in_edges()`. In-edge iterators - are models of the [SgiBidirectionalIterator] concept. - ] - ] - [ - [`graph_traits::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::vertices_size_type`] - [The type used for dealing with the number of vertices in the graph.] - ] - [ - [`graph_traits::edge_size_type`] - [The type used for dealing with the number of edges in the graph.] - ] - [ - [`graph_traits::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::type` - - `property_map::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::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_category`] - [ - This is always `undirectedS`, indicating that the graph supports operations - for undirected graphs. - ] - ] - [ - [`graph_traits::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 -vertices(const undirected_graph& g) -`` - ] - [Returns an iterator range providing access to the vertex list of `g`.] - ] - [ - [ -`` -std::pair -edges(const undirected_graph& g) -`` - ] - [Returns an iterator range providing access to the edge list of `g`.] - ] - [ - [ -`` -std::pair -incident_edges(vertex_descriptor v, const undirected_graph& g) -`` - -`` -std::pair -out_edges(vertex_descriptor v, const undirected_graph& g) -`` - -`` -std::pair -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 -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(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 -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 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 void -remove_incident_edge_if(vertex_descriptor v, Predicate p - undirected_graph& g) -`` - -`` -template void -remove_out_edge_if(vertex_descriptor v, Predicate p, - undirected_graph& g) -`` - -`` -template 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 -property_map::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 -typename - property_traits< - property_map::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 -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 -typename graph_property::type& -get_property(undirected_graph& g, GraphProperty) -`` - -`` -template -const typename graph_property::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 -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] \ No newline at end of file diff --git a/quickbook/sgi_concepts.qbk b/quickbook/sgi_concepts.qbk deleted file mode 100644 index 5be8449e..00000000 --- a/quickbook/sgi_concepts.qbk +++ /dev/null @@ -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]]] /] diff --git a/quickbook/tutorial.qbk b/quickbook/tutorial.qbk deleted file mode 100644 index 8f733c51..00000000 --- a/quickbook/tutorial.qbk +++ /dev/null @@ -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] \ No newline at end of file diff --git a/src/graphml.cpp b/src/graphml.cpp index 76ef0a29..302d03a5 100644 --- a/src/graphml.cpp +++ b/src/graphml.cpp @@ -33,16 +33,29 @@ public: return boost::property_tree::ptree::path_type(str, '/'); } - static void get_graphs(const boost::property_tree::ptree& top, - size_t desired_idx /* or -1 for all */, + void get_graphs(const boost::property_tree::ptree& top, + size_t desired_idx /* or -1 for all */, bool is_root, std::vector& result) { using boost::property_tree::ptree; size_t current_idx = 0; + bool is_first = is_root; BOOST_FOREACH(const ptree::value_type& n, top) { if (n.first == "graph") { if (current_idx == desired_idx || desired_idx == (size_t)(-1)) { result.push_back(&n.second); - get_graphs(n.second, (size_t)(-1), result); + if(is_first) + { + is_first = false; + BOOST_FOREACH(const ptree::value_type& attr, n.second) { + if (attr.first != "data") + continue; + std::string key = attr.second.get(path("/key")); + std::string value = attr.second.get_value(""); + handle_graph_property(key, value); + } + } + + get_graphs(n.second, (size_t)(-1), false, result); if (desired_idx != (size_t)(-1)) break; } ++current_idx; @@ -81,7 +94,8 @@ public: } // Search for graphs std::vector graphs; - get_graphs(gml, desired_idx, graphs); + handle_graph(); + get_graphs(gml, desired_idx, true, graphs); BOOST_FOREACH(const ptree* gr, graphs) { // Search for nodes BOOST_FOREACH(const ptree::value_type& node, *gr) { @@ -193,6 +207,22 @@ private: } } + void + handle_graph() + { + std::map::iterator iter; + for (iter = m_key_default.begin(); iter != m_key_default.end(); ++iter) + { + if (m_keys[iter->first] == graph_key) + handle_graph_property(iter->first, iter->second); + } + } + + void handle_graph_property(const std::string& key_id, const std::string& value) + { + m_g.set_graph_property(m_key_name[key_id], value, m_key_type[key_id]); + } + void handle_node_property(const std::string& key_id, const std::string& descriptor, const std::string& value) { m_g.set_vertex_property(m_key_name[key_id], m_vertex[descriptor], value, m_key_type[key_id]); diff --git a/src/read_graphviz_new.cpp b/src/read_graphviz_new.cpp index 02dee38e..2881bb12 100644 --- a/src/read_graphviz_new.cpp +++ b/src/read_graphviz_new.cpp @@ -18,7 +18,7 @@ // and page 34 or http://www.graphviz.org/pdf/dotguide.pdf // // See documentation for this code at: -// http://www.boost.org/libs/graph/doc/read-graphviz.html +// http://www.boost.org/libs/graph/doc/read_graphviz.html // // Author: Jeremiah Willcock @@ -726,8 +726,8 @@ namespace read_graphviz_detail { } default: error("Wanted identifier as name of attribute"); } - if (peek().type == token::comma) {get(); continue;} - break; + if (peek().type == token::comma || peek().type == token::semicolon) get(); + else if(peek().type == token::right_bracket) break; } if (peek().type == token::right_bracket) get(); else error("Wanted right bracket to end attribute list"); if (peek().type != token::left_bracket) break; diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 5487631f..263365cb 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -24,6 +24,7 @@ test-suite graph_test : [ run test_graphs.cpp ] [ run index_graph.cpp ] # TODO: Make this part of the test_graphs framework [ run labeled_graph.cpp ] + [ run finish_edge_bug.cpp ] [ run transitive_closure_test.cpp ] [ compile adj_list_cc.cpp ] @@ -40,7 +41,7 @@ test-suite graph_test : [ run betweenness_centrality_test.cpp : 100 ] [ run bidir_remove_edge.cpp ] [ run bipartite_test.cpp ] - [ run csr_graph_test.cpp : : : : : release ] + # [ run csr_graph_test.cpp : : : : : release ] [ run dag_longest_paths.cpp ] [ run dfs.cpp ../../test/build//boost_test_exec_monitor ] [ run undirected_dfs.cpp ../../test/build//boost_test_exec_monitor ] @@ -79,6 +80,7 @@ test-suite graph_test : [ run adjacency_matrix_test.cpp ] [ compile vector_graph_cc.cpp ] [ compile copy.cpp ] + [ compile swap.cpp ] [ compile property_iter.cpp ] [ run bundled_properties.cpp ] [ run floyd_warshall_test.cpp ] @@ -132,6 +134,9 @@ test-suite graph_test : [ run hawick_circuits.cpp ] [ run successive_shortest_path_nonnegative_weights_test.cpp ../../test/build//boost_unit_test_framework/static ] [ run cycle_canceling_test.cpp ../../test/build//boost_unit_test_framework/static ] + [ run strong_components_test.cpp ] + [ run find_flow_cost_bundled_properties_and_named_params_test.cpp ../../test/build//boost_unit_test_framework/static ] + [ run max_flow_algorithms_bundled_properties_and_named_params.cpp ../../test/build//boost_unit_test_framework/static ] ; # Run SDB tests only when -sSDB= is set. diff --git a/test/adj_list_cc.cpp b/test/adj_list_cc.cpp index b1e2d544..32de3286 100644 --- a/test/adj_list_cc.cpp +++ b/test/adj_list_cc.cpp @@ -168,7 +168,6 @@ int main(int,char*[]) { typedef adjacency_list Graph; typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); @@ -183,7 +182,6 @@ int main(int,char*[]) { typedef adjacency_list Graph; typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); @@ -196,8 +194,6 @@ int main(int,char*[]) } { typedef adjacency_list< listS, listS, directedS> Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); @@ -207,8 +203,6 @@ int main(int,char*[]) } { typedef adjacency_list< listS, listS, undirectedS> Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); @@ -220,7 +214,6 @@ int main(int,char*[]) { typedef adjacency_list Graph; typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); @@ -233,15 +226,11 @@ int main(int,char*[]) } { typedef adjacency_list< setS, listS, directedS> Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; BOOST_CONCEPT_ASSERT(( MutableIncidenceGraphConcept )); BOOST_CONCEPT_ASSERT(( MutableEdgeListGraphConcept )); } { typedef adjacency_list< setS, listS, undirectedS> Graph; - typedef graph_traits::vertex_descriptor Vertex; - typedef graph_traits::edge_descriptor Edge; BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept )); BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept )); diff --git a/test/csr_graph_test.cpp b/test/csr_graph_test.cpp index b6a99603..013aca31 100644 --- a/test/csr_graph_test.cpp +++ b/test/csr_graph_test.cpp @@ -464,6 +464,8 @@ int test_main(int argc, char* argv[]) // Check in edge access typedef boost::graph_traits::in_edge_iterator in_edge_iterator; std::pair ie(in_edges(vertex(0, g2b), g2b)); + // quiet unused variable warning + ie.first = ie.second; std::cout << "Testing CSR graph built using add_edges" << std::endl; // Test building a graph using add_edges on unsorted lists diff --git a/test/cycle_ratio_s382.90.dot b/test/cycle_ratio_s382.90.dot old mode 100755 new mode 100644 diff --git a/test/filtered_graph_cc.cpp b/test/filtered_graph_cc.cpp index 52221b1e..9b39dee5 100644 --- a/test/filtered_graph_cc.cpp +++ b/test/filtered_graph_cc.cpp @@ -38,5 +38,13 @@ int main(int,char*[]) typedef filtered_graph > ResGraph; BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); } + // Check filtered_graph with undirected adjacency_list + { + typedef adjacency_list > Graph; + typedef property_map::type ResCapMap; + typedef filtered_graph > ResGraph; + BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); + } return 0; } diff --git a/test/find_flow_cost_bundled_properties_and_named_params_test.cpp b/test/find_flow_cost_bundled_properties_and_named_params_test.cpp new file mode 100644 index 00000000..efc76206 --- /dev/null +++ b/test/find_flow_cost_bundled_properties_and_named_params_test.cpp @@ -0,0 +1,79 @@ +#define BOOST_TEST_MODULE find_flow_cost_bundled_properties_and_named_params_test + +#include +#include +#include +#include "min_cost_max_flow_utils.hpp" + +typedef boost::adjacency_list_traits traits; +struct edge_t { + double capacity; + float cost; + float residual_capacity; + traits::edge_descriptor reversed_edge; +}; +struct node_t { + traits::edge_descriptor predecessor; + int dist; + int dist_prev; + boost::vertex_index_t id; +}; +typedef boost::adjacency_list Graph; + +// Unit test written in order to fails (at compile time) if the find_flow_cost() +// is not properly handling bundled properties +BOOST_AUTO_TEST_CASE(using_bundled_properties_with_find_max_flow_test) +{ + Graph g; + traits::vertex_descriptor s,t; + + boost::property_map::type capacity = get(&edge_t::capacity, g); + boost::property_map::type cost = get(&edge_t::cost, g); + boost::property_map::type residual_capacity = get(&edge_t::residual_capacity, g); + boost::property_map::type rev = get(&edge_t::reversed_edge, g); + boost::property_map::type pred = get(&node_t::predecessor, g); + boost::property_map::type vertex_indices = get(boost::vertex_index, g); + boost::property_map::type dist = get(&node_t::dist, g); + boost::property_map::type dist_prev = get(&node_t::dist_prev, g); + + + boost::SampleGraph::getSampleGraph(g,s,t,capacity,residual_capacity,cost,rev); + + boost::successive_shortest_path_nonnegative_weights(g,s,t, + capacity,residual_capacity,cost,rev,vertex_indices, + pred,dist,dist_prev); + + // The "bundled properties" version (producing errors) + int flow_cost = boost::find_flow_cost(g,capacity,residual_capacity,cost); + BOOST_CHECK_EQUAL(flow_cost, 29); +} + +// Unit test written in order to fails (at compile time) if the find_flow_cost() +// is not properly handling bundled properties +BOOST_AUTO_TEST_CASE(using_named_params_and_bundled_properties_with_find_max_flow_test) +{ + Graph g; + traits::vertex_descriptor s,t; + + boost::property_map::type capacity = get(&edge_t::capacity, g); + boost::property_map::type cost = get(&edge_t::cost, g); + boost::property_map::type residual_capacity = get(&edge_t::residual_capacity, g); + boost::property_map::type rev = get(&edge_t::reversed_edge, g); + boost::property_map::type pred = get(&node_t::predecessor, g); + boost::property_map::type vertex_indices = get(boost::vertex_index, g); + boost::property_map::type dist = get(&node_t::dist, g); + boost::property_map::type dist_prev = get(&node_t::dist_prev, g); + + boost::SampleGraph::getSampleGraph(g,s,t,capacity,residual_capacity,cost,rev); + + boost::successive_shortest_path_nonnegative_weights(g,s,t, + capacity,residual_capacity,cost,rev,vertex_indices, + pred,dist,dist_prev); + + // The "named parameters" version (with "bundled properties"; producing errors) + int flow_cost = boost::find_flow_cost(g, + boost::capacity_map(capacity) + .residual_capacity_map(residual_capacity) + .weight_map(cost)); + BOOST_CHECK_EQUAL(flow_cost, 29); +} diff --git a/test/finish_edge_bug.cpp b/test/finish_edge_bug.cpp new file mode 100644 index 00000000..cc31f0b9 --- /dev/null +++ b/test/finish_edge_bug.cpp @@ -0,0 +1,82 @@ +// Author: Alex Lauser + +// Output (Note that 'finish_edge' is never printed): +// The example graph: +// 0 --> 1 2 +// 1 --> 2 +// 2 --> 0 + +#include +#include +#include +#include +#include + +template +struct TalkativeVisitor + : boost::dfs_visitor<> +{ + typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + + // // Commented out to avoid clutter of the output. + // void discover_vertex(vertex_descriptor u, const graph_t&) { // check! + // std::cout << "discover_vertex: " << u << std::endl; + // } + // void finish_vertex(vertex_descriptor u, const graph_t&) { // check! + // std::cout << "finish_vertex: " << u << std::endl; + // } + // void initialize_vertex(vertex_descriptor u, const graph_t&) { // check! + // std::cout << "initialize_vertex: " << u << std::endl; + // } + // void start_vertex(vertex_descriptor u, const graph_t&) { // check! + // std::cout << "start_vertex: " << u << std::endl; + // } + // void examine_edge(edge_descriptor u, const graph_t&) { // check! + // std::cout << "examine_edge: " << u << std::endl; + // } + // void tree_edge(edge_descriptor u, const graph_t&) { // check! + // std::cout << "tree_edge: " << u << std::endl; + // } + // void back_edge(edge_descriptor u, const graph_t&) { // check! + // std::cout << "back_edge: " << u << std::endl; + // } + // void forward_or_cross_edge(edge_descriptor u, const graph_t&) { // check! + // std::cout << "forward_or_cross_edge: " << u << std::endl; + // } + void finish_edge(edge_descriptor u, const graph_t&) { // uncalled! + std::cout << "finish_edge: " << u << std::endl; + } +}; + +template +std::ostream &operator<<(std::ostream &os, const std::pair &x) { + return os << "(" << x.first << ", " << x.second << ")"; +} + + +int main(int, char*[]) +{ + using namespace boost; + + typedef adjacency_list Graph; + Graph G; + + typedef graph_traits >::vertex_descriptor Vertex; + Vertex a = add_vertex(G); + Vertex b = add_vertex(G); + Vertex c = add_vertex(G); + + add_edge(a, b, G); + add_edge(b, c, G); + add_edge(c, a, G); + add_edge(a, c, G); + + std::cout << "The example graph:" << std::endl; + print_graph(G); + + std::vector color(num_vertices(G)); + depth_first_search(G, visitor(TalkativeVisitor())); + + return 0; +} diff --git a/test/graph.cpp b/test/graph.cpp index 50fd18ef..08428f20 100644 --- a/test/graph.cpp +++ b/test/graph.cpp @@ -64,6 +64,8 @@ bool check_vertex_cleared(Graph& g, Vertex v, ID id) found = ai; break; } +#elif defined(BOOST_NO_CXX98_BINDERS) + found = std::find_if(ai, aiend, std::bind(cmp,v,std::placeholders::_1)); #else found = std::find_if(ai, aiend, std::bind1st(cmp,v)); #endif diff --git a/test/graphml_test.cpp b/test/graphml_test.cpp index 972768e8..617938a2 100644 --- a/test/graphml_test.cpp +++ b/test/graphml_test.cpp @@ -28,34 +28,43 @@ #include #include +#include +#include #include #include + using namespace std; using namespace boost; -int main(int argc, char** argv) +int test_main(int argc, char** argv) { typedef adjacency_list >, - property > graph_t; + property, + property > graph_t; graph_t g; dynamic_properties dp; dp.property("foo",get(vertex_color_t(),g)); dp.property("weight",get(edge_weight_t(),g)); dp.property("name",get(vertex_name_t(),g)); + boost::ref_property_map + gname(get_property(g, graph_name)); + dp.property("description",gname); ifstream ifile(argv[1]); read_graphml(ifile, g, dp); ifile.close(); - assert(num_vertices(g) == 9); - assert(num_edges(g) == 9); - assert(get(vertex_color_t(), g, vertex(2,g)) == 100); - assert(get(vertex_color_t(), g, vertex(3,g)) == 42); - assert(get(edge_weight_t(), g, edge(vertex(0,g),vertex(1,g),g).first) == 0.0); - assert(get(edge_weight_t(), g, edge(vertex(1,g),vertex(2,g),g).first) == 0.8); + BOOST_CHECK(num_vertices(g) == 9); + BOOST_CHECK(num_edges(g) == 9); + BOOST_CHECK(get(vertex_color_t(), g, vertex(2,g)) == 100); + BOOST_CHECK(get(vertex_color_t(), g, vertex(3,g)) == 42); + BOOST_CHECK(std::abs(get(edge_weight_t(), g, edge(vertex(0,g),vertex(1,g),g).first) - 0.0) < 0.00001); + BOOST_CHECK(std::abs(get(edge_weight_t(), g, edge(vertex(1,g),vertex(2,g),g).first) - 0.8) < 0.00001); + BOOST_CHECK(get("description", dp, &g) == "Root graph."); + ofstream ofile("graphml_test_out.xml"); write_graphml(ofile, g, dp); @@ -66,20 +75,24 @@ int main(int argc, char** argv) dp2.property("foo",get(vertex_color_t(),g2)); dp2.property("weight",get(edge_weight_t(),g2)); dp2.property("name",get(vertex_name_t(),g2)); + boost::ref_property_map + gname2(get_property(g2, graph_name)); + dp2.property("description",gname2); ifile.open("graphml_test_out.xml"); read_graphml(ifile, g2, dp2); ifile.close(); - assert(num_vertices(g) == num_vertices(g2)); - assert(num_edges(g) == num_edges(g2)); + BOOST_CHECK(num_vertices(g) == num_vertices(g2)); + BOOST_CHECK(num_edges(g) == num_edges(g2)); + BOOST_CHECK(get("description", dp, &g) == get("description", dp2, &g2)); graph_traits::vertex_iterator v, v_end; for (boost::tie(v,v_end) = vertices(g); v != v_end; ++v) - assert(get(vertex_color_t(), g, *v) == get(vertex_color_t(), g2, *v)); + BOOST_CHECK(get(vertex_color_t(), g, *v) == get(vertex_color_t(), g2, *v)); graph_traits::edge_iterator e, e_end; for (boost::tie(e,e_end) = edges(g); e != e_end; ++e) - assert(get(edge_weight_t(), g, *e) == get(edge_weight_t(), g2, *e)); + BOOST_CHECK(std::abs(get(edge_weight_t(), g, *e) - get(edge_weight_t(), g2, *e)) < 0.00001); return 0; } diff --git a/test/graphml_test.xml b/test/graphml_test.xml index f805fa23..467d29bb 100644 --- a/test/graphml_test.xml +++ b/test/graphml_test.xml @@ -18,8 +18,10 @@ hello + + Root graph. @@ -56,6 +58,7 @@ 0.1 + Nested graph. diff --git a/test/isomorphism.cpp b/test/isomorphism.cpp index fee22a21..bf7ddb5d 100644 --- a/test/isomorphism.cpp +++ b/test/isomorphism.cpp @@ -31,19 +31,28 @@ #include #include +#ifndef BOOST_NO_CXX11_HDR_RANDOM +#include +typedef std::mt19937 random_generator_type; +#else +typedef boost::mt19937 random_generator_type; +#endif + using namespace boost; +#ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE template struct random_functor { random_functor(Generator& g) : g(g) { } std::size_t operator()(std::size_t n) { boost::uniform_int distrib(0, n-1); - boost::variate_generator > + boost::variate_generator > x(g, distrib); return x(); } Generator& g; }; +#endif template void randomly_permute_graph(const Graph1& g1, Graph2& g2) @@ -56,13 +65,20 @@ void randomly_permute_graph(const Graph1& g1, Graph2& g2) typedef typename graph_traits::vertex_descriptor vertex2; typedef typename graph_traits::edge_iterator edge_iterator; - boost::mt19937 gen; - random_functor rand_fun(gen); + random_generator_type gen; + +#ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE + random_functor rand_fun(gen); +#endif // Decide new order std::vector orig_vertices; std::copy(vertices(g1).first, vertices(g1).second, std::back_inserter(orig_vertices)); +#ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE std::random_shuffle(orig_vertices.begin(), orig_vertices.end(), rand_fun); +#else + std::shuffle(orig_vertices.begin(), orig_vertices.end(), gen); +#endif std::map vertex_map; for (std::size_t i = 0; i < num_vertices(g1); ++i) { @@ -78,9 +94,9 @@ template void generate_random_digraph(Graph& g, double edge_probability) { typedef typename graph_traits::vertex_iterator vertex_iterator; - boost::mt19937 random_gen; + random_generator_type random_gen; boost::uniform_real distrib(0.0, 1.0); - boost::variate_generator > + boost::variate_generator > random_dist(random_gen, distrib); for (vertex_iterator u = vertices(g).first; u != vertices(g).second; ++u) { diff --git a/test/make_connected_test.cpp b/test/make_connected_test.cpp index d1d5d41d..1372194c 100644 --- a/test/make_connected_test.cpp +++ b/test/make_connected_test.cpp @@ -72,40 +72,40 @@ void make_disconnected_cycles(Graph& g, int num_cycles, int cycle_size) int test_main(int, char* []) { - typedef adjacency_list - , property - > + > VVgraph_t; - - typedef adjacency_list - , property - > + > VLgraph_t; typedef adjacency_list - , property - > + > LVgraph_t; - typedef adjacency_list - , property - > + > LLgraph_t; VVgraph_t gVV; @@ -118,7 +118,7 @@ int test_main(int, char* []) std::vector::iterator, boost::property_map::const_type > gVV_components_pm(gVV_components.begin(), get(boost::vertex_index, gVV)); - BOOST_CHECK(connected_components(gVV, gVV_components_pm) == + BOOST_CHECK(connected_components(gVV, gVV_components_pm) == static_cast(num_cycles)); make_connected(gVV); BOOST_CHECK(connected_components(gVV, gVV_components_pm) == 1); @@ -134,7 +134,7 @@ int test_main(int, char* []) std::vector::iterator, boost::property_map::const_type > gLV_components_pm(gLV_components.begin(), get(boost::vertex_index, gLV)); - BOOST_CHECK(connected_components(gLV, gLV_components_pm) == + BOOST_CHECK(connected_components(gLV, gLV_components_pm) == static_cast(num_cycles)); make_connected(gLV); BOOST_CHECK(connected_components(gLV, gLV_components_pm) == 1); @@ -146,11 +146,11 @@ int test_main(int, char* []) make_disconnected_cycles(gVL, num_cycles, cycle_size); reset_edge_index(gVL); reset_vertex_index(gVL); - BOOST_CHECK(connected_components(gVL, make_vector_property_map(get(vertex_index,gVL))) + BOOST_CHECK(connected_components(gVL, make_vector_property_map(get(vertex_index,gVL))) == static_cast(num_cycles) ); make_connected(gVL); - BOOST_CHECK(connected_components(gVL, make_vector_property_map(get(vertex_index,gVL))) + BOOST_CHECK(connected_components(gVL, make_vector_property_map(get(vertex_index,gVL))) == 1 ); BOOST_CHECK(num_edges(gVL) == num_cycles * cycle_size + num_cycles - 1); @@ -161,10 +161,10 @@ int test_main(int, char* []) make_disconnected_cycles(gLL, num_cycles, cycle_size); reset_edge_index(gLL); reset_vertex_index(gLL); - BOOST_CHECK(connected_components(gLL, make_vector_property_map(get(vertex_index,gLL))) + BOOST_CHECK(connected_components(gLL, make_vector_property_map(get(vertex_index,gLL))) == static_cast(num_cycles)); make_connected(gLL); - BOOST_CHECK(connected_components(gLL, make_vector_property_map(get(vertex_index,gLL))) + BOOST_CHECK(connected_components(gLL, make_vector_property_map(get(vertex_index,gLL))) == 1 ); BOOST_CHECK(num_edges(gLL) == num_cycles * cycle_size + num_cycles - 1); diff --git a/test/max_flow_algorithms_bundled_properties_and_named_params.cpp b/test/max_flow_algorithms_bundled_properties_and_named_params.cpp new file mode 100644 index 00000000..8b7a609a --- /dev/null +++ b/test/max_flow_algorithms_bundled_properties_and_named_params.cpp @@ -0,0 +1,49 @@ +#define BOOST_TEST_MODULE max_flow_algorithms_named_parameters_and_bundled_params_test + +#include +#include +#include + +#include "min_cost_max_flow_utils.hpp" + +typedef boost::adjacency_list_traits traits; +struct edge_t { + double capacity; + float cost; + float residual_capacity; + traits::edge_descriptor reversed_edge; +}; +struct node_t { + traits::edge_descriptor predecessor; + int dist; + int dist_prev; + boost::vertex_index_t id; + boost::default_color_type color; +}; +typedef boost::adjacency_list Graph; + +BOOST_AUTO_TEST_CASE(using_named_parameters_and_bundled_params_on_edmonds_karp_max_flow_test) +{ + Graph g; + traits::vertex_descriptor s,t; + + boost::property_map::type capacity = get(&edge_t::capacity, g); + boost::property_map::type cost = get(&edge_t::cost, g); + boost::property_map::type residual_capacity = get(&edge_t::residual_capacity, g); + boost::property_map::type rev = get(&edge_t::reversed_edge, g); + boost::property_map::type pred = get(&node_t::predecessor, g); + boost::property_map::type col = get(&node_t::color, g); + + boost::SampleGraph::getSampleGraph(g,s,t,capacity,residual_capacity,cost,rev); + + // The "named parameter version" (producing errors) + // I chose to show the error with edmonds_karp_max_flow(). + int flow_value = edmonds_karp_max_flow(g, s, t, + boost::capacity_map(capacity) + .residual_capacity_map(residual_capacity) + .reverse_edge_map(rev) + .color_map(col) + .predecessor_map(pred)); + + BOOST_CHECK_EQUAL(flow_value,4); +} diff --git a/test/min_cost_max_flow_utils.hpp b/test/min_cost_max_flow_utils.hpp index 37c97953..88707c2b 100644 --- a/test/min_cost_max_flow_utils.hpp +++ b/test/min_cost_max_flow_utils.hpp @@ -34,54 +34,63 @@ struct SampleGraph { typedef boost::graph_traits::vertices_size_type size_type; typedef Traits::vertex_descriptor vertex_descriptor; + template class EdgeAdder { public: - EdgeAdder(Graph & g, Weight & w, Capacity & c, Reversed & rev, ResidualCapacity & residualCapacity) - : m_g(g), m_w(w), m_cap(c), m_resCap(residualCapacity), m_rev(rev) {} + EdgeAdder(Graph& g, Weight& w, Capacity& c, Reversed& rev + , ResidualCapacity&) : m_g(g), m_w(w), m_cap(c), m_rev(rev) {} void addEdge(vertex_descriptor v, vertex_descriptor w, long weight, long capacity) { - Traits::edge_descriptor e,f; - e = add(v, w, weight, capacity); - f = add(w, v, -weight, 0); - m_rev[e] = f; - m_rev[f] = e; + Traits::edge_descriptor e,f; + e = add(v, w, weight, capacity); + f = add(w, v, -weight, 0); + m_rev[e] = f; + m_rev[f] = e; } + private: - Traits::edge_descriptor add(vertex_descriptor v, vertex_descriptor w, long weight, long capacity) { - bool b; - Traits::edge_descriptor e; - boost::tie(e, b) = add_edge(vertex(v, m_g), vertex(w, m_g), m_g); - if (!b) { - std::cerr << "Edge between " << v << " and " << w << " already exists." << std::endl; - std::abort(); - } - m_cap[e] = capacity; - m_w[e] = weight; - return e; + Traits::edge_descriptor add(vertex_descriptor v, vertex_descriptor w + , long weight, long capacity) + { + bool b; + Traits::edge_descriptor e; + boost::tie(e, b) = add_edge(vertex(v, m_g), vertex(w, m_g), m_g); + if (!b) { + std::cerr << "Edge between " << v << " and " << w << " already exists." << std::endl; + std::abort(); } - Graph & m_g; - Weight & m_w; - Capacity & m_cap; - ResidualCapacity & m_resCap; - Reversed & m_rev; + m_cap[e] = capacity; + m_w[e] = weight; + return e; + } + Graph & m_g; + Weight & m_w; + Capacity & m_cap; + Reversed & m_rev; }; static void getSampleGraph(Graph &g, vertex_descriptor & s, vertex_descriptor & t) { - size_type N(6); - typedef property_map < Graph, edge_reverse_t >::type Reversed; - - for(size_type i = 0; i < N; ++i){ - add_vertex(g); - } Capacity capacity = get(edge_capacity, g); Reversed rev = get(edge_reverse, g); ResidualCapacity residual_capacity = get(edge_residual_capacity, g); Weight weight = get(edge_weight, g); + getSampleGraph(g,s,t,capacity,residual_capacity,weight,rev); + } + + template + static void + getSampleGraph(Graph &g, vertex_descriptor & s, vertex_descriptor & t, + Capacity capacity, ResidualCapacity residual_capacity, Weight weight, Reversed rev) { + size_type N(6); + + for(size_type i = 0; i < N; ++i){ + add_vertex(g); + } s = 0; t = 5; - EdgeAdder ea(g, weight, capacity, rev, residual_capacity); + EdgeAdder ea(g, weight, capacity, rev, residual_capacity); ea.addEdge(0, 1, 4 ,2); ea.addEdge(0, 2, 2 ,2); @@ -112,7 +121,7 @@ struct SampleGraph { s = 0; t = 4; - EdgeAdder ea(g, weight, capacity, rev, residual_capacity); + EdgeAdder ea(g, weight, capacity, rev, residual_capacity); ea.addEdge(0, 1, 4 ,2); ea.addEdge(0, 2, 2 ,2); diff --git a/test/regression.cfg b/test/regression.cfg deleted file mode 100644 index b9d1c9a3..00000000 --- a/test/regression.cfg +++ /dev/null @@ -1,22 +0,0 @@ -// Boost Graph Library regression test configuration file -// -// From the boost/status directory, run -// ./regression --tests ../libs/graph/test/regression.cfg -o graph.html -// -// Please keep the entries ordered alphabetically by the test's file name. - -run libs/graph/test/graph.cpp -compile libs/graph/test/dijkstra_cc.cpp -compile libs/graph/test/adj_list_cc.cpp -compile libs/graph/test/bfs_cc.cpp -compile libs/graph/test/dfs_cc.cpp -compile libs/graph/test/graph_concepts.cpp -compile libs/graph/test/edge_list_cc.cpp -compile libs/graph/test/reverse_graph_cc.cpp -compile libs/graph/test/adj_matrix_cc.cpp -compile libs/graph/test/filtered_graph_cc.cpp -compile libs/graph/test/stanford_graph_cc.cpp -compile libs/graph/test/vector_graph_cc.cpp -run libs/graph/test/adj_list_test.cpp -run libs/graph/test/bfs.cpp -run libs/graph/test/dfs.cpp diff --git a/test/reverse_graph_cc.cpp b/test/reverse_graph_cc.cpp index eef53bf9..145eb306 100644 --- a/test/reverse_graph_cc.cpp +++ b/test/reverse_graph_cc.cpp @@ -25,6 +25,7 @@ int main(int,char*[]) > AdjList; typedef reverse_graph Graph; BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); + BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); typedef graph_traits::vertex_descriptor Vertex; typedef graph_traits::edge_descriptor Edge; BOOST_CONCEPT_ASSERT(( ReadablePropertyGraphConcept )); @@ -43,6 +44,7 @@ int main(int,char*[]) > AdjList; typedef reverse_graph Graph; BOOST_CONCEPT_ASSERT(( VertexListGraphConcept )); + BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept )); typedef graph_traits::vertex_descriptor Vertex; typedef graph_traits::edge_descriptor Edge; BOOST_CONCEPT_ASSERT(( PropertyGraphConcept )); diff --git a/test/strong_components_test.cpp b/test/strong_components_test.cpp new file mode 100644 index 00000000..7e3b0b81 --- /dev/null +++ b/test/strong_components_test.cpp @@ -0,0 +1,115 @@ +//======================================================================= +// Copyright 2014 Alexander Lauser. +// Authors: Alexander Lauser +// +// 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 test is an adapted version of the MWE for Bug #10231 (showing +// incorrect root_map computation). + +/* Output should be: +The example graph: +a --> b +b --> a c +c --> b + +Vertex a is in component 0 and has root 0 +Vertex b is in component 0 and has root 0 +Vertex c is in component 0 and has root 0 +*/ +#include +#include +#include +#include +#include +#include + +int main(int, char*[]) +{ + using namespace boost; + + adjacency_list G; + + typedef graph_traits >::vertex_descriptor Vertex; + Vertex a = add_vertex(G); + Vertex b = add_vertex(G); + Vertex c = add_vertex(G); + + add_edge(a, b, G); + add_edge(b, a, G); + + add_edge(c, b, G); + add_edge(b, c, G); + +#if VERBOSE + std::cout << "The example graph:" << std::endl; + const char* name = "abc"; + print_graph(G, name); + std::cout << std::endl; +#endif + + std::vector component(num_vertices(G)), discover_time(num_vertices(G)); + std::vector color(num_vertices(G)); + std::vector root(num_vertices(G)); + strong_components(G, make_iterator_property_map(component.begin(), get(vertex_index, G)), + root_map(make_iterator_property_map(root.begin(), get(vertex_index, G))). + color_map(make_iterator_property_map(color.begin(), get(vertex_index, G))). + discover_time_map(make_iterator_property_map(discover_time.begin(), get(vertex_index, G)))); + +#if VERBOSE + for (std::vector::size_type i = 0; i != component.size(); ++i) + std::cout << "Vertex " << name[i] + << " is in component " << component[i] + << " and has root " << root[i] << std::endl; +#endif + +#if VERBOSE + bool test_failed; +#endif + int ret = 0; + + ////////// +#if VERBOSE + test_failed = false; + std::cerr << "Testing component-computation of strong_components ..." << std::endl; +#endif + for (std::vector::size_type i = 0; i != component.size(); ++i) { + if(component[i] != 0) { +#if VERBOSE + test_failed = true; +#endif + ret = -1; + break; + } + } +#if VERBOSE + std::cerr << (test_failed ? " **** Failed." : " Passed.") << std::endl; +#endif + ////////// + + ////////// +#if VERBOSE + test_failed = false; + std::cerr << "Testing root_map-computation of strong_components ..." << std::endl; +#endif + for (std::vector::size_type i = 0; i != component.size(); ++i) { + if(root[i] != 0) { +#if VERBOSE + test_failed = true; +#endif + ret = -1; + break; + } + } +#if VERBOSE + std::cerr << (test_failed ? " **** Failed." : " Passed.") << std::endl; +#endif + ////////// + + if (ret == 0) + std::cout << "tests passed" << std::endl; + return ret; +} diff --git a/test/swap.cpp b/test/swap.cpp new file mode 100644 index 00000000..f47b234f --- /dev/null +++ b/test/swap.cpp @@ -0,0 +1,21 @@ +// Copyright (C) Ben Pope 2014. +// 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 +#include + +template +void test_member_swap() +{ + Graph lhs, rhs; + lhs.swap(rhs); +} + +int main() +{ + test_member_swap >(); + test_member_swap >(); + test_member_swap >(); +} diff --git a/test/test_properties.hpp b/test/test_properties.hpp index 2d71b9b2..751a838d 100644 --- a/test/test_properties.hpp +++ b/test/test_properties.hpp @@ -21,7 +21,7 @@ void test_graph_bundle(Graph& g, boost::mpl::true_) { GraphBundle& b2 = get_property(g); ignore(b1); ignore(b2); - GraphBundle const& cb1 = as_const(g)[graph_bundle]; + GraphBundle const& cb1 = ::as_const(g)[graph_bundle]; GraphBundle const& cb2 = get_property(g); ignore(cb1); ignore(cb2); } diff --git a/test/vf2_sub_graph_iso_test.cpp b/test/vf2_sub_graph_iso_test.cpp index 21ef97ee..e5d15436 100644 --- a/test/vf2_sub_graph_iso_test.cpp +++ b/test/vf2_sub_graph_iso_test.cpp @@ -31,9 +31,16 @@ #include #include +#ifndef BOOST_NO_CXX11_HDR_RANDOM +#include +typedef std::mt19937 random_generator_type; +#else +typedef boost::mt19937 random_generator_type; +#endif + using namespace boost; - +#ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE template struct random_functor { random_functor(Generator& g) : g(g) { } @@ -45,7 +52,7 @@ struct random_functor { } Generator& g; }; - +#endif template void randomly_permute_graph(Graph1& g1, const Graph2& g2) { @@ -56,14 +63,20 @@ void randomly_permute_graph(Graph1& g1, const Graph2& g2) { typedef typename graph_traits::vertex_descriptor vertex2; typedef typename graph_traits::vertex_iterator vertex_iterator; typedef typename graph_traits::edge_iterator edge_iterator; - - boost::mt19937 gen; - random_functor rand_fun(gen); + + random_generator_type gen; +#ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE + random_functor rand_fun(gen); +#endif // Decide new order std::vector orig_vertices; std::copy(vertices(g2).first, vertices(g2).second, std::back_inserter(orig_vertices)); +#ifndef BOOST_NO_CXX98_RANDOM_SHUFFLE std::random_shuffle(orig_vertices.begin(), orig_vertices.end(), rand_fun); +#else + std::shuffle(orig_vertices.begin(), orig_vertices.end(), gen); +#endif std::map vertex_map; std::size_t i = 0; @@ -94,9 +107,9 @@ void generate_random_digraph(Graph& g, double edge_probability, BOOST_REQUIRE(0 <= max_vertex_name); typedef typename graph_traits::vertex_iterator vertex_iterator; - boost::mt19937 random_gen; + random_generator_type random_gen; boost::uniform_real dist_real(0.0, 1.0); - boost::variate_generator > + boost::variate_generator > random_real_dist(random_gen, dist_real); for (vertex_iterator u = vertices(g).first; u != vertices(g).second; ++u) { @@ -113,14 +126,14 @@ void generate_random_digraph(Graph& g, double edge_probability, { boost::uniform_int dist_int(0, max_edge_name); - boost::variate_generator > + boost::variate_generator > random_int_dist(random_gen, dist_int); randomize_property(g, random_int_dist); } { boost::uniform_int dist_int(0, max_vertex_name); - boost::variate_generator > + boost::variate_generator > random_int_dist(random_gen, dist_int); randomize_property(g, random_int_dist); @@ -170,6 +183,23 @@ private: bool output_; }; +// we pretend this is something more complicated which calculates indices somehow +template +struct IndirectIndexMap { + typedef std::size_t value_type; + typedef value_type reference; + typedef typename boost::graph_traits::vertex_descriptor key_type; + typedef boost::readable_property_map_tag category; + explicit IndirectIndexMap(const G &g) : g(g) {} +public: + const G &g; +}; + +template +std::size_t get(const IndirectIndexMap &map, typename boost::graph_traits::vertex_descriptor v) { + // we pretend this is something more complicated which calculates indices somehow + return get(vertex_index_t(), map.g, v); +} void test_vf2_sub_graph_iso(int n1, int n2, double edge_probability, int max_parallel_edges, double parallel_edge_probability, @@ -219,6 +249,11 @@ void test_vf2_sub_graph_iso(int n1, int n2, double edge_probability, std::cout << std::endl; BOOST_CHECK(vf2_subgraph_iso(g1, g2, callback, vertex_order_by_mult(g1), edges_equivalent(edge_comp).vertices_equivalent(vertex_comp))); + BOOST_CHECK(vf2_subgraph_iso(g1, g2, callback, + IndirectIndexMap(g1), + IndirectIndexMap(g2), + vertex_order_by_mult(g1), + edge_comp, vertex_comp)); std::clock_t end1 = std::clock(); std::cout << "vf2_subgraph_iso: elapsed time (clock cycles): " << (end1 - start) << std::endl;