[DEV] add v1.66.0

This commit is contained in:
2018-01-12 21:47:58 +01:00
parent 87059bb1af
commit a97e9ae7d4
49032 changed files with 7668950 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
# Copyright (c) 2002 Trustees of Indiana University
#
# 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)
import mpi ;
project boost/graph_parallel
: requirements <include>../src
: source-location ../src
;
local optional_sources ;
local optional_reqs ;
if [ mpi.configured ]
{
lib boost_graph_parallel
: mpi_process_group.cpp tag_allocator.cpp
: <library>../../mpi/build//boost_mpi
<library>/mpi//mpi [ mpi.extra-requirements ]
<define>BOOST_GRAPH_NO_LIB=1
<link>shared:<define>BOOST_GRAPH_DYN_LINK=1
# # Intel compiler ICEs if we turn optimization on
<toolset>intel-vc71-win-9.1:<optimization>off
# Without these flags, MSVC 7.1 crash
# User reports that VC++ 8 no longer has this problem
<toolset>msvc-7.1:<cxxflags>-GR-
;
}
else
{
message boost_graph_parallel
: "warning: Graph library does not contain MPI-based parallel components."
: "note: to enable them, add \"using mpi ;\" to your user-config.jam"
;
}
boost-install boost_graph_parallel ;

View File

@@ -0,0 +1,33 @@
#!/bin/sh
# \
exec tclsh "$0" "$@"
# Copyright (C) 2009 The Trustees of Indiana University.
# Use, modification and distribution is 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)
# Authors: Jeremiah Willcock, Andrew Lumsdaine
foreach input [glob *.rst] {
set output [file join html "[file rootname $input].html"]
puts "Processing $input -> $output"
set processor [open "|rst2html.py --stylesheet=../../../../rst.css -gdt --link-stylesheet --traceback --trim-footnote-reference-space --footnote-references=superscript >$output" w]
set inputfd [open $input r]
set data [read $inputfd]
close $inputfd
foreach line [split $data \n] {
if {[regexp {^\.\. image:: (http:.*)$} $line _ url]} {
set tag $url
regsub -all {.*/} $tag {} tag
regsub -all {[^a-zA-Z0-9]} $tag _ tag
set imageoutput [file join html "$tag.png"]
puts "Getting image $url -> $imageoutput"
exec wget -q -O $imageoutput $url
puts $processor ".. image:: [file tail $imageoutput]"
} else {
puts $processor $line
}
}
close $processor
}

View File

@@ -0,0 +1,86 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
==========================================
|Logo| Concept Distributed Edge List Graph
==========================================
.. contents::
Description
-----------
A Distributed Edge List Graph is a graph whose vertices are
distributed across multiple processes or address spaces. The
``vertices`` and ``num_vertices`` functions retain the same
signatures as in the `Edge List Graph`_ concept, but return only
the local set (and size of the local set) of vertices.
Notation
--------
G
A type that models the Distributed Edge List Graph concept.
g
An object of type ``G``.
Refinement of
-------------
- `Graph`_
Associated types
----------------
+----------------+---------------------------------------+---------------------------------+
|Edge |``graph_traits<G>::edge_descriptor`` |Must model the |
|descriptor type | |`Global Descriptor`_ concept. |
+----------------+---------------------------------------+---------------------------------+
|Edge iterator |``graph_traits<G>::edge_iterator`` |Iterates over edges stored |
|type | |locally. The value type must be |
| | |``edge_descriptor``. |
+----------------+---------------------------------------+---------------------------------+
|Edges size |``graph_traits<G>::edges_size_type`` |The unsigned integral type used |
|type | |to store the number of edges |
| | |in the local subgraph. |
+----------------+---------------------------------------+---------------------------------+
Valid Expressions
-----------------
+----------------+---------------------+----------------------+-------------------------------------+
|Name |Expression |Type |Semantics |
+================+=====================+======================+=====================================+
|Local edge set |``edges(g)`` |``std::pair<`` |Returns an iterator range |
| | |``edge_iterator,`` |providing access to the local |
| | |``edge_iterator>`` |edges in the graph. |
+----------------+---------------------+----------------------+-------------------------------------+
|Number of local |``num_edges(g)`` |``edges_size_type`` |Returns the number of edges |
|edges. | | |stored locally in the graph. |
+----------------+---------------------+----------------------+-------------------------------------+
Models
------
- `Distributed adjacency list`_
-----------------------------------------------------------------------------
Copyright (C) 2005 The Trustees of Indiana University.
Authors: Douglas Gregor and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _Graph: http://www.boost.org/libs/graph/doc/Graph.html
.. _Edge List Graph: http://www.boost.org/libs/graph/doc/EdgeListGraph.html
.. _Distributed Graph: DistributedGraph.html
.. _Global descriptor: GlobalDescriptor.html
.. _Distributed adjacency list: distributed_adjacency_list.html

View File

@@ -0,0 +1,62 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
================================
|Logo| Concept Distributed Graph
================================
.. contents::
Description
-----------
A Distributed Graph is a graph whose vertices or edges are
distributed across multiple processes or address spaces. The
descriptors of a Distributed Graph must model the `Global
Descriptor`_ concept.
Notation
--------
G
A type that models the Distributed Graph concept.
Refinement of
-------------
- Graph_
Associated types
----------------
+----------------+---------------------------------------+---------------------------------+
|Vertex |``graph_traits<G>::vertex_descriptor`` |Must model the |
|descriptor type | |`Global Descriptor`_ concept. |
+----------------+---------------------------------------+---------------------------------+
|Edge |``graph_traits<G>::edge_descriptor`` |Must model the |
|descriptor type | |`Global Descriptor`_ concept. |
+----------------+---------------------------------------+---------------------------------+
Models
------
- `Distributed adjacency list`_
-----------------------------------------------------------------------------
Copyright (C) 2005 The Trustees of Indiana University.
Authors: Douglas Gregor and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _Graph: http://www.boost.org/libs/graph/doc/Graph.html
.. _Global descriptor: GlobalDescriptor.html
.. _Distributed adjacency list: distributed_adjacency_list.html

View File

@@ -0,0 +1,86 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
============================================
|Logo| Concept Distributed Vertex List Graph
============================================
.. contents::
Description
-----------
A Distributed Vertex List Graph is a graph whose vertices are
distributed across multiple processes or address spaces. The
``vertices`` and ``num_vertices`` functions retain the same
signatures as in the `Vertex List Graph`_ concept, but return only
the local set (and size of the local set) of vertices.
Notation
--------
G
A type that models the Distributed Vertex List Graph concept.
g
An object of type ``G``.
Refinement of
-------------
- `Graph`_
Associated types
----------------
+----------------+---------------------------------------+---------------------------------+
|Vertex |``graph_traits<G>::vertex_descriptor`` |Must model the |
|descriptor type | |`Global Descriptor`_ concept. |
+----------------+---------------------------------------+---------------------------------+
|Vertex iterator |``graph_traits<G>::vertex_iterator`` |Iterates over vertices stored |
|type | |locally. The value type must be |
| | |``vertex_descriptor``. |
+----------------+---------------------------------------+---------------------------------+
|Vertices size |``graph_traits<G>::vertices_size_type``|The unsigned integral type used |
|type | |to store the number of vertices |
| | |in the local subgraph. |
+----------------+---------------------------------------+---------------------------------+
Valid Expressions
-----------------
+----------------+---------------------+----------------------+-------------------------------------+
|Name |Expression |Type |Semantics |
+================+=====================+======================+=====================================+
|Local vertex set|``vertices(g)`` |``std::pair<`` |Returns an iterator range |
| | |``vertex_iterator,`` |providing access to the local |
| | |``vertex_iterator>`` |vertices in the graph. |
+----------------+---------------------+----------------------+-------------------------------------+
|Number of local |``num_vertices(g)`` |``vertices_size_type``|Returns the number of vertices |
|vertices. | | |stored locally in the graph. |
+----------------+---------------------+----------------------+-------------------------------------+
Models
------
- `Distributed adjacency list`_
-----------------------------------------------------------------------------
Copyright (C) 2005 The Trustees of Indiana University.
Authors: Douglas Gregor and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _Graph: http://www.boost.org/libs/graph/doc/Graph.html
.. _Vertex List Graph: http://www.boost.org/libs/graph/doc/VertexListGraph.html
.. _Distributed Graph: DistributedGraph.html
.. _Global descriptor: GlobalDescriptor.html
.. _Distributed adjacency list: distributed_adjacency_list.html

View File

@@ -0,0 +1,78 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
================================
|Logo| Concept Global Descriptor
================================
.. contents::
Description
-----------
A global descriptor is an object that represents an entity that is
owned by some process and may reside in an address space not
accessible to the currently-executing process. The global descriptor
consists of two parts: the *owner* of the entity, which is the
identifier of that process in which the entity resides, and a *local
descriptor*, that uniquely identifies the entity with the address
space of the owner.
Refinement of
-------------
- `Default Constructible`_
- Assignable_
Notation
--------
X
A type that models the Global Descriptor concept.
x
Object of type X
Associated types
----------------
+----------------+--------------------+---------------------------------+
|Process ID type |``process_id_type`` |Determined by the process group |
| | |associated with type X. |
+----------------+--------------------+---------------------------------+
|Local descriptor|``local_type`` |Determined by the data structure |
|type | |the descriptor accesses. |
| | |Must model `Equality Comparable`_|
| | |and `Copy Constructible`_. |
+----------------+--------------------+---------------------------------+
Valid Expressions
-----------------
+----------------+---------------------+---------------------+-------------------------------------+
|Name |Expression |Type |Semantics |
+================+=====================+=====================+=====================================+
|Owner |``owner(x)`` |``process_id_type`` |Returns the owner of ``x``. |
+----------------+---------------------+---------------------+-------------------------------------+
|Local descriptor|``local(x)`` |``local_type`` |Returns the local descriptor |
| | | |uniquely identifying ``x``. |
+----------------+---------------------+---------------------+-------------------------------------+
-----------------------------------------------------------------------------
Copyright (C) 2005 The Trustees of Indiana University.
Authors: Douglas Gregor and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _Assignable: http://www.sgi.com/tech/stl/Assignable.html
.. _Copy constructible: http://www.sgi.com/tech/stl/CopyConstructible.html
.. _Default constructible: http://www.sgi.com/tech/stl/DefaultConstructible.html
.. _Equality comparable: http://www.sgi.com/tech/stl/EqualityComparable.html

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

View File

@@ -0,0 +1,236 @@
.. Copyright (C) 2004-2009 The Trustees of Indiana University.
Use, modification and distribution is 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)
=============================
|Logo| Betweenness Centrality
=============================
::
// named parameter versions
template<typename Graph, typename Param, typename Tag, typename Rest>
void
brandes_betweenness_centrality(const Graph& g,
const bgl_named_params<Param,Tag,Rest>& params);
template<typename Graph, typename CentralityMap>
void
brandes_betweenness_centrality(const Graph& g, CentralityMap centrality);
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap>
void
brandes_betweenness_centrality(const Graph& g, CentralityMap centrality,
EdgeCentralityMap edge_centrality_map);
// non-named parameter versions
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename IncomingMap, typename DistanceMap, typename DependencyMap,
typename PathCountMap, typename VertexIndexMap, typename Buffer>
void
brandes_betweenness_centrality(const Graph& g,
CentralityMap centrality,
EdgeCentralityMap edge_centrality_map,
IncomingMap incoming,
DistanceMap distance,
DependencyMap dependency,
PathCountMap path_count,
VertexIndexMap vertex_index,
Buffer sources,
typename property_traits<DistanceMap>::value_type delta);
template<typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename IncomingMap, typename DistanceMap, typename DependencyMap,
typename PathCountMap, typename VertexIndexMap, typename WeightMap,
typename Buffer>
void
brandes_betweenness_centrality(const Graph& g,
CentralityMap centrality,
EdgeCentralityMap edge_centrality_map,
IncomingMap incoming,
DistanceMap distance,
DependencyMap dependency,
PathCountMap path_count,
VertexIndexMap vertex_index,
Buffer sources,
typename property_traits<WeightMap>::value_type delta,
WeightMap weight_map);
// helper functions
template<typename Graph, typename CentralityMap>
typename property_traits<CentralityMap>::value_type
central_point_dominance(const Graph& g, CentralityMap centrality);
The ``brandes_betweenness_centrality()`` function computes the
betweenness centrality of the vertices and edges in a graph. The
method of calculating betweenness centrality in *O(V)* space is due to
Brandes [Brandes01]_. The algorithm itself is a modification of
Brandes algorithm by Edmonds [Edmonds09]_.
.. contents::
Where Defined
-------------
<``boost/graph/distributed/betweenness_centrality.hpp``>
also accessible from
<``boost/graph/betweenness_centrality.hpp``>
Parameters
----------
IN: ``const Graph& g``
The graph type must be a model of `Distributed Graph`_. The graph
type must also model the `Incidence Graph`_ concept. 0-weighted
edges in ``g`` will result in undefined behavior.
IN: ``CentralityMap centrality``
A centrality map may be supplied to the algorithm, if not supplied a
``dummy_property_map`` will be used and no vertex centrality
information will be recorded. The ``CentralityMap`` type must be a
`Distributed Property Map`_. The key type must be the graph's
vertex descriptor type.
**Default**: A ``dummy_property_map``.
IN: ``EdgeCentralityMap edge_centrality_map``
An edge centrality map may be supplied to the algorithm, if not
supplied a ``dummy_property_map`` will be used and no edge
centrality information will be recorded. The ``EdgeCentralityMap``
type must be a `Distributed Property Map`_. The key type must be
the graph's vertex descriptor type.
**Default**: A ``dummy_property_map``.
IN: ``IncomingMap incoming``
The incoming map contains the incoming edges to a vertex that are
part of shortest paths to that vertex. The ``IncomingMap`` type
must be a `Distributed Property Map`_. Its key type and value type
must both be the graph's vertex descriptor type.
**Default**: An ``iterator_property_map`` created from a
``std::vector`` of ``std::vector`` of the graph's vertex
descriptor type.
IN: ``DistanceMap distance``
The distance map records the distance to vertices during the
shortest paths portion of the algorithm. The ``DistanceMap`` type
must be a `Distributed Property Map`_. Its key type must be the
graph's vertex descriptor type.
**Default**: An ``iterator_property_map`` created from a
``std::vector`` of the value type of the ``CentralityMap``.
IN: ``DependencyMap dependency``
The dependency map records the dependency of each vertex during the
centrality calculation portion of the algorithm. The
``DependencyMap`` type must be a `Distributed Property Map`_. Its
key type must be the graph's vertex descriptor type.
**Default**: An ``iterator_property_map`` created from a
``std::vector`` of the value type of the ``CentralityMap``.
IN: ``PathCountMap path_count``
The path count map records the number of shortest paths each vertex
is on during the centrality calculation portion of the algorithm.
The ``PathCountMap`` type must be a `Distributed Property Map`_.
Its key type must be the graph's vertex descriptor type.
**Default**: An ``iterator_property_map`` created from a
``std::vector`` of the graph's degree size type.
IN: ``VertexIndexMap vertex_index``
A model of `Readable Property Map`_ whose key type is the vertex
descriptor type of the graph ``g`` and whose value type is an
integral type. The property map should map from vertices to their
(local) indices in the range *[0, num_vertices(g))*.
**Default**: ``get(vertex_index, g)``
IN: ``WeightMap weight_map``
A model of `Readable Property Map`_ whose key type is the edge
descriptor type of the graph ``g``. If not supplied the betweenness
centrality calculation will be unweighted.
IN: ``Buffer sources``
A model of Buffer_ containing the starting vertices for the
algorithm. If ``sources`` is empty a complete betweenness
centrality calculation using all vertices in ``g`` will be
performed. The value type of the Buffer must be the graph's vertex
descriptor type.
**Default**: An empty ``boost::queue`` of int.
Complexity
----------
Computing the shortest paths, counting them, and computing the
contribution to the centrality map is *O(V log V)*. Calculating exact
betweenness centrality requires counting the shortest paths from all
vertices in ``g``, thus exact betweenness centrality is *O(V^2 log
V)*.
Algorithm Description
---------------------
For the vertices in ``sources`` (or all vertices in ``g`` when
``sources`` is empty) the algorithm first calls a customized
implementation of delta_stepping_shortest_paths_ which maintains a
shortest path tree using an ``IncomingMap``. The ``IncomingMap``
contains the source of all incoming edges on shortest paths.
The ``IncomingMap`` defines the shortest path DAG at the target of the
edges in the shortest paths tree. In the bidirectional case edge
flags could be used to translate the shortest paths information to the
source of the edges. Setting edge flags during the shortest path
computation rather than using an ``IncomingMap`` would result in
adding an *O(V)* factor to the inner loop of the shortest paths
computation to account for having to clear edge flags when a new
shortest path is found. This would increase the complexity of the
algorithm. Asymptotically, the current implementation is better,
however using edge flags in the bidirectional case would reduce the
number of supersteps required by the depth of the shortest paths DAG
for each vertex. Currently an ``outgoing`` map is explicitly
constructed by simply reversing the edges in the incoming map. Once
the ``outgoing`` map is constructed it is traversed in dependency
order from the source of the shortest paths calculation in order to
compute path counts. Once path counts are computed the shortest paths
DAG is again traversed in dependency order from the source to
calculate the dependency and centrality of each vertex.
The algorithm is complete when the centrality has been computed from
all vertices in ``g``.
Bibliography
------------
.. [Brandes01] Ulrik Brandes. A Faster Algorithm for Betweenness
Centrality. In the Journal of Mathematical Sociology, volume 25
number 2, pages 163--177, 2001.
.. [Edmonds09] Nick Edmonds, Torsten Hoefler, and Andrew Lumsdaine.
A Space-Efficient Parallel Algorithm for Computing Betweenness
Centrality in Sparse Networks. Indiana University tech report.
2009.
-----------------------------------------------------------------------------
Copyright (C) 2009 The Trustees of Indiana University.
Authors: Nick Edmonds and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _delta_stepping_shortest_paths: dijkstra_shortest_paths.html
.. _Distributed Graph: DistributedGraph.html
.. _Incidence Graph: http://www.boost.org/libs/graph/doc/IncidenceGraph.html
.. _Readable Property Map: http://www.boost.org/libs/property_map/ReadablePropertyMap.html
.. _Buffer: http://www.boost.org/libs/graph/doc/Buffer.html
.. _Process Group: process_group.html
.. _Distributed Property Map: distributed_property_map.html

View File

@@ -0,0 +1,191 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
=================================
|Logo| Boman et al graph coloring
=================================
::
namespace graph {
template<typename DistributedGraph, typename ColorMap>
typename property_traits<ColorMap>::value_type
boman_et_al_graph_coloring
(const DistributedGraph& g,
ColorMap color,
typename graph_traits<DistributedGraph>::vertices_size_type s = 100);
template<typename DistributedGraph, typename ColorMap, typename ChooseColor>
typename property_traits<ColorMap>::value_type
boman_et_al_graph_coloring
(const DistributedGraph& g,
ColorMap color,
typename graph_traits<DistributedGraph>::vertices_size_type s,
ChooseColor choose_color);
template<typename DistributedGraph, typename ColorMap, typename ChooseColor,
typename VertexOrdering>
typename property_traits<ColorMap>::value_type
boman_et_al_graph_coloring
(const DistributedGraph& g, ColorMap color,
typename graph_traits<DistributedGraph>::vertices_size_type s,
ChooseColor choose_color, VertexOrdering ordering);
template<typename DistributedGraph, typename ColorMap, typename ChooseColor,
typename VertexOrdering, typename VertexIndexMap>
typename property_traits<ColorMap>::value_type
boman_et_al_graph_coloring
(const DistributedGraph& g,
ColorMap color,
typename graph_traits<DistributedGraph>::vertices_size_type s,
ChooseColor choose_color,
VertexOrdering ordering, VertexIndexMap vertex_index);
}
The ``boman_et_al_graph_coloring`` function colors the vertices of an
undirected, distributed graph such that no two adjacent vertices have
the same color. All of the vertices of a given color form an
independent set in the graph. Graph coloring has been used to solve
various problems, including register allocation in compilers,
optimization problems, and scheduling problems.
.. image:: ../vertex_coloring.png
:width: 462
:height: 269
:alt: Vertex coloring example
:align: right
The problem of coloring a graph with the fewest possible number of
colors is NP-complete, so many algorithms (including the one
implemented here) are heuristic algorithms that try to minimize the
number of colors but are not guaranteed to provide an optimal
solution. This algorithm [BBC05]_ is similar to the
``sequential_vertex_coloring`` algorithm, that iterates through the
vertices once and selects the lowest-numbered color that the current
vertex can have. The coloring and the number of colors is therefore
related to the ordering of the vertices in the sequential case.
The distributed ``boman_et_al_graph_coloring`` algorithm will produce
different colorings depending on the ordering and distribution of the
vertices and the number of parallel processes cooperating to perform
the coloring.
The algorithm returns the number of colors ``num_colors`` used to
color the graph.
.. contents::
Where Defined
~~~~~~~~~~~~~
<``boost/graph/distributed/boman_et_al_graph_coloring.hpp``>
Parameters
~~~~~~~~~~
IN: ``Graph& g``
The graph type must be a model of `Distributed Vertex List Graph`_ and
`Distributed Edge List Graph`_.
UTIL/OUT: ``ColorMap color``
Stores the color of each vertex, which will be a value in the range
[0, ``num_colors``). The type ``ColorMap`` must model the
`Read/Write Property Map`_ concept and must be a `distributed
property map`_.
IN: ``vertices_size_type s``
The number of vertices to color within each superstep. After
``s`` vertices have been colored, the colors of boundary vertices
will be sent to their out-of-process neighbors. Smaller values
communicate more often but may reduce the risk of conflicts,
whereas larger values do more work in between communication steps
but may create many conflicts.
**Default**: 100
IN: ``ChooseColor choose_color``
A function object that chooses the color for a vertex given the
colors of its neighbors. The function object will be passed a vector
of values (``marked``) and a ``marked_true`` value, and should
return a ``color`` value such that ``color >= marked.size()`` or
``marked[color] != marked_true``.
**Default**:
``boost::graph::distributed::first_fit_color<color_type>()``, where
``color_type`` is the value type of the ``ColorMap`` property map.
IN: ``VertexOrdering ordering``
A binary predicate function object that provides total ordering on
the vertices in the graph. Whenever a conflict arises, only one of
the processes involved will recolor the vertex in the next round,
and this ordering determines which vertex should be considered
conflicting (its owning process will then handle the
conflict). Ideally, this predicate should order vertices so that
conflicting vertices will be spread uniformly across
processes. However, this predicate *must* resolve the same way on
both processors.
**Default**: *unspecified*
IN: ``VertexIndexMap index``
A mapping from vertex descriptors to indices in the range *[0,
num_vertices(g))*. This must be a `Readable Property Map`_ whose
key type is a vertex descriptor and whose value type is an integral
type, typically the ``vertices_size_type`` of the graph.
**Default:** ``get(vertex_index, g)``
Complexity
~~~~~~~~~~
The complexity of this algorithm is hard to characterize,
because it depends greatly on the number of *conflicts* that occur
during the algorithm. A conflict occurs when a *boundary vertex*
(i.e., a vertex that is adjacent to a vertex stored on a different
processor) is given the same color is a boundary vertex adjacency to
it (but on another processor). Conflicting vertices must be assigned
new colors, requiring additional work and communication. The work
involved in reassigning a color for a conflicting vertex is *O(d)*,
where *d* is the degree of the vertex and *O(1)* messages of *O(1)*
size are needed to resolve the conflict. Note that the number of
conflicts grows with (1) the number of processes and (2) the number
of inter-process edges.
Performance
~~~~~~~~~~~
The performance of this implementation of Bomen et al's graph coloring
algorithm is illustrated by the following charts. Scaling and
performance is reasonable for all of the graphs we have tried.
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&cluster=Odin&columns=11
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&cluster=Odin&columns=11&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&cluster=Odin&columns=11
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&cluster=Odin&columns=11&speedup=1
-----------------------------------------------------------------------------
Copyright (C) 2005 The Trustees of Indiana University.
Authors: Douglas Gregor and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _Distributed Vertex List Graph: DistributedVertexListGraph.html
.. _Distributed Edge List Graph: DistributedEdgeListGraph.html
.. _Distributed property map: distributed_property_map.html
.. _Readable Property Map: http://www.boost.org/libs/property_map/ReadablePropertyMap.html
.. _Read/Write Property Map: http://www.boost.org/libs/property_map/ReadWritePropertyMap.html
.. [BBC05] Erik G. Boman, Doruk Bozdag, Umit Catalyurek, Assefaw
H. Gebremedhin, and Fredrik Manne. A Scalable Parallel Graph Coloring
Algorithm for Distributed Memory Computers. [preprint]

View File

@@ -0,0 +1,278 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
===========================
|Logo| Breadth-First Search
===========================
::
// named parameter version
template <class Graph, class P, class T, class R>
void breadth_first_search(Graph& G,
typename graph_traits<Graph>::vertex_descriptor s,
const bgl_named_params<P, T, R>& params);
// non-named parameter version
template <class Graph, class Buffer, class BFSVisitor,
class ColorMap>
void breadth_first_search(const Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
Buffer& Q, BFSVisitor vis, ColorMap color);
The ``breadth_first_search()`` function performs a distributed breadth-first
traversal of a directed or undirected graph. The distributed BFS is
syntactically equivalent to its `sequential counterpart`_, which
provides additional background and discussion. Differences in
semantics are highlighted here, and we refer the reader to the
documentation of the `sequential breadth-first search`_ for the
remainder of the details.
This distributed breadth-first search algorithm implements a
*level-synchronized* breadth-first search, meaning that all vertices
in a given level of the BFS tree will be processed (potentially in
parallel) before any vertices from a successive level in the tree are
processed. Distributed breadth-first search visitors should account
for this behavior, a topic discussed further in `Visitor Event
Points`_.
.. contents::
Where Defined
-------------
<``boost/graph/breadth_first_search.hpp``>
Parameter Defaults
------------------
All parameters of the `sequential breadth-first search`_ are supported
and have essentially the same meaning. Only differences are documented
here.
IN: ``Graph& g``
The graph type must be a model of `Distributed Graph`_.
IN: ``vertex_descriptor s``
The start vertex must be the same in every process.
IN: ``visitor(BFSVisitor vis)``
The visitor must be a distributed BFS visitor. The suble differences
between sequential and distributed BFS visitors are discussed in the
section `Visitor Event Points`_.
UTIL/OUT: ``color_map(ColorMap color)``
The color map must be a `Distributed Property Map`_ with the same
process group as the graph ``g`` whose colors must monotonically
darken (white -> gray -> black). The default value is a distributed
``iterator_property_map`` created from a ``std::vector`` of
``default_color_type``.
UTIL: ``buffer(Buffer& Q)``
The queue must be a distributed queue that passes vertices to their
owning process. If already-visited vertices should not be visited
again (as is typical for BFS), the queue must filter duplicates
itself. The queue controls synchronization within the algorithm: its
``empty()`` method must not return ``true`` until all local queues
are empty.
**Default:** A ``distributed_queue`` of a ``filtered_queue`` over a
standard ``boost::queue``. This queue filters out duplicate
vertices and distributes vertices appropriately.
Complexity
----------
This algorithm performs *O(V + E)* work in *d + 1* BSP supersteps,
where *d* is the diameter of the connected component being
searched. Over all supersteps, *O(E)* messages of constant size will
be transmitted.
Visitor Event Points
--------------------
The `BFS Visitor`_ concept defines 9 event points that will be
triggered by the `sequential breadth-first search`_. The distributed
BFS retains these nine event points, but the sequence of events
triggered and the process in which each event occurs will change
depending on the distribution of the graph.
``initialize_vertex(s, g)``
This will be invoked by every process for each local vertex.
``discover_vertex(u, g)``
This will be invoked each time a process discovers a new vertex
``u``. Due to incomplete information in distributed property maps,
this event may be triggered many times for the same vertex ``u``.
``examine_vertex(u, g)``
This will be invoked by the process owning the vertex ``u``. If the
distributed queue prevents duplicates, it will be invoked only
once for a particular vertex ``u``.
``examine_edge(e, g)``
This will be invoked by the process owning the source vertex of
``e``. If the distributed queue prevents duplicates, it will be
invoked only once for a particular edge ``e``.
``tree_edge(e, g)``
Similar to ``examine_edge``, this will be invoked by the process
owning the source vertex and may be invoked only once. Unlike the
sequential BFS, this event may be triggered even when the target has
already been discovered (but by a different process). Thus, some
``non_tree_edge`` events in a sequential BFS may become
``tree_edge`` in a distributed BFS.
``non_tree_edge(e, g)``
Some ``non_tree_edge`` events in a sequential BFS may become
``tree_edge`` events in a distributed BFS. See the description of
``tree_edge`` for additional details.
``gray_target(e, g)``
As with ``tree_edge`` not knowing when another process has already
discovered a vertex, ``gray_target`` events may occur in a
distributed BFS when ``black_target`` events may occur in a
sequential BFS, due to a lack of information on a given
processor. The source of edge ``e`` will be local to the process
executing this event.
``black_target(e, g)``
See documentation for ``gray_target``
``finish_vertex(e, g)``
See documentation for ``examine_vertex``.
Making Visitors Safe for Distributed BFS
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The three most important things to remember when updating an existing
BFS visitor for distributed BFS or writing a new distributed BFS
visitor are:
1. Be sure that all state is either entirely local or in a
distributed data structure (most likely a property map!) using
the same process group as the graph.
2. Be sure that the visitor doesn't require precise event sequences
that cannot be guaranteed by distributed BFS, e.g., requiring
``tree_edge`` and ``non_tree_edge`` events to be completely
distinct.
3. Be sure that the visitor can operate on incomplete
information. This often includes using an appropriate reduction
operation in a `distributed property map`_ and verifying that
results written are "better" that what was previously written.
Distributed BFS Visitor Example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To illustrate the differences between sequential and distributed BFS
visitors, we consider a BFS visitor that places the distance from the
source vertex to every other vertex in a property map. The sequential
visitor is very simple::
template<typename DistanceMap>
struct bfs_discovery_visitor : bfs_visitor<>
{
bfs_discovery_visitor(DistanceMap distance) : distance(distance) {}
template<typename Edge, typename Graph>
void tree_edge(Edge e, const Graph& g)
{
std::size_t new_distance = get(distance, source(e, g)) + 1;
put(distance, target(e, g), new_distance);
}
private:
DistanceMap distance;
};
To revisit this code for distributed BFS, we consider the three points
in the section `Making Visitors Safe for Distributed BFS`_:
1. The distance map will need to become distributed, because the
distance to each vertex should be stored in the process owning the
vertex. This is actually a requirement on the user to provide such
a distributed property map, although in many cases the property map
will automatically be distributed and no syntactic changes will be
required.
2. This visitor *does* require a precise sequence of events that may
change with a distributed BFS. The extraneous ``tree_edge`` events
that may occur could result in attempts to put distances into the
distance map multiple times for a single vertex. We therefore need
to consider bullet #3.
3. Since multiple distance values may be written for each vertex, we
must always choose the best value we can find to update the
distance map. The distributed property map ``distance`` needs to
resolve distances to the smallest distance it has seen. For
instance, process 0 may find vertex ``u`` at level 3 but process 1
finds it at level 5: the distance must remain at 3. To do this, we
state that the property map's *role* is as a distance map, which
introduces an appropriate reduction operation::
set_property_map_role(vertex_distance, distance);
The resulting distributed BFS visitor (which also applies, with no
changes, in the sequential BFS) is very similar to our original
sequential BFS visitor. Note the single-line difference in the
constructor::
template<typename DistanceMap>
struct bfs_discovery_visitor : bfs_visitor<>
{
bfs_discovery_visitor(DistanceMap distance) : distance(distance)
{
set_property_map_role(vertex_distance, distance);
}
template<typename Edge, typename Graph>
void tree_edge(Edge e, const Graph& g)
{
std::size_t new_distance = get(distance, source(e, g)) + 1;
put(distance, target(e, g), new_distance);
}
private:
DistanceMap distance;
};
Performance
-----------
The performance of Breadth-First Search is illustrated by the
following charts. Scaling and performance is reasonable for all of the
graphs we have tried.
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&columns=4
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&columns=4&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&columns=4
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&columns=4&speedup=1
-----------------------------------------------------------------------------
Copyright (C) 2004 The Trustees of Indiana University.
Authors: Douglas Gregor and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _sequential counterpart: http://www.boost.org/libs/graph/doc/breadth_first_search.html
.. _sequential breadth-first search: http://www.boost.org/libs/graph/doc/breadth_first_search.html
.. _Distributed Graph: DistributedGraph.html
.. _Distributed Property Map: distributed_property_map.html
.. _BFS Visitor: http://www.boost.org/libs/graph/doc/BFSVisitor.html

View File

@@ -0,0 +1,147 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
===========================
|Logo| Connected Components
===========================
::
namespace graph {
// Default constructed ParentMap
template<typename Graph, typename ComponentMap, typename ParentMap>
typename property_traits<ComponentMap>::value_type
connected_components( const Graph& g, ComponentMap c);
// User supplied ParentMap
template<typename Graph, typename ComponentMap, typename ParentMap>
typename property_traits<ComponentMap>::value_type
connected_components( const Graph& g, ComponentMap c, ParentMap p);
}
The ``connected_components()`` function computes the connected
components of an undirected graph. The distributed connected
components algorithm uses the sequential version of the connected
components algorithm to compute the connected components of the local
subgraph, then executes the parallel phase of the algorithm. The
parallel portion of the connected components algorithm is loosely
based on the work of Goddard, Kumar, and Prins. The interface is a
superset of the interface to the BGL `sequential connected
components`_ algorithm.
Prior to executing the sequential phase of the algorithm, each process
identifies the roots of its local components. An adjacency list of
all vertices adjacent to members of the component is then constructed
at the root vertex of each component.
The parallel phase of the distributed connected components algorithm
consists of a series of supersteps. In each superstep, each root
attempts to hook to a member of it's adjacency list by assigning it's
parent pointer to that vertex. Hooking is restricted to vertices
which are logically less than the current vertex to prevent looping.
Vertices which hook successfully are removed from the list of roots
and placed on another list of completed vertices. All completed
vertices now execute a pointer jumping step until every completed
vertex has as its parent the root of a component. This pointer
jumping step may be further optimized by the addition of Cycle
Reduction (CR) rules developed by Johnson and Metaxas, however current
performance evaluations indicate that this would have a negligible
impact on the overall performance of the algorithm. These CR rules
reduce the number of pointer jumping steps from *O(n)* to *O(log n)*.
Following this pointer jumping step, roots which have hooked in this
phase transmit their adjacency list to their new parent. The
remaining roots receive these edges and execute a pruning step on
their adjacency lists to remove vertices that are now members of their
component. The parallel phase of the algorithm is complete when no
root successfully hooks. Once the parallel phase is complete a final
pointer jumping step is performed on all vertices to assign the parent
pointers of the leaves of the initial local subgraph components to
their final parent which has now been determined.
The single largest performance bottleneck in the distributed connected
components algorithm is the effect of poor vertex distribution on the
algorithm. For sparse graphs with a single large component, many
roots may hook to the same component, resulting in severe load
imbalance at the process owning this component. Several methods of
modifying the hooking strategy to avoid this behavior have been
implemented but none has been successful as of yet.
.. contents::
Where Defined
-------------
<``boost/graph/connected_components.hpp``>
Parameters
----------
IN: ``Graph& g``
The graph typed must be a model of `Distributed Graph`_.
OUT: ``ComponentMap c``
The algorithm computes how many connected components are in the
graph, and assigns each component an integer label. The algorithm
then records to which component each vertex in the graph belongs by
recording the component number in the component property map. The
``ComponentMap`` type must be a `Distributed Property Map`_. The
value type must be the ``vertices_size_type`` of the graph. The key
type must be the graph's vertex descriptor type. If you do not wish
to compute component numbers, pass ``dummy_property_map`` as the
component map and parent information will be provided in the parent
map.
UTIL: ``ParentMap p``
A parent map may be supplied to the algorithm, if not supplied the
parent map will be constructed automatically. The ``ParentMap`` type
must be a `Distributed Property Map`_. The value type and key type
must be the graph's vertex descriptor type.
OUT: ``property_traits<ComponentMap>::value_type``
The number of components found will be returned as the value type of
the component map.
Complexity
----------
The local phase of the algorithm is *O(V + E)*. The parallel phase of
the algorithm requires at most *O(d)* supersteps where *d* is the
number of initial roots. *d* is at most *O(V)* but becomes
significantly smaller as *E* increases. The pointer jumping phase
within each superstep requires at most *O(c)* steps on each of the
completed roots where *c* is the length of the longest cycle.
Application of CR rules can reduce this to *O(log c)*.
Performance
-----------
The following charts illustrate the performance of the Parallel BGL
connected components algorithm. It performs well on very sparse and
very dense graphs. However, for cases where the graph has a medium
density with a giant connected component, the algorithm will perform
poorly. This is a known problem with the algorithm and as far as we
know all implemented algorithms have this degenerate behavior.
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&columns=9
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&columns=9&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&columns=9
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&columns=9&speedup=1
-----------------------------------------------------------------------------
Copyright (C) 2004 The Trustees of Indiana University.
Authors: Nick Edmonds, Douglas Gregor, and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _Sequential connected components: http://www.boost.org/libs/graph/doc/connected_components.html
.. _Distributed Graph: DistributedGraph.html
.. _Distributed Property Map: distributed_property_map.html

View File

@@ -0,0 +1,88 @@
.. Copyright (C) 2004-2009 The Trustees of Indiana University.
Use, modification and distribution is 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)
===========================================
|Logo| Connected Components Parallel Search
===========================================
::
namespace graph { namespace distributed {
template<typename Graph, typename ComponentMap>
typename property_traits<ComponentMap>::value_type
connected_components_ps(const Graph& g, ComponentMap c)
} }
The ``connected_components_ps()`` function computes the connected
components of a graph by performing a breadth-first search from
several sources in parallel while recording and eventually resolving
the collisions.
.. contents::
Where Defined
-------------
<``boost/graph/distributed/connected_components_parallel_search.hpp``>
Parameters
----------
IN: ``const Graph& g``
The graph type must be a model of `Distributed Graph`_. The graph
type must also model the `Incidence Graph`_ and be directed.
OUT: ``ComponentMap c``
The algorithm computes how many connected components are in the
graph, and assigns each component an integer label. The algorithm
then records to which component each vertex in the graph belongs by
recording the component number in the component property map. The
``ComponentMap`` type must be a `Distributed Property Map`_. The
value type must be the ``vertices_size_type`` of the graph. The key
type must be the graph's vertex descriptor type.
Complexity
----------
*O(PN^2 + VNP)* work, in *O(N + V)* time, where N is the
number of mappings and V is the number of local vertices.
Algorithm Description
---------------------
Every *N* th nodes starts a parallel search from the first vertex in
their local vertex list during the first superstep (the other nodes
remain idle during the first superstep to reduce the number of
conflicts in numbering the components). At each superstep, all new
component mappings from remote nodes are handled. If there is no work
from remote updates, a new vertex is removed from the local list and
added to the work queue.
Components are allocated from the ``component_value_allocator``
object, which ensures that a given component number is unique in the
system, currently by using the rank and number of processes to stride
allocations.
When two components are discovered to actually be the same component,
a collision is recorded. The lower component number is prefered in
the resolution, so component numbering resolution is consistent.
After the search has exhausted all vertices in the graph, the mapping
is shared with all processes and they independently resolve the
comonent mapping. This phase can likely be significantly sped up if a
clever algorithm for the reduction can be found.
-----------------------------------------------------------------------------
Copyright (C) 2009 The Trustees of Indiana University.
Authors: Brian Barrett, Douglas Gregor, and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _Distributed Graph: DistributedGraph.html
.. _Distributed Property Map: distributed_property_map.html
.. _Incidence Graph: http://www.boost.org/libs/graph/doc/IncidenceGraph.html

View File

@@ -0,0 +1,423 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
============================
|Logo| Minimum Spanning Tree
============================
The Parallel BGL contains four `minimum spanning tree`_ (MST)
algorithms [DG98]_ for use on undirected, weighted, distributed
graphs. The graphs need not be connected: each algorithm will compute
a minimum spanning forest (MSF) when provided with a disconnected
graph.
The interface to each of the four algorithms is similar to the
implementation of 'Kruskal's algorithm'_ in the sequential BGL. Each
accepts, at a minimum, a graph, a weight map, and an output
iterator. The edges of the MST (or MSF) will be output via the output
iterator on process 0: other processes may receive edges on their
output iterators, but the set may not be complete, depending on the
algorithm. The algorithm parameters are documented together, because
they do not vary greatly. See the section `Selecting an MST
algorithm`_ for advice on algorithm selection.
The graph itself must model the `Vertex List Graph`_ concept and the
Distributed Edge List Graph concept. Since the most common
distributed graph structure, the `distributed adjacency list`_, only
models the Distributed Vertex List Graph concept, it may only be used
with these algorithms when wrapped in a suitable adaptor, such as the
`vertex_list_adaptor`_.
.. contents::
Where Defined
-------------
<``boost/graph/distributed/dehne_gotz_min_spanning_tree.hpp``>
Parameters
----------
IN: ``Graph& g``
The graph type must be a model of `Vertex List Graph`_ and
`Distributed Edge List Graph`_.
IN/OUT: ``WeightMap weight``
The weight map must be a `Distributed Property Map`_ and a `Readable
Property Map`_ whose key type is the edge descriptor of the graph
and whose value type is numerical.
IN/OUT: ``OutputIterator out``
The output iterator through which the edges of the MSF will be
written. Must be capable of accepting edge descriptors for output.
IN: ``VertexIndexMap index``
A mapping from vertex descriptors to indices in the range *[0,
num_vertices(g))*. This must be a `Readable Property Map`_ whose
key type is a vertex descriptor and whose value type is an integral
type, typically the ``vertices_size_type`` of the graph.
**Default:** ``get(vertex_index, g)``
IN/UTIL: ``RankMap rank_map``
Stores the rank of each vertex, which is used for maintaining
union-find data structures. This must be a `Read/Write Property Map`_
whose key type is a vertex descriptor and whose value type is an
integral type.
**Default:** An ``iterator_property_map`` built from an STL vector
of the ``vertices_size_type`` of the graph and the vertex index map.
IN/UTIL: ``ParentMap parent_map``
Stores the parent (representative) of each vertex, which is used for
maintaining union-find data structures. This must be a `Read/Write
Property Map`_ whose key type is a vertex descriptor and whose value
type is also a vertex descriptor.
**Default:** An ``iterator_property_map`` built from an STL vector
of the ``vertex_descriptor`` of the graph and the vertex index map.
IN/UTIL: ``SupervertexMap supervertex_map``
Stores the supervertex index of each vertex, which is used for
maintaining the supervertex list data structures. This must be a
`Read/Write Property Map`_ whose key type is a vertex descriptor and
whose value type is an integral type.
**Default:** An ``iterator_property_map`` built from an STL vector
of the ``vertices_size_type`` of the graph and the vertex index map.
``dense_boruvka_minimum_spanning_tree``
---------------------------------------
::
namespace graph {
template<typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndexMap, typename RankMap, typename ParentMap,
typename SupervertexMap>
OutputIterator
dense_boruvka_minimum_spanning_tree(const Graph& g, WeightMap weight_map,
OutputIterator out,
VertexIndexMap index,
RankMap rank_map, ParentMap parent_map,
SupervertexMap supervertex_map);
template<typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndex>
OutputIterator
dense_boruvka_minimum_spanning_tree(const Graph& g, WeightMap weight_map,
OutputIterator out, VertexIndex index);
template<typename Graph, typename WeightMap, typename OutputIterator>
OutputIterator
dense_boruvka_minimum_spanning_tree(const Graph& g, WeightMap weight_map,
OutputIterator out);
}
Description
~~~~~~~~~~~
The dense Boruvka distributed minimum spanning tree algorithm is a
direct parallelization of the sequential MST algorithm by
Boruvka. The algorithm first creates a *supervertex* out of each
vertex. Then, in each iteration, it finds the smallest-weight edge
incident to each vertex, collapses supervertices along these edges,
and removals all self loops. The only difference between the
sequential and parallel algorithms is that the parallel algorithm
performs an all-reduce operation so that all processes have the
global minimum set of edges.
Unlike the other three algorithms, this algorithm emits the complete
list of edges in the minimum spanning forest via the output iterator
on all processes. It may therefore be more useful than the others
when parallelizing sequential BGL programs.
Complexity
~~~~~~~~~~
The distributed algorithm requires *O(log n)* BSP supersteps, each of
which requires *O(m/p + n)* time and *O(n)* communication per
process.
Performance
~~~~~~~~~~~
The following charts illustrate the performance of this algorithm on
various random graphs. We see that the algorithm scales well up to 64
or 128 processors, depending on the type of graph, for dense
graphs. However, for sparse graphs performance tapers off as the
number of processors surpases *m/n*, i.e., the average degree (which
is 30 for this graph). This behavior is expected from the algorithm.
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&columns=5
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&columns=5&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&columns=5
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&columns=5&speedup=1
``merge_local_minimum_spanning_trees``
--------------------------------------
::
namespace graph {
template<typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndexMap>
OutputIterator
merge_local_minimum_spanning_trees(const Graph& g, WeightMap weight,
OutputIterator out,
VertexIndexMap index);
template<typename Graph, typename WeightMap, typename OutputIterator>
inline OutputIterator
merge_local_minimum_spanning_trees(const Graph& g, WeightMap weight,
OutputIterator out);
}
Description
~~~~~~~~~~~
The merging local MSTs algorithm operates by computing minimum
spanning forests from the edges stored on each process. Then the
processes merge their edge lists along a tree. The child nodes cease
participating in the computation, but the parent nodes recompute MSFs
from the newly acquired edges. In the final round, the root of the
tree computes the global MSFs, having received candidate edges from
every other process via the tree.
Complexity
~~~~~~~~~~
This algorithm requires *O(log_D p)* BSP supersteps (where *D* is the
number of children in the tree, and is currently fixed at 3). Each
superstep requires *O((m/p) log (m/p) + n)* time and *O(m/p)*
communication per process.
Performance
~~~~~~~~~~~
The following charts illustrate the performance of this algorithm on
various random graphs. The algorithm only scales well for very dense
graphs, where most of the work is performed in the initial stage and
there is very little work in the later stages.
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&columns=6
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&columns=6&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&columns=6
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&columns=6&speedup=1
``boruvka_then_merge``
----------------------
::
namespace graph {
template<typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndexMap, typename RankMap, typename ParentMap,
typename SupervertexMap>
OutputIterator
boruvka_then_merge(const Graph& g, WeightMap weight, OutputIterator out,
VertexIndexMap index, RankMap rank_map,
ParentMap parent_map, SupervertexMap
supervertex_map);
template<typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndexMap>
inline OutputIterator
boruvka_then_merge(const Graph& g, WeightMap weight, OutputIterator out,
VertexIndexMap index);
template<typename Graph, typename WeightMap, typename OutputIterator>
inline OutputIterator
boruvka_then_merge(const Graph& g, WeightMap weight, OutputIterator out);
}
Description
~~~~~~~~~~~
This algorithm applies both Boruvka steps and local MSF merging steps
together to achieve better asymptotic performance than either
algorithm alone. It first executes Boruvka steps until only *n/(log_d
p)^2* supervertices remain, then completes the MSF computation by
performing local MSF merging on the remaining edges and
supervertices.
Complexity
~~~~~~~~~~
This algorithm requires *log_D p* + *log log_D p* BSP supersteps. The
time required by each superstep depends on the type of superstep
being performed; see the distributed Boruvka or merging local MSFS
algorithms for details.
Performance
~~~~~~~~~~~
The following charts illustrate the performance of this algorithm on
various random graphs. We see that the algorithm scales well up to 64
or 128 processors, depending on the type of graph, for dense
graphs. However, for sparse graphs performance tapers off as the
number of processors surpases *m/n*, i.e., the average degree (which
is 30 for this graph). This behavior is expected from the algorithm.
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&columns=7
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&columns=7&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&columns=7
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&columns=7&speedup=1
``boruvka_mixed_merge``
-----------------------
::
namespace {
template<typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndexMap, typename RankMap, typename ParentMap,
typename SupervertexMap>
OutputIterator
boruvka_mixed_merge(const Graph& g, WeightMap weight, OutputIterator out,
VertexIndexMap index, RankMap rank_map,
ParentMap parent_map, SupervertexMap
supervertex_map);
template<typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndexMap>
inline OutputIterator
boruvka_mixed_merge(const Graph& g, WeightMap weight, OutputIterator out,
VertexIndexMap index);
template<typename Graph, typename WeightMap, typename OutputIterator>
inline OutputIterator
boruvka_mixed_merge(const Graph& g, WeightMap weight, OutputIterator out);
}
Description
~~~~~~~~~~~
This algorithm applies both Boruvka steps and local MSF merging steps
together to achieve better asymptotic performance than either method
alone. In each iteration, the algorithm first performs a Boruvka step
and then merges the local MSFs computed based on the supervertex
graph.
Complexity
~~~~~~~~~~
This algorithm requires *log_D p* BSP supersteps. The
time required by each superstep depends on the type of superstep
being performed; see the distributed Boruvka or merging local MSFS
algorithms for details. However, the algorithm is
communication-optional (requiring *O(n)* communication overall) when
the graph is sufficiently dense, i.e., *m/n >= p*.
Performance
~~~~~~~~~~~
The following charts illustrate the performance of this algorithm on
various random graphs. We see that the algorithm scales well up to 64
or 128 processors, depending on the type of graph, for dense
graphs. However, for sparse graphs performance tapers off as the
number of processors surpases *m/n*, i.e., the average degree (which
is 30 for this graph). This behavior is expected from the algorithm.
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&columns=8
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeSparse&columns=8&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&columns=8
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER,SF,SW&dataset=TimeDense&columns=8&speedup=1
Selecting an MST algorithm
--------------------------
Dehne and Gotz reported [DG98]_ mixed results when evaluating these
four algorithms. No particular algorithm was clearly better than the
others in all cases. However, the asymptotically best algorithm
(``boruvka_mixed_merge``) seemed to perform more poorly in their tests
than the other merging-based algorithms. The following performance
charts illustrate the performance of these four minimum spanning tree
implementations.
Overall, ``dense_boruvka_minimum_spanning_tree`` gives the most
consistent performance and scalability for the graphs we
tested. Additionally, it may be more suitable for sequential programs
that are being parallelized, because it emits complete MSF edge lists
via the output iterators in every process.
Performance on Sparse Graphs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER&dataset=TimeSparse&columns=5,6,7,8
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER&dataset=TimeSparse&columns=5,6,7,8&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=SF&dataset=TimeSparse&columns=5,6,7,8
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=SF&dataset=TimeSparse&columns=5,6,7,8&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=SW&dataset=TimeSparse&columns=5,6,7,8
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=SW&dataset=TimeSparse&columns=5,6,7,8&speedup=1
Performance on Dense Graphs
~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER&dataset=TimeDense&columns=5,6,7,8
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=ER&dataset=TimeDense&columns=5,6,7,8&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=SF&dataset=TimeDense&columns=5,6,7,8
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=SF&dataset=TimeDense&columns=5,6,7,8&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=SW&dataset=TimeDense&columns=5,6,7,8
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?generator=SW&dataset=TimeDense&columns=5,6,7,8&speedup=1
-----------------------------------------------------------------------------
Copyright (C) 2004 The Trustees of Indiana University.
Authors: Douglas Gregor and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _minimum spanning tree: http://www.boost.org/libs/graph/doc/graph_theory_review.html#sec:minimum-spanning-tree
.. _Kruskal's algorithm: http://www.boost.org/libs/graph/doc/kruskal_min_spanning_tree.html
.. _Vertex list graph: http://www.boost.org/libs/graph/doc/VertexListGraph.html
.. _distributed adjacency list: distributed_adjacency_list.html
.. _vertex_list_adaptor: vertex_list_adaptor.html
.. _Distributed Edge List Graph: DistributedEdgeListGraph.html
.. _Distributed property map: distributed_property_map.html
.. _Readable Property Map: http://www.boost.org/libs/property_map/ReadablePropertyMap.html
.. _Read/Write Property Map: http://www.boost.org/libs/property_map/ReadWritePropertyMap.html
.. [DG98] Frank Dehne and Silvia Gotz. *Practical Parallel Algorithms
for Minimum Spanning Trees*. In Symposium on Reliable Distributed Systems,
pages 366--371, 1998.

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,164 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
=======================
Parallel Shortest Paths
=======================
To illustrate the use of the Parallel Boost Graph Library, we
illustrate the use of both the sequential and parallel BGL to find
the shortest paths from vertex A to every other vertex in the
following simple graph:
.. image:: ../dijkstra_seq_graph.png
With the sequential BGL_, the program to calculate shortest paths has
three stages. Readers familiar with the BGL may wish to skip ahead to
the section `Distributing the graph`_.
- `Define the graph type`_
- `Construct the graph`_
- `Invoke Dijkstra's algorithm`_
Define the graph type
~~~~~~~~~~~~~~~~~~~~~
For this problem we use an adjacency list representation of the graph,
using the BGL ``adjacency_list``_ class template. It will be a directed
graph (``directedS`` parameter ) whose vertices are stored in an
``std::vector`` (``vecS`` parameter) where the outgoing edges of each
vertex are stored in an ``std::list`` (``listS`` parameter). To each
of the edges we attach an integral weight.
::
typedef adjacency_list<listS, vecS, directedS,
no_property, // Vertex properties
property<edge_weight_t, int> // Edge properties
> graph_t;
typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor;
typedef graph_traits < graph_t >::edge_descriptor edge_descriptor;
Construct the graph
~~~~~~~~~~~~~~~~~~~
To build the graph, we declare an enumeration containing the node
names (for our own use) and create two arrays: the first,
``edge_array``, contains the source and target of each edge, whereas
the second, ``weights``, contains the integral weight of each
edge. We pass the contents of the arrays via pointers (used here as
iterators) to the graph constructor to build our graph:
::
typedef std::pair<int, int> Edge;
const int num_nodes = 5;
enum nodes { A, B, C, D, E };
char name[] = "ABCDE";
Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E),
Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B)
};
int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 };
int num_arcs = sizeof(edge_array) / sizeof(Edge);
graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
Invoke Dijkstra's algorithm
~~~~~~~~~~~~~~~~~~~~~~~~~~~
To invoke Dijkstra's algorithm, we need to first decide how we want
to receive the results of the algorithm, namely the distance to each
vertex and the predecessor of each vertex (allowing reconstruction of
the shortest paths themselves). In our case, we will create two
vectors, ``p`` for predecessors and ``d`` for distances.
Next, we determine our starting vertex ``s`` using the ``vertex``
operation on the ``adjacency_list``_ and call
``dijkstra_shortest_paths``_ with the graph ``g``, starting vertex
``s``, and two ``property maps``_ that instruct the algorithm to
store predecessors in the ``p`` vector and distances in the ``d``
vector. The algorithm automatically uses the edge weights stored
within the graph, although this capability can be overridden.
::
// Keeps track of the predecessor of each vertex
std::vector<vertex_descriptor> p(num_vertices(g));
// Keeps track of the distance to each vertex
std::vector<int> d(num_vertices(g));
vertex_descriptor s = vertex(A, g);
dijkstra_shortest_paths
(g, s,
predecessor_map(
make_iterator_property_map(p.begin(), get(vertex_index, g))).
distance_map(
make_iterator_property_map(d.begin(), get(vertex_index, g)))
);
Distributing the graph
~~~~~~~~~~~~~~~~~~~~~~
The prior computation is entirely sequential, with the graph stored
within a single address space. To distribute the graph across several
processors without a shared address space, we need to represent the
processors and communication among them and alter the graph type.
Processors and their interactions are abstracted via a *process
group*. In our case, we will use MPI_ for communication with
inter-processor messages sent immediately:
::
typedef mpi::process_group<mpi::immediateS> process_group_type;
Next, we instruct the ``adjacency_list`` template
to distribute the vertices of the graph across our process group,
storing the local vertices in an ``std::vector``::
typedef adjacency_list<listS,
distributedS<process_group_type, vecS>,
directedS,
no_property, // Vertex properties
property<edge_weight_t, int> // Edge properties
> graph_t;
typedef graph_traits < graph_t >::vertex_descriptor vertex_descriptor;
typedef graph_traits < graph_t >::edge_descriptor edge_descriptor;
Note that the only difference from the sequential BGL is the use of
the ``distributedS`` selector, which identifies a distributed
graph. The vertices of the graph will be distributed among the
various processors, and the processor that owns a vertex also stores
the edges outgoing from that vertex and any properties associated
with that vertex or its edges. With three processors and the default
block distribution, the graph would be distributed in this manner:
.. image:: ../dijkstra_dist3_graph.png
Processor 0 (red) owns vertices A and B, including all edges outoing
from those vertices, processor 1 (green) owns vertices C and D (and
their edges), and processor 2 (blue) owns vertex E. Constructing this
graph uses the same syntax is the sequential graph, as in the section
`Construct the graph`_.
The call to ``dijkstra_shortest_paths`` is syntactically equivalent to
the sequential call, but the mechanisms used are very different. The
property maps passed to ``dijkstra_shortest_paths`` are actually
*distributed* property maps, which store properties for local edges
or vertices and perform implicit communication to access properties
of remote edges or vertices when needed. The formulation of Dijkstra's
algorithm is also slightly different, because each processor can
only attempt to relax edges outgoing from local vertices: as shorter
paths to a vertex are discovered, messages to the processor owning
that vertex indicate that the vertex may require reprocessing.
----------------------------------------------------------------------
Return to the `Parallel BGL home page`_
.. _Parallel BGL home page: index.html
.. _dijkstra_shortest_paths: http://www.boost.org/libs/graph/doc/dijkstra_shortest_paths.html
.. _property maps: http://www.boost.org/libs/graph/doc/using_property_maps.html
.. _adjacency_list: http://www.boost.org/libs/graph/doc/adjacency_list.html
.. _MPI: http://www-unix.mcs.anl.gov/mpi/
.. _BGL: http://www.boost.org/libs/graph/doc

View File

@@ -0,0 +1,977 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CanvasColor</key>
<dict>
<key>a</key>
<string>1</string>
<key>w</key>
<string>1</string>
</dict>
<key>ColumnAlign</key>
<integer>0</integer>
<key>ColumnSpacing</key>
<real>3.600000e+01</real>
<key>GraphDocumentVersion</key>
<integer>2</integer>
<key>GraphicsList</key>
<array>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>ID</key>
<integer>13</integer>
<key>Labels</key>
<array>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\fs24 \cf0 1}</string>
</dict>
<key>LabelVisible</key>
<string>YES</string>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>6.324090e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>1.000000e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>9.000000e-01</real>
</dict>
</array>
<key>Points</key>
<array>
<string>{153, 216}</string>
<string>{225, 243}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>ID</key>
<integer>12</integer>
<key>Labels</key>
<array>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\fs24 \cf0 2}</string>
</dict>
<key>LabelVisible</key>
<string>YES</string>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>4.489754e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>1.000000e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>9.000000e-01</real>
</dict>
</array>
<key>Points</key>
<array>
<string>{234, 225}</string>
<string>{162, 198}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>1</integer>
</dict>
<key>ID</key>
<integer>11</integer>
<key>Labels</key>
<array>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\fs24 \cf0 1}</string>
</dict>
<key>LabelVisible</key>
<string>YES</string>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>5.430677e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>1.000000e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>9.000000e-01</real>
</dict>
</array>
<key>Points</key>
<array>
<string>{159.992, 187.764}</string>
<string>{263.031, 145.292}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>5</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>5</integer>
</dict>
<key>ID</key>
<integer>10</integer>
<key>Labels</key>
<array>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\fs24 \cf0 1}</string>
</dict>
<key>LabelVisible</key>
<string>YES</string>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>4.791616e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>1.000000e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>9.000000e-01</real>
</dict>
</array>
<key>Points</key>
<array>
<string>{164.147, 306.88}</string>
<string>{141.983, 224.086}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>4</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>4</integer>
</dict>
<key>ID</key>
<integer>9</integer>
<key>Labels</key>
<array>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\fs24 \cf0 3}</string>
</dict>
<key>LabelVisible</key>
<string>YES</string>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>4.960202e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>1.000000e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>9.000000e-01</real>
</dict>
</array>
<key>Points</key>
<array>
<string>{361.707, 261.466}</string>
<string>{196.286, 323.515}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>2</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>3</integer>
</dict>
<key>ID</key>
<integer>8</integer>
<key>Labels</key>
<array>
<dict>
<key>FixedWidth</key>
<real>1.455365e+01</real>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\fs24 \cf0 7}</string>
</dict>
<key>LabelVisible</key>
<string>YES</string>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>4.780268e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>1.000000e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>9.000000e-01</real>
</dict>
</array>
<key>Points</key>
<array>
<string>{360.059, 250.204}</string>
<string>{278.941, 244.796}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>2</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>4</integer>
</dict>
<key>ID</key>
<integer>7</integer>
<key>Labels</key>
<array>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\fs24 \cf0 1}</string>
</dict>
<key>LabelVisible</key>
<string>YES</string>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>5.246289e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>1.000000e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>9.000000e-01</real>
</dict>
</array>
<key>Points</key>
<array>
<string>{233.86, 262.999}</string>
<string>{189.04, 312.91}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>3</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>2</integer>
</dict>
<key>ID</key>
<integer>6</integer>
<key>Labels</key>
<array>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural
\f0\fs24 \cf0 1}</string>
</dict>
<key>LabelVisible</key>
<string>YES</string>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>4.966548e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>1.000000e-01</real>
</dict>
<dict>
<key>Label</key>
<dict>
<key>Align</key>
<integer>0</integer>
</dict>
<key>Offset</key>
<real>0.000000e+00</real>
<key>Position</key>
<real>9.000000e-01</real>
</dict>
</array>
<key>Points</key>
<array>
<string>{305.275, 155.753}</string>
<string>{369.523, 231.418}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>1</integer>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{108, 171}, {54, 54}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>5</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 E}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{144, 306}, {54, 54}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>4</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 D}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{225, 216}, {54, 54}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>3</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 B}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{360, 225}, {54, 54}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>2</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 C}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{261, 108}, {54, 54}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>1</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 A}</string>
</dict>
</dict>
</array>
<key>GridInfo</key>
<dict/>
<key>HPages</key>
<integer>1</integer>
<key>ImageCounter</key>
<integer>1</integer>
<key>IsPalette</key>
<string>NO</string>
<key>Layers</key>
<array>
<dict>
<key>Lock</key>
<string>NO</string>
<key>Name</key>
<string>Layer 1</string>
<key>Print</key>
<string>YES</string>
<key>View</key>
<string>YES</string>
</dict>
</array>
<key>LayoutInfo</key>
<dict>
<key>AutoAdjust</key>
<string>YES</string>
<key>MagneticFieldCenter</key>
<string>{0, 0}</string>
</dict>
<key>MagnetsEnabled</key>
<string>YES</string>
<key>PageBreakColor</key>
<dict>
<key>a</key>
<string>1</string>
<key>w</key>
<string>0.666667</string>
</dict>
<key>PageBreaks</key>
<string>YES</string>
<key>PageSetup</key>
<data>
BAt0eXBlZHN0cmVhbYED6IQBQISEhAtOU1ByaW50SW5mbwGEhAhOU09iamVjdACFkoSE
hBNOU011dGFibGVEaWN0aW9uYXJ5AISEDE5TRGljdGlvbmFyeQCUhAFpFJKEhIQITlNT
dHJpbmcBlIQBKxBOU0pvYkRpc3Bvc2l0aW9uhpKEmZkPTlNQcmludFNwb29sSm9ihpKE
mZkLTlNQYXBlclNpemWGkoSEhAdOU1ZhbHVlAJSEASqEhAx7X05TU2l6ZT1mZn2cgQJk
gQMYhpKEmZkZTlNQcmludFJldmVyc2VPcmllbnRhdGlvboaShISECE5TTnVtYmVyAJ2b
hIQBc54AhpKEmZkUTlNWZXJ0aWNhbFBhZ2luYXRpb26GkoShm6KeAIaShJmZFE5TVmVy
dGljYWxseUNlbnRlcmVkhpKEoZuingGGkoSZmQ5OU1BNUGFnZUZvcm1hdIaShISEBk5T
RGF0YQCUl4EjGYQHWzg5ODVjXTw/eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVU
Ri04Ij8+CjwhRE9DVFlQRSBwbGlzdCBQVUJMSUMgIi0vL0FwcGxlIENvbXB1dGVyLy9E
VEQgUExJU1QgMS4wLy9FTiIgImh0dHA6Ly93d3cuYXBwbGUuY29tL0RURHMvUHJvcGVy
dHlMaXN0LTEuMC5kdGQiPgo8cGxpc3QgdmVyc2lvbj0iMS4wIj4KPGRpY3Q+Cgk8a2V5
PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LkZvcm1hdHRpbmdQcmludGVyPC9rZXk+
Cgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5
PgoJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCTxr
ZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQk8YXJyYXk+
CgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5Gb3Jt
YXR0aW5nUHJpbnRlcjwva2V5PgoJCQkJPHN0cmluZz5wc2xhbTwvc3RyaW5nPgoJCQkJ
PGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVudDwva2V5PgoJCQkJPHN0cmlu
Zz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJCQk8a2V5PmNvbS5h
cHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJPGRhdGU+MjAwNC0wOC0x
M1QxNTo0ODoxM1o8L2RhdGU+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQu
c3RhdGVGbGFnPC9rZXk+CgkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQk8L2RpY3Q+
CgkJPC9hcnJheT4KCTwvZGljdD4KCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3Jt
YXQuUE1Ib3Jpem9udGFsUmVzPC9rZXk+Cgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5w
cmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50
aW5nbWFuYWdlcjwvc3RyaW5nPgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5p
dGVtQXJyYXk8L2tleT4KCQk8YXJyYXk+CgkJCTxkaWN0PgoJCQkJPGtleT5jb20uYXBw
bGUucHJpbnQuUGFnZUZvcm1hdC5QTUhvcml6b250YWxSZXM8L2tleT4KCQkJCTxyZWFs
PjcuMjAwMDAwMDAwMDAwMDAwZSswMTwvcmVhbD4KCQkJCTxrZXk+Y29tLmFwcGxlLnBy
aW50LnRpY2tldC5jbGllbnQ8L2tleT4KCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50
aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0
Lm1vZERhdGU8L2tleT4KCQkJCTxkYXRlPjIwMDQtMDgtMTNUMTU6NDg6MTNaPC9kYXRl
PgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJ
CQkJPGludGVnZXI+MDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk+Cgk8L2Rp
Y3Q+Cgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNT3JpZW50YXRpb248
L2tleT4KCTxkaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9y
PC9rZXk+CgkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+
CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxh
cnJheT4KCQkJPGRpY3Q+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0
LlBNT3JpZW50YXRpb248L2tleT4KCQkJCTxpbnRlZ2VyPjE8L2ludGVnZXI+CgkJCQk8
a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJCQk8c3RyaW5n
PmNvbS5hcHBsZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJCTxrZXk+Y29tLmFw
cGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQk8ZGF0ZT4yMDA0LTA4LTEz
VDE1OjQ4OjEzWjwvZGF0ZT4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5z
dGF0ZUZsYWc8L2tleT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCTwvZGljdD4K
CQk8L2FycmF5PgoJPC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1h
dC5QTVNjYWxpbmc8L2tleT4KCTxkaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRp
Y2tldC5jcmVhdG9yPC9rZXk+CgkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5h
Z2VyPC9zdHJpbmc+CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJh
eTwva2V5PgoJCTxhcnJheT4KCQkJPGRpY3Q+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmlu
dC5QYWdlRm9ybWF0LlBNU2NhbGluZzwva2V5PgoJCQkJPHJlYWw+MS4wMDAwMDAwMDAw
MDAwMDBlKzAwPC9yZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNs
aWVudDwva2V5PgoJCQkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9z
dHJpbmc+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5
PgoJCQkJPGRhdGU+MjAwNC0wOC0xM1QxNTo0ODoxM1o8L2RhdGU+CgkJCQk8a2V5PmNv
bS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQk8aW50ZWdlcj4w
PC9pbnRlZ2VyPgoJCQk8L2RpY3Q+CgkJPC9hcnJheT4KCTwvZGljdD4KCTxrZXk+Y29t
LmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1WZXJ0aWNhbFJlczwva2V5PgoJPGRpY3Q+
CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3Ry
aW5nPmNvbS5hcHBsZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4KCQk8a2V5PmNvbS5h
cHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJPGFycmF5PgoJCQk8ZGlj
dD4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1WZXJ0aWNhbFJl
czwva2V5PgoJCQkJPHJlYWw+Ny4yMDAwMDAwMDAwMDAwMDBlKzAxPC9yZWFsPgoJCQkJ
PGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVudDwva2V5PgoJCQkJPHN0cmlu
Zz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJCQk8a2V5PmNvbS5h
cHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJPGRhdGU+MjAwNC0wOC0x
M1QxNTo0ODoxM1o8L2RhdGU+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQu
c3RhdGVGbGFnPC9rZXk+CgkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQk8L2RpY3Q+
CgkJPC9hcnJheT4KCTwvZGljdD4KCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3Jt
YXQuUE1WZXJ0aWNhbFNjYWxpbmc8L2tleT4KCTxkaWN0PgoJCTxrZXk+Y29tLmFwcGxl
LnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJPHN0cmluZz5jb20uYXBwbGUucHJp
bnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0
Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJPGRpY3Q+CgkJCQk8a2V5PmNvbS5h
cHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxTY2FsaW5nPC9rZXk+CgkJCQk8
cmVhbD4xLjAwMDAwMDAwMDAwMDAwMGUrMDA8L3JlYWw+CgkJCQk8a2V5PmNvbS5hcHBs
ZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJCQk8c3RyaW5nPmNvbS5hcHBsZS5w
cmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRp
Y2tldC5tb2REYXRlPC9rZXk+CgkJCQk8ZGF0ZT4yMDA0LTA4LTEzVDE1OjQ4OjEzWjwv
ZGF0ZT4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tl
eT4KCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCTwvZGljdD4KCQk8L2FycmF5PgoJ
PC9kaWN0PgoJPGtleT5jb20uYXBwbGUucHJpbnQuc3ViVGlja2V0LnBhcGVyX2luZm9f
dGlja2V0PC9rZXk+Cgk8ZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9y
bWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5h
cHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBs
ZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQu
dGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk+CgkJCQk8ZGljdD4KCQkJCQk8
a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYWdlUmVjdDwv
a2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw+MC4wMDAwMDAwMDAwMDAwMDBlKzAw
PC9yZWFsPgoJCQkJCQk8cmVhbD4wLjAwMDAwMDAwMDAwMDAwMGUrMDA8L3JlYWw+CgkJ
CQkJCTxyZWFsPjcuNTQ4MDAwNDg4MjgxMjUwZSswMjwvcmVhbD4KCQkJCQkJPHJlYWw+
NS43ODgwMDA0ODgyODEyNTBlKzAyPC9yZWFsPgoJCQkJCTwvYXJyYXk+CgkJCQkJPGtl
eT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVudDwva2V5PgoJCQkJCTxzdHJpbmc+
Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQkJCTxrZXk+Y29tLmFw
cGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQkJPGRhdGU+MjAwNC0wOC0x
M1QxNTo0ODoxM1o8L2RhdGU+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0
LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+CgkJCQk8L2Rp
Y3Q+CgkJCTwvYXJyYXk+CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBh
Z2VGb3JtYXQuUE1BZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5
PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNv
bS5hcHBsZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUu
cHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk+CgkJCQk8ZGljdD4K
CQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYXBl
clJlY3Q8L2tleT4KCQkJCQk8YXJyYXk+CgkJCQkJCTxyZWFsPi0xLjg1OTk5NzU1ODU5
Mzc1MGUrMDE8L3JlYWw+CgkJCQkJCTxyZWFsPi0xLjY2MDAwMDAzODE0Njk3M2UrMDE8
L3JlYWw+CgkJCQkJCTxyZWFsPjcuNzM0MDAwMjQ0MTQwNjI1ZSswMjwvcmVhbD4KCQkJ
CQkJPHJlYWw+NS45NTQwMDAyNDQxNDA2MjVlKzAyPC9yZWFsPgoJCQkJCTwvYXJyYXk+
CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVudDwva2V5PgoJCQkJ
CTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQkJCTxr
ZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQkJPGRhdGU+
MjAwNC0wOC0xM1QxNTo0ODoxM1o8L2RhdGU+CgkJCQkJPGtleT5jb20uYXBwbGUucHJp
bnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjA8L2ludGVnZXI+
CgkJCQk8L2RpY3Q+CgkJCTwvYXJyYXk+CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFwcGxl
LnByaW50LlBhcGVySW5mby5QTUNvbnN0cmFpbmVkUGFwZXI8L2tleT4KCQk8ZGljdD4K
CQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0
cmluZz5DVVBTX0NQTDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNr
ZXQuaXRlbUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+
Y29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTUNvbnN0cmFpbmVkUGFwZXI8L2tleT4K
CQkJCQk8ZmFsc2UvPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jbGll
bnQ8L2tleT4KCQkJCQk8c3RyaW5nPkNVUFNfQ1BMPC9zdHJpbmc+CgkJCQkJPGtleT5j
b20uYXBwbGUucHJpbnQudGlja2V0Lm1vZERhdGU8L2tleT4KCQkJCQk8ZGF0ZT4yMDA0
LTA4LTEzVDE1OjQ4OjEyWjwvZGF0ZT4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50
aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQkJPGludGVnZXI+MTwvaW50ZWdlcj4KCQkJ
CTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJp
bnQuUGFwZXJJbmZvLlBNUGFwZXJOYW1lPC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29t
LmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Q1VQU19D
UEw8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJh
eTwva2V5PgoJCQk8YXJyYXk+CgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5w
cmludC5QYXBlckluZm8uUE1QYXBlck5hbWU8L2tleT4KCQkJCQk8c3RyaW5nPm5hLWxl
dHRlcjwvc3RyaW5nPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jbGll
bnQ8L2tleT4KCQkJCQk8c3RyaW5nPkNVUFNfQ1BMPC9zdHJpbmc+CgkJCQkJPGtleT5j
b20uYXBwbGUucHJpbnQudGlja2V0Lm1vZERhdGU8L2tleT4KCQkJCQk8ZGF0ZT4yMDA0
LTA4LTEzVDE1OjQ4OjEyWjwvZGF0ZT4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50
aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQkJPGludGVnZXI+MTwvaW50ZWdlcj4KCQkJ
CTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJp
bnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhZ2VSZWN0PC9rZXk+CgkJPGRpY3Q+CgkJ
CTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJCTxzdHJp
bmc+Q1VQU19DUEw8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0
Lml0ZW1BcnJheTwva2V5PgoJCQk8YXJyYXk+CgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNv
bS5hcHBsZS5wcmludC5QYXBlckluZm8uUE1VbmFkanVzdGVkUGFnZVJlY3Q8L2tleT4K
CQkJCQk8YXJyYXk+CgkJCQkJCTxyZWFsPjAuMDAwMDAwMDAwMDAwMDAwZSswMDwvcmVh
bD4KCQkJCQkJPHJlYWw+MC4wMDAwMDAwMDAwMDAwMDBlKzAwPC9yZWFsPgoJCQkJCQk8
cmVhbD43LjU0ODAwMDQ4ODI4MTI1MGUrMDI8L3JlYWw+CgkJCQkJCTxyZWFsPjUuNzg4
MDAwNDg4MjgxMjUwZSswMjwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk+Y29t
LmFwcGxlLnByaW50LnRpY2tldC5jbGllbnQ8L2tleT4KCQkJCQk8c3RyaW5nPmNvbS5h
cHBsZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5w
cmludC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJCTxkYXRlPjIwMDQtMDgtMTNUMTU6
NDg6MTNaPC9kYXRlPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0
ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJ
CQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlcklu
Zm8uUE1VbmFkanVzdGVkUGFwZXJSZWN0PC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29t
LmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Q1VQU19D
UEw8L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJh
eTwva2V5PgoJCQk8YXJyYXk+CgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5w
cmludC5QYXBlckluZm8uUE1VbmFkanVzdGVkUGFwZXJSZWN0PC9rZXk+CgkJCQkJPGFy
cmF5PgoJCQkJCQk8cmVhbD4tMS44NTk5OTc1NTg1OTM3NTBlKzAxPC9yZWFsPgoJCQkJ
CQk8cmVhbD4tMS42NjAwMDAwMzgxNDY5NzNlKzAxPC9yZWFsPgoJCQkJCQk8cmVhbD43
LjczNDAwMDI0NDE0MDYyNWUrMDI8L3JlYWw+CgkJCQkJCTxyZWFsPjUuOTU0MDAwMjQ0
MTQwNjI1ZSswMjwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk+Y29tLmFwcGxl
LnByaW50LnRpY2tldC5jbGllbnQ8L2tleT4KCQkJCQk8c3RyaW5nPmNvbS5hcHBsZS5w
cmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50
aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJCTxkYXRlPjIwMDQtMDgtMTNUMTU6NDg6MTNa
PC9kYXRlPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8
L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2Fy
cmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlckluZm8ucHBk
LlBNUGFwZXJOYW1lPC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29tLmFwcGxlLnByaW50
LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Q1VQU19DUEw8L3N0cmluZz4K
CQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8
YXJyYXk+CgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlcklu
Zm8ucHBkLlBNUGFwZXJOYW1lPC9rZXk+CgkJCQkJPHN0cmluZz5MZXR0ZXI8L3N0cmlu
Zz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJ
CQkJPHN0cmluZz5DVVBTX0NQTDwvc3RyaW5nPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnBy
aW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQkJPGRhdGU+MjAwNC0wOC0xM1QxNTo0
ODoxMlo8L2RhdGU+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRl
RmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjE8L2ludGVnZXI+CgkJCQk8L2RpY3Q+CgkJ
CTwvYXJyYXk+CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5B
UElWZXJzaW9uPC9rZXk+CgkJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJCTxrZXk+Y29t
LmFwcGxlLnByaW50LnRpY2tldC5wcml2YXRlTG9jazwva2V5PgoJCTxmYWxzZS8+CgkJ
PGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnR5cGU8L2tleT4KCQk8c3RyaW5nPmNv
bS5hcHBsZS5wcmludC5QYXBlckluZm9UaWNrZXQ8L3N0cmluZz4KCTwvZGljdD4KCTxr
ZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5BUElWZXJzaW9uPC9rZXk+Cgk8c3RyaW5n
PjAwLjIwPC9zdHJpbmc+Cgk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQucHJpdmF0
ZUxvY2s8L2tleT4KCTxmYWxzZS8+Cgk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQu
dHlwZTwva2V5PgoJPHN0cmluZz5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdFRpY2tl
dDwvc3RyaW5nPgo8L2RpY3Q+CjwvcGxpc3Q+CoaShJmZD05TUHJpbnRBbGxQYWdlc4aS
oJKEmZkLTlNQYXBlck5hbWWGkoSZmQZMZXR0ZXKGkoSZmRVOU0hvcml6b25hbFBhZ2lu
YXRpb26GkoShm6KeAIaShJmZFk5TSG9yaXpvbnRhbGx5Q2VudGVyZWSGkqaShJmZCU5T
UHJpbnRlcoaShISECU5TUHJpbnRlcgCUkoSZmQVwc2xhbYaGkoSZmQhOU0NvcGllc4aS
hKGbhIQBU6IBhpKEmZkPTlNTY2FsaW5nRmFjdG9yhpKEoZuEhAFmowGGkoSZmQ1OU1Jp
Z2h0TWFyZ2luhpKEoZu5oySGkoSZmQ5OU0JvdHRvbU1hcmdpboaShKGbuaMkhpKEmZkM
TlNMZWZ0TWFyZ2luhpKEoZu5oySGkoSZmQtOU1RvcE1hcmdpboaShKGbuaMkhpKEmZkK
TlNMYXN0UGFnZYaShKGbhJeXgn////+GkoSZmQtOU0ZpcnN0UGFnZYaShKGbtqIBhpKE
mZkNTlNPcmllbnRhdGlvboaShKGbop4AhoaG
</data>
<key>RowAlign</key>
<integer>0</integer>
<key>RowSpacing</key>
<real>3.600000e+01</real>
<key>VPages</key>
<integer>1</integer>
<key>WindowInfo</key>
<dict>
<key>Frame</key>
<string>{{724, 272}, {555, 797}}</string>
<key>VisibleRegion</key>
<string>{{0, 0}, {540, 720}}</string>
<key>Zoom</key>
<string>1</string>
</dict>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

@@ -0,0 +1,408 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
==============================================
|Logo| Dijkstra's Single-Source Shortest Paths
==============================================
::
// named parameter version
template <typename Graph, typename P, typename T, typename R>
void
dijkstra_shortest_paths(Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
const bgl_named_params<P, T, R>& params);
// non-named parameter version
template <typename Graph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap,
typename WeightMap, typename VertexIndexMap, typename CompareFunction, typename CombineFunction,
typename DistInf, typename DistZero>
void dijkstra_shortest_paths
(const Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
VertexIndexMap index_map,
CompareFunction compare, CombineFunction combine, DistInf inf, DistZero zero,
DijkstraVisitor vis);
The ``dijkstra_shortest_paths()`` function solves the single-source
shortest paths problem on a weighted, undirected or directed
distributed graph. There are two implementations of distributed
Dijkstra's algorithm, which offer different performance
tradeoffs. Both are accessible via the ``dijkstra_shortest_paths()``
function (for compatibility with sequential BGL programs). The
distributed Dijkstra algorithms are very similar to their sequential
counterparts. Only the differences are highlighted here; please refer
to the `sequential Dijkstra implementation`_ for additional
details. The best-performing implementation for most cases is the
`Delta-Stepping algorithm`_; however, one can also employ the more
conservative `Crauser et al.'s algorithm`_ or the simlistic `Eager
Dijkstra's algorithm`_.
.. contents::
Where Defined
-------------
<``boost/graph/dijkstra_shortest_paths.hpp``>
Parameters
----------
All parameters of the `sequential Dijkstra implementation`_ are
supported and have essentially the same meaning. The distributed
Dijkstra implementations introduce a new parameter that allows one to
select `Eager Dijkstra's algorithm`_ and control the amount of work it
performs. Only differences and new parameters are documented here.
IN: ``Graph& g``
The graph type must be a model of `Distributed Graph`_.
IN: ``vertex_descriptor s``
The start vertex must be the same in every process.
OUT: ``predecessor_map(PredecessorMap p_map)``
The predecessor map must be a `Distributed Property Map`_ or
``dummy_property_map``, although only the local portions of the map
will be written.
**Default:** ``dummy_property_map``
UTIL/OUT: ``distance_map(DistanceMap d_map)``
The distance map must be either a `Distributed Property Map`_ or
``dummy_property_map``. It will be given the ``vertex_distance``
role.
IN: ``visitor(DijkstraVisitor vis)``
The visitor must be a distributed Dijkstra visitor. The suble differences
between sequential and distributed Dijkstra visitors are discussed in the
section `Visitor Event Points`_.
UTIL/OUT: ``color_map(ColorMap color)``
The color map must be a `Distributed Property Map`_ with the same
process group as the graph ``g`` whose colors must monotonically
darken (white -> gray -> black). The default value is a distributed
``iterator_property_map`` created from a ``std::vector`` of
``default_color_type``.
IN: ``lookahead(distance_type look)``
When this parameter is supplied, the implementation will use the
`Eager Dijkstra's algorithm`_ with the given lookahead value.
Lookahead permits distributed Dijkstra's algorithm to speculatively
process vertices whose shortest distance from the source may not
have been found yet. When the distance found is the shortest
distance, parallelism is improved and the algorithm may terminate
more quickly. However, if the distance is not the shortest distance,
the vertex will need to be reprocessed later, resulting in more
work.
The type ``distance_type`` is the value type of the ``DistanceMap``
property map. It is a nonnegative value specifying how far ahead
Dijkstra's algorithm may process values.
**Default:** no value (lookahead is not employed; uses `Crauser et
al.'s algorithm`_).
Visitor Event Points
--------------------
The `Dijkstra Visitor`_ concept defines 7 event points that will be
triggered by the `sequential Dijkstra implementation`_. The distributed
Dijkstra retains these event points, but the sequence of events
triggered and the process in which each event occurs will change
depending on the distribution of the graph, lookahead, and edge
weights.
``initialize_vertex(s, g)``
This will be invoked by every process for each local vertex.
``discover_vertex(u, g)``
This will be invoked each type a process discovers a new vertex
``u``. Due to incomplete information in distributed property maps,
this event may be triggered many times for the same vertex ``u``.
``examine_vertex(u, g)``
This will be invoked by the process owning the vertex ``u``. This
event may be invoked multiple times for the same vertex when the
graph contains negative edges or lookahead is employed.
``examine_edge(e, g)``
This will be invoked by the process owning the source vertex of
``e``. As with ``examine_vertex``, this event may be invoked
multiple times for the same edge.
``edge_relaxed(e, g)``
Similar to ``examine_edge``, this will be invoked by the process
owning the source vertex and may be invoked multiple times (even
without lookahead or negative edges).
``edge_not_relaxed(e, g)``
Similar to ``edge_relaxed``. Some ``edge_not_relaxed`` events that
would be triggered by sequential Dijkstra's will become
``edge_relaxed`` events in distributed Dijkstra's algorithm.
``finish_vertex(e, g)``
See documentation for ``examine_vertex``. Note that a "finished"
vertex is not necessarily finished if lookahead is permitted or
negative edges exist in the graph.
Crauser et al.'s algorithm
--------------------------
::
namespace graph {
template<typename DistributedGraph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap, typename WeightMap,
typename IndexMap, typename ColorMap, typename Compare,
typename Combine, typename DistInf, typename DistZero>
void
crauser_et_al_shortest_paths
(const DistributedGraph& g,
typename graph_traits<DistributedGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map, ColorMap color_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis);
template<typename DistributedGraph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap, typename WeightMap>
void
crauser_et_al_shortest_paths
(const DistributedGraph& g,
typename graph_traits<DistributedGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight);
template<typename DistributedGraph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap>
void
crauser_et_al_shortest_paths
(const DistributedGraph& g,
typename graph_traits<DistributedGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance);
}
The formulation of Dijkstra's algorithm by Crauser, Mehlhorn, Meyer,
and Sanders [CMMS98a]_ improves the scalability of parallel Dijkstra's
algorithm by increasing the number of vertices that can be processed
in a given superstep. This algorithm adapts well to various graph
types, and is a simple algorithm to use, requiring no additional user
input to achieve reasonable performance. The disadvantage of this
algorithm is that the implementation is required to manage three
priority queues, which creates a large amount of work at each node.
This algorithm is used by default in distributed
``dijkstra_shortest_paths()``.
Where Defined
~~~~~~~~~~~~~
<``boost/graph/distributed/crauser_et_al_shortest_paths.hpp``>
Complexity
~~~~~~~~~~
This algorithm performs *O(V log V)* work in *d + 1* BSP supersteps,
where *d* is at most *O(V)* but is generally much smaller. On directed
Erdos-Renyi graphs with edge weights in [0, 1), the expected number of
supersteps *d* is *O(n^(1/3))* with high probability.
Performance
~~~~~~~~~~~
The following charts illustrate the performance of the Parallel BGL implementation of Crauser et al.'s
algorithm on graphs with edge weights uniformly selected from the
range *[0, 1)*.
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?cluster=Odin&generator=ER,SF,SW&dataset=TimeSparse&columns=4
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?cluster=Odin&generator=ER,SF,SW&dataset=TimeSparse&columns=4&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?cluster=Odin&generator=ER,SF,SW&dataset=TimeDense&columns=4
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?cluster=Odin&generator=ER,SF,SW&dataset=TimeDense&columns=4&speedup=1
Eager Dijkstra's algorithm
--------------------------
::
namespace graph {
template<typename DistributedGraph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap, typename WeightMap,
typename IndexMap, typename ColorMap, typename Compare,
typename Combine, typename DistInf, typename DistZero>
void
eager_dijkstra_shortest_paths
(const DistributedGraph& g,
typename graph_traits<DistributedGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance,
typename property_traits<DistanceMap>::value_type lookahead,
WeightMap weight, IndexMap index_map, ColorMap color_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis);
template<typename DistributedGraph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap, typename WeightMap>
void
eager_dijkstra_shortest_paths
(const DistributedGraph& g,
typename graph_traits<DistributedGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance,
typename property_traits<DistanceMap>::value_type lookahead,
WeightMap weight);
template<typename DistributedGraph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap>
void
eager_dijkstra_shortest_paths
(const DistributedGraph& g,
typename graph_traits<DistributedGraph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance,
typename property_traits<DistanceMap>::value_type lookahead);
}
In each superstep, parallel Dijkstra's algorithm typically only
processes nodes whose distances equivalent to the global minimum
distance, because these distances are guaranteed to be correct. This
variation on the algorithm allows the algorithm to process all
vertices whose distances are within some constant value of the
minimum distance. The value is called the "lookahead" value and is
provided by the user as the fifth parameter to the function. Small
values of the lookahead parameter will likely result in limited
parallelization opportunities, whereas large values will expose more
parallelism but may introduce (non-infinite) looping and result in
extra work. The optimal value for the lookahead parameter depends on
the input graph; see [CMMS98b]_ and [MS98]_.
This algorithm will be used by ``dijkstra_shortest_paths()`` when it
is provided with a lookahead value.
Where Defined
~~~~~~~~~~~~~
<``boost/graph/distributed/eager_dijkstra_shortest_paths.hpp``>
Complexity
~~~~~~~~~~
This algorithm performs *O(V log V)* work in *d
+ 1* BSP supersteps, where *d* is at most *O(V)* but may be smaller
depending on the lookahead value. the algorithm may perform more work
when a large lookahead is provided, because vertices will be
reprocessed.
Performance
~~~~~~~~~~~
The performance of the eager Dijkstra's algorithm varies greatly
depending on the lookahead value. The following charts illustrate the
performance of the Parallel BGL on graphs with edge weights uniformly
selected from the range *[0, 1)* and a constant lookahead of 0.1.
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?cluster=Odin&generator=ER,SF,SW&dataset=TimeSparse&columns=5
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?cluster=Odin&generator=ER,SF,SW&dataset=TimeSparse&columns=5&speedup=1
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?cluster=Odin&generator=ER,SF,SW&dataset=TimeDense&columns=5
:align: left
.. image:: http://www.osl.iu.edu/research/pbgl/performance/chart.php?cluster=Odin&generator=ER,SF,SW&dataset=TimeDense&columns=5&speedup=1
Delta-Stepping algorithm
--------------------------
::
namespace boost { namespace graph { namespace distributed {
template <typename Graph, typename PredecessorMap,
typename DistanceMap, typename WeightMap>
void delta_stepping_shortest_paths
(const Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
typename property_traits<WeightMap>::value_type delta)
template <typename Graph, typename PredecessorMap,
typename DistanceMap, typename WeightMap>
void delta_stepping_shortest_paths
(const Graph& g,
typename graph_traits<Graph>::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight)
}
} } }
The delta-stepping algorithm [MS98]_ is another variant of the parallel
Dijkstra algorithm. Like the eager Dijkstra algorithm, it employs a
lookahead (``delta``) value that allows processors to process vertices
before we are guaranteed to find their minimum distances, permitting
more parallelism than a conservative strategy. Delta-stepping also
introduces a multi-level bucket data structure that provides more
relaxed ordering constraints than the priority queues employed by the
other Dijkstra variants, reducing the complexity of insertions,
relaxations, and removals from the central data structure. The
delta-stepping algorithm is the best-performing of the Dijkstra
variants.
The lookahead value ``delta`` determines how large each of the
"buckets" within the delta-stepping queue will be, where the ith
bucket contains edges within tentative distances between ``delta``*i
and ``delta``*(i+1). ``delta`` must be a positive value. When omitted,
``delta`` will be set to the maximum edge weight divided by the
maximum degree.
Where Defined
~~~~~~~~~~~~~
<``boost/graph/distributed/delta_stepping_shortest_paths.hpp``>
Example
-------
See the separate `Dijkstra example`_.
Bibliography
------------
.. [CMMS98a] Andreas Crauser, Kurt Mehlhorn, Ulrich Meyer, and Peter Sanders. A
Parallelization of Dijkstra's Shortest Path Algorithm. In
*Mathematical Foundations of Computer Science (MFCS)*, volume 1450 of
Lecture Notes in Computer Science, pages 722--731, 1998. Springer.
.. [CMMS98b] Andreas Crauser, Kurt Mehlhorn, Ulrich Meyer, and Peter
Sanders. Parallelizing Dijkstra's shortest path algorithm. Technical
report, MPI-Informatik, 1998.
.. [MS98] Ulrich Meyer and Peter Sanders. Delta-stepping: A parallel
shortest path algorithm. In *6th ESA*, LNCS. Springer, 1998.
-----------------------------------------------------------------------------
Copyright (C) 2004, 2005, 2006, 2007, 2008 The Trustees of Indiana University.
Authors: Douglas Gregor and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _sequential Dijkstra implementation: http://www.boost.org/libs/graph/doc/dijkstra_shortest_paths.html
.. _distributed breadth-first search: breadth_first_search.html
.. _Distributed Graph: DistributedGraph.html
.. _Distributed Property Map: distributed_property_map.html
.. _Dijkstra Visitor: http://www.boost.org/libs/graph/doc/DijkstraVisitor.html
.. _Dijkstra example: dijkstra_example.html

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -0,0 +1,973 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CanvasColor</key>
<dict>
<key>a</key>
<string>1</string>
<key>w</key>
<string>1</string>
</dict>
<key>ColumnAlign</key>
<integer>0</integer>
<key>ColumnSpacing</key>
<real>36</real>
<key>GraphDocumentVersion</key>
<integer>2</integer>
<key>GraphicsList</key>
<array>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>46</integer>
</dict>
<key>ID</key>
<integer>59</integer>
<key>Points</key>
<array>
<string>{78.7196, 152.817}</string>
<string>{83.2804, 180.183}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>44</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>45</integer>
</dict>
<key>ID</key>
<integer>58</integer>
<key>Points</key>
<array>
<string>{95.0459, 183.954}</string>
<string>{120.954, 158.046}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>46</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>45</integer>
</dict>
<key>ID</key>
<integer>57</integer>
<key>Points</key>
<array>
<string>{89.8174, 141.72}</string>
<string>{117.183, 146.28}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>44</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>44</integer>
</dict>
<key>ID</key>
<integer>56</integer>
<key>Points</key>
<array>
<string>{115.912, 52.7933}</string>
<string>{82.0879, 127.207}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>38</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>40</integer>
</dict>
<key>ID</key>
<integer>55</integer>
<key>Points</key>
<array>
<string>{87.3014, 131.399}</string>
<string>{137.699, 93.601}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>44</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>42</integer>
</dict>
<key>ID</key>
<integer>54</integer>
<key>Points</key>
<array>
<string>{243.216, 186.914}</string>
<string>{206.884, 191.727}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>43</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>40</integer>
</dict>
<key>ID</key>
<integer>53</integer>
<key>Points</key>
<array>
<string>{188.361, 181.013}</string>
<string>{153.701, 97.9619}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>42</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>42</integer>
</dict>
<key>ID</key>
<integer>52</integer>
<key>Points</key>
<array>
<string>{207.778, 152.479}</string>
<string>{197.939, 180.747}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>41</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>43</integer>
</dict>
<key>ID</key>
<integer>51</integer>
<key>Points</key>
<array>
<string>{220.905, 149.185}</string>
<string>{246.916, 174.992}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>41</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>41</integer>
</dict>
<key>ID</key>
<integer>50</integer>
<key>Points</key>
<array>
<string>{180.136, 53.1824}</string>
<string>{206.889, 126.809}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>39</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>41</integer>
</dict>
<key>ID</key>
<integer>49</integer>
<key>Points</key>
<array>
<string>{158.773, 94.2599}</string>
<string>{201.254, 130.709}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>40</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>40</integer>
</dict>
<key>ID</key>
<integer>48</integer>
<key>Points</key>
<array>
<string>{168.747, 52.1935}</string>
<string>{155.514, 73.9616}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>39</integer>
</dict>
</dict>
<dict>
<key>Class</key>
<string>LineGraphic</string>
<key>Head</key>
<dict>
<key>ID</key>
<integer>39</integer>
</dict>
<key>ID</key>
<integer>47</integer>
<key>Points</key>
<array>
<string>{134.999, 40.625}</string>
<string>{162, 40.5416}</string>
</array>
<key>Style</key>
<dict>
<key>stroke</key>
<dict>
<key>HeadArrow</key>
<string>FilledArrow</string>
<key>LineType</key>
<integer>1</integer>
<key>TailArrow</key>
<string>0</string>
</dict>
</dict>
<key>Tail</key>
<dict>
<key>ID</key>
<integer>38</integer>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{72, 180}, {27, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>46</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 e}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{117, 135}, {27, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>45</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 f}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{63, 126}, {27, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>44</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 d}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{243, 171}, {27, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>43</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 i}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{180, 180}, {27, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>42</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 g}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{198, 126}, {27, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>41</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 h}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{135, 72}, {27, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>40</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 c}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{162, 27}, {27, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>39</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 b}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{108, 27}, {27, 27}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>38</integer>
<key>Shape</key>
<string>Circle</string>
<key>Text</key>
<dict>
<key>Text</key>
<string>{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\qc
\f0\fs24 \cf0 a}</string>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{171, 117}, {108, 99}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>37</integer>
<key>Layer</key>
<integer>1</integer>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>1</string>
<key>b</key>
<string>0.824421</string>
<key>g</key>
<string>0.847826</string>
<key>r</key>
<string>0.825761</string>
</dict>
</dict>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{45, 117}, {108, 99}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>36</integer>
<key>Layer</key>
<integer>1</integer>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>1</string>
<key>b</key>
<string>0.824421</string>
<key>g</key>
<string>0.847826</string>
<key>r</key>
<string>0.825761</string>
</dict>
</dict>
</dict>
</dict>
<dict>
<key>Bounds</key>
<string>{{99, 18}, {99, 90}}</string>
<key>Class</key>
<string>ShapedGraphic</string>
<key>ID</key>
<integer>35</integer>
<key>Layer</key>
<integer>1</integer>
<key>Shape</key>
<string>Rectangle</string>
<key>Style</key>
<dict>
<key>fill</key>
<dict>
<key>Color</key>
<dict>
<key>a</key>
<string>1</string>
<key>b</key>
<string>0.824421</string>
<key>g</key>
<string>0.847826</string>
<key>r</key>
<string>0.825761</string>
</dict>
</dict>
</dict>
</dict>
</array>
<key>GridInfo</key>
<dict/>
<key>HPages</key>
<integer>1</integer>
<key>ImageCounter</key>
<integer>1</integer>
<key>IsPalette</key>
<string>NO</string>
<key>Layers</key>
<array>
<dict>
<key>Lock</key>
<string>NO</string>
<key>Name</key>
<string>Layer 1</string>
<key>Print</key>
<string>YES</string>
<key>View</key>
<string>YES</string>
</dict>
<dict>
<key>Lock</key>
<string>NO</string>
<key>Name</key>
<string>Layer 2</string>
<key>Print</key>
<string>YES</string>
<key>View</key>
<string>YES</string>
</dict>
</array>
<key>LayoutInfo</key>
<dict>
<key>AutoAdjust</key>
<string>YES</string>
<key>MagneticFieldCenter</key>
<string>{0, 0}</string>
</dict>
<key>MagnetsEnabled</key>
<string>YES</string>
<key>PageBreakColor</key>
<dict>
<key>a</key>
<string>1</string>
<key>w</key>
<string>0.666667</string>
</dict>
<key>PageBreaks</key>
<string>YES</string>
<key>PageSetup</key>
<data>
BAt0eXBlZHN0cmVhbYED6IQBQISEhAtOU1ByaW50SW5mbwGEhAhOU09iamVjdACFkoSE
hBNOU011dGFibGVEaWN0aW9uYXJ5AISEDE5TRGljdGlvbmFyeQCUhAFpFJKEhIQITlNT
dHJpbmcBlIQBKxBOU0pvYkRpc3Bvc2l0aW9uhpKEmZkPTlNQcmludFNwb29sSm9ihpKE
mZkLTlNQYXBlclNpemWGkoSEhAdOU1ZhbHVlAJSEASqEhAx7X05TU2l6ZT1mZn2cgQJk
gQMYhpKEmZkZTlNQcmludFJldmVyc2VPcmllbnRhdGlvboaShISECE5TTnVtYmVyAJ2b
hJeXAIaShJmZFE5TVmVydGljYWxQYWdpbmF0aW9uhpKEoZuilwCGkoSZmRROU1ZlcnRp
Y2FsbHlDZW50ZXJlZIaShKGbopcBhpKEmZkOTlNQTVBhZ2VGb3JtYXSGkoSEhAZOU0Rh
dGEAlJeBIk+EB1s4NzgzY108P3htbCB2ZXJzaW9uPSIxLjAiIGVuY29kaW5nPSJVVEYt
OCI/Pgo8IURPQ1RZUEUgcGxpc3QgUFVCTElDICItLy9BcHBsZSBDb21wdXRlci8vRFRE
IFBMSVNUIDEuMC8vRU4iICJodHRwOi8vd3d3LmFwcGxlLmNvbS9EVERzL1Byb3BlcnR5
TGlzdC0xLjAuZHRkIj4KPHBsaXN0IHZlcnNpb249IjEuMCI+CjxkaWN0PgoJPGtleT5j
b20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5Gb3JtYXR0aW5nUHJpbnRlcjwva2V5PgoJ
PGRpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4K
CQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21hbmFnZXI8L3N0cmluZz4KCQk8a2V5
PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJPGFycmF5PgoJ
CQk8ZGljdD4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuRm9ybWF0
dGluZ1ByaW50ZXI8L2tleT4KCQkJCTxzdHJpbmc+cHNsYW08L3N0cmluZz4KCQkJCTxr
ZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jbGllbnQ8L2tleT4KCQkJCTxzdHJpbmc+
Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJCQkJPGtleT5jb20uYXBw
bGUucHJpbnQudGlja2V0Lm1vZERhdGU8L2tleT4KCQkJCTxkYXRlPjIwMDQtMTAtMDZU
MTQ6NTk6NTRaPC9kYXRlPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0
YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI+MDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJ
CTwvYXJyYXk+Cgk8L2RpY3Q+Cgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0
LlBNSG9yaXpvbnRhbFJlczwva2V5PgoJPGRpY3Q+CgkJPGtleT5jb20uYXBwbGUucHJp
bnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludGlu
Z21hbmFnZXI8L3N0cmluZz4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuaXRl
bUFycmF5PC9rZXk+CgkJPGFycmF5PgoJCQk8ZGljdD4KCQkJCTxrZXk+Y29tLmFwcGxl
LnByaW50LlBhZ2VGb3JtYXQuUE1Ib3Jpem9udGFsUmVzPC9rZXk+CgkJCQk8cmVhbD43
MjwvcmVhbD4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jbGllbnQ8L2tl
eT4KCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdlcjwvc3RyaW5nPgoJ
CQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lm1vZERhdGU8L2tleT4KCQkJCTxk
YXRlPjIwMDQtMTAtMDZUMTQ6NTk6NTRaPC9kYXRlPgoJCQkJPGtleT5jb20uYXBwbGUu
cHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJPGludGVnZXI+MDwvaW50ZWdl
cj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk+Cgk8L2RpY3Q+Cgk8a2V5PmNvbS5hcHBsZS5w
cmludC5QYWdlRm9ybWF0LlBNT3JpZW50YXRpb248L2tleT4KCTxkaWN0PgoJCTxrZXk+
Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJPHN0cmluZz5jb20u
YXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJPGtleT5jb20uYXBwbGUucHJp
bnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJPGRpY3Q+CgkJCQk8
a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNT3JpZW50YXRpb248L2tleT4K
CQkJCTxpbnRlZ2VyPjE8L2ludGVnZXI+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50
aWNrZXQuY2xpZW50PC9rZXk+CgkJCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21h
bmFnZXI8L3N0cmluZz4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5tb2RE
YXRlPC9rZXk+CgkJCQk8ZGF0ZT4yMDA0LTEwLTA2VDE0OjU5OjU0WjwvZGF0ZT4KCQkJ
CTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCTxp
bnRlZ2VyPjA8L2ludGVnZXI+CgkJCTwvZGljdD4KCQk8L2FycmF5PgoJPC9kaWN0PgoJ
PGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTVNjYWxpbmc8L2tleT4KCTxk
aWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJ
PHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJPGtleT5j
b20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJheT4KCQkJ
PGRpY3Q+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNU2NhbGlu
Zzwva2V5PgoJCQkJPHJlYWw+MTwvcmVhbD4KCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50
LnRpY2tldC5jbGllbnQ8L2tleT4KCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5n
bWFuYWdlcjwvc3RyaW5nPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lm1v
ZERhdGU8L2tleT4KCQkJCTxkYXRlPjIwMDQtMTAtMDZUMTQ6NTk6NTRaPC9kYXRlPgoJ
CQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJ
PGludGVnZXI+MDwvaW50ZWdlcj4KCQkJPC9kaWN0PgoJCTwvYXJyYXk+Cgk8L2RpY3Q+
Cgk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBNVmVydGljYWxSZXM8L2tl
eT4KCTxkaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5jcmVhdG9yPC9r
ZXk+CgkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJ
PGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCTxhcnJh
eT4KCQkJPGRpY3Q+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYWdlRm9ybWF0LlBN
VmVydGljYWxSZXM8L2tleT4KCQkJCTxyZWFsPjcyPC9yZWFsPgoJCQkJPGtleT5jb20u
YXBwbGUucHJpbnQudGlja2V0LmNsaWVudDwva2V5PgoJCQkJPHN0cmluZz5jb20uYXBw
bGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmlu
dC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJPGRhdGU+MjAwNC0xMC0wNlQxNDo1OTo1
NFo8L2RhdGU+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFn
PC9rZXk+CgkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQk8L2RpY3Q+CgkJPC9hcnJh
eT4KCTwvZGljdD4KCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1WZXJ0
aWNhbFNjYWxpbmc8L2tleT4KCTxkaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRp
Y2tldC5jcmVhdG9yPC9rZXk+CgkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5h
Z2VyPC9zdHJpbmc+CgkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJh
eTwva2V5PgoJCTxhcnJheT4KCQkJPGRpY3Q+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmlu
dC5QYWdlRm9ybWF0LlBNVmVydGljYWxTY2FsaW5nPC9rZXk+CgkJCQk8cmVhbD4xPC9y
ZWFsPgoJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNsaWVudDwva2V5PgoJ
CQkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJCQk8
a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJPGRhdGU+
MjAwNC0xMC0wNlQxNDo1OTo1NFo8L2RhdGU+CgkJCQk8a2V5PmNvbS5hcHBsZS5wcmlu
dC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJ
CQk8L2RpY3Q+CgkJPC9hcnJheT4KCTwvZGljdD4KCTxrZXk+Y29tLmFwcGxlLnByaW50
LnN1YlRpY2tldC5wYXBlcl9pbmZvX3RpY2tldDwva2V5PgoJPGRpY3Q+CgkJPGtleT5j
b20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdC5QTUFkanVzdGVkUGFnZVJlY3Q8L2tleT4K
CQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tl
eT4KCQkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJ
CTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFy
cmF5PgoJCQkJPGRpY3Q+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1h
dC5QTUFkanVzdGVkUGFnZVJlY3Q8L2tleT4KCQkJCQk8YXJyYXk+CgkJCQkJCTxyZWFs
PjAuMDwvcmVhbD4KCQkJCQkJPHJlYWw+MC4wPC9yZWFsPgoJCQkJCQk8cmVhbD43NTQu
ODAwMDQ4ODI4MTI1PC9yZWFsPgoJCQkJCQk8cmVhbD41NzguODAwMDQ4ODI4MTI1PC9y
ZWFsPgoJCQkJCTwvYXJyYXk+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0
LmNsaWVudDwva2V5PgoJCQkJCTxzdHJpbmc+Y29tLmFwcGxlLnByaW50aW5nbWFuYWdl
cjwvc3RyaW5nPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5tb2REYXRl
PC9rZXk+CgkJCQkJPGRhdGU+MjAwNC0xMC0wNlQxNDo1OTo1NFo8L2RhdGU+CgkJCQkJ
PGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRlRmxhZzwva2V5PgoJCQkJCTxp
bnRlZ2VyPjA8L2ludGVnZXI+CgkJCQk8L2RpY3Q+CgkJCTwvYXJyYXk+CgkJPC9kaWN0
PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhZ2VGb3JtYXQuUE1BZGp1c3RlZFBhcGVy
UmVjdDwva2V5PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQu
Y3JlYXRvcjwva2V5PgoJCQk8c3RyaW5nPmNvbS5hcHBsZS5wcmludGluZ21hbmFnZXI8
L3N0cmluZz4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwv
a2V5PgoJCQk8YXJyYXk+CgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmlu
dC5QYWdlRm9ybWF0LlBNQWRqdXN0ZWRQYXBlclJlY3Q8L2tleT4KCQkJCQk8YXJyYXk+
CgkJCQkJCTxyZWFsPi0xOC41OTk5NzU1ODU5Mzc1PC9yZWFsPgoJCQkJCQk8cmVhbD4t
MTYuNjAwMDAwMzgxNDY5NzI3PC9yZWFsPgoJCQkJCQk8cmVhbD43NzMuNDAwMDI0NDE0
MDYyNTwvcmVhbD4KCQkJCQkJPHJlYWw+NTk1LjQwMDAyNDQxNDA2MjU8L3JlYWw+CgkJ
CQkJPC9hcnJheT4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY2xpZW50
PC9rZXk+CgkJCQkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJp
bmc+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lm1vZERhdGU8L2tleT4K
CQkJCQk8ZGF0ZT4yMDA0LTEwLTA2VDE0OjU5OjU0WjwvZGF0ZT4KCQkJCQk8a2V5PmNv
bS5hcHBsZS5wcmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQkJPGludGVnZXI+
MDwvaW50ZWdlcj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q+CgkJPGtl
eT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNQ29uc3RyYWluZWRQYXBlcjwva2V5
PgoJCTxkaWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwv
a2V5PgoJCQk8c3RyaW5nPkNVUFNfQ1BMPC9zdHJpbmc+CgkJCTxrZXk+Y29tLmFwcGxl
LnByaW50LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q+
CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNQ29uc3RyYWluZWRQ
YXBlcjwva2V5PgoJCQkJCTxmYWxzZS8+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQu
dGlja2V0LmNsaWVudDwva2V5PgoJCQkJCTxzdHJpbmc+Q1VQU19DUEw8L3N0cmluZz4K
CQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJ
CTxkYXRlPjIwMDQtMTAtMDZUMTQ6NTk6NTJaPC9kYXRlPgoJCQkJCTxrZXk+Y29tLmFw
cGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4xPC9p
bnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNv
bS5hcHBsZS5wcmludC5QYXBlckluZm8uUE1QYXBlck5hbWU8L2tleT4KCQk8ZGljdD4K
CQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tleT4KCQkJPHN0
cmluZz5DVVBTX0NQTDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNr
ZXQuaXRlbUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJCQkJCTxrZXk+
Y29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVBhcGVyTmFtZTwva2V5PgoJCQkJCTxz
dHJpbmc+bmEtbGV0dGVyPC9zdHJpbmc+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQu
dGlja2V0LmNsaWVudDwva2V5PgoJCQkJCTxzdHJpbmc+Q1VQU19DUEw8L3N0cmluZz4K
CQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJ
CTxkYXRlPjIwMDQtMTAtMDZUMTQ6NTk6NTJaPC9kYXRlPgoJCQkJCTxrZXk+Y29tLmFw
cGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8L2tleT4KCQkJCQk8aW50ZWdlcj4xPC9p
bnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2FycmF5PgoJCTwvZGljdD4KCQk8a2V5PmNv
bS5hcHBsZS5wcmludC5QYXBlckluZm8uUE1VbmFkanVzdGVkUGFnZVJlY3Q8L2tleT4K
CQk8ZGljdD4KCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LmNyZWF0b3I8L2tl
eT4KCQkJPHN0cmluZz5DVVBTX0NQTDwvc3RyaW5nPgoJCQk8a2V5PmNvbS5hcHBsZS5w
cmludC50aWNrZXQuaXRlbUFycmF5PC9rZXk+CgkJCTxhcnJheT4KCQkJCTxkaWN0PgoJ
CQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LlBhcGVySW5mby5QTVVuYWRqdXN0ZWRQYWdl
UmVjdDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw+MC4wPC9yZWFsPgoJCQkJ
CQk8cmVhbD4wLjA8L3JlYWw+CgkJCQkJCTxyZWFsPjc1NC44MDAwNDg4MjgxMjU8L3Jl
YWw+CgkJCQkJCTxyZWFsPjU3OC44MDAwNDg4MjgxMjU8L3JlYWw+CgkJCQkJPC9hcnJh
eT4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJ
CQkJPHN0cmluZz5jb20uYXBwbGUucHJpbnRpbmdtYW5hZ2VyPC9zdHJpbmc+CgkJCQkJ
PGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lm1vZERhdGU8L2tleT4KCQkJCQk8ZGF0
ZT4yMDA0LTEwLTA2VDE0OjU5OjU0WjwvZGF0ZT4KCQkJCQk8a2V5PmNvbS5hcHBsZS5w
cmludC50aWNrZXQuc3RhdGVGbGFnPC9rZXk+CgkJCQkJPGludGVnZXI+MDwvaW50ZWdl
cj4KCQkJCTwvZGljdD4KCQkJPC9hcnJheT4KCQk8L2RpY3Q+CgkJPGtleT5jb20uYXBw
bGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhcGVyUmVjdDwva2V5PgoJCTxk
aWN0PgoJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY3JlYXRvcjwva2V5PgoJ
CQk8c3RyaW5nPkNVUFNfQ1BMPC9zdHJpbmc+CgkJCTxrZXk+Y29tLmFwcGxlLnByaW50
LnRpY2tldC5pdGVtQXJyYXk8L2tleT4KCQkJPGFycmF5PgoJCQkJPGRpY3Q+CgkJCQkJ
PGtleT5jb20uYXBwbGUucHJpbnQuUGFwZXJJbmZvLlBNVW5hZGp1c3RlZFBhcGVyUmVj
dDwva2V5PgoJCQkJCTxhcnJheT4KCQkJCQkJPHJlYWw+LTE4LjU5OTk3NTU4NTkzNzU8
L3JlYWw+CgkJCQkJCTxyZWFsPi0xNi42MDAwMDAzODE0Njk3Mjc8L3JlYWw+CgkJCQkJ
CTxyZWFsPjc3My40MDAwMjQ0MTQwNjI1PC9yZWFsPgoJCQkJCQk8cmVhbD41OTUuNDAw
MDI0NDE0MDYyNTwvcmVhbD4KCQkJCQk8L2FycmF5PgoJCQkJCTxrZXk+Y29tLmFwcGxl
LnByaW50LnRpY2tldC5jbGllbnQ8L2tleT4KCQkJCQk8c3RyaW5nPmNvbS5hcHBsZS5w
cmludGluZ21hbmFnZXI8L3N0cmluZz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50
aWNrZXQubW9kRGF0ZTwva2V5PgoJCQkJCTxkYXRlPjIwMDQtMTAtMDZUMTQ6NTk6NTRa
PC9kYXRlPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5zdGF0ZUZsYWc8
L2tleT4KCQkJCQk8aW50ZWdlcj4wPC9pbnRlZ2VyPgoJCQkJPC9kaWN0PgoJCQk8L2Fy
cmF5PgoJCTwvZGljdD4KCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlckluZm8ucHBk
LlBNUGFwZXJOYW1lPC9rZXk+CgkJPGRpY3Q+CgkJCTxrZXk+Y29tLmFwcGxlLnByaW50
LnRpY2tldC5jcmVhdG9yPC9rZXk+CgkJCTxzdHJpbmc+Q1VQU19DUEw8L3N0cmluZz4K
CQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0Lml0ZW1BcnJheTwva2V5PgoJCQk8
YXJyYXk+CgkJCQk8ZGljdD4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC5QYXBlcklu
Zm8ucHBkLlBNUGFwZXJOYW1lPC9rZXk+CgkJCQkJPHN0cmluZz5MZXR0ZXI8L3N0cmlu
Zz4KCQkJCQk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQuY2xpZW50PC9rZXk+CgkJ
CQkJPHN0cmluZz5DVVBTX0NQTDwvc3RyaW5nPgoJCQkJCTxrZXk+Y29tLmFwcGxlLnBy
aW50LnRpY2tldC5tb2REYXRlPC9rZXk+CgkJCQkJPGRhdGU+MjAwNC0xMC0wNlQxNDo1
OTo1Mlo8L2RhdGU+CgkJCQkJPGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnN0YXRl
RmxhZzwva2V5PgoJCQkJCTxpbnRlZ2VyPjE8L2ludGVnZXI+CgkJCQk8L2RpY3Q+CgkJ
CTwvYXJyYXk+CgkJPC9kaWN0PgoJCTxrZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5B
UElWZXJzaW9uPC9rZXk+CgkJPHN0cmluZz4wMC4yMDwvc3RyaW5nPgoJCTxrZXk+Y29t
LmFwcGxlLnByaW50LnRpY2tldC5wcml2YXRlTG9jazwva2V5PgoJCTxmYWxzZS8+CgkJ
PGtleT5jb20uYXBwbGUucHJpbnQudGlja2V0LnR5cGU8L2tleT4KCQk8c3RyaW5nPmNv
bS5hcHBsZS5wcmludC5QYXBlckluZm9UaWNrZXQ8L3N0cmluZz4KCTwvZGljdD4KCTxr
ZXk+Y29tLmFwcGxlLnByaW50LnRpY2tldC5BUElWZXJzaW9uPC9rZXk+Cgk8c3RyaW5n
PjAwLjIwPC9zdHJpbmc+Cgk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQucHJpdmF0
ZUxvY2s8L2tleT4KCTxmYWxzZS8+Cgk8a2V5PmNvbS5hcHBsZS5wcmludC50aWNrZXQu
dHlwZTwva2V5PgoJPHN0cmluZz5jb20uYXBwbGUucHJpbnQuUGFnZUZvcm1hdFRpY2tl
dDwvc3RyaW5nPgo8L2RpY3Q+CjwvcGxpc3Q+CoaShJmZD05TUHJpbnRBbGxQYWdlc4aS
oJKEmZkLTlNQYXBlck5hbWWGkoSZmQZMZXR0ZXKGkoSZmRVOU0hvcml6b25hbFBhZ2lu
YXRpb26GkoShm6KXAIaShJmZFk5TSG9yaXpvbnRhbGx5Q2VudGVyZWSGkqaShJmZCU5T
UHJpbnRlcoaShISECU5TUHJpbnRlcgCUkoSZmQVwc2xhbYaGkoSZmQhOU0NvcGllc4aS
hKGbopcBhpKEmZkPTlNTY2FsaW5nRmFjdG9yhpKEoZuEhAFmoQGGkoSZmQ1OU1JpZ2h0
TWFyZ2luhpKEoZu4oSSGkoSZmQ5OU0JvdHRvbU1hcmdpboaShKGbuKEkhpKEmZkMTlNM
ZWZ0TWFyZ2luhpKEoZu4oSSGkoSZmQtOU1RvcE1hcmdpboaShKGbuKEkhpKEmZkKTlNM
YXN0UGFnZYaShKGbopeCf////4aShJmZC05TRmlyc3RQYWdlhpKEoZuilwGGkoSZmQ1O
U09yaWVudGF0aW9uhpKEoZuilwCGhoY=
</data>
<key>RowAlign</key>
<integer>0</integer>
<key>RowSpacing</key>
<real>36</real>
<key>VPages</key>
<integer>1</integer>
<key>WindowInfo</key>
<dict>
<key>Frame</key>
<string>{{243, 152}, {555, 797}}</string>
<key>VisibleRegion</key>
<string>{{0, 0}, {540, 720}}</string>
<key>Zoom</key>
<string>1</string>
</dict>
</dict>
</plist>

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -0,0 +1,49 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
======================================
``distributedS`` Distribution Selector
======================================
The Boost Graph Library's class template adjacency_list_ supports
several selectors that indicate what data structure should be used for
the storage of edges or vertices. The selector ``vecS``, for instance,
indicates storage in a ``std::vector`` whereas ``listS`` indicates
storage in a ``std::list``. The Parallel BGL's `distributed
adjacency list`_ supports an additional selector, ``distributedS``,
that indicates that the storage should be distributed across multiple
processes. This selector can transform a sequential adjacency list
into a distributed adjacency list.
::
template<typename ProcessGroup, typename LocalSelector = vecS>
struct distributedS;
Template parameters
~~~~~~~~~~~~~~~~~~~
**ProcessGroup**:
The type of the process group over which the property map is
distributed and also the medium for communication. This type must
model the `Process Group`_ concept, but certain data structures may
place additional requirements on this parameter.
**LocalSelector**:
A selector type (e.g., ``vecS``) that indicates how vertices or
edges should be stored in each process.
-----------------------------------------------------------------------------
Copyright (C) 2005 The Trustees of Indiana University.
Authors: Douglas Gregor and Andrew Lumsdaine
.. _adjacency_list: http://www.boost.org/libs/graph/doc/adjacency_list.html
.. _Distributed adjacency list: distributed_adjacency_list.html
.. _Process group: process_group.html

View File

@@ -0,0 +1,964 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
=================================
|Logo| Distributed Adjacency List
=================================
.. contents::
Introduction
------------
The distributed adjacency list implements a graph data structure using
an adjacency list representation. Its interface and behavior are
roughly equivalent to the Boost Graph Library's adjacency_list_
class template. However, the distributed adjacency list partitions the
vertices of the graph across several processes (which need not share
an address space). Edges outgoing from any vertex stored by a process
are also stored on that process, except in the case of undirected
graphs, where either the source or the target may store the edge.
::
template<typename OutEdgeListS, typename ProcessGroup, typename VertexListS,
typename DirectedS, typename VertexProperty, typename EdgeProperty,
typename GraphProperty, typename EdgeListS>
class adjacency_list<OutEdgeListS,
distributedS<ProcessGroup, VertexListS>,
DirectedS, VertexProperty,
EdgeProperty, GraphProperty, EdgeListS>;
Defining a Distributed Adjacency List
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To create a distributed adjacency list, first determine the
representation of the graph in a single address space using these
guidelines_. Next, replace the vertex list selector (``VertexListS``)
with an instantiation of distributedS_, which includes:
- Selecting a `process group`_ type that represents the various
coordinating processes that will store the distributed graph. For
example, the `MPI process group`_.
- A selector indicating how the vertex lists in each process will be
stored. Only the ``vecS`` and ``listS`` selectors are well-supported
at this time.
The following ``typedef`` defines a distributed adjacency list
containing directed edges. The vertices in the graph will be
distributed over several processes, using the MPI process group
for communication. In each process, the vertices and outgoing edges
will be stored in STL vectors. There are no properties attached to the
vertices or edges of the graph.
::
using namespace boost;
typedef adjacency_list<vecS,
distributedS<parallel::mpi::bsp_process_group, vecS>,
directedS>
Graph;
Distributed Vertex and Edge Properties
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Vertex and edge properties for distributed graphs mirror their
counterparts for non-distributed graphs. With a distributed graph,
however, vertex and edge properties are stored only in the process
that owns the vertex or edge.
The most direct way to attach properties to a distributed graph is to
create a structure that will be attached to each of the vertices and
edges of the graph. For example, if we wish to model a simplistic map
of the United States interstate highway system, we might state that
the vertices of the graph are cities and the edges are highways, then
define the information that we maintain for each city and highway:
::
struct City {
City() { }
City(const std::string& name, const std::string& mayor = "Unknown", int population = 0)
: name(name), mayor(mayor), population(population) { }
std::string name;
std::string mayor;
int population;
// Serialization support is required!
template<typename Archiver>
void serialize(Archiver& ar, const unsigned int /*version*/) {
ar & name & mayor & population;
}
};
struct Highway {
Highway() { }
Highway(const std::string& name, int lanes, int miles_per_hour, int length)
: name(name), lanes(lanes), miles_per_hour(miles_per_hour), length(length) { }
std::string name;
int lanes;
int miles_per_hour;
int length;
// Serialization support is required!
template<typename Archiver>
void serialize(Archiver& ar, const unsigned int /*version*/) {
ar & name & lanes & miles_per_hour & length;
}
};
To create a distributed graph for a road map, we supply ``City`` and
``Highway`` as the fourth and fifth parameters to ``adjacency_list``,
respectively:
::
typedef adjacency_list<vecS,
distributedS<parallel::mpi::bsp_process_group, vecS>,
directedS,
City, Highway>
RoadMap;
Property maps for internal properties retain their behavior with
distributed graphs via `distributed property maps`_, which automate
communication among processes so that ``put`` and ``get`` operations
may be applied to non-local vertices and edges. However, for
distributed adjacency lists that store vertices in a vector
(``VertexListS`` is ``vecS``), the automatic ``vertex_index``
property map restricts the domain of ``put`` and ``get`` operations
to vertices local to the process executing the operation. For example,
we can create a property map that accesses the length of each highway
as follows:
::
RoadMap map; // distributed graph instance
typedef property_map<RoadMap, int Highway::*>::type
road_length = get(&Highway::length, map);
Now, one can access the length of any given road based on its edge
descriptor ``e`` with the expression ``get(road_length, e)``,
regardless of which process stores the edge ``e``.
Named Vertices
~~~~~~~~~~~~~~
The vertices of a graph typically correspond to named entities within
the application domain. In the road map example from the previous
section, the vertices in the graph represent cities. The distributed
adjacency list supports named vertices, which provides an implicit
mapping from the names of the vertices in the application domain
(e.g., the name of a city, such as "Bloomington") to the actual vertex
descriptor stored within the distributed graph (e.g., the third vertex
on processor 1). By enabling support for named vertices, one can refer
to vertices by name when manipulating the graph. For example, one can
add a highway from Indianapolis to Chicago:
::
add_edge("Indianapolis", "Chicago", Highway("I-65", 4, 65, 151), map);
The distributed adjacency list will find vertices associated with the
names "Indianapolis" and "Chicago", then add an edge between these
vertices that represents I-65. The vertices may be stored on any
processor, local or remote.
To enable named vertices, specialize the ``internal_vertex_name``
property for the structure attached to the vertices in your
graph. ``internal_vertex_name`` contains a single member, ``type``,
which is the type of a function object that accepts a vertex property
and returns the name stored within that vertex property. In the case
of our road map, the ``name`` field contains the name of each city, so
we use the ``member`` function object from the `Boost.MultiIndex`_
library to extract the name, e.g.,
::
namespace boost { namespace graph {
template<>
struct internal_vertex_name<City>
{
typedef multi_index::member<City, std::string, &City::name> type;
};
} }
That's it! One can now refer to vertices by name when interacting with
the distributed adjacency list.
What happens when one uses the name of a vertex that does not exist?
For example, in our ``add_edge`` call above, what happens if the
vertex named "Indianapolis" has not yet been added to the graph? By
default, the distributed adjacency list will throw an exception if a
named vertex does not yet exist. However, one can customize this
behavior by specifying a function object that constructs an instance
of the vertex property (e.g., ``City``) from just the name of the
vertex. This customization occurs via the
``internal_vertex_constructor`` trait. For example, using the
``vertex_from_name`` template (provided with the Parallel BGL), we can
state that a ``City`` can be constructed directly from the name of the
city using its second constructor:
::
namespace boost { namespace graph {
template<>
struct internal_vertex_constructor<City>
{
typedef vertex_from_name<City> type;
};
} }
Now, one can add edges by vertex name freely, without worrying about
the explicit addition of vertices. The ``mayor`` and ``population``
fields will have default values, but the graph structure will be
correct.
Building a Distributed Graph
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Once you have determined the layout of your graph type, including the
specific data structures and properties, it is time to construct an
instance of the graph by adding the appropriate vertices and
edges. Construction of distributed graphs can be slightly more
complicated than construction of normal, non-distributed graph data
structures, because one must account for both the distribution of the
vertices and edges and the multiple processes executing
concurrently. There are three main ways to construct distributed
graphs:
1. *Sequence constructors*: if your data can easily be generated by a
pair of iterators that produce (source, target) pairs, you can use the
sequence constructors to build the distributed graph in parallel. This
method is often preferred when creating benchmarks, because random
graph generators like the sorted_erdos_renyi_iterator_ create the
appropriate input sequence. Note that one must provide the same input
iterator sequence on all processes. This method has the advantage that
the sequential graph-building code is identical to the parallel
graph-building code. An example constructing a random graph this way:
::
typedef boost::sorted_erdos_renyi_iterator<boost::minstd_rand, Graph> ERIter;
boost::minstd_rand gen;
unsigned long n = 1000000; // 1M vertices
Graph g(ERIter(gen, n, 0.00005), ERIter(), n);
2. *Adding edges by vertex number*: if you are able to map your
vertices into values in the random [0, *n*), where *n* is the number
of vertices in the distributed graph. Use this method rather than the
sequence constructors when your algorithm cannot easily be moved into
input iterators, or if you can't replicate the input sequence. For
example, you might be reading the graph from an input file:
::
Graph g(n); // initialize with the total number of vertices, n
if (process_id(g.process_group()) == 0) {
// Only process 0 loads the graph, which is distributed automatically
int source, target;
for (std::cin >> source >> target)
add_edge(vertex(source, g), vertex(target, g), g);
}
// All processes synchronize at this point, then the graph is complete
synchronize(g.process_group());
3. *Adding edges by name*: if you are using named vertices, you can
construct your graph just by calling ``add_edge`` with the names of
the source and target vertices. Be careful to make sure that each edge
is added by only one process (it doesn't matter which process it is),
otherwise you will end up with multiple edges. For example, in the
following program we read edges from the standard input of process 0,
adding those edges by name. Vertices and edges will be created and
distributed automatically.
::
Graph g;
if (process_id(g.process_group()) == 0) {
// Only process 0 loads the graph, which is distributed automatically
std:string source, target;
for(std::cin >> source >> target)
add_edge(source, target, g);
}
// All processes synchronize at this point, then the graph is complete
synchronize(g.process_group());
Graph Concepts
~~~~~~~~~~~~~~
The distributed adjacency list models the Graph_ concept, and in
particular the `Distributed Graph`_ concept. It also models the
`Incidence Graph`_ and `Adjacency Graph`_ concept, but restricts the
input domain of the operations to correspond to local vertices
only. For instance, a process may only access the outgoing edges of a
vertex if that vertex is stored in that process. Undirected and
bidirectional distributed adjacency lists model the `Bidirectional
Graph`_ concept, with the same domain restrictions. Distributed
adjacency lists also model the `Mutable Graph`_ concept (with domain
restrictions; see the Reference_ section), `Property Graph`_ concept,
and `Mutable Property Graph`_ concept.
Unlike its non-distributed counterpart, the distributed adjacency
list does **not** model the `Vertex List Graph`_ or `Edge List
Graph`_ concepts, because one cannot enumerate all vertices or edges
within a distributed graph. Instead, it models the weaker
`Distributed Vertex List Graph`_ and `Distributed Edge List Graph`_
concepts, which permit access to the local edges and vertices on each
processor. Note that if all processes within the process group over
which the graph is distributed iterator over their respective vertex
or edge lists, all vertices and edges will be covered once.
Reference
---------
Since the distributed adjacency list closely follows the
non-distributed adjacency_list_, this reference documentation
only describes where the two implementations differ.
Where Defined
~~~~~~~~~~~~~
<boost/graph/distributed/adjacency_list.hpp>
Associated Types
~~~~~~~~~~~~~~~~
::
adjacency_list::process_group_type
The type of the process group over which the graph will be
distributed.
-----------------------------------------------------------------------------
adjacency_list::distribution_type
The type of distribution used to partition vertices in the graph.
-----------------------------------------------------------------------------
adjacency_list::vertex_name_type
If the graph supports named vertices, this is the type used to name
vertices. Otherwise, this type is not present within the distributed
adjacency list.
Member Functions
~~~~~~~~~~~~~~~~
::
adjacency_list(const ProcessGroup& pg = ProcessGroup());
adjacency_list(const GraphProperty& g,
const ProcessGroup& pg = ProcessGroup());
Construct an empty distributed adjacency list with the given process
group (or default) and graph property (or default).
-----------------------------------------------------------------------------
::
adjacency_list(vertices_size_type n, const GraphProperty& p,
const ProcessGroup& pg, const Distribution& distribution);
adjacency_list(vertices_size_type n, const ProcessGroup& pg,
const Distribution& distribution);
adjacency_list(vertices_size_type n, const GraphProperty& p,
const ProcessGroup& pg = ProcessGroup());
adjacency_list(vertices_size_type n,
const ProcessGroup& pg = ProcessGroup());
Construct a distributed adjacency list with ``n`` vertices,
optionally providing the graph property, process group, or
distribution. The ``n`` vertices will be distributed via the given
(or default-constructed) distribution. This operation is collective,
requiring all processes with the process group to execute it
concurrently.
-----------------------------------------------------------------------------
::
template <class EdgeIterator>
adjacency_list(EdgeIterator first, EdgeIterator last,
vertices_size_type n,
const ProcessGroup& pg = ProcessGroup(),
const GraphProperty& p = GraphProperty());
template <class EdgeIterator, class EdgePropertyIterator>
adjacency_list(EdgeIterator first, EdgeIterator last,
EdgePropertyIterator ep_iter,
vertices_size_type n,
const ProcessGroup& pg = ProcessGroup(),
const GraphProperty& p = GraphProperty());
template <class EdgeIterator>
adjacency_list(EdgeIterator first, EdgeIterator last,
vertices_size_type n,
const ProcessGroup& process_group,
const Distribution& distribution,
const GraphProperty& p = GraphProperty());
template <class EdgeIterator, class EdgePropertyIterator>
adjacency_list(EdgeIterator first, EdgeIterator last,
EdgePropertyIterator ep_iter,
vertices_size_type n,
const ProcessGroup& process_group,
const Distribution& distribution,
const GraphProperty& p = GraphProperty());
Construct a distributed adjacency list with ``n`` vertices and with
edges specified in the edge list given by the range ``[first, last)``. The
``EdgeIterator`` must be a model of InputIterator_. The value type of the
``EdgeIterator`` must be a ``std::pair``, where the type in the pair is an
integer type. The integers will correspond to vertices, and they must
all fall in the range of ``[0, n)``. When provided, ``ep_iter``
refers to an edge property list ``[ep_iter, ep_iter + m)`` contains
properties for each of the edges.
This constructor is a collective operation and must be executed
concurrently by each process with the same argument list. Most
importantly, the edge lists provided to the constructor in each process
should be equivalent. The vertices will be partitioned among the
processes according to the ``distribution``, with edges placed on the
process owning the source of the edge. Note that this behavior
permits sequential graph construction code to be parallelized
automatically, regardless of the underlying distribution.
-----------------------------------------------------------------------------
::
void clear()
Removes all of the edges and vertices from the local graph. To
eliminate all vertices and edges from the graph, this routine must be
executed in all processes.
-----------------------------------------------------------------------------
::
process_group_type& process_group();
const process_group_type& process_group() const;
Returns the process group over which this graph is distributed.
-----------------------------------------------------------------------------
::
distribution_type& distribution();
const distribution_type& distribution() const;
Returns the distribution used for initial placement of vertices.
-----------------------------------------------------------------------------
::
template<typename VertexProcessorMap>
void redistribute(VertexProcessorMap vertex_to_processor);
Redistributes the vertices (and, therefore, the edges) of the
graph. The property map ``vertex_to_processor`` provides, for each
vertex, the process identifier indicating where the vertex should be
moved. Once this collective routine has completed, the distributed
graph will reflect the new distribution. All vertex and edge
descsriptors and internal and external property maps are invalidated
by this operation.
-----------------------------------------------------------------------------
::
template<typename OStreamConstructibleArchive>
void save(std::string const& filename) const;
template<typename IStreamConstructibleArchive>
void load(std::string const& filename);
Serializes the graph to a Boost.Serialization archive.
``OStreamConstructibleArchive`` and ``IStreamConstructibleArchive``
are models of Boost.Serialization *Archive* with the extra
requirement that they can be constructed from a ``std::ostream``
and ``std::istream``.
``filename`` names a directory that will hold files for
the different processes.
Non-Member Functions
~~~~~~~~~~~~~~~~~~~~
::
std::pair<vertex_iterator, vertex_iterator>
vertices(const adjacency_list& g);
Returns an iterator-range providing access to the vertex set of graph
``g`` stored in this process. Each of the processes that contain ``g``
will get disjoint sets of vertices.
-----------------------------------------------------------------------------
::
std::pair<edge_iterator, edge_iterator>
edges(const adjacency_list& g);
Returns an iterator-range providing access to the edge set of graph
``g`` stored in this process.
-----------------------------------------------------------------------------
::
std::pair<adjacency_iterator, adjacency_iterator>
adjacent_vertices(vertex_descriptor u, const adjacency_list& g);
Returns an iterator-range providing access to the vertices adjacent to
vertex ``u`` in graph ``g``. The vertex ``u`` must be local to this process.
-----------------------------------------------------------------------------
::
std::pair<out_edge_iterator, out_edge_iterator>
out_edges(vertex_descriptor u, const adjacency_list& g);
Returns an iterator-range providing access to the out-edges of vertex
``u`` in graph ``g``. If the graph is undirected, this iterator-range
provides access to all edges incident on vertex ``u``. For both
directed and undirected graphs, for an out-edge ``e``, ``source(e, g)
== u`` and ``target(e, g) == v`` where ``v`` is a vertex adjacent to
``u``. The vertex ``u`` must be local to this process.
-----------------------------------------------------------------------------
::
std::pair<in_edge_iterator, in_edge_iterator>
in_edges(vertex_descriptor v, const adjacency_list& g);
Returns an iterator-range providing access to the in-edges of vertex
``v`` in graph ``g``. This operation is only available if
``bidirectionalS`` was specified for the ``Directed`` template
parameter. For an in-edge ``e``, ``target(e, g) == v`` and ``source(e,
g) == u`` for some vertex ``u`` that is adjacent to ``v``, whether the
graph is directed or undirected. The vertex ``v`` must be local to
this process.
-----------------------------------------------------------------------------
::
degree_size_type
out_degree(vertex_descriptor u, const adjacency_list& g);
Returns the number of edges leaving vertex ``u``. Vertex ``u`` must
be local to the executing process.
-----------------------------------------------------------------------------
::
degree_size_type
in_degree(vertex_descriptor u, const adjacency_list& g);
Returns the number of edges entering vertex ``u``. This operation is
only available if ``bidirectionalS`` was specified for the
``Directed`` template parameter. Vertex ``u`` must be local to the
executing process.
-----------------------------------------------------------------------------
::
vertices_size_type
num_vertices(const adjacency_list& g);
Returns the number of vertices in the graph ``g`` that are stored in
the executing process.
-----------------------------------------------------------------------------
::
edges_size_type
num_edges(const adjacency_list& g);
Returns the number of edges in the graph ``g`` that are stored in the
executing process.
-----------------------------------------------------------------------------
::
vertex_descriptor
vertex(vertices_size_type n, const adjacency_list& g);
Returns the ``n``th vertex in the graph's vertex list, according to the
distribution used to partition the graph. ``n`` must be a value
between zero and the sum of ``num_vertices(g)`` in each process (minus
one). Note that it is not necessarily the case that ``vertex(0, g) ==
*num_vertices(g).first``. This function is only guaranteed to be
accurate when no vertices have been added to or removed from the
graph after its initial construction.
-----------------------------------------------------------------------------
::
std::pair<edge_descriptor, bool>
edge(vertex_descriptor u, vertex_descriptor v,
const adjacency_list& g);
Returns an edge connecting vertex ``u`` to vertex ``v`` in graph
``g``. For bidirectional and undirected graphs, either vertex ``u`` or
vertex ``v`` must be local; for directed graphs, vertex ``u`` must be
local.
-----------------------------------------------------------------------------
::
std::pair<out_edge_iterator, out_edge_iterator>
edge_range(vertex_descriptor u, vertex_descriptor v,
const adjacency_list& g);
TODO: Not implemented. Returns a pair of out-edge iterators that give
the range for all the parallel edges from ``u`` to ``v``. This function only
works when the ``OutEdgeList`` for the ``adjacency_list`` is a container that
sorts the out edges according to target vertex, and allows for
parallel edges. The ``multisetS`` selector chooses such a
container. Vertex ``u`` must be stored in the executing process.
Structure Modification
~~~~~~~~~~~~~~~~~~~~~~
::
unspecified add_edge(vertex_descriptor u, vertex_descriptor v, adjacency_list& g);
unspecified add_edge(vertex_name_type u, vertex_descriptor v, adjacency_list& g);
unspecified add_edge(vertex_descriptor u, vertex_name_type v, adjacency_list& g);
unspecified add_edge(vertex_name_type u, vertex_name_type v, adjacency_list& g);
Adds edge ``(u,v)`` to the graph. The return type itself is
unspecified, but the type can be copy-constructed and implicitly
converted into a ``std::pair<edge_descriptor,bool>``. The edge
descriptor describes the added (or found) edge. For graphs that do not
allow parallel edges, if the edge
is already in the graph then a duplicate will not be added and the
``bool`` flag will be ``false``. Also, if u and v are descriptors for
the same vertex (creating a self loop) and the graph is undirected,
then the edge will not be added and the flag will be ``false``. When
the flag is ``false``, the returned edge descriptor points to the
already existing edge.
The parameters ``u`` and ``v`` can be either vertex descriptors or, if
the graph uses named vertices, the names of vertices. If no vertex
with the given name exists, the internal vertex constructor will be
invoked to create a new vertex property and a vertex with that
property will be added to the graph implicitly. The default internal
vertex constructor throws an exception.
-----------------------------------------------------------------------------
::
unspecified add_edge(vertex_descriptor u, vertex_descriptor v, const EdgeProperties& p, adjacency_list& g);
unspecified add_edge(vertex_name_type u, vertex_descriptor v, const EdgeProperties& p, adjacency_list& g);
unspecified add_edge(vertex_descriptor u, vertex_name_type v, const EdgeProperties& p, adjacency_list& g);
unspecified add_edge(vertex_name_type u, vertex_name_type v, const EdgeProperties& p, adjacency_list& g);
Adds edge ``(u,v)`` to the graph and attaches ``p`` as the value of the edge's
internal property storage. See the previous ``add_edge()`` member
function for more details.
-----------------------------------------------------------------------------
::
void
remove_edge(vertex_descriptor u, vertex_descriptor v,
adjacency_list& g);
Removes the edge ``(u,v)`` from the graph. If the directed selector is
``bidirectionalS`` or ``undirectedS``, either the source or target
vertex of the graph must be local. If the directed selector is
``directedS``, then the source vertex must be local.
-----------------------------------------------------------------------------
::
void
remove_edge(edge_descriptor e, adjacency_list& g);
Removes the edge ``e`` from the graph. If the directed selector is
``bidirectionalS`` or ``undirectedS``, either the source or target
vertex of the graph must be local. If the directed selector is
``directedS``, then the source vertex must be local.
-----------------------------------------------------------------------------
::
void remove_edge(out_edge_iterator iter, adjacency_list& g);
This has the same effect as ``remove_edge(*iter, g)``. For directed
(but not bidirectional) graphs, this will be more efficient than
``remove_edge(*iter, g)``.
-----------------------------------------------------------------------------
::
template <class Predicate >
void remove_out_edge_if(vertex_descriptor u, Predicate predicate,
adjacency_list& g);
Removes all out-edges of vertex ``u`` from the graph that satisfy the
predicate. That is, if the predicate returns ``true`` when applied to an
edge descriptor, then the edge is removed. The vertex ``u`` must be local.
The affect on descriptor and iterator stability is the same as that of
invoking remove_edge() on each of the removed edges.
-----------------------------------------------------------------------------
::
template <class Predicate >
void remove_in_edge_if(vertex_descriptor v, Predicate predicate,
adjacency_list& g);
Removes all in-edges of vertex ``v`` from the graph that satisfy the
predicate. That is, if the predicate returns true when applied to an
edge descriptor, then the edge is removed. The vertex ``v`` must be local.
The affect on descriptor and iterator stability is the same as that of
invoking ``remove_edge()`` on each of the removed edges.
This operation is available for undirected and bidirectional
adjacency_list graphs, but not for directed.
-----------------------------------------------------------------------------
::
template <class Predicate>
void remove_edge_if(Predicate predicate, adjacency_list& g);
Removes all edges from the graph that satisfy the predicate. That is,
if the predicate returns true when applied to an edge descriptor, then
the edge is removed.
The affect on descriptor and iterator stability is the same as that
of invoking ``remove_edge()`` on each of the removed edges.
-----------------------------------------------------------------------------
::
vertex_descriptor add_vertex(adjacency_list& g);
Adds a vertex to the graph and returns the vertex descriptor for the
new vertex. The vertex will be stored in the local process. This
function is not available when using named vertices.
-----------------------------------------------------------------------------
::
unspecified add_vertex(const VertexProperties& p, adjacency_list& g);
unspecified add_vertex(const vertex_name_type& p, adjacency_list& g);
Adds a vertex to the graph with the specified properties. If the graph
is using vertex names, the vertex will be added on whichever process
"owns" that name. Otherwise, the vertex will be stored in the local
process. Note that the second constructor will invoke the
user-customizable internal vertex constructor, which (by default)
throws an exception when it sees an unknown vertex.
The return type is of unspecified type, but can be copy-constructed
and can be implicitly converted into a vertex descriptor.
-----------------------------------------------------------------------------
::
void clear_vertex(vertex_descriptor u, adjacency_list& g);
Removes all edges to and from vertex ``u``. The vertex still appears
in the vertex set of the graph.
The affect on descriptor and iterator stability is the same as that of
invoking ``remove_edge()`` for all of the edges that have ``u`` as the source
or target.
This operation is not applicable to directed graphs, because the
incoming edges to vertex ``u`` are not known.
-----------------------------------------------------------------------------
::
void clear_out_edges(vertex_descriptor u, adjacency_list& g);
Removes all out-edges from vertex ``u``. The vertex still appears in
the vertex set of the graph.
The affect on descriptor and iterator stability is the same as that of
invoking ``remove_edge()`` for all of the edges that have ``u`` as the
source.
This operation is not applicable to undirected graphs (use
``clear_vertex()`` instead).
-----------------------------------------------------------------------------
::
void clear_in_edges(vertex_descriptor u, adjacency_list& g);
Removes all in-edges from vertex ``u``. The vertex still appears in
the vertex set of the graph.
The affect on descriptor and iterator stability is the same as that of
invoking ``remove_edge()`` for all of the edges that have ``u`` as the
target.
This operation is only applicable to bidirectional graphs.
-----------------------------------------------------------------------------
::
void remove_vertex(vertex_descriptor u, adjacency_list& g);
Remove vertex ``u`` from the vertex set of the graph. It is assumed
that there are no edges to or from vertex ``u`` when it is
removed. One way to make sure of this is to invoke ``clear_vertex()``
beforehand. The vertex ``u`` must be stored locally.
Property Map Accessors
~~~~~~~~~~~~~~~~~~~~~~
::
template <class PropertyTag>
property_map<adjacency_list, PropertyTag>::type
get(PropertyTag, adjacency_list& g);
template <class PropertyTag>
property_map<adjacency_list, Tag>::const_type
get(PropertyTag, const adjacency_list& g);
Returns the property map object for the vertex property specified by
``PropertyTag``. The ``PropertyTag`` must match one of the properties
specified in the graph's ``VertexProperty`` template argument. The
returned property map will be a `distributed property map`_.
-----------------------------------------------------------------------------
::
template <class PropertyTag , class X>
typename property_traits<property_map<adjacency_list, PropertyTag>::const_type>::value_type
get(PropertyTag, const adjacency_list& g, X x);
This returns the property value for ``x``, where ``x`` is either a vertex or
edge descriptor. The entity referred to by descriptor ``x`` must be
stored in the local process.
-----------------------------------------------------------------------------
::
template <class PropertyTag , class X, class Value>
void put(PropertyTag, const adjacency_list& g, X x, const Value& value);
This sets the property value for ``x`` to value. ``x`` is either a
vertex or edge descriptor. ``Value`` must be convertible to ``typename
property_traits<property_map<adjacency_list,
PropertyTag>::type>::value_type``.
-----------------------------------------------------------------------------
::
template <class GraphProperties, class GraphPropertyTag>
typename graph_property<adjacency_list, GraphPropertyTag>::type&
get_property(adjacency_list& g, GraphPropertyTag);
template <class GraphProperties, class GraphPropertyTag >
const typename graph_property<adjacency_list, GraphPropertyTag>::type&
get_property(const adjacency_list& g, GraphPropertyTag);
TODO: not implemented.
Return the property specified by ``GraphPropertyTag`` that is attached
to the graph object ``g``. The ``graph_property`` traits class is
defined in ``boost/graph/adjacency_list.hpp``.
-----------------------------------------------------------------------------
Copyright (C) 2004 The Trustees of Indiana University.
Copyright (C) 2007 Douglas Gregor
Authors: Douglas Gregor and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _adjacency_list: http://www.boost.org/libs/graph/doc/adjacency_list.html
.. _guidelines: http://www.boost.org/libs/graph/doc/using_adjacency_list.html
.. _process group: process_group.html
.. _mpi process group: process_group.html
.. _distributedS: distributedS.html
.. _Graph: http://www.boost.org/libs/graph/doc/Graph.html
.. _Distributed graph: DistributedGraph.html
.. _Incidence Graph: http://www.boost.org/libs/graph/doc/IncidenceGraph.html
.. _Adjacency Graph: http://www.boost.org/libs/graph/doc/AdjacencyGraph.html
.. _Bidirectional Graph: http://www.boost.org/libs/graph/doc/BidirectionalGraph.html
.. _Mutable Graph: http://www.boost.org/libs/graph/doc/MutableGraph.html
.. _Property Graph: http://www.boost.org/libs/graph/doc/PropertyGraph.html
.. _Mutable Property Graph: http://www.boost.org/libs/graph/doc/MutablePropertyGraph.html
.. _Vertex List Graph: http://www.boost.org/libs/graph/doc/VertexListGraph.html
.. _Edge List Graph: http://www.boost.org/libs/graph/doc/EdgeListGraph.html
.. _Distribution: concepts/Distribution.html
.. _distributed property map: distributed_property_map.html
.. _distributed property maps: distributed_property_map.html
.. _Distributed Vertex List Graph: DistributedVertexListGraph.html
.. _Distributed Edge List Graph: DistributedEdgeListGraph.html
.. _InputIterator: http://www.boost.org/doc/html/InputIterator.html
.. _member: http://www.boost.org/libs/multi_index/doc/reference/key_extraction.html#member_synopsis
.. _Boost.MultiIndex: http://www.boost.org/libs/multi_index/doc/index.html
.. _sorted_erdos_renyi_iterator: http://www.boost.org/libs/graph/doc/sorted_erdos_renyi_gen.html

View File

@@ -0,0 +1,744 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
===============================
|Logo| Distributed Property Map
===============================
A distributed property map adaptor is a property map whose stored
values are distributed across multiple non-overlapping memory spaces
on different processes. Values local to the current process are stored
within a local property map and may be immediately accessed via
``get`` and ``put``. Values stored on remote processes may also be
accessed via ``get`` and ``put``, but the behavior differs slightly:
- ``put`` operations update a local ghost cell and send a "put"
message to the process that owns the value. The owner is free to
update its own "official" value or may ignore the put request.
- ``get`` operations returns the contents of the local ghost
cell. If no ghost cell is available, one is created using a
(customizable) default value.
Using distributed property maps requires a bit more care than using
local, sequential property maps. While the syntax and semantics are
similar, distributed property maps may contain out-of-date
information that can only be guaranteed to be synchronized by
calling the ``synchronize`` function in all processes.
To address the issue of out-of-date values, distributed property
maps support multiple `consistency models`_ and may be supplied with a
`reduction operation`_.
Distributed property maps meet the requirements of the `Readable
Property Map`_ and, potentially, the `Writable Property Map`_ and
`Read/Write Property Map`_ concepts. Distributed property maps do
*not*, however, meet the requirements of the `Lvalue Property Map`_
concept, because elements residing in another process are not
directly addressible. There are several forms of distributed property
maps:
- `Distributed property map adaptor`_
- `Distributed iterator property map`_
- `Distributed safe iterator property map`_
- `Local property map`_
------------------
Consistency models
------------------
Distributed property maps offer many consistency models, which affect
how the values read from and written to remote keys relate to the
"official" value for that key stored in the owning process. The
consistency model of a distributed property map can be set with the
member function ``set_consistency_model`` to a bitwise-OR of the
flags in the ``boost::parallel::consistency_model`` enumeration. The
individual flags are:
- ``cm_forward``: The default consistency model, which propagates
values forward from ``put`` operations on remote processors to
the owner of the value being changed.
- ``cm_backward``: After all values have been forwarded or flushed
to the owning processes, each process receives updates values for
each of its ghost cells. After synchronization, the values in
ghost cells are guaranteed to match the values stored on the
owning processor.
- ``cm_bidirectional``: A combination of both ``cm_forward`` and
``cm_backward``.
- ``cm_flush``: At the beginning of synchronization, all of the
values stored locally in ghost cells are sent to their owning
processors.
- ``cm_reset``: Executes a ``reset()`` operation after
synchronization, setting the values in each ghost cell to their
default value.
- ``cm_clear``: Executes a ``clear()`` operation after
synchronizing, eliminating all ghost cells.
There are several common combinations of flags that result in
interesting consistency models. Some of these combinations are:
- ``cm_forward``: By itself, the forward consistency model enables
algorithms such as `Dijkstra's shortest paths`_ and
`Breadth-First Search`_ to operate correctly.
- ``cm_flush & cm_reset``: All updates values are queued locally,
then flushed during the synchronization step. Once the flush has
occurred, the ghost cells are restored to their default
values. This consistency model is used by the PageRank_
implementation to locally accumulate rank for each node.
-------------------
Reduction operation
-------------------
The reduction operation maintains consistency by determining how
multiple writes to a property map are resolved and what the property
map should do if unknown values are requested. More specifically, a
reduction operation is used in two cases:
1. When a value is needed for a remote key but no value is
immediately available, the reduction operation provides a
suitable default. For instance, a distributed property map
storing distances may have a reduction operation that returns
an infinite value as the default, whereas a distributed
property map for vertex colors may return white as the
default.
2. When a value is received from a remote process, the process
owning the key associated with that value must determine which
value---the locally stored value, the value received from a
remote process, or some combination of the two---will be
stored as the "official" value in the property map. The
reduction operation transforms the local and remote values
into the "official" value to be stored.
The reduction operation of a distributed property map can be set with
the ``set_reduce`` method of ``distributed_property_map``. The reduce
operation is a function object with two signatures. The first
signature takes a (remote) key and returns a default value for it,
whereas the second signatures takes a key and two values (local first,
then remote) and will return the combined value that will be stored in
the local property map. Reduction operations must also contain a
static constant ``non_default_resolver", which states whether the
reduction operation's default value actually acts like a default
value. It should be ``true`` when the default is meaningful (e.g.,
infinity for a distance) and ``false`` when the default should not be
used.
The following reduction operation is used by the distributed PageRank
algorithm. The default rank for a remote node is 0. Rank is
accumulated locally, and then the reduction operation combines local
and remote values by adding them. Combined with a consistency model
that flushes all values to the owner and then resets the values
locally in each step, the resulting property map will compute partial
sums on each processor and then accumulate the results on the owning
processor. The PageRank reduction operation is defined as follows.
::
template<typename T>
struct rank_accumulate_reducer {
static const bool non_default_resolver = true;
// The default rank of an unknown node
template<typename K>
T operator()(const K&) const { return T(0); }
template<typename K>
T operator()(const K&, const T& x, const T& y) const { return x + y; }
};
--------------------------------
Distributed property map adaptor
--------------------------------
The distributed property map adaptor creates a distributed property
map from a local property map, a `process group`_ over which
distribution should occur, and a `global descriptor`_ type that
indexes the distributed property map.
Synopsis
~~~~~~~~
::
template<typename ProcessGroup, typename LocalPropertyMap, typename Key,
typename GhostCellS = gc_mapS>
class distributed_property_map
{
public:
typedef ... ghost_regions_type;
distributed_property_map();
distributed_property_map(const ProcessGroup& pg,
const LocalPropertyMap& pm);
template<typename Reduce>
distributed_property_map(const ProcessGroup& pg,
const LocalPropertyMap& pm,
const Reduce& reduce);
template<typename Reduce> void set_reduce(const Reduce& reduce);
void set_consistency_model(int model);
void flush();
void reset();
void clear();
};
reference get(distributed_property_map pm, const key_type& key);
void
put(distributed_property_map pm, const key_type& key, const value_type& value);
local_put(distributed_property_map pm, const key_type& key, const value_type& value);
void request(distributed_property_map pm, const key_type& key);
void synchronize(distributed_property_map& pm);
template<typename Key, typename ProcessGroup, typename LocalPropertyMap>
distributed_property_map<ProcessGroup, LocalPropertyMap, Key>
make_distributed_property_map(const ProcessGroup& pg, LocalPropertyMap pmap);
template<typename Key, typename ProcessGroup, typename LocalPropertyMap,
typename Reduce>
distributed_property_map<ProcessGroup, LocalPropertyMap, Key>
make_distributed_property_map(const ProcessGroup& pg, LocalPropertyMap pmap,
Reduce reduce);
Template parameters
~~~~~~~~~~~~~~~~~~~
**ProcessGroup**:
The type of the process group over which the
property map is distributed and is also the medium for
communication.
**LocalPropertyMap**:
The type of the property map that will store values
for keys local to this processor. The ``value_type`` of this
property map will become the ``value_type`` of the distributed
property map. The distributed property map models the same property
map concepts as the ``LocalPropertyMap``, with one exception: a
distributed property map cannot be an `Lvalue Property Map`_
(because remote values are not addressable), and is therefore
limited to `Read/Write Property Map`_.
**Key**:
The ``key_type`` of the distributed property map, which
must model the `Global Descriptor`_ concept. The process ID type of
the ``Key`` parameter must match the process ID type of the
``ProcessGroup``, and the local descriptor type of the ``Key`` must
be convertible to the ``key_type`` of the ``LocalPropertyMap``.
**GhostCellS**:
A selector type that indicates how ghost cells should be stored in
the distributed property map. There are either two or three
options, depending on your compiler:
- ``boost::parallel::gc_mapS`` (default): Uses an STL ``map`` to
store the ghost cells for each process.
- ``boost::parallel::gc_vector_mapS``: Uses a sorted STL
``vector`` to store the ghost cells for each process. This
option works well when there are likely to be few insertions
into the ghost cells; for instance, if the only ghost cells used
are for neighboring vertices, the property map can be
initialized with cells for each neighboring vertex, providing
faster lookups than a ``map`` and using less space.
- ``boost::parallel::gc_hash_mapS``: Uses the GCC ``hash_map`` to
store ghost cells. This option may improve performance over
``map`` for large problems sizes, where the set of ghost cells
cannot be predetermined.
Member functions
~~~~~~~~~~~~~~~~
::
distributed_property_map();
Default-construct a distributed property map. The property map is in
an invalid state, and may only be used if it is reassigned to a valid
property map.
------------------------------------------------------------------------------
::
distributed_property_map(const ProcessGroup& pg,
const LocalPropertyMap& pm);
template<typename Reduce>
distributed_property_map(const ProcessGroup& pg,
const LocalPropertyMap& pm,
const Reduce& reduce);
Construct a property map from a process group and a local property
map. If a ``reduce`` operation is not supplied, a default of
``basic_reduce<value_type>`` will be used.
------------------------------------------------------------------------------
::
template<typename Reduce> void set_reduce(const Reduce& reduce);
Replace the current reduction operation with the new operation
``reduce``.
------------------------------------------------------------------------------
::
void set_consistency_model(int model);
Sets the consistency model of the distributed property map, which will
take effect on the next synchronization step. See the section
`Consistency models`_ for a description of the effect of various
consistency model flags.
------------------------------------------------------------------------------
::
void flush();
Emits a message sending the contents of all local ghost cells to the
owners of those cells.
------------------------------------------------------------------------------
::
void reset();
Replaces the values stored in each of the ghost cells with the default
value generated by the reduction operation.
------------------------------------------------------------------------------
::
void clear();
Removes all ghost cells from the property map.
Free functions
~~~~~~~~~~~~~~
::
reference get(distributed_property_map pm, const key_type& key);
Retrieves the element in ``pm`` associated with the given ``key``. If
the key refers to data stored locally, returns the actual value
associated with the key. If the key refers to nonlocal data, returns
the value of the ghost cell. If no ghost cell exists, the behavior
depends on the current reduction operation: if a reduction operation
has been set and has ``non_default_resolver`` set ``true``, then a
ghost cell will be created according to the default value provided by
the reduction operation. Otherwise, the call to ``get`` will abort
because no value exists for this remote cell. To avoid this problem,
either set a reduction operation that generates default values,
``request()`` the value and then perform a synchronization step, or
``put`` a value into the cell before reading it.
------------------------------------------------------------------------------
::
void
put(distributed_property_map pm, const key_type& key, const value_type& value);
Places the given ``value`` associated with ``key`` into property map
``pm``. If the key refers to data stored locally, the value is
immediately updates. If the key refers to data stored in a remote
process, updates (or creates) a local ghost cell containing this
value for the key and sends the new value to the owning process. Note
that the owning process may reject this value based on the reduction
operation, but this will not be detected until the next
synchronization step.
------------------------------------------------------------------------------
::
void
local_put(distributed_property_map pm, const key_type& key, const value_type& value);
Equivalent to ``put(pm, key, value)``, except that no message is sent
to the owning process when the value is changed for a nonlocal key.
------------------------------------------------------------------------------
::
void synchronize(distributed_property_map& pm);
Synchronize the values stored in the distributed property maps. Each
process much execute ``synchronize`` at the same time, after which
the ghost cells in every process will reflect the actual value stored
in the owning process.
------------------------------------------------------------------------------
::
void request(distributed_property_map pm, const key_type& key);
Request that the element "key" be available after the next
synchronization step. For a non-local key, this means establishing a
ghost cell and requesting.
------------------------------------------------------------------------------
::
template<typename Key, typename ProcessGroup, typename LocalPropertyMap>
distributed_property_map<ProcessGroup, LocalPropertyMap, Key>
make_distributed_property_map(const ProcessGroup& pg, LocalPropertyMap pmap);
template<typename Key, typename ProcessGroup, typename LocalPropertyMap,
typename Reduce>
distributed_property_map<ProcessGroup, LocalPropertyMap, Key>
make_distributed_property_map(const ProcessGroup& pg, LocalPropertyMap pmap,
Reduce reduce);
Create a distributed property map over process group ``pg`` and local
property map ``pmap``. A default reduction operation will be generated
if it is not provided.
---------------------------------
Distributed iterator property map
---------------------------------
The distributed iterator property map adaptor permits the creation of
distributed property maps from random access iterators using the same
syntax as non-distributed iterator property maps. The specialization
is based on a `local property map`_, which contains the
indices for local descriptors and is typically returned to describe
the vertex indices of a distributed graph.
Synopsis
~~~~~~~~
::
template<typename RandomAccessIterator, typename ProcessGroup,
typename GlobalKey, typename LocalMap, typename ValueType,
typename Reference>
class iterator_property_map<RandomAccessIterator,
local_property_map<ProcessGroup, GlobalKey, LocalMap>,
ValueType, Reference>
{
public:
typedef local_property_map<ProcessGroup, GlobalKey, LocalMap> index_map_type;
iterator_property_map();
iterator_property_map(RandomAccessIterator iter, const index_map_type& id);
};
reference get(iterator_property_map pm, const key_type& key);
void put(iterator_property_map pm, const key_type& key, const value_type& value);
template<typename RandomAccessIterator, typename ProcessGroup,
typename GlobalKey, typename LocalMap>
iterator_property_map<RandomAccessIterator,
local_property_map<ProcessGroup, GlobalKey, LocalMap> >
make_iterator_property_map(RandomAccessIterator iter,
local_property_map<ProcessGroup, GlobalKey, LocalMap> id);
Member functions
~~~~~~~~~~~~~~~~
::
iterator_property_map();
Default-constructs a distributed iterator property map. The property
map is in an invalid state, and must be reassigned before it may be
used.
------------------------------------------------------------------------------
::
iterator_property_map(RandomAccessIterator iter, const index_map_type& id);
Constructs a distributed iterator property map using the property map
``id`` to map global descriptors to local indices. The random access
iterator sequence ``[iter, iter + n)`` must be a valid range, where
``[0, n)`` is the range of local indices.
Free functions
~~~~~~~~~~~~~~
::
reference get(iterator_property_map pm, const key_type& key);
Returns the value associated with the given ``key`` from the
distributed property map.
------------------------------------------------------------------------------
::
void put(iterator_property_map pm, const key_type& key, const value_type& value);
Associates the value with the given key in the distributed property map.
------------------------------------------------------------------------------
::
template<typename RandomAccessIterator, typename ProcessGroup,
typename GlobalKey, typename LocalMap, typename ValueType,
typename Reference>
iterator_property_map<RandomAccessIterator,
local_property_map<ProcessGroup, GlobalKey, LocalMap>,
ValueType, Reference>
make_iterator_property_map(RandomAccessIterator iter,
local_property_map<ProcessGroup, GlobalKey, LocalMap>,
ValueType, Reference> id);
Creates a distributed iterator property map using the given iterator
``iter`` and local index property map ``id``.
--------------------------------------
Distributed safe iterator property map
--------------------------------------
The distributed safe iterator property map adaptor permits the
creation of distributed property maps from random access iterators
using the same syntax as non-distributed safe iterator property
maps. The specialization is based on a `local property map`_, which
contains the indices for local descriptors and is typically returned
to describe the vertex indices of a distributed graph. Safe iterator
property maps check the indices of accesses to ensure that they are
not out-of-bounds before attempting to access an value.
Synopsis
~~~~~~~~
::
template<typename RandomAccessIterator, typename ProcessGroup,
typename GlobalKey, typename LocalMap, typename ValueType,
typename Reference>
class safe_iterator_property_map<RandomAccessIterator,
local_property_map<ProcessGroup, GlobalKey, LocalMap>,
ValueType, Reference>
{
public:
typedef local_property_map<ProcessGroup, GlobalKey, LocalMap> index_map_type;
safe_iterator_property_map();
safe_iterator_property_map(RandomAccessIterator iter, std::size_t n,
const index_map_type& id);
};
reference get(safe_iterator_property_map pm, const key_type& key);
void put(safe_iterator_property_map pm, const key_type& key, const value_type& value);
template<typename RandomAccessIterator, typename ProcessGroup,
typename GlobalKey, typename LocalMap, typename ValueType,
typename Reference>
safe_iterator_property_map<RandomAccessIterator,
local_property_map<ProcessGroup, GlobalKey, LocalMap>,
ValueType, Reference>
make_safe_iterator_property_map(RandomAccessIterator iter,
std::size_t n,
local_property_map<ProcessGroup, GlobalKey, LocalMap>,
ValueType, Reference> id);
Member functions
~~~~~~~~~~~~~~~~
::
safe_iterator_property_map();
Default-constructs a distributed safe iterator property map. The property
map is in an invalid state, and must be reassigned before it may be
used.
------------------------------------------------------------------------------
::
safe_iterator_property_map(RandomAccessIterator iter, std::size_t n,
const index_map_type& id);
Constructs a distributed safe iterator property map using the property map
``id`` to map global descriptors to local indices. The random access
iterator sequence ``[iter, iter + n)``.
Free functions
~~~~~~~~~~~~~~
::
reference get(safe_iterator_property_map pm, const key_type& key);
Returns the value associated with the given ``key`` from the
distributed property map.
------------------------------------------------------------------------------
::
void put(safe_iterator_property_map pm, const key_type& key, const value_type& value);
Associates the value with the given key in the distributed property map.
------------------------------------------------------------------------------
::
template<typename RandomAccessIterator, typename ProcessGroup,
typename GlobalKey, typename LocalMap, typename ValueType,
typename Reference>
safe_iterator_property_map<RandomAccessIterator,
local_property_map<ProcessGroup, GlobalKey, LocalMap>,
ValueType, Reference>
make_safe_iterator_property_map(RandomAccessIterator iter,
std::size_t n,
local_property_map<ProcessGroup, GlobalKey, LocalMap>,
ValueType, Reference> id);
Creates a distributed safe iterator property map using the given iterator
``iter`` and local index property map ``id``. The indices in ``id`` must
------------------
Local property map
------------------
A property map adaptor that accesses an underlying property map whose
key type is the local part of the ``Key`` type for the local subset
of keys. Local property maps are typically used by distributed graph
types for vertex index properties.
Synopsis
~~~~~~~~
::
template<typename ProcessGroup, typename GlobalKey, typename LocalMap>
class local_property_map
{
public:
typedef typename property_traits<LocalMap>::value_type value_type;
typedef GlobalKey key_type;
typedef typename property_traits<LocalMap>::reference reference;
typedef typename property_traits<LocalMap>::category category;
explicit
local_property_map(const ProcessGroup& process_group = ProcessGroup(),
const LocalMap& local_map = LocalMap());
reference operator[](const key_type& key);
};
reference get(const local_property_map& pm, key_type key);
void put(local_property_map pm, const key_type& key, const value_type& value);
Template parameters
~~~~~~~~~~~~~~~~~~~
:ProcessGroup: the type of the process group over which the global
keys are distributed.
:GlobalKey: The ``key_type`` of the local property map, which
must model the `Global Descriptor`_ concept. The process ID type of
the ``GlobalKey`` parameter must match the process ID type of the
``ProcessGroup``, and the local descriptor type of the ``GlobalKey``
must be convertible to the ``key_type`` of the ``LocalMap``.
:LocalMap: the type of the property map that will store values
for keys local to this processor. The ``value_type`` of this
property map will become the ``value_type`` of the local
property map. The local property map models the same property
map concepts as the ``LocalMap``.
Member functions
~~~~~~~~~~~~~~~~
::
explicit
local_property_map(const ProcessGroup& process_group = ProcessGroup(),
const LocalMap& local_map = LocalMap());
Constructs a local property map whose keys are distributed across the
given process group and which accesses the given local map.
------------------------------------------------------------------------------
::
reference operator[](const key_type& key);
Access the value associated with the given key, which must be local
to this process.
Free functions
~~~~~~~~~~~~~~
::
reference get(const local_property_map& pm, key_type key);
Return the value associated with the given key, which must be local
to this process.
------------------------------------------------------------------------------
::
void put(local_property_map pm, const key_type& key, const value_type& value);
Set the value associated with the given key, which must be local to
this process.
-----------------------------------------------------------------------------
Copyright (C) 2004, 2005 The Trustees of Indiana University.
Authors: Douglas Gregor and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _Readable Property Map: http://www.boost.org/libs/property_map/ReadablePropertyMap.html
.. _Writable Property Map: http://www.boost.org/libs/property_map/WritablePropertyMap.html
.. _Read/Write Property Map: http://www.boost.org/libs/property_map/ReadWritePropertyMap.html
.. _Lvalue Property Map: http://www.boost.org/libs/property_map/LvaluePropertyMap.html
.. _Process Group: process_group.html
.. _Global Descriptor: GlobalDescriptor.html
.. _Dijkstra's shortest paths: dijkstra_shortest_paths.html
.. _Breadth-First Search: breadth_first_search.html
.. _PageRank: page_rank.html

View File

@@ -0,0 +1,210 @@
.. Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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)
================================
|Logo| Distributed queue adaptor
================================
::
template<typename ProcessGroup, typename Buffer>
class distributed_queue
{
public:
typedef ProcessGroup process_group_type;
typedef Buffer buffer_type;
typedef typename buffer_type::value_type value_type;
typedef typename buffer_type::size_type size_type;
explicit
distributed_queue(const ProcessGroup& process_group = ProcessGroup(),
const Buffer& buffer = Buffer(),
bool polling = false);
distributed_queue(const ProcessGroup& process_group, bool polling);
void push(const value_type& x);
void pop();
value_type& top();
const value_type& top() const;
bool empty() const;
size_type size() const;
};
template<typename ProcessGroup, typename Buffer>
inline distributed_queue<ProcessGroup, Buffer>
make_distributed_queue(const ProcessGroup& process_group, const Buffer& buffer,
bool polling = false);
Class template ``distributed_queue`` implements a distributed queue
across a process group. The distributed queue is an adaptor over an
existing (local) queue, which must model the Buffer_ concept. Each
process stores a distinct copy of the local queue, from which it draws
or removes elements via the ``pop`` and ``top`` members.
The value type of the local queue must be a model of the
`Global Descriptor`_ concept. The ``push`` operation of the
distributed queue passes (via a message) the value to its owning
processor. Thus, the elements within a particular local queue are
guaranteed to have the process owning that local queue as an owner.
Synchronization of distributed queues occurs in the ``empty`` and
``size`` functions, which will only return "empty" values (true or 0,
respectively) when the entire distributed queue is empty. If the local
queue is empty but the distributed queue is not, the operation will
block until either condition changes. When the ``size`` function of a
nonempty queue returns, it returns the size of the local queue. These
semantics were selected so that sequential code that processes
elements in the queue via the following idiom can be parallelized via
introduction of a distributed queue:
::
distributed_queue<...> Q;
Q.push(x);
while (!Q.empty()) {
// do something, that may push a value onto Q
}
In the parallel version, the initial ``push`` operation will place
the value ``x`` onto its owner's queue. All processes will
synchronize at the call to empty, and only the process owning ``x``
will be allowed to execute the loop (``Q.empty()`` returns
false). This iteration may in turn push values onto other remote
queues, so when that process finishes execution of the loop body
and all processes synchronize again in ``empty``, more processes
may have nonempty local queues to execute. Once all local queues
are empty, ``Q.empty()`` returns ``false`` for all processes.
The distributed queue can receive messages at two different times:
during synchronization and when polling ``empty``. Messages are
always received during synchronization, to ensure that accurate
local queue sizes can be determines. However, whether ``empty``
should poll for messages is specified as an option to the
constructor. Polling may be desired when the order in which
elements in the queue are processed is not important, because it
permits fewer synchronization steps and less communication
overhead. However, when more strict ordering guarantees are
required, polling may be semantically incorrect. By disabling
polling, one ensures that parallel execution using the idiom above
will not process an element at a later "level" before an earlier
"level".
The distributed queue nearly models the Buffer_
concept. However, the ``push`` routine does not necessarily
increase the result of ``size()`` by one (although the size of the
global queue does increase by one).
Member Functions
----------------
::
explicit
distributed_queue(const ProcessGroup& process_group = ProcessGroup(),
const Buffer& buffer = Buffer(),
bool polling = false);
Build a new distributed queue that communicates over the given
``process_group``, whose local queue is initialized via ``buffer`` and
which may or may not poll for messages.
-----------------------------------------------------------------------------
::
distributed_queue(const ProcessGroup& process_group, bool polling);
Build a new distributed queue that communicates over the given
``process_group``, whose local queue is default-initalized and which
may or may not poll for messages.
-----------------------------------------------------------------------------
::
void push(const value_type& x);
Push an element onto the distributed queue.
The element will be sent to its owner process to be added to that
process's local queue. If polling is enabled for this queue and
the owner process is the current process, the value will be
immediately pushed onto the local queue.
Complexity: O(1) messages of size O(``sizeof(value_type)``) will be
transmitted.
-----------------------------------------------------------------------------
::
void pop();
Pop an element off the local queue. The queue must not be ``empty()``.
-----------------------------------------------------------------------------
::
value_type& top();
const value_type& top();
Returns the top element in the local queue. The queue must not be
``empty()``.
-----------------------------------------------------------------------------
::
bool empty() const;
Determines if the queue is empty.
When the local queue is nonempty, returns true. If the local queue is
empty, synchronizes with all other processes in the process group
until either (1) the local queue is nonempty (returns true) (2) the
entire distributed queue is empty (returns false).
-----------------------------------------------------------------------------
::
size_type size() const;
Determines the size of the local queue.
The behavior of this routine is equivalent to the behavior of
``empty``, except that when ``empty`` returns true this
function returns the size of the local queue and when ``empty``
returns false this function returns zero.
Free Functions
--------------
::
template<typename ProcessGroup, typename Buffer>
inline distributed_queue<ProcessGroup, Buffer>
make_distributed_queue(const ProcessGroup& process_group, const Buffer& buffer,
bool polling = false);
Constructs a distributed queue.
-----------------------------------------------------------------------------
Copyright (C) 2004, 2005 The Trustees of Indiana University.
Authors: Douglas Gregor and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _Global descriptor: GlobalDescriptor.html
.. _Buffer: http://www.boost.org/libs/graph/doc/Buffer.html

View File

@@ -0,0 +1,100 @@
.. Copyright (C) 2004-2009 The Trustees of Indiana University.
Use, modification and distribution is 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)
===========================
|Logo| Fruchterman Reingold
===========================
::
namespace graph { namespace distributed {
template<typename Graph, typename PositionMap,
typename AttractiveForce, typename RepulsiveForce,
typename ForcePairs, typename Cooling, typename DisplacementMap>
void
fruchterman_reingold_force_directed_layout
(const Graph& g,
PositionMap position,
typename property_traits<PositionMap>::value_type const& origin,
typename property_traits<PositionMap>::value_type const& extent,
AttractiveForce attractive_force,
RepulsiveForce repulsive_force,
ForcePairs force_pairs,
Cooling cool,
DisplacementMap displacement)
template<typename Graph, typename PositionMap,
typename AttractiveForce, typename RepulsiveForce,
typename ForcePairs, typename Cooling, typename DisplacementMap>
void
fruchterman_reingold_force_directed_layout
(const Graph& g,
PositionMap position,
typename property_traits<PositionMap>::value_type const& origin,
typename property_traits<PositionMap>::value_type const& extent,
AttractiveForce attractive_force,
RepulsiveForce repulsive_force,
ForcePairs force_pairs,
Cooling cool,
DisplacementMap displacement,
simple_tiling tiling)
} }
.. contents::
Where Defined
-------------
<``boost/graph/distributed/fruchterman_reingold.hpp``>
also accessible from
<``boost/graph/fruchterman_reingold.hpp``>
Parameters
----------
IN: ``const Graph& g``
The graph type must be a model of `Distributed Graph`_. The graph
type must also model the `Incidence Graph`_.
OUT: ``PositionMap position``
IN: ``property_traits<PositionMap>::value_type origin``
IN: ``property_traits<PositionMap>::value_type extent``
IN: ``AttractiveForce attractive_force``
IN: ``RepulsiveForce repulsive_force``
IN: ``ForcePairs force_pairs``
IN: ``Cooling cool``
IN: ``DisplacementMap displacement``
..
Complexity
----------
..
Algorithm Description
---------------------
-----------------------------------------------------------------------------
Copyright (C) 2009 The Trustees of Indiana University.
Authors: Nick Edmonds and Andrew Lumsdaine
.. |Logo| image:: pbgl-logo.png
:align: middle
:alt: Parallel BGL
:target: http://www.osl.iu.edu/research/pbgl
.. _Distributed Graph: DistributedGraph.html
.. _Incidence Graph: http://www.boost.org/libs/graph/doc/IncidenceGraph.html
.. _Distributed Property Map: distributed_property_map.html

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View File

@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Concept Distributed Edge List Graph</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-concept-distributed-edge-list-graph">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Concept Distributed Edge List Graph</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#description" id="id1">Description</a></li>
<li><a class="reference internal" href="#notation" id="id2">Notation</a></li>
<li><a class="reference internal" href="#refinement-of" id="id3">Refinement of</a></li>
<li><a class="reference internal" href="#associated-types" id="id4">Associated types</a></li>
<li><a class="reference internal" href="#valid-expressions" id="id5">Valid Expressions</a></li>
<li><a class="reference internal" href="#models" id="id6">Models</a></li>
</ul>
</div>
<div class="section" id="description">
<h1><a class="toc-backref" href="#id1">Description</a></h1>
<p>A Distributed Edge List Graph is a graph whose vertices are
distributed across multiple processes or address spaces. The
<tt class="docutils literal"><span class="pre">vertices</span></tt> and <tt class="docutils literal"><span class="pre">num_vertices</span></tt> functions retain the same
signatures as in the <a class="reference external" href="http://www.boost.org/libs/graph/doc/EdgeListGraph.html">Edge List Graph</a> concept, but return only
the local set (and size of the local set) of vertices.</p>
</div>
<div class="section" id="notation">
<h1><a class="toc-backref" href="#id2">Notation</a></h1>
<dl class="docutils">
<dt>G</dt>
<dd>A type that models the Distributed Edge List Graph concept.</dd>
<dt>g</dt>
<dd>An object of type <tt class="docutils literal"><span class="pre">G</span></tt>.</dd>
</dl>
</div>
<div class="section" id="refinement-of">
<h1><a class="toc-backref" href="#id3">Refinement of</a></h1>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="http://www.boost.org/libs/graph/doc/Graph.html">Graph</a></li>
</ul>
</blockquote>
</div>
<div class="section" id="associated-types">
<h1><a class="toc-backref" href="#id4">Associated types</a></h1>
<table border="1" class="docutils">
<colgroup>
<col width="18%" />
<col width="44%" />
<col width="38%" />
</colgroup>
<tbody valign="top">
<tr><td>Edge
descriptor type</td>
<td><tt class="docutils literal"><span class="pre">graph_traits&lt;G&gt;::edge_descriptor</span></tt></td>
<td>Must model the
<a class="reference external" href="GlobalDescriptor.html">Global Descriptor</a> concept.</td>
</tr>
<tr><td>Edge iterator
type</td>
<td><tt class="docutils literal"><span class="pre">graph_traits&lt;G&gt;::edge_iterator</span></tt></td>
<td>Iterates over edges stored
locally. The value type must be
<tt class="docutils literal"><span class="pre">edge_descriptor</span></tt>.</td>
</tr>
<tr><td>Edges size
type</td>
<td><tt class="docutils literal"><span class="pre">graph_traits&lt;G&gt;::edges_size_type</span></tt></td>
<td>The unsigned integral type used
to store the number of edges
in the local subgraph.</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="valid-expressions">
<h1><a class="toc-backref" href="#id5">Valid Expressions</a></h1>
<table border="1" class="docutils">
<colgroup>
<col width="17%" />
<col width="22%" />
<col width="23%" />
<col width="39%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Name</th>
<th class="head">Expression</th>
<th class="head">Type</th>
<th class="head">Semantics</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>Local edge set</td>
<td><tt class="docutils literal"><span class="pre">edges(g)</span></tt></td>
<td><tt class="docutils literal"><span class="pre">std::pair&lt;</span></tt>
<tt class="docutils literal"><span class="pre">edge_iterator,</span></tt>
<tt class="docutils literal"><span class="pre">edge_iterator&gt;</span></tt></td>
<td>Returns an iterator range
providing access to the local
edges in the graph.</td>
</tr>
<tr><td>Number of local
edges.</td>
<td><tt class="docutils literal"><span class="pre">num_edges(g)</span></tt></td>
<td><tt class="docutils literal"><span class="pre">edges_size_type</span></tt></td>
<td>Returns the number of edges
stored locally in the graph.</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="models">
<h1><a class="toc-backref" href="#id6">Models</a></h1>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="distributed_adjacency_list.html">Distributed adjacency list</a></li>
</ul>
</blockquote>
<hr class="docutils" />
<p>Copyright (C) 2005 The Trustees of Indiana University.</p>
<p>Authors: Douglas Gregor and Andrew Lumsdaine</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:21 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,93 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Concept Distributed Graph</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-concept-distributed-graph">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Concept Distributed Graph</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#description" id="id1">Description</a></li>
<li><a class="reference internal" href="#notation" id="id2">Notation</a></li>
<li><a class="reference internal" href="#refinement-of" id="id3">Refinement of</a></li>
<li><a class="reference internal" href="#associated-types" id="id4">Associated types</a></li>
<li><a class="reference internal" href="#models" id="id5">Models</a></li>
</ul>
</div>
<div class="section" id="description">
<h1><a class="toc-backref" href="#id1">Description</a></h1>
<p>A Distributed Graph is a graph whose vertices or edges are
distributed across multiple processes or address spaces. The
descriptors of a Distributed Graph must model the <a class="reference external" href="GlobalDescriptor.html">Global
Descriptor</a> concept.</p>
</div>
<div class="section" id="notation">
<h1><a class="toc-backref" href="#id2">Notation</a></h1>
<dl class="docutils">
<dt>G</dt>
<dd>A type that models the Distributed Graph concept.</dd>
</dl>
</div>
<div class="section" id="refinement-of">
<h1><a class="toc-backref" href="#id3">Refinement of</a></h1>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="http://www.boost.org/libs/graph/doc/Graph.html">Graph</a></li>
</ul>
</blockquote>
</div>
<div class="section" id="associated-types">
<h1><a class="toc-backref" href="#id4">Associated types</a></h1>
<table border="1" class="docutils">
<colgroup>
<col width="18%" />
<col width="44%" />
<col width="38%" />
</colgroup>
<tbody valign="top">
<tr><td>Vertex
descriptor type</td>
<td><tt class="docutils literal"><span class="pre">graph_traits&lt;G&gt;::vertex_descriptor</span></tt></td>
<td>Must model the
<a class="reference external" href="GlobalDescriptor.html">Global Descriptor</a> concept.</td>
</tr>
<tr><td>Edge
descriptor type</td>
<td><tt class="docutils literal"><span class="pre">graph_traits&lt;G&gt;::edge_descriptor</span></tt></td>
<td>Must model the
<a class="reference external" href="GlobalDescriptor.html">Global Descriptor</a> concept.</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="models">
<h1><a class="toc-backref" href="#id5">Models</a></h1>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="distributed_adjacency_list.html">Distributed adjacency list</a></li>
</ul>
</blockquote>
<hr class="docutils" />
<p>Copyright (C) 2005 The Trustees of Indiana University.</p>
<p>Authors: Douglas Gregor and Andrew Lumsdaine</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:22 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,141 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Concept Distributed Vertex List Graph</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-concept-distributed-vertex-list-graph">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Concept Distributed Vertex List Graph</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#description" id="id1">Description</a></li>
<li><a class="reference internal" href="#notation" id="id2">Notation</a></li>
<li><a class="reference internal" href="#refinement-of" id="id3">Refinement of</a></li>
<li><a class="reference internal" href="#associated-types" id="id4">Associated types</a></li>
<li><a class="reference internal" href="#valid-expressions" id="id5">Valid Expressions</a></li>
<li><a class="reference internal" href="#models" id="id6">Models</a></li>
</ul>
</div>
<div class="section" id="description">
<h1><a class="toc-backref" href="#id1">Description</a></h1>
<p>A Distributed Vertex List Graph is a graph whose vertices are
distributed across multiple processes or address spaces. The
<tt class="docutils literal"><span class="pre">vertices</span></tt> and <tt class="docutils literal"><span class="pre">num_vertices</span></tt> functions retain the same
signatures as in the <a class="reference external" href="http://www.boost.org/libs/graph/doc/VertexListGraph.html">Vertex List Graph</a> concept, but return only
the local set (and size of the local set) of vertices.</p>
</div>
<div class="section" id="notation">
<h1><a class="toc-backref" href="#id2">Notation</a></h1>
<dl class="docutils">
<dt>G</dt>
<dd>A type that models the Distributed Vertex List Graph concept.</dd>
<dt>g</dt>
<dd>An object of type <tt class="docutils literal"><span class="pre">G</span></tt>.</dd>
</dl>
</div>
<div class="section" id="refinement-of">
<h1><a class="toc-backref" href="#id3">Refinement of</a></h1>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="http://www.boost.org/libs/graph/doc/Graph.html">Graph</a></li>
</ul>
</blockquote>
</div>
<div class="section" id="associated-types">
<h1><a class="toc-backref" href="#id4">Associated types</a></h1>
<table border="1" class="docutils">
<colgroup>
<col width="18%" />
<col width="44%" />
<col width="38%" />
</colgroup>
<tbody valign="top">
<tr><td>Vertex
descriptor type</td>
<td><tt class="docutils literal"><span class="pre">graph_traits&lt;G&gt;::vertex_descriptor</span></tt></td>
<td>Must model the
<a class="reference external" href="GlobalDescriptor.html">Global Descriptor</a> concept.</td>
</tr>
<tr><td>Vertex iterator
type</td>
<td><tt class="docutils literal"><span class="pre">graph_traits&lt;G&gt;::vertex_iterator</span></tt></td>
<td>Iterates over vertices stored
locally. The value type must be
<tt class="docutils literal"><span class="pre">vertex_descriptor</span></tt>.</td>
</tr>
<tr><td>Vertices size
type</td>
<td><tt class="docutils literal"><span class="pre">graph_traits&lt;G&gt;::vertices_size_type</span></tt></td>
<td>The unsigned integral type used
to store the number of vertices
in the local subgraph.</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="valid-expressions">
<h1><a class="toc-backref" href="#id5">Valid Expressions</a></h1>
<table border="1" class="docutils">
<colgroup>
<col width="17%" />
<col width="22%" />
<col width="23%" />
<col width="39%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Name</th>
<th class="head">Expression</th>
<th class="head">Type</th>
<th class="head">Semantics</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>Local vertex set</td>
<td><tt class="docutils literal"><span class="pre">vertices(g)</span></tt></td>
<td><tt class="docutils literal"><span class="pre">std::pair&lt;</span></tt>
<tt class="docutils literal"><span class="pre">vertex_iterator,</span></tt>
<tt class="docutils literal"><span class="pre">vertex_iterator&gt;</span></tt></td>
<td>Returns an iterator range
providing access to the local
vertices in the graph.</td>
</tr>
<tr><td>Number of local
vertices.</td>
<td><tt class="docutils literal"><span class="pre">num_vertices(g)</span></tt></td>
<td><tt class="docutils literal"><span class="pre">vertices_size_type</span></tt></td>
<td>Returns the number of vertices
stored locally in the graph.</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="models">
<h1><a class="toc-backref" href="#id6">Models</a></h1>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="distributed_adjacency_list.html">Distributed adjacency list</a></li>
</ul>
</blockquote>
<hr class="docutils" />
<p>Copyright (C) 2005 The Trustees of Indiana University.</p>
<p>Authors: Douglas Gregor and Andrew Lumsdaine</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:21 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Concept Global Descriptor</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-concept-global-descriptor">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Concept Global Descriptor</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#description" id="id1">Description</a></li>
<li><a class="reference internal" href="#refinement-of" id="id2">Refinement of</a></li>
<li><a class="reference internal" href="#notation" id="id3">Notation</a></li>
<li><a class="reference internal" href="#associated-types" id="id4">Associated types</a></li>
<li><a class="reference internal" href="#valid-expressions" id="id5">Valid Expressions</a></li>
</ul>
</div>
<div class="section" id="description">
<h1><a class="toc-backref" href="#id1">Description</a></h1>
<p>A global descriptor is an object that represents an entity that is
owned by some process and may reside in an address space not
accessible to the currently-executing process. The global descriptor
consists of two parts: the <em>owner</em> of the entity, which is the
identifier of that process in which the entity resides, and a <em>local
descriptor</em>, that uniquely identifies the entity with the address
space of the owner.</p>
</div>
<div class="section" id="refinement-of">
<h1><a class="toc-backref" href="#id2">Refinement of</a></h1>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="http://www.sgi.com/tech/stl/DefaultConstructible.html">Default Constructible</a></li>
<li><a class="reference external" href="http://www.sgi.com/tech/stl/Assignable.html">Assignable</a></li>
</ul>
</blockquote>
</div>
<div class="section" id="notation">
<h1><a class="toc-backref" href="#id3">Notation</a></h1>
<dl class="docutils">
<dt>X</dt>
<dd>A type that models the Global Descriptor concept.</dd>
<dt>x</dt>
<dd>Object of type X</dd>
</dl>
</div>
<div class="section" id="associated-types">
<h1><a class="toc-backref" href="#id4">Associated types</a></h1>
<table border="1" class="docutils">
<colgroup>
<col width="23%" />
<col width="29%" />
<col width="48%" />
</colgroup>
<tbody valign="top">
<tr><td>Process ID type</td>
<td><tt class="docutils literal"><span class="pre">process_id_type</span></tt></td>
<td>Determined by the process group
associated with type X.</td>
</tr>
<tr><td>Local descriptor
type</td>
<td><tt class="docutils literal"><span class="pre">local_type</span></tt></td>
<td>Determined by the data structure
the descriptor accesses.
Must model <a class="reference external" href="http://www.sgi.com/tech/stl/EqualityComparable.html">Equality Comparable</a>
and <a class="reference external" href="http://www.sgi.com/tech/stl/CopyConstructible.html">Copy Constructible</a>.</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="valid-expressions">
<h1><a class="toc-backref" href="#id5">Valid Expressions</a></h1>
<table border="1" class="docutils">
<colgroup>
<col width="17%" />
<col width="22%" />
<col width="22%" />
<col width="39%" />
</colgroup>
<thead valign="bottom">
<tr><th class="head">Name</th>
<th class="head">Expression</th>
<th class="head">Type</th>
<th class="head">Semantics</th>
</tr>
</thead>
<tbody valign="top">
<tr><td>Owner</td>
<td><tt class="docutils literal"><span class="pre">owner(x)</span></tt></td>
<td><tt class="docutils literal"><span class="pre">process_id_type</span></tt></td>
<td>Returns the owner of <tt class="docutils literal"><span class="pre">x</span></tt>.</td>
</tr>
<tr><td>Local descriptor</td>
<td><tt class="docutils literal"><span class="pre">local(x)</span></tt></td>
<td><tt class="docutils literal"><span class="pre">local_type</span></tt></td>
<td>Returns the local descriptor
uniquely identifying <tt class="docutils literal"><span class="pre">x</span></tt>.</td>
</tr>
</tbody>
</table>
<hr class="docutils" />
<p>Copyright (C) 2005 The Trustees of Indiana University.</p>
<p>Authors: Douglas Gregor and Andrew Lumsdaine</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:22 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,248 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Betweenness Centrality</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-betweenness-centrality">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Betweenness Centrality</h1>
<!-- Copyright (C) 2004-2009 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<pre class="literal-block">
// named parameter versions
template&lt;typename Graph, typename Param, typename Tag, typename Rest&gt;
void
brandes_betweenness_centrality(const Graph&amp; g,
const bgl_named_params&lt;Param,Tag,Rest&gt;&amp; params);
template&lt;typename Graph, typename CentralityMap&gt;
void
brandes_betweenness_centrality(const Graph&amp; g, CentralityMap centrality);
template&lt;typename Graph, typename CentralityMap, typename EdgeCentralityMap&gt;
void
brandes_betweenness_centrality(const Graph&amp; g, CentralityMap centrality,
EdgeCentralityMap edge_centrality_map);
// non-named parameter versions
template&lt;typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename IncomingMap, typename DistanceMap, typename DependencyMap,
typename PathCountMap, typename VertexIndexMap, typename Buffer&gt;
void
brandes_betweenness_centrality(const Graph&amp; g,
CentralityMap centrality,
EdgeCentralityMap edge_centrality_map,
IncomingMap incoming,
DistanceMap distance,
DependencyMap dependency,
PathCountMap path_count,
VertexIndexMap vertex_index,
Buffer sources,
typename property_traits&lt;DistanceMap&gt;::value_type delta);
template&lt;typename Graph, typename CentralityMap, typename EdgeCentralityMap,
typename IncomingMap, typename DistanceMap, typename DependencyMap,
typename PathCountMap, typename VertexIndexMap, typename WeightMap,
typename Buffer&gt;
void
brandes_betweenness_centrality(const Graph&amp; g,
CentralityMap centrality,
EdgeCentralityMap edge_centrality_map,
IncomingMap incoming,
DistanceMap distance,
DependencyMap dependency,
PathCountMap path_count,
VertexIndexMap vertex_index,
Buffer sources,
typename property_traits&lt;WeightMap&gt;::value_type delta,
WeightMap weight_map);
// helper functions
template&lt;typename Graph, typename CentralityMap&gt;
typename property_traits&lt;CentralityMap&gt;::value_type
central_point_dominance(const Graph&amp; g, CentralityMap centrality);
</pre>
<p>The <tt class="docutils literal"><span class="pre">brandes_betweenness_centrality()</span></tt> function computes the
betweenness centrality of the vertices and edges in a graph. The
method of calculating betweenness centrality in <em>O(V)</em> space is due to
Brandes <a class="citation-reference" href="#brandes01" id="id1">[Brandes01]</a>. The algorithm itself is a modification of
Brandes algorithm by Edmonds <a class="citation-reference" href="#edmonds09" id="id2">[Edmonds09]</a>.</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#where-defined" id="id3">Where Defined</a></li>
<li><a class="reference internal" href="#parameters" id="id4">Parameters</a></li>
<li><a class="reference internal" href="#complexity" id="id5">Complexity</a></li>
<li><a class="reference internal" href="#algorithm-description" id="id6">Algorithm Description</a></li>
<li><a class="reference internal" href="#bibliography" id="id7">Bibliography</a></li>
</ul>
</div>
<div class="section" id="where-defined">
<h1><a class="toc-backref" href="#id3">Where Defined</a></h1>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/distributed/betweenness_centrality.hpp</span></tt>&gt;</p>
<p>also accessible from</p>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/betweenness_centrality.hpp</span></tt>&gt;</p>
</div>
<div class="section" id="parameters">
<h1><a class="toc-backref" href="#id4">Parameters</a></h1>
<dl class="docutils">
<dt>IN: <tt class="docutils literal"><span class="pre">const</span> <span class="pre">Graph&amp;</span> <span class="pre">g</span></tt></dt>
<dd>The graph type must be a model of <a class="reference external" href="DistributedGraph.html">Distributed Graph</a>. The graph
type must also model the <a class="reference external" href="http://www.boost.org/libs/graph/doc/IncidenceGraph.html">Incidence Graph</a> concept. 0-weighted
edges in <tt class="docutils literal"><span class="pre">g</span></tt> will result in undefined behavior.</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">CentralityMap</span> <span class="pre">centrality</span></tt></dt>
<dd><p class="first">A centrality map may be supplied to the algorithm, if not supplied a
<tt class="docutils literal"><span class="pre">dummy_property_map</span></tt> will be used and no vertex centrality
information will be recorded. The <tt class="docutils literal"><span class="pre">CentralityMap</span></tt> type must be a
<a class="reference external" href="distributed_property_map.html">Distributed Property Map</a>. The key type must be the graph's
vertex descriptor type.</p>
<p class="last"><strong>Default</strong>: A <tt class="docutils literal"><span class="pre">dummy_property_map</span></tt>.</p>
</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">EdgeCentralityMap</span> <span class="pre">edge_centrality_map</span></tt></dt>
<dd><p class="first">An edge centrality map may be supplied to the algorithm, if not
supplied a <tt class="docutils literal"><span class="pre">dummy_property_map</span></tt> will be used and no edge
centrality information will be recorded. The <tt class="docutils literal"><span class="pre">EdgeCentralityMap</span></tt>
type must be a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a>. The key type must be
the graph's vertex descriptor type.</p>
<p class="last"><strong>Default</strong>: A <tt class="docutils literal"><span class="pre">dummy_property_map</span></tt>.</p>
</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">IncomingMap</span> <span class="pre">incoming</span></tt></dt>
<dd><p class="first">The incoming map contains the incoming edges to a vertex that are
part of shortest paths to that vertex. The <tt class="docutils literal"><span class="pre">IncomingMap</span></tt> type
must be a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a>. Its key type and value type
must both be the graph's vertex descriptor type.</p>
<dl class="last docutils">
<dt><strong>Default</strong>: An <tt class="docutils literal"><span class="pre">iterator_property_map</span></tt> created from a</dt>
<dd><tt class="docutils literal"><span class="pre">std::vector</span></tt> of <tt class="docutils literal"><span class="pre">std::vector</span></tt> of the graph's vertex
descriptor type.</dd>
</dl>
</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">DistanceMap</span> <span class="pre">distance</span></tt></dt>
<dd><p class="first">The distance map records the distance to vertices during the
shortest paths portion of the algorithm. The <tt class="docutils literal"><span class="pre">DistanceMap</span></tt> type
must be a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a>. Its key type must be the
graph's vertex descriptor type.</p>
<dl class="last docutils">
<dt><strong>Default</strong>: An <tt class="docutils literal"><span class="pre">iterator_property_map</span></tt> created from a</dt>
<dd><tt class="docutils literal"><span class="pre">std::vector</span></tt> of the value type of the <tt class="docutils literal"><span class="pre">CentralityMap</span></tt>.</dd>
</dl>
</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">DependencyMap</span> <span class="pre">dependency</span></tt></dt>
<dd><p class="first">The dependency map records the dependency of each vertex during the
centrality calculation portion of the algorithm. The
<tt class="docutils literal"><span class="pre">DependencyMap</span></tt> type must be a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a>. Its
key type must be the graph's vertex descriptor type.</p>
<dl class="last docutils">
<dt><strong>Default</strong>: An <tt class="docutils literal"><span class="pre">iterator_property_map</span></tt> created from a</dt>
<dd><tt class="docutils literal"><span class="pre">std::vector</span></tt> of the value type of the <tt class="docutils literal"><span class="pre">CentralityMap</span></tt>.</dd>
</dl>
</dd>
</dl>
<p>IN: <tt class="docutils literal"><span class="pre">PathCountMap</span> <span class="pre">path_count</span></tt></p>
<blockquote>
<p>The path count map records the number of shortest paths each vertex
is on during the centrality calculation portion of the algorithm.
The <tt class="docutils literal"><span class="pre">PathCountMap</span></tt> type must be a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a>.
Its key type must be the graph's vertex descriptor type.</p>
<dl class="docutils">
<dt><strong>Default</strong>: An <tt class="docutils literal"><span class="pre">iterator_property_map</span></tt> created from a</dt>
<dd><tt class="docutils literal"><span class="pre">std::vector</span></tt> of the graph's degree size type.</dd>
</dl>
</blockquote>
<dl class="docutils">
<dt>IN: <tt class="docutils literal"><span class="pre">VertexIndexMap</span> <span class="pre">vertex_index</span></tt></dt>
<dd><p class="first">A model of <a class="reference external" href="http://www.boost.org/libs/property_map/ReadablePropertyMap.html">Readable Property Map</a> whose key type is the vertex
descriptor type of the graph <tt class="docutils literal"><span class="pre">g</span></tt> and whose value type is an
integral type. The property map should map from vertices to their
(local) indices in the range <em>[0, num_vertices(g))</em>.</p>
<p class="last"><strong>Default</strong>: <tt class="docutils literal"><span class="pre">get(vertex_index,</span> <span class="pre">g)</span></tt></p>
</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">WeightMap</span> <span class="pre">weight_map</span></tt></dt>
<dd>A model of <a class="reference external" href="http://www.boost.org/libs/property_map/ReadablePropertyMap.html">Readable Property Map</a> whose key type is the edge
descriptor type of the graph <tt class="docutils literal"><span class="pre">g</span></tt>. If not supplied the betweenness
centrality calculation will be unweighted.</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">Buffer</span> <span class="pre">sources</span></tt></dt>
<dd><p class="first">A model of <a class="reference external" href="http://www.boost.org/libs/graph/doc/Buffer.html">Buffer</a> containing the starting vertices for the
algorithm. If <tt class="docutils literal"><span class="pre">sources</span></tt> is empty a complete betweenness
centrality calculation using all vertices in <tt class="docutils literal"><span class="pre">g</span></tt> will be
performed. The value type of the Buffer must be the graph's vertex
descriptor type.</p>
<p class="last"><strong>Default</strong>: An empty <tt class="docutils literal"><span class="pre">boost::queue</span></tt> of int.</p>
</dd>
</dl>
</div>
<div class="section" id="complexity">
<h1><a class="toc-backref" href="#id5">Complexity</a></h1>
<p>Computing the shortest paths, counting them, and computing the
contribution to the centrality map is <em>O(V log V)</em>. Calculating exact
betweenness centrality requires counting the shortest paths from all
vertices in <tt class="docutils literal"><span class="pre">g</span></tt>, thus exact betweenness centrality is <em>O(V^2 log
V)</em>.</p>
</div>
<div class="section" id="algorithm-description">
<h1><a class="toc-backref" href="#id6">Algorithm Description</a></h1>
<p>For the vertices in <tt class="docutils literal"><span class="pre">sources</span></tt> (or all vertices in <tt class="docutils literal"><span class="pre">g</span></tt> when
<tt class="docutils literal"><span class="pre">sources</span></tt> is empty) the algorithm first calls a customized
implementation of <a class="reference external" href="dijkstra_shortest_paths.html">delta_stepping_shortest_paths</a> which maintains a
shortest path tree using an <tt class="docutils literal"><span class="pre">IncomingMap</span></tt>. The <tt class="docutils literal"><span class="pre">IncomingMap</span></tt>
contains the source of all incoming edges on shortest paths.</p>
<p>The <tt class="docutils literal"><span class="pre">IncomingMap</span></tt> defines the shortest path DAG at the target of the
edges in the shortest paths tree. In the bidirectional case edge
flags could be used to translate the shortest paths information to the
source of the edges. Setting edge flags during the shortest path
computation rather than using an <tt class="docutils literal"><span class="pre">IncomingMap</span></tt> would result in
adding an <em>O(V)</em> factor to the inner loop of the shortest paths
computation to account for having to clear edge flags when a new
shortest path is found. This would increase the complexity of the
algorithm. Asymptotically, the current implementation is better,
however using edge flags in the bidirectional case would reduce the
number of supersteps required by the depth of the shortest paths DAG
for each vertex. Currently an <tt class="docutils literal"><span class="pre">outgoing</span></tt> map is explicitly
constructed by simply reversing the edges in the incoming map. Once
the <tt class="docutils literal"><span class="pre">outgoing</span></tt> map is constructed it is traversed in dependency
order from the source of the shortest paths calculation in order to
compute path counts. Once path counts are computed the shortest paths
DAG is again traversed in dependency order from the source to
calculate the dependency and centrality of each vertex.</p>
<p>The algorithm is complete when the centrality has been computed from
all vertices in <tt class="docutils literal"><span class="pre">g</span></tt>.</p>
</div>
<div class="section" id="bibliography">
<h1><a class="toc-backref" href="#id7">Bibliography</a></h1>
<table class="docutils citation" frame="void" id="brandes01" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[Brandes01]</a></td><td>Ulrik Brandes. A Faster Algorithm for Betweenness
Centrality. In the Journal of Mathematical Sociology, volume 25
number 2, pages 163--177, 2001.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="edmonds09" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id2">[Edmonds09]</a></td><td>Nick Edmonds, Torsten Hoefler, and Andrew Lumsdaine.
A Space-Efficient Parallel Algorithm for Computing Betweenness
Centrality in Sparse Networks. Indiana University tech report.
2009.</td></tr>
</tbody>
</table>
<hr class="docutils" />
<p>Copyright (C) 2009 The Trustees of Indiana University.</p>
<p>Authors: Nick Edmonds and Andrew Lumsdaine</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:21 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,184 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Boman et al graph coloring</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-boman-et-al-graph-coloring">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Boman et al graph coloring</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<pre class="literal-block">
namespace graph {
template&lt;typename DistributedGraph, typename ColorMap&gt;
typename property_traits&lt;ColorMap&gt;::value_type
boman_et_al_graph_coloring
(const DistributedGraph&amp; g,
ColorMap color,
typename graph_traits&lt;DistributedGraph&gt;::vertices_size_type s = 100);
template&lt;typename DistributedGraph, typename ColorMap, typename ChooseColor&gt;
typename property_traits&lt;ColorMap&gt;::value_type
boman_et_al_graph_coloring
(const DistributedGraph&amp; g,
ColorMap color,
typename graph_traits&lt;DistributedGraph&gt;::vertices_size_type s,
ChooseColor choose_color);
template&lt;typename DistributedGraph, typename ColorMap, typename ChooseColor,
typename VertexOrdering&gt;
typename property_traits&lt;ColorMap&gt;::value_type
boman_et_al_graph_coloring
(const DistributedGraph&amp; g, ColorMap color,
typename graph_traits&lt;DistributedGraph&gt;::vertices_size_type s,
ChooseColor choose_color, VertexOrdering ordering);
template&lt;typename DistributedGraph, typename ColorMap, typename ChooseColor,
typename VertexOrdering, typename VertexIndexMap&gt;
typename property_traits&lt;ColorMap&gt;::value_type
boman_et_al_graph_coloring
(const DistributedGraph&amp; g,
ColorMap color,
typename graph_traits&lt;DistributedGraph&gt;::vertices_size_type s,
ChooseColor choose_color,
VertexOrdering ordering, VertexIndexMap vertex_index);
}
</pre>
<p>The <tt class="docutils literal"><span class="pre">boman_et_al_graph_coloring</span></tt> function colors the vertices of an
undirected, distributed graph such that no two adjacent vertices have
the same color. All of the vertices of a given color form an
independent set in the graph. Graph coloring has been used to solve
various problems, including register allocation in compilers,
optimization problems, and scheduling problems.</p>
<img align="right" alt="Vertex coloring example" class="align-right" src="../vertex_coloring.png" style="width: 462px; height: 269px;" />
<p>The problem of coloring a graph with the fewest possible number of
colors is NP-complete, so many algorithms (including the one
implemented here) are heuristic algorithms that try to minimize the
number of colors but are not guaranteed to provide an optimal
solution. This algorithm <a class="citation-reference" href="#bbc05" id="id1">[BBC05]</a> is similar to the
<tt class="docutils literal"><span class="pre">sequential_vertex_coloring</span></tt> algorithm, that iterates through the
vertices once and selects the lowest-numbered color that the current
vertex can have. The coloring and the number of colors is therefore
related to the ordering of the vertices in the sequential case.</p>
<p>The distributed <tt class="docutils literal"><span class="pre">boman_et_al_graph_coloring</span></tt> algorithm will produce
different colorings depending on the ordering and distribution of the
vertices and the number of parallel processes cooperating to perform
the coloring.</p>
<p>The algorithm returns the number of colors <tt class="docutils literal"><span class="pre">num_colors</span></tt> used to
color the graph.</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#where-defined" id="id2">Where Defined</a></li>
<li><a class="reference internal" href="#parameters" id="id3">Parameters</a></li>
<li><a class="reference internal" href="#complexity" id="id4">Complexity</a></li>
<li><a class="reference internal" href="#performance" id="id5">Performance</a></li>
</ul>
</div>
<div class="section" id="where-defined">
<h1><a class="toc-backref" href="#id2">Where Defined</a></h1>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/distributed/boman_et_al_graph_coloring.hpp</span></tt>&gt;</p>
</div>
<div class="section" id="parameters">
<h1><a class="toc-backref" href="#id3">Parameters</a></h1>
<dl class="docutils">
<dt>IN: <tt class="docutils literal"><span class="pre">Graph&amp;</span> <span class="pre">g</span></tt></dt>
<dd>The graph type must be a model of <a class="reference external" href="DistributedVertexListGraph.html">Distributed Vertex List Graph</a> and
<a class="reference external" href="DistributedEdgeListGraph.html">Distributed Edge List Graph</a>.</dd>
<dt>UTIL/OUT: <tt class="docutils literal"><span class="pre">ColorMap</span> <span class="pre">color</span></tt></dt>
<dd>Stores the color of each vertex, which will be a value in the range
[0, <tt class="docutils literal"><span class="pre">num_colors</span></tt>). The type <tt class="docutils literal"><span class="pre">ColorMap</span></tt> must model the
<a class="reference external" href="http://www.boost.org/libs/property_map/ReadWritePropertyMap.html">Read/Write Property Map</a> concept and must be a <a class="reference external" href="distributed_property_map.html">distributed
property map</a>.</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">vertices_size_type</span> <span class="pre">s</span></tt></dt>
<dd><p class="first">The number of vertices to color within each superstep. After
<tt class="docutils literal"><span class="pre">s</span></tt> vertices have been colored, the colors of boundary vertices
will be sent to their out-of-process neighbors. Smaller values
communicate more often but may reduce the risk of conflicts,
whereas larger values do more work in between communication steps
but may create many conflicts.</p>
<p class="last"><strong>Default</strong>: 100</p>
</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">ChooseColor</span> <span class="pre">choose_color</span></tt></dt>
<dd><p class="first">A function object that chooses the color for a vertex given the
colors of its neighbors. The function object will be passed a vector
of values (<tt class="docutils literal"><span class="pre">marked</span></tt>) and a <tt class="docutils literal"><span class="pre">marked_true</span></tt> value, and should
return a <tt class="docutils literal"><span class="pre">color</span></tt> value such that <tt class="docutils literal"><span class="pre">color</span> <span class="pre">&gt;=</span> <span class="pre">marked.size()</span></tt> or
<tt class="docutils literal"><span class="pre">marked[color]</span> <span class="pre">!=</span> <span class="pre">marked_true</span></tt>.</p>
<p class="last"><strong>Default</strong>:
<tt class="docutils literal"><span class="pre">boost::graph::distributed::first_fit_color&lt;color_type&gt;()</span></tt>, where
<tt class="docutils literal"><span class="pre">color_type</span></tt> is the value type of the <tt class="docutils literal"><span class="pre">ColorMap</span></tt> property map.</p>
</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">VertexOrdering</span> <span class="pre">ordering</span></tt></dt>
<dd><p class="first">A binary predicate function object that provides total ordering on
the vertices in the graph. Whenever a conflict arises, only one of
the processes involved will recolor the vertex in the next round,
and this ordering determines which vertex should be considered
conflicting (its owning process will then handle the
conflict). Ideally, this predicate should order vertices so that
conflicting vertices will be spread uniformly across
processes. However, this predicate <em>must</em> resolve the same way on
both processors.</p>
<p class="last"><strong>Default</strong>: <em>unspecified</em></p>
</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">VertexIndexMap</span> <span class="pre">index</span></tt></dt>
<dd><p class="first">A mapping from vertex descriptors to indices in the range <em>[0,
num_vertices(g))</em>. This must be a <a class="reference external" href="http://www.boost.org/libs/property_map/ReadablePropertyMap.html">Readable Property Map</a> whose
key type is a vertex descriptor and whose value type is an integral
type, typically the <tt class="docutils literal"><span class="pre">vertices_size_type</span></tt> of the graph.</p>
<p class="last"><strong>Default:</strong> <tt class="docutils literal"><span class="pre">get(vertex_index,</span> <span class="pre">g)</span></tt></p>
</dd>
</dl>
</div>
<div class="section" id="complexity">
<h1><a class="toc-backref" href="#id4">Complexity</a></h1>
<p>The complexity of this algorithm is hard to characterize,
because it depends greatly on the number of <em>conflicts</em> that occur
during the algorithm. A conflict occurs when a <em>boundary vertex</em>
(i.e., a vertex that is adjacent to a vertex stored on a different
processor) is given the same color is a boundary vertex adjacency to
it (but on another processor). Conflicting vertices must be assigned
new colors, requiring additional work and communication. The work
involved in reassigning a color for a conflicting vertex is <em>O(d)</em>,
where <em>d</em> is the degree of the vertex and <em>O(1)</em> messages of <em>O(1)</em>
size are needed to resolve the conflict. Note that the number of
conflicts grows with (1) the number of processes and (2) the number
of inter-process edges.</p>
</div>
<div class="section" id="performance">
<h1><a class="toc-backref" href="#id5">Performance</a></h1>
<p>The performance of this implementation of Bomen et al's graph coloring
algorithm is illustrated by the following charts. Scaling and
performance is reasonable for all of the graphs we have tried.</p>
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_cluster_Odin_columns_11.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_cluster_Odin_columns_11.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_cluster_Odin_columns_11_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_cluster_Odin_columns_11_speedup_1.png" />
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_cluster_Odin_columns_11.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_cluster_Odin_columns_11.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_cluster_Odin_columns_11_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_cluster_Odin_columns_11_speedup_1.png" />
<hr class="docutils" />
<p>Copyright (C) 2005 The Trustees of Indiana University.</p>
<p>Authors: Douglas Gregor and Andrew Lumsdaine</p>
<table class="docutils citation" frame="void" id="bbc05" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[BBC05]</a></td><td>Erik G. Boman, Doruk Bozdag, Umit Catalyurek, Assefaw
H. Gebremedhin, and Fredrik Manne. A Scalable Parallel Graph Coloring
Algorithm for Distributed Memory Computers. [preprint]</td></tr>
</tbody>
</table>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:21 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,269 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Breadth-First Search</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-breadth-first-search">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Breadth-First Search</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<pre class="literal-block">
// named parameter version
template &lt;class Graph, class P, class T, class R&gt;
void breadth_first_search(Graph&amp; G,
typename graph_traits&lt;Graph&gt;::vertex_descriptor s,
const bgl_named_params&lt;P, T, R&gt;&amp; params);
// non-named parameter version
template &lt;class Graph, class Buffer, class BFSVisitor,
class ColorMap&gt;
void breadth_first_search(const Graph&amp; g,
typename graph_traits&lt;Graph&gt;::vertex_descriptor s,
Buffer&amp; Q, BFSVisitor vis, ColorMap color);
</pre>
<p>The <tt class="docutils literal"><span class="pre">breadth_first_search()</span></tt> function performs a distributed breadth-first
traversal of a directed or undirected graph. The distributed BFS is
syntactically equivalent to its <a class="reference external" href="http://www.boost.org/libs/graph/doc/breadth_first_search.html">sequential counterpart</a>, which
provides additional background and discussion. Differences in
semantics are highlighted here, and we refer the reader to the
documentation of the <a class="reference external" href="http://www.boost.org/libs/graph/doc/breadth_first_search.html">sequential breadth-first search</a> for the
remainder of the details.</p>
<p>This distributed breadth-first search algorithm implements a
<em>level-synchronized</em> breadth-first search, meaning that all vertices
in a given level of the BFS tree will be processed (potentially in
parallel) before any vertices from a successive level in the tree are
processed. Distributed breadth-first search visitors should account
for this behavior, a topic discussed further in <a class="reference internal" href="#visitor-event-points">Visitor Event
Points</a>.</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#where-defined" id="id1">Where Defined</a></li>
<li><a class="reference internal" href="#parameter-defaults" id="id2">Parameter Defaults</a></li>
<li><a class="reference internal" href="#complexity" id="id3">Complexity</a></li>
<li><a class="reference internal" href="#visitor-event-points" id="id4">Visitor Event Points</a><ul>
<li><a class="reference internal" href="#making-visitors-safe-for-distributed-bfs" id="id5">Making Visitors Safe for Distributed BFS</a></li>
<li><a class="reference internal" href="#distributed-bfs-visitor-example" id="id6">Distributed BFS Visitor Example</a></li>
</ul>
</li>
<li><a class="reference internal" href="#performance" id="id7">Performance</a></li>
</ul>
</div>
<div class="section" id="where-defined">
<h1><a class="toc-backref" href="#id1">Where Defined</a></h1>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/breadth_first_search.hpp</span></tt>&gt;</p>
</div>
<div class="section" id="parameter-defaults">
<h1><a class="toc-backref" href="#id2">Parameter Defaults</a></h1>
<p>All parameters of the <a class="reference external" href="http://www.boost.org/libs/graph/doc/breadth_first_search.html">sequential breadth-first search</a> are supported
and have essentially the same meaning. Only differences are documented
here.</p>
<dl class="docutils">
<dt>IN: <tt class="docutils literal"><span class="pre">Graph&amp;</span> <span class="pre">g</span></tt></dt>
<dd>The graph type must be a model of <a class="reference external" href="DistributedGraph.html">Distributed Graph</a>.</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">vertex_descriptor</span> <span class="pre">s</span></tt></dt>
<dd>The start vertex must be the same in every process.</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">visitor(BFSVisitor</span> <span class="pre">vis)</span></tt></dt>
<dd>The visitor must be a distributed BFS visitor. The suble differences
between sequential and distributed BFS visitors are discussed in the
section <a class="reference internal" href="#visitor-event-points">Visitor Event Points</a>.</dd>
<dt>UTIL/OUT: <tt class="docutils literal"><span class="pre">color_map(ColorMap</span> <span class="pre">color)</span></tt></dt>
<dd>The color map must be a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a> with the same
process group as the graph <tt class="docutils literal"><span class="pre">g</span></tt> whose colors must monotonically
darken (white -&gt; gray -&gt; black). The default value is a distributed
<tt class="docutils literal"><span class="pre">iterator_property_map</span></tt> created from a <tt class="docutils literal"><span class="pre">std::vector</span></tt> of
<tt class="docutils literal"><span class="pre">default_color_type</span></tt>.</dd>
<dt>UTIL: <tt class="docutils literal"><span class="pre">buffer(Buffer&amp;</span> <span class="pre">Q)</span></tt></dt>
<dd><p class="first">The queue must be a distributed queue that passes vertices to their
owning process. If already-visited vertices should not be visited
again (as is typical for BFS), the queue must filter duplicates
itself. The queue controls synchronization within the algorithm: its
<tt class="docutils literal"><span class="pre">empty()</span></tt> method must not return <tt class="docutils literal"><span class="pre">true</span></tt> until all local queues
are empty.</p>
<dl class="last docutils">
<dt><strong>Default:</strong> A <tt class="docutils literal"><span class="pre">distributed_queue</span></tt> of a <tt class="docutils literal"><span class="pre">filtered_queue</span></tt> over a</dt>
<dd>standard <tt class="docutils literal"><span class="pre">boost::queue</span></tt>. This queue filters out duplicate
vertices and distributes vertices appropriately.</dd>
</dl>
</dd>
</dl>
</div>
<div class="section" id="complexity">
<h1><a class="toc-backref" href="#id3">Complexity</a></h1>
<p>This algorithm performs <em>O(V + E)</em> work in <em>d + 1</em> BSP supersteps,
where <em>d</em> is the diameter of the connected component being
searched. Over all supersteps, <em>O(E)</em> messages of constant size will
be transmitted.</p>
</div>
<div class="section" id="visitor-event-points">
<h1><a class="toc-backref" href="#id4">Visitor Event Points</a></h1>
<p>The <a class="reference external" href="http://www.boost.org/libs/graph/doc/BFSVisitor.html">BFS Visitor</a> concept defines 9 event points that will be
triggered by the <a class="reference external" href="http://www.boost.org/libs/graph/doc/breadth_first_search.html">sequential breadth-first search</a>. The distributed
BFS retains these nine event points, but the sequence of events
triggered and the process in which each event occurs will change
depending on the distribution of the graph.</p>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">initialize_vertex(s,</span> <span class="pre">g)</span></tt></dt>
<dd>This will be invoked by every process for each local vertex.</dd>
<dt><tt class="docutils literal"><span class="pre">discover_vertex(u,</span> <span class="pre">g)</span></tt></dt>
<dd>This will be invoked each time a process discovers a new vertex
<tt class="docutils literal"><span class="pre">u</span></tt>. Due to incomplete information in distributed property maps,
this event may be triggered many times for the same vertex <tt class="docutils literal"><span class="pre">u</span></tt>.</dd>
<dt><tt class="docutils literal"><span class="pre">examine_vertex(u,</span> <span class="pre">g)</span></tt></dt>
<dd>This will be invoked by the process owning the vertex <tt class="docutils literal"><span class="pre">u</span></tt>. If the
distributed queue prevents duplicates, it will be invoked only
once for a particular vertex <tt class="docutils literal"><span class="pre">u</span></tt>.</dd>
<dt><tt class="docutils literal"><span class="pre">examine_edge(e,</span> <span class="pre">g)</span></tt></dt>
<dd>This will be invoked by the process owning the source vertex of
<tt class="docutils literal"><span class="pre">e</span></tt>. If the distributed queue prevents duplicates, it will be
invoked only once for a particular edge <tt class="docutils literal"><span class="pre">e</span></tt>.</dd>
<dt><tt class="docutils literal"><span class="pre">tree_edge(e,</span> <span class="pre">g)</span></tt></dt>
<dd>Similar to <tt class="docutils literal"><span class="pre">examine_edge</span></tt>, this will be invoked by the process
owning the source vertex and may be invoked only once. Unlike the
sequential BFS, this event may be triggered even when the target has
already been discovered (but by a different process). Thus, some
<tt class="docutils literal"><span class="pre">non_tree_edge</span></tt> events in a sequential BFS may become
<tt class="docutils literal"><span class="pre">tree_edge</span></tt> in a distributed BFS.</dd>
<dt><tt class="docutils literal"><span class="pre">non_tree_edge(e,</span> <span class="pre">g)</span></tt></dt>
<dd>Some <tt class="docutils literal"><span class="pre">non_tree_edge</span></tt> events in a sequential BFS may become
<tt class="docutils literal"><span class="pre">tree_edge</span></tt> events in a distributed BFS. See the description of
<tt class="docutils literal"><span class="pre">tree_edge</span></tt> for additional details.</dd>
<dt><tt class="docutils literal"><span class="pre">gray_target(e,</span> <span class="pre">g)</span></tt></dt>
<dd>As with <tt class="docutils literal"><span class="pre">tree_edge</span></tt> not knowing when another process has already
discovered a vertex, <tt class="docutils literal"><span class="pre">gray_target</span></tt> events may occur in a
distributed BFS when <tt class="docutils literal"><span class="pre">black_target</span></tt> events may occur in a
sequential BFS, due to a lack of information on a given
processor. The source of edge <tt class="docutils literal"><span class="pre">e</span></tt> will be local to the process
executing this event.</dd>
<dt><tt class="docutils literal"><span class="pre">black_target(e,</span> <span class="pre">g)</span></tt></dt>
<dd>See documentation for <tt class="docutils literal"><span class="pre">gray_target</span></tt></dd>
<dt><tt class="docutils literal"><span class="pre">finish_vertex(e,</span> <span class="pre">g)</span></tt></dt>
<dd>See documentation for <tt class="docutils literal"><span class="pre">examine_vertex</span></tt>.</dd>
</dl>
<div class="section" id="making-visitors-safe-for-distributed-bfs">
<h2><a class="toc-backref" href="#id5">Making Visitors Safe for Distributed BFS</a></h2>
<p>The three most important things to remember when updating an existing
BFS visitor for distributed BFS or writing a new distributed BFS
visitor are:</p>
<ol class="arabic simple">
<li>Be sure that all state is either entirely local or in a
distributed data structure (most likely a property map!) using
the same process group as the graph.</li>
<li>Be sure that the visitor doesn't require precise event sequences
that cannot be guaranteed by distributed BFS, e.g., requiring
<tt class="docutils literal"><span class="pre">tree_edge</span></tt> and <tt class="docutils literal"><span class="pre">non_tree_edge</span></tt> events to be completely
distinct.</li>
<li>Be sure that the visitor can operate on incomplete
information. This often includes using an appropriate reduction
operation in a <a class="reference external" href="distributed_property_map.html">distributed property map</a> and verifying that
results written are &quot;better&quot; that what was previously written.</li>
</ol>
</div>
<div class="section" id="distributed-bfs-visitor-example">
<h2><a class="toc-backref" href="#id6">Distributed BFS Visitor Example</a></h2>
<p>To illustrate the differences between sequential and distributed BFS
visitors, we consider a BFS visitor that places the distance from the
source vertex to every other vertex in a property map. The sequential
visitor is very simple:</p>
<pre class="literal-block">
template&lt;typename DistanceMap&gt;
struct bfs_discovery_visitor : bfs_visitor&lt;&gt;
{
bfs_discovery_visitor(DistanceMap distance) : distance(distance) {}
template&lt;typename Edge, typename Graph&gt;
void tree_edge(Edge e, const Graph&amp; g)
{
std::size_t new_distance = get(distance, source(e, g)) + 1;
put(distance, target(e, g), new_distance);
}
private:
DistanceMap distance;
};
</pre>
<p>To revisit this code for distributed BFS, we consider the three points
in the section <a class="reference internal" href="#making-visitors-safe-for-distributed-bfs">Making Visitors Safe for Distributed BFS</a>:</p>
<ol class="arabic">
<li><p class="first">The distance map will need to become distributed, because the
distance to each vertex should be stored in the process owning the
vertex. This is actually a requirement on the user to provide such
a distributed property map, although in many cases the property map
will automatically be distributed and no syntactic changes will be
required.</p>
</li>
<li><p class="first">This visitor <em>does</em> require a precise sequence of events that may
change with a distributed BFS. The extraneous <tt class="docutils literal"><span class="pre">tree_edge</span></tt> events
that may occur could result in attempts to put distances into the
distance map multiple times for a single vertex. We therefore need
to consider bullet #3.</p>
</li>
<li><p class="first">Since multiple distance values may be written for each vertex, we
must always choose the best value we can find to update the
distance map. The distributed property map <tt class="docutils literal"><span class="pre">distance</span></tt> needs to
resolve distances to the smallest distance it has seen. For
instance, process 0 may find vertex <tt class="docutils literal"><span class="pre">u</span></tt> at level 3 but process 1
finds it at level 5: the distance must remain at 3. To do this, we
state that the property map's <em>role</em> is as a distance map, which
introduces an appropriate reduction operation:</p>
<pre class="literal-block">
set_property_map_role(vertex_distance, distance);
</pre>
</li>
</ol>
<p>The resulting distributed BFS visitor (which also applies, with no
changes, in the sequential BFS) is very similar to our original
sequential BFS visitor. Note the single-line difference in the
constructor:</p>
<pre class="literal-block">
template&lt;typename DistanceMap&gt;
struct bfs_discovery_visitor : bfs_visitor&lt;&gt;
{
bfs_discovery_visitor(DistanceMap distance) : distance(distance)
{
set_property_map_role(vertex_distance, distance);
}
template&lt;typename Edge, typename Graph&gt;
void tree_edge(Edge e, const Graph&amp; g)
{
std::size_t new_distance = get(distance, source(e, g)) + 1;
put(distance, target(e, g), new_distance);
}
private:
DistanceMap distance;
};
</pre>
</div>
</div>
<div class="section" id="performance">
<h1><a class="toc-backref" href="#id7">Performance</a></h1>
<p>The performance of Breadth-First Search is illustrated by the
following charts. Scaling and performance is reasonable for all of the
graphs we have tried.</p>
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_4.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_4.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_4_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_4_speedup_1.png" />
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_4.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_4.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_4_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_4_speedup_1.png" />
<hr class="docutils" />
<p>Copyright (C) 2004 The Trustees of Indiana University.</p>
<p>Authors: Douglas Gregor and Andrew Lumsdaine</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:21 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Connected Components</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-connected-components">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Connected Components</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<pre class="literal-block">
namespace graph {
// Default constructed ParentMap
template&lt;typename Graph, typename ComponentMap, typename ParentMap&gt;
typename property_traits&lt;ComponentMap&gt;::value_type
connected_components( const Graph&amp; g, ComponentMap c);
// User supplied ParentMap
template&lt;typename Graph, typename ComponentMap, typename ParentMap&gt;
typename property_traits&lt;ComponentMap&gt;::value_type
connected_components( const Graph&amp; g, ComponentMap c, ParentMap p);
}
</pre>
<p>The <tt class="docutils literal"><span class="pre">connected_components()</span></tt> function computes the connected
components of an undirected graph. The distributed connected
components algorithm uses the sequential version of the connected
components algorithm to compute the connected components of the local
subgraph, then executes the parallel phase of the algorithm. The
parallel portion of the connected components algorithm is loosely
based on the work of Goddard, Kumar, and Prins. The interface is a
superset of the interface to the BGL <a class="reference external" href="http://www.boost.org/libs/graph/doc/connected_components.html">sequential connected
components</a> algorithm.</p>
<p>Prior to executing the sequential phase of the algorithm, each process
identifies the roots of its local components. An adjacency list of
all vertices adjacent to members of the component is then constructed
at the root vertex of each component.</p>
<p>The parallel phase of the distributed connected components algorithm
consists of a series of supersteps. In each superstep, each root
attempts to hook to a member of it's adjacency list by assigning it's
parent pointer to that vertex. Hooking is restricted to vertices
which are logically less than the current vertex to prevent looping.
Vertices which hook successfully are removed from the list of roots
and placed on another list of completed vertices. All completed
vertices now execute a pointer jumping step until every completed
vertex has as its parent the root of a component. This pointer
jumping step may be further optimized by the addition of Cycle
Reduction (CR) rules developed by Johnson and Metaxas, however current
performance evaluations indicate that this would have a negligible
impact on the overall performance of the algorithm. These CR rules
reduce the number of pointer jumping steps from <em>O(n)</em> to <em>O(log n)</em>.
Following this pointer jumping step, roots which have hooked in this
phase transmit their adjacency list to their new parent. The
remaining roots receive these edges and execute a pruning step on
their adjacency lists to remove vertices that are now members of their
component. The parallel phase of the algorithm is complete when no
root successfully hooks. Once the parallel phase is complete a final
pointer jumping step is performed on all vertices to assign the parent
pointers of the leaves of the initial local subgraph components to
their final parent which has now been determined.</p>
<p>The single largest performance bottleneck in the distributed connected
components algorithm is the effect of poor vertex distribution on the
algorithm. For sparse graphs with a single large component, many
roots may hook to the same component, resulting in severe load
imbalance at the process owning this component. Several methods of
modifying the hooking strategy to avoid this behavior have been
implemented but none has been successful as of yet.</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#where-defined" id="id1">Where Defined</a></li>
<li><a class="reference internal" href="#parameters" id="id2">Parameters</a></li>
<li><a class="reference internal" href="#complexity" id="id3">Complexity</a></li>
<li><a class="reference internal" href="#performance" id="id4">Performance</a></li>
</ul>
</div>
<div class="section" id="where-defined">
<h1><a class="toc-backref" href="#id1">Where Defined</a></h1>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/connected_components.hpp</span></tt>&gt;</p>
</div>
<div class="section" id="parameters">
<h1><a class="toc-backref" href="#id2">Parameters</a></h1>
<dl class="docutils">
<dt>IN: <tt class="docutils literal"><span class="pre">Graph&amp;</span> <span class="pre">g</span></tt></dt>
<dd>The graph typed must be a model of <a class="reference external" href="DistributedGraph.html">Distributed Graph</a>.</dd>
<dt>OUT: <tt class="docutils literal"><span class="pre">ComponentMap</span> <span class="pre">c</span></tt></dt>
<dd>The algorithm computes how many connected components are in the
graph, and assigns each component an integer label. The algorithm
then records to which component each vertex in the graph belongs by
recording the component number in the component property map. The
<tt class="docutils literal"><span class="pre">ComponentMap</span></tt> type must be a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a>. The
value type must be the <tt class="docutils literal"><span class="pre">vertices_size_type</span></tt> of the graph. The key
type must be the graph's vertex descriptor type. If you do not wish
to compute component numbers, pass <tt class="docutils literal"><span class="pre">dummy_property_map</span></tt> as the
component map and parent information will be provided in the parent
map.</dd>
<dt>UTIL: <tt class="docutils literal"><span class="pre">ParentMap</span> <span class="pre">p</span></tt></dt>
<dd>A parent map may be supplied to the algorithm, if not supplied the
parent map will be constructed automatically. The <tt class="docutils literal"><span class="pre">ParentMap</span></tt> type
must be a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a>. The value type and key type
must be the graph's vertex descriptor type.</dd>
<dt>OUT: <tt class="docutils literal"><span class="pre">property_traits&lt;ComponentMap&gt;::value_type</span></tt></dt>
<dd>The number of components found will be returned as the value type of
the component map.</dd>
</dl>
</div>
<div class="section" id="complexity">
<h1><a class="toc-backref" href="#id3">Complexity</a></h1>
<p>The local phase of the algorithm is <em>O(V + E)</em>. The parallel phase of
the algorithm requires at most <em>O(d)</em> supersteps where <em>d</em> is the
number of initial roots. <em>d</em> is at most <em>O(V)</em> but becomes
significantly smaller as <em>E</em> increases. The pointer jumping phase
within each superstep requires at most <em>O(c)</em> steps on each of the
completed roots where <em>c</em> is the length of the longest cycle.
Application of CR rules can reduce this to <em>O(log c)</em>.</p>
</div>
<div class="section" id="performance">
<h1><a class="toc-backref" href="#id4">Performance</a></h1>
<p>The following charts illustrate the performance of the Parallel BGL
connected components algorithm. It performs well on very sparse and
very dense graphs. However, for cases where the graph has a medium
density with a giant connected component, the algorithm will perform
poorly. This is a known problem with the algorithm and as far as we
know all implemented algorithms have this degenerate behavior.</p>
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_9.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_9.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_9_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_9_speedup_1.png" />
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_9.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_9.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_9_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_9_speedup_1.png" />
<hr class="docutils" />
<p>Copyright (C) 2004 The Trustees of Indiana University.</p>
<p>Authors: Nick Edmonds, Douglas Gregor, and Andrew Lumsdaine</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:22 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Connected Components Parallel Search</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-connected-components-parallel-search">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Connected Components Parallel Search</h1>
<!-- Copyright (C) 2004-2009 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<pre class="literal-block">
namespace graph { namespace distributed {
template&lt;typename Graph, typename ComponentMap&gt;
typename property_traits&lt;ComponentMap&gt;::value_type
connected_components_ps(const Graph&amp; g, ComponentMap c)
} }
</pre>
<p>The <tt class="docutils literal"><span class="pre">connected_components_ps()</span></tt> function computes the connected
components of a graph by performing a breadth-first search from
several sources in parallel while recording and eventually resolving
the collisions.</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#where-defined" id="id1">Where Defined</a></li>
<li><a class="reference internal" href="#parameters" id="id2">Parameters</a></li>
<li><a class="reference internal" href="#complexity" id="id3">Complexity</a></li>
<li><a class="reference internal" href="#algorithm-description" id="id4">Algorithm Description</a></li>
</ul>
</div>
<div class="section" id="where-defined">
<h1><a class="toc-backref" href="#id1">Where Defined</a></h1>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/distributed/connected_components_parallel_search.hpp</span></tt>&gt;</p>
</div>
<div class="section" id="parameters">
<h1><a class="toc-backref" href="#id2">Parameters</a></h1>
<dl class="docutils">
<dt>IN: <tt class="docutils literal"><span class="pre">const</span> <span class="pre">Graph&amp;</span> <span class="pre">g</span></tt></dt>
<dd>The graph type must be a model of <a class="reference external" href="DistributedGraph.html">Distributed Graph</a>. The graph
type must also model the <a class="reference external" href="http://www.boost.org/libs/graph/doc/IncidenceGraph.html">Incidence Graph</a> and be directed.</dd>
<dt>OUT: <tt class="docutils literal"><span class="pre">ComponentMap</span> <span class="pre">c</span></tt></dt>
<dd>The algorithm computes how many connected components are in the
graph, and assigns each component an integer label. The algorithm
then records to which component each vertex in the graph belongs by
recording the component number in the component property map. The
<tt class="docutils literal"><span class="pre">ComponentMap</span></tt> type must be a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a>. The
value type must be the <tt class="docutils literal"><span class="pre">vertices_size_type</span></tt> of the graph. The key
type must be the graph's vertex descriptor type.</dd>
</dl>
</div>
<div class="section" id="complexity">
<h1><a class="toc-backref" href="#id3">Complexity</a></h1>
<p><em>O(PN^2 + VNP)</em> work, in <em>O(N + V)</em> time, where N is the
number of mappings and V is the number of local vertices.</p>
</div>
<div class="section" id="algorithm-description">
<h1><a class="toc-backref" href="#id4">Algorithm Description</a></h1>
<p>Every <em>N</em> th nodes starts a parallel search from the first vertex in
their local vertex list during the first superstep (the other nodes
remain idle during the first superstep to reduce the number of
conflicts in numbering the components). At each superstep, all new
component mappings from remote nodes are handled. If there is no work
from remote updates, a new vertex is removed from the local list and
added to the work queue.</p>
<p>Components are allocated from the <tt class="docutils literal"><span class="pre">component_value_allocator</span></tt>
object, which ensures that a given component number is unique in the
system, currently by using the rank and number of processes to stride
allocations.</p>
<p>When two components are discovered to actually be the same component,
a collision is recorded. The lower component number is prefered in
the resolution, so component numbering resolution is consistent.
After the search has exhausted all vertices in the graph, the mapping
is shared with all processes and they independently resolve the
comonent mapping. This phase can likely be significantly sped up if a
clever algorithm for the reduction can be found.</p>
<hr class="docutils" />
<p>Copyright (C) 2009 The Trustees of Indiana University.</p>
<p>Authors: Brian Barrett, Douglas Gregor, and Andrew Lumsdaine</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:21 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,393 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Minimum Spanning Tree</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-minimum-spanning-tree">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Minimum Spanning Tree</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<p>The Parallel BGL contains four <a class="reference external" href="http://www.boost.org/libs/graph/doc/graph_theory_review.html#sec:minimum-spanning-tree">minimum spanning tree</a> (MST)
algorithms <a class="citation-reference" href="#dg98" id="id1">[DG98]</a> for use on undirected, weighted, distributed
graphs. The graphs need not be connected: each algorithm will compute
a minimum spanning forest (MSF) when provided with a disconnected
graph.</p>
<p>The interface to each of the four algorithms is similar to the
implementation of 'Kruskal's algorithm'_ in the sequential BGL. Each
accepts, at a minimum, a graph, a weight map, and an output
iterator. The edges of the MST (or MSF) will be output via the output
iterator on process 0: other processes may receive edges on their
output iterators, but the set may not be complete, depending on the
algorithm. The algorithm parameters are documented together, because
they do not vary greatly. See the section <a class="reference internal" href="#selecting-an-mst-algorithm">Selecting an MST
algorithm</a> for advice on algorithm selection.</p>
<p>The graph itself must model the <a class="reference external" href="http://www.boost.org/libs/graph/doc/VertexListGraph.html">Vertex List Graph</a> concept and the
Distributed Edge List Graph concept. Since the most common
distributed graph structure, the <a class="reference external" href="distributed_adjacency_list.html">distributed adjacency list</a>, only
models the Distributed Vertex List Graph concept, it may only be used
with these algorithms when wrapped in a suitable adaptor, such as the
<a class="reference external" href="vertex_list_adaptor.html">vertex_list_adaptor</a>.</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#where-defined" id="id12">Where Defined</a></li>
<li><a class="reference internal" href="#parameters" id="id13">Parameters</a></li>
<li><a class="reference internal" href="#dense-boruvka-minimum-spanning-tree" id="id14"><tt class="docutils literal"><span class="pre">dense_boruvka_minimum_spanning_tree</span></tt></a><ul>
<li><a class="reference internal" href="#description" id="id15">Description</a></li>
<li><a class="reference internal" href="#complexity" id="id16">Complexity</a></li>
<li><a class="reference internal" href="#performance" id="id17">Performance</a></li>
</ul>
</li>
<li><a class="reference internal" href="#merge-local-minimum-spanning-trees" id="id18"><tt class="docutils literal"><span class="pre">merge_local_minimum_spanning_trees</span></tt></a><ul>
<li><a class="reference internal" href="#id2" id="id19">Description</a></li>
<li><a class="reference internal" href="#id3" id="id20">Complexity</a></li>
<li><a class="reference internal" href="#id4" id="id21">Performance</a></li>
</ul>
</li>
<li><a class="reference internal" href="#boruvka-then-merge" id="id22"><tt class="docutils literal"><span class="pre">boruvka_then_merge</span></tt></a><ul>
<li><a class="reference internal" href="#id5" id="id23">Description</a></li>
<li><a class="reference internal" href="#id6" id="id24">Complexity</a></li>
<li><a class="reference internal" href="#id7" id="id25">Performance</a></li>
</ul>
</li>
<li><a class="reference internal" href="#boruvka-mixed-merge" id="id26"><tt class="docutils literal"><span class="pre">boruvka_mixed_merge</span></tt></a><ul>
<li><a class="reference internal" href="#id8" id="id27">Description</a></li>
<li><a class="reference internal" href="#id9" id="id28">Complexity</a></li>
<li><a class="reference internal" href="#id10" id="id29">Performance</a></li>
</ul>
</li>
<li><a class="reference internal" href="#selecting-an-mst-algorithm" id="id30">Selecting an MST algorithm</a><ul>
<li><a class="reference internal" href="#performance-on-sparse-graphs" id="id31">Performance on Sparse Graphs</a></li>
<li><a class="reference internal" href="#performance-on-dense-graphs" id="id32">Performance on Dense Graphs</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="where-defined">
<h1><a class="toc-backref" href="#id12">Where Defined</a></h1>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/distributed/dehne_gotz_min_spanning_tree.hpp</span></tt>&gt;</p>
</div>
<div class="section" id="parameters">
<h1><a class="toc-backref" href="#id13">Parameters</a></h1>
<dl class="docutils">
<dt>IN: <tt class="docutils literal"><span class="pre">Graph&amp;</span> <span class="pre">g</span></tt></dt>
<dd>The graph type must be a model of <a class="reference external" href="http://www.boost.org/libs/graph/doc/VertexListGraph.html">Vertex List Graph</a> and
<a class="reference external" href="DistributedEdgeListGraph.html">Distributed Edge List Graph</a>.</dd>
<dt>IN/OUT: <tt class="docutils literal"><span class="pre">WeightMap</span> <span class="pre">weight</span></tt></dt>
<dd>The weight map must be a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a> and a <a class="reference external" href="http://www.boost.org/libs/property_map/ReadablePropertyMap.html">Readable
Property Map</a> whose key type is the edge descriptor of the graph
and whose value type is numerical.</dd>
<dt>IN/OUT: <tt class="docutils literal"><span class="pre">OutputIterator</span> <span class="pre">out</span></tt></dt>
<dd>The output iterator through which the edges of the MSF will be
written. Must be capable of accepting edge descriptors for output.</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">VertexIndexMap</span> <span class="pre">index</span></tt></dt>
<dd><p class="first">A mapping from vertex descriptors to indices in the range <em>[0,
num_vertices(g))</em>. This must be a <a class="reference external" href="http://www.boost.org/libs/property_map/ReadablePropertyMap.html">Readable Property Map</a> whose
key type is a vertex descriptor and whose value type is an integral
type, typically the <tt class="docutils literal"><span class="pre">vertices_size_type</span></tt> of the graph.</p>
<p class="last"><strong>Default:</strong> <tt class="docutils literal"><span class="pre">get(vertex_index,</span> <span class="pre">g)</span></tt></p>
</dd>
<dt>IN/UTIL: <tt class="docutils literal"><span class="pre">RankMap</span> <span class="pre">rank_map</span></tt></dt>
<dd><p class="first">Stores the rank of each vertex, which is used for maintaining
union-find data structures. This must be a <a class="reference external" href="http://www.boost.org/libs/property_map/ReadWritePropertyMap.html">Read/Write Property Map</a>
whose key type is a vertex descriptor and whose value type is an
integral type.</p>
<p class="last"><strong>Default:</strong> An <tt class="docutils literal"><span class="pre">iterator_property_map</span></tt> built from an STL vector
of the <tt class="docutils literal"><span class="pre">vertices_size_type</span></tt> of the graph and the vertex index map.</p>
</dd>
<dt>IN/UTIL: <tt class="docutils literal"><span class="pre">ParentMap</span> <span class="pre">parent_map</span></tt></dt>
<dd><p class="first">Stores the parent (representative) of each vertex, which is used for
maintaining union-find data structures. This must be a <a class="reference external" href="http://www.boost.org/libs/property_map/ReadWritePropertyMap.html">Read/Write
Property Map</a> whose key type is a vertex descriptor and whose value
type is also a vertex descriptor.</p>
<p class="last"><strong>Default:</strong> An <tt class="docutils literal"><span class="pre">iterator_property_map</span></tt> built from an STL vector
of the <tt class="docutils literal"><span class="pre">vertex_descriptor</span></tt> of the graph and the vertex index map.</p>
</dd>
<dt>IN/UTIL: <tt class="docutils literal"><span class="pre">SupervertexMap</span> <span class="pre">supervertex_map</span></tt></dt>
<dd><p class="first">Stores the supervertex index of each vertex, which is used for
maintaining the supervertex list data structures. This must be a
<a class="reference external" href="http://www.boost.org/libs/property_map/ReadWritePropertyMap.html">Read/Write Property Map</a> whose key type is a vertex descriptor and
whose value type is an integral type.</p>
<p class="last"><strong>Default:</strong> An <tt class="docutils literal"><span class="pre">iterator_property_map</span></tt> built from an STL vector
of the <tt class="docutils literal"><span class="pre">vertices_size_type</span></tt> of the graph and the vertex index map.</p>
</dd>
</dl>
</div>
<div class="section" id="dense-boruvka-minimum-spanning-tree">
<h1><a class="toc-backref" href="#id14"><tt class="docutils literal"><span class="pre">dense_boruvka_minimum_spanning_tree</span></tt></a></h1>
<pre class="literal-block">
namespace graph {
template&lt;typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndexMap, typename RankMap, typename ParentMap,
typename SupervertexMap&gt;
OutputIterator
dense_boruvka_minimum_spanning_tree(const Graph&amp; g, WeightMap weight_map,
OutputIterator out,
VertexIndexMap index,
RankMap rank_map, ParentMap parent_map,
SupervertexMap supervertex_map);
template&lt;typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndex&gt;
OutputIterator
dense_boruvka_minimum_spanning_tree(const Graph&amp; g, WeightMap weight_map,
OutputIterator out, VertexIndex index);
template&lt;typename Graph, typename WeightMap, typename OutputIterator&gt;
OutputIterator
dense_boruvka_minimum_spanning_tree(const Graph&amp; g, WeightMap weight_map,
OutputIterator out);
}
</pre>
<div class="section" id="description">
<h2><a class="toc-backref" href="#id15">Description</a></h2>
<p>The dense Boruvka distributed minimum spanning tree algorithm is a
direct parallelization of the sequential MST algorithm by
Boruvka. The algorithm first creates a <em>supervertex</em> out of each
vertex. Then, in each iteration, it finds the smallest-weight edge
incident to each vertex, collapses supervertices along these edges,
and removals all self loops. The only difference between the
sequential and parallel algorithms is that the parallel algorithm
performs an all-reduce operation so that all processes have the
global minimum set of edges.</p>
<p>Unlike the other three algorithms, this algorithm emits the complete
list of edges in the minimum spanning forest via the output iterator
on all processes. It may therefore be more useful than the others
when parallelizing sequential BGL programs.</p>
</div>
<div class="section" id="complexity">
<h2><a class="toc-backref" href="#id16">Complexity</a></h2>
<p>The distributed algorithm requires <em>O(log n)</em> BSP supersteps, each of
which requires <em>O(m/p + n)</em> time and <em>O(n)</em> communication per
process.</p>
</div>
<div class="section" id="performance">
<h2><a class="toc-backref" href="#id17">Performance</a></h2>
<p>The following charts illustrate the performance of this algorithm on
various random graphs. We see that the algorithm scales well up to 64
or 128 processors, depending on the type of graph, for dense
graphs. However, for sparse graphs performance tapers off as the
number of processors surpases <em>m/n</em>, i.e., the average degree (which
is 30 for this graph). This behavior is expected from the algorithm.</p>
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_5.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_5.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_5_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_5_speedup_1.png" />
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_5.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_5.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_5_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_5_speedup_1.png" />
</div>
</div>
<div class="section" id="merge-local-minimum-spanning-trees">
<h1><a class="toc-backref" href="#id18"><tt class="docutils literal"><span class="pre">merge_local_minimum_spanning_trees</span></tt></a></h1>
<pre class="literal-block">
namespace graph {
template&lt;typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndexMap&gt;
OutputIterator
merge_local_minimum_spanning_trees(const Graph&amp; g, WeightMap weight,
OutputIterator out,
VertexIndexMap index);
template&lt;typename Graph, typename WeightMap, typename OutputIterator&gt;
inline OutputIterator
merge_local_minimum_spanning_trees(const Graph&amp; g, WeightMap weight,
OutputIterator out);
}
</pre>
<div class="section" id="id2">
<h2><a class="toc-backref" href="#id19">Description</a></h2>
<p>The merging local MSTs algorithm operates by computing minimum
spanning forests from the edges stored on each process. Then the
processes merge their edge lists along a tree. The child nodes cease
participating in the computation, but the parent nodes recompute MSFs
from the newly acquired edges. In the final round, the root of the
tree computes the global MSFs, having received candidate edges from
every other process via the tree.</p>
</div>
<div class="section" id="id3">
<h2><a class="toc-backref" href="#id20">Complexity</a></h2>
<p>This algorithm requires <em>O(log_D p)</em> BSP supersteps (where <em>D</em> is the
number of children in the tree, and is currently fixed at 3). Each
superstep requires <em>O((m/p) log (m/p) + n)</em> time and <em>O(m/p)</em>
communication per process.</p>
</div>
<div class="section" id="id4">
<h2><a class="toc-backref" href="#id21">Performance</a></h2>
<p>The following charts illustrate the performance of this algorithm on
various random graphs. The algorithm only scales well for very dense
graphs, where most of the work is performed in the initial stage and
there is very little work in the later stages.</p>
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_6.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_6.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_6_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_6_speedup_1.png" />
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_6.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_6.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_6_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_6_speedup_1.png" />
</div>
</div>
<div class="section" id="boruvka-then-merge">
<h1><a class="toc-backref" href="#id22"><tt class="docutils literal"><span class="pre">boruvka_then_merge</span></tt></a></h1>
<pre class="literal-block">
namespace graph {
template&lt;typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndexMap, typename RankMap, typename ParentMap,
typename SupervertexMap&gt;
OutputIterator
boruvka_then_merge(const Graph&amp; g, WeightMap weight, OutputIterator out,
VertexIndexMap index, RankMap rank_map,
ParentMap parent_map, SupervertexMap
supervertex_map);
template&lt;typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndexMap&gt;
inline OutputIterator
boruvka_then_merge(const Graph&amp; g, WeightMap weight, OutputIterator out,
VertexIndexMap index);
template&lt;typename Graph, typename WeightMap, typename OutputIterator&gt;
inline OutputIterator
boruvka_then_merge(const Graph&amp; g, WeightMap weight, OutputIterator out);
}
</pre>
<div class="section" id="id5">
<h2><a class="toc-backref" href="#id23">Description</a></h2>
<p>This algorithm applies both Boruvka steps and local MSF merging steps
together to achieve better asymptotic performance than either
algorithm alone. It first executes Boruvka steps until only <em>n/(log_d
p)^2</em> supervertices remain, then completes the MSF computation by
performing local MSF merging on the remaining edges and
supervertices.</p>
</div>
<div class="section" id="id6">
<h2><a class="toc-backref" href="#id24">Complexity</a></h2>
<p>This algorithm requires <em>log_D p</em> + <em>log log_D p</em> BSP supersteps. The
time required by each superstep depends on the type of superstep
being performed; see the distributed Boruvka or merging local MSFS
algorithms for details.</p>
</div>
<div class="section" id="id7">
<h2><a class="toc-backref" href="#id25">Performance</a></h2>
<p>The following charts illustrate the performance of this algorithm on
various random graphs. We see that the algorithm scales well up to 64
or 128 processors, depending on the type of graph, for dense
graphs. However, for sparse graphs performance tapers off as the
number of processors surpases <em>m/n</em>, i.e., the average degree (which
is 30 for this graph). This behavior is expected from the algorithm.</p>
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_7.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_7.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_7_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_7_speedup_1.png" />
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_7.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_7.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_7_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_7_speedup_1.png" />
</div>
</div>
<div class="section" id="boruvka-mixed-merge">
<h1><a class="toc-backref" href="#id26"><tt class="docutils literal"><span class="pre">boruvka_mixed_merge</span></tt></a></h1>
<pre class="literal-block">
namespace {
template&lt;typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndexMap, typename RankMap, typename ParentMap,
typename SupervertexMap&gt;
OutputIterator
boruvka_mixed_merge(const Graph&amp; g, WeightMap weight, OutputIterator out,
VertexIndexMap index, RankMap rank_map,
ParentMap parent_map, SupervertexMap
supervertex_map);
template&lt;typename Graph, typename WeightMap, typename OutputIterator,
typename VertexIndexMap&gt;
inline OutputIterator
boruvka_mixed_merge(const Graph&amp; g, WeightMap weight, OutputIterator out,
VertexIndexMap index);
template&lt;typename Graph, typename WeightMap, typename OutputIterator&gt;
inline OutputIterator
boruvka_mixed_merge(const Graph&amp; g, WeightMap weight, OutputIterator out);
}
</pre>
<div class="section" id="id8">
<h2><a class="toc-backref" href="#id27">Description</a></h2>
<p>This algorithm applies both Boruvka steps and local MSF merging steps
together to achieve better asymptotic performance than either method
alone. In each iteration, the algorithm first performs a Boruvka step
and then merges the local MSFs computed based on the supervertex
graph.</p>
</div>
<div class="section" id="id9">
<h2><a class="toc-backref" href="#id28">Complexity</a></h2>
<p>This algorithm requires <em>log_D p</em> BSP supersteps. The
time required by each superstep depends on the type of superstep
being performed; see the distributed Boruvka or merging local MSFS
algorithms for details. However, the algorithm is
communication-optional (requiring <em>O(n)</em> communication overall) when
the graph is sufficiently dense, i.e., <em>m/n &gt;= p</em>.</p>
</div>
<div class="section" id="id10">
<h2><a class="toc-backref" href="#id29">Performance</a></h2>
<p>The following charts illustrate the performance of this algorithm on
various random graphs. We see that the algorithm scales well up to 64
or 128 processors, depending on the type of graph, for dense
graphs. However, for sparse graphs performance tapers off as the
number of processors surpases <em>m/n</em>, i.e., the average degree (which
is 30 for this graph). This behavior is expected from the algorithm.</p>
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_8.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_8.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_8_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeSparse_columns_8_speedup_1.png" />
<img align="left" alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_8.png" class="align-left" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_8.png" />
<img alt="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_8_speedup_1.png" src="chart_php_generator_ER_SF_SW_dataset_TimeDense_columns_8_speedup_1.png" />
</div>
</div>
<div class="section" id="selecting-an-mst-algorithm">
<h1><a class="toc-backref" href="#id30">Selecting an MST algorithm</a></h1>
<p>Dehne and Gotz reported <a class="citation-reference" href="#dg98" id="id11">[DG98]</a> mixed results when evaluating these
four algorithms. No particular algorithm was clearly better than the
others in all cases. However, the asymptotically best algorithm
(<tt class="docutils literal"><span class="pre">boruvka_mixed_merge</span></tt>) seemed to perform more poorly in their tests
than the other merging-based algorithms. The following performance
charts illustrate the performance of these four minimum spanning tree
implementations.</p>
<p>Overall, <tt class="docutils literal"><span class="pre">dense_boruvka_minimum_spanning_tree</span></tt> gives the most
consistent performance and scalability for the graphs we
tested. Additionally, it may be more suitable for sequential programs
that are being parallelized, because it emits complete MSF edge lists
via the output iterators in every process.</p>
<div class="section" id="performance-on-sparse-graphs">
<h2><a class="toc-backref" href="#id31">Performance on Sparse Graphs</a></h2>
<img align="left" alt="chart_php_generator_ER_dataset_TimeSparse_columns_5_6_7_8.png" class="align-left" src="chart_php_generator_ER_dataset_TimeSparse_columns_5_6_7_8.png" />
<img alt="chart_php_generator_ER_dataset_TimeSparse_columns_5_6_7_8_speedup_1.png" src="chart_php_generator_ER_dataset_TimeSparse_columns_5_6_7_8_speedup_1.png" />
<img align="left" alt="chart_php_generator_SF_dataset_TimeSparse_columns_5_6_7_8.png" class="align-left" src="chart_php_generator_SF_dataset_TimeSparse_columns_5_6_7_8.png" />
<img alt="chart_php_generator_SF_dataset_TimeSparse_columns_5_6_7_8_speedup_1.png" src="chart_php_generator_SF_dataset_TimeSparse_columns_5_6_7_8_speedup_1.png" />
<img align="left" alt="chart_php_generator_SW_dataset_TimeSparse_columns_5_6_7_8.png" class="align-left" src="chart_php_generator_SW_dataset_TimeSparse_columns_5_6_7_8.png" />
<img alt="chart_php_generator_SW_dataset_TimeSparse_columns_5_6_7_8_speedup_1.png" src="chart_php_generator_SW_dataset_TimeSparse_columns_5_6_7_8_speedup_1.png" />
</div>
<div class="section" id="performance-on-dense-graphs">
<h2><a class="toc-backref" href="#id32">Performance on Dense Graphs</a></h2>
<img align="left" alt="chart_php_generator_ER_dataset_TimeDense_columns_5_6_7_8.png" class="align-left" src="chart_php_generator_ER_dataset_TimeDense_columns_5_6_7_8.png" />
<img alt="chart_php_generator_ER_dataset_TimeDense_columns_5_6_7_8_speedup_1.png" src="chart_php_generator_ER_dataset_TimeDense_columns_5_6_7_8_speedup_1.png" />
<img align="left" alt="chart_php_generator_SF_dataset_TimeDense_columns_5_6_7_8.png" class="align-left" src="chart_php_generator_SF_dataset_TimeDense_columns_5_6_7_8.png" />
<img alt="chart_php_generator_SF_dataset_TimeDense_columns_5_6_7_8_speedup_1.png" src="chart_php_generator_SF_dataset_TimeDense_columns_5_6_7_8_speedup_1.png" />
<img align="left" alt="chart_php_generator_SW_dataset_TimeDense_columns_5_6_7_8.png" class="align-left" src="chart_php_generator_SW_dataset_TimeDense_columns_5_6_7_8.png" />
<img alt="chart_php_generator_SW_dataset_TimeDense_columns_5_6_7_8_speedup_1.png" src="chart_php_generator_SW_dataset_TimeDense_columns_5_6_7_8_speedup_1.png" />
<hr class="docutils" />
<p>Copyright (C) 2004 The Trustees of Indiana University.</p>
<p>Authors: Douglas Gregor and Andrew Lumsdaine</p>
<table class="docutils citation" frame="void" id="dg98" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[DG98]</td><td><em>(<a class="fn-backref" href="#id1">1</a>, <a class="fn-backref" href="#id11">2</a>)</em> Frank Dehne and Silvia Gotz. <em>Practical Parallel Algorithms
for Minimum Spanning Trees</em>. In Symposium on Reliable Distributed Systems,
pages 366--371, 1998.</td></tr>
</tbody>
</table>
</div>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:21 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,161 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel Shortest Paths</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="parallel-shortest-paths">
<h1 class="title">Parallel Shortest Paths</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<p>To illustrate the use of the Parallel Boost Graph Library, we
illustrate the use of both the sequential and parallel BGL to find
the shortest paths from vertex A to every other vertex in the
following simple graph:</p>
<img alt="../dijkstra_seq_graph.png" src="../dijkstra_seq_graph.png" />
<p>With the sequential <a class="reference external" href="http://www.boost.org/libs/graph/doc">BGL</a>, the program to calculate shortest paths has
three stages. Readers familiar with the BGL may wish to skip ahead to
the section <a class="reference internal" href="#distributing-the-graph">Distributing the graph</a>.</p>
<blockquote>
<ul class="simple">
<li><a class="reference internal" href="#define-the-graph-type">Define the graph type</a></li>
<li><a class="reference internal" href="#construct-the-graph">Construct the graph</a></li>
<li><a class="reference internal" href="#invoke-dijkstra-s-algorithm">Invoke Dijkstra's algorithm</a></li>
</ul>
</blockquote>
<div class="section" id="define-the-graph-type">
<h1>Define the graph type</h1>
<p>For this problem we use an adjacency list representation of the graph,
using the BGL <tt class="docutils literal"><span class="pre">adjacency_list``_</span> <span class="pre">class</span> <span class="pre">template.</span> <span class="pre">It</span> <span class="pre">will</span> <span class="pre">be</span> <span class="pre">a</span> <span class="pre">directed</span>
<span class="pre">graph</span> <span class="pre">(``directedS</span></tt> parameter ) whose vertices are stored in an
<tt class="docutils literal"><span class="pre">std::vector</span></tt> (<tt class="docutils literal"><span class="pre">vecS</span></tt> parameter) where the outgoing edges of each
vertex are stored in an <tt class="docutils literal"><span class="pre">std::list</span></tt> (<tt class="docutils literal"><span class="pre">listS</span></tt> parameter). To each
of the edges we attach an integral weight.</p>
<pre class="literal-block">
typedef adjacency_list&lt;listS, vecS, directedS,
no_property, // Vertex properties
property&lt;edge_weight_t, int&gt; // Edge properties
&gt; graph_t;
typedef graph_traits &lt; graph_t &gt;::vertex_descriptor vertex_descriptor;
typedef graph_traits &lt; graph_t &gt;::edge_descriptor edge_descriptor;
</pre>
</div>
<div class="section" id="construct-the-graph">
<h1>Construct the graph</h1>
<p>To build the graph, we declare an enumeration containing the node
names (for our own use) and create two arrays: the first,
<tt class="docutils literal"><span class="pre">edge_array</span></tt>, contains the source and target of each edge, whereas
the second, <tt class="docutils literal"><span class="pre">weights</span></tt>, contains the integral weight of each
edge. We pass the contents of the arrays via pointers (used here as
iterators) to the graph constructor to build our graph:</p>
<pre class="literal-block">
typedef std::pair&lt;int, int&gt; Edge;
const int num_nodes = 5;
enum nodes { A, B, C, D, E };
char name[] = &quot;ABCDE&quot;;
Edge edge_array[] = { Edge(A, C), Edge(B, B), Edge(B, D), Edge(B, E),
Edge(C, B), Edge(C, D), Edge(D, E), Edge(E, A), Edge(E, B)
};
int weights[] = { 1, 2, 1, 2, 7, 3, 1, 1, 1 };
int num_arcs = sizeof(edge_array) / sizeof(Edge);
graph_t g(edge_array, edge_array + num_arcs, weights, num_nodes);
</pre>
</div>
<div class="section" id="invoke-dijkstra-s-algorithm">
<h1>Invoke Dijkstra's algorithm</h1>
<p>To invoke Dijkstra's algorithm, we need to first decide how we want
to receive the results of the algorithm, namely the distance to each
vertex and the predecessor of each vertex (allowing reconstruction of
the shortest paths themselves). In our case, we will create two
vectors, <tt class="docutils literal"><span class="pre">p</span></tt> for predecessors and <tt class="docutils literal"><span class="pre">d</span></tt> for distances.</p>
<p>Next, we determine our starting vertex <tt class="docutils literal"><span class="pre">s</span></tt> using the <tt class="docutils literal"><span class="pre">vertex</span></tt>
operation on the <tt class="docutils literal"><span class="pre">adjacency_list``_</span> <span class="pre">and</span> <span class="pre">call</span>
<span class="pre">``dijkstra_shortest_paths``_</span> <span class="pre">with</span> <span class="pre">the</span> <span class="pre">graph</span> <span class="pre">``g</span></tt>, starting vertex
<tt class="docutils literal"><span class="pre">s</span></tt>, and two <tt class="docutils literal"><span class="pre">property</span> <span class="pre">maps``_</span> <span class="pre">that</span> <span class="pre">instruct</span> <span class="pre">the</span> <span class="pre">algorithm</span> <span class="pre">to</span>
<span class="pre">store</span> <span class="pre">predecessors</span> <span class="pre">in</span> <span class="pre">the</span> <span class="pre">``p</span></tt> vector and distances in the <tt class="docutils literal"><span class="pre">d</span></tt>
vector. The algorithm automatically uses the edge weights stored
within the graph, although this capability can be overridden.</p>
<pre class="literal-block">
// Keeps track of the predecessor of each vertex
std::vector&lt;vertex_descriptor&gt; p(num_vertices(g));
// Keeps track of the distance to each vertex
std::vector&lt;int&gt; d(num_vertices(g));
vertex_descriptor s = vertex(A, g);
dijkstra_shortest_paths
(g, s,
predecessor_map(
make_iterator_property_map(p.begin(), get(vertex_index, g))).
distance_map(
make_iterator_property_map(d.begin(), get(vertex_index, g)))
);
</pre>
</div>
<div class="section" id="distributing-the-graph">
<h1>Distributing the graph</h1>
<p>The prior computation is entirely sequential, with the graph stored
within a single address space. To distribute the graph across several
processors without a shared address space, we need to represent the
processors and communication among them and alter the graph type.</p>
<p>Processors and their interactions are abstracted via a <em>process
group</em>. In our case, we will use <a class="reference external" href="http://www-unix.mcs.anl.gov/mpi/">MPI</a> for communication with
inter-processor messages sent immediately:</p>
<pre class="literal-block">
typedef mpi::process_group&lt;mpi::immediateS&gt; process_group_type;
</pre>
<p>Next, we instruct the <tt class="docutils literal"><span class="pre">adjacency_list</span></tt> template
to distribute the vertices of the graph across our process group,
storing the local vertices in an <tt class="docutils literal"><span class="pre">std::vector</span></tt>:</p>
<pre class="literal-block">
typedef adjacency_list&lt;listS,
distributedS&lt;process_group_type, vecS&gt;,
directedS,
no_property, // Vertex properties
property&lt;edge_weight_t, int&gt; // Edge properties
&gt; graph_t;
typedef graph_traits &lt; graph_t &gt;::vertex_descriptor vertex_descriptor;
typedef graph_traits &lt; graph_t &gt;::edge_descriptor edge_descriptor;
</pre>
<p>Note that the only difference from the sequential BGL is the use of
the <tt class="docutils literal"><span class="pre">distributedS</span></tt> selector, which identifies a distributed
graph. The vertices of the graph will be distributed among the
various processors, and the processor that owns a vertex also stores
the edges outgoing from that vertex and any properties associated
with that vertex or its edges. With three processors and the default
block distribution, the graph would be distributed in this manner:</p>
<img alt="../dijkstra_dist3_graph.png" src="../dijkstra_dist3_graph.png" />
<p>Processor 0 (red) owns vertices A and B, including all edges outoing
from those vertices, processor 1 (green) owns vertices C and D (and
their edges), and processor 2 (blue) owns vertex E. Constructing this
graph uses the same syntax is the sequential graph, as in the section
<a class="reference internal" href="#construct-the-graph">Construct the graph</a>.</p>
<p>The call to <tt class="docutils literal"><span class="pre">dijkstra_shortest_paths</span></tt> is syntactically equivalent to
the sequential call, but the mechanisms used are very different. The
property maps passed to <tt class="docutils literal"><span class="pre">dijkstra_shortest_paths</span></tt> are actually
<em>distributed</em> property maps, which store properties for local edges
or vertices and perform implicit communication to access properties
of remote edges or vertices when needed. The formulation of Dijkstra's
algorithm is also slightly different, because each processor can
only attempt to relax edges outgoing from local vertices: as shorter
paths to a vertex are discovered, messages to the processor owning
that vertex indicate that the vertex may require reprocessing.</p>
<hr class="docutils" />
<p>Return to the <a class="reference external" href="index.html">Parallel BGL home page</a></p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:22 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,400 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Dijkstra's Single-Source Shortest Paths</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-dijkstra-s-single-source-shortest-paths">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Dijkstra's Single-Source Shortest Paths</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<pre class="literal-block">
// named parameter version
template &lt;typename Graph, typename P, typename T, typename R&gt;
void
dijkstra_shortest_paths(Graph&amp; g,
typename graph_traits&lt;Graph&gt;::vertex_descriptor s,
const bgl_named_params&lt;P, T, R&gt;&amp; params);
// non-named parameter version
template &lt;typename Graph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap,
typename WeightMap, typename VertexIndexMap, typename CompareFunction, typename CombineFunction,
typename DistInf, typename DistZero&gt;
void dijkstra_shortest_paths
(const Graph&amp; g,
typename graph_traits&lt;Graph&gt;::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
VertexIndexMap index_map,
CompareFunction compare, CombineFunction combine, DistInf inf, DistZero zero,
DijkstraVisitor vis);
</pre>
<p>The <tt class="docutils literal"><span class="pre">dijkstra_shortest_paths()</span></tt> function solves the single-source
shortest paths problem on a weighted, undirected or directed
distributed graph. There are two implementations of distributed
Dijkstra's algorithm, which offer different performance
tradeoffs. Both are accessible via the <tt class="docutils literal"><span class="pre">dijkstra_shortest_paths()</span></tt>
function (for compatibility with sequential BGL programs). The
distributed Dijkstra algorithms are very similar to their sequential
counterparts. Only the differences are highlighted here; please refer
to the <a class="reference external" href="http://www.boost.org/libs/graph/doc/dijkstra_shortest_paths.html">sequential Dijkstra implementation</a> for additional
details. The best-performing implementation for most cases is the
<a class="reference internal" href="#delta-stepping-algorithm">Delta-Stepping algorithm</a>; however, one can also employ the more
conservative <a class="reference internal" href="#crauser-et-al-s-algorithm">Crauser et al.'s algorithm</a> or the simlistic <a class="reference internal" href="#eager-dijkstra-s-algorithm">Eager
Dijkstra's algorithm</a>.</p>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#where-defined" id="id10">Where Defined</a></li>
<li><a class="reference internal" href="#parameters" id="id11">Parameters</a></li>
<li><a class="reference internal" href="#visitor-event-points" id="id12">Visitor Event Points</a></li>
<li><a class="reference internal" href="#crauser-et-al-s-algorithm" id="id13">Crauser et al.'s algorithm</a><ul>
<li><a class="reference internal" href="#id2" id="id14">Where Defined</a></li>
<li><a class="reference internal" href="#complexity" id="id15">Complexity</a></li>
<li><a class="reference internal" href="#performance" id="id16">Performance</a></li>
</ul>
</li>
<li><a class="reference internal" href="#eager-dijkstra-s-algorithm" id="id17">Eager Dijkstra's algorithm</a><ul>
<li><a class="reference internal" href="#id5" id="id18">Where Defined</a></li>
<li><a class="reference internal" href="#id6" id="id19">Complexity</a></li>
<li><a class="reference internal" href="#id7" id="id20">Performance</a></li>
</ul>
</li>
<li><a class="reference internal" href="#delta-stepping-algorithm" id="id21">Delta-Stepping algorithm</a><ul>
<li><a class="reference internal" href="#id9" id="id22">Where Defined</a></li>
</ul>
</li>
<li><a class="reference internal" href="#example" id="id23">Example</a></li>
<li><a class="reference internal" href="#bibliography" id="id24">Bibliography</a></li>
</ul>
</div>
<div class="section" id="where-defined">
<h1><a class="toc-backref" href="#id10">Where Defined</a></h1>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/dijkstra_shortest_paths.hpp</span></tt>&gt;</p>
</div>
<div class="section" id="parameters">
<h1><a class="toc-backref" href="#id11">Parameters</a></h1>
<p>All parameters of the <a class="reference external" href="http://www.boost.org/libs/graph/doc/dijkstra_shortest_paths.html">sequential Dijkstra implementation</a> are
supported and have essentially the same meaning. The distributed
Dijkstra implementations introduce a new parameter that allows one to
select <a class="reference internal" href="#eager-dijkstra-s-algorithm">Eager Dijkstra's algorithm</a> and control the amount of work it
performs. Only differences and new parameters are documented here.</p>
<dl class="docutils">
<dt>IN: <tt class="docutils literal"><span class="pre">Graph&amp;</span> <span class="pre">g</span></tt></dt>
<dd>The graph type must be a model of <a class="reference external" href="DistributedGraph.html">Distributed Graph</a>.</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">vertex_descriptor</span> <span class="pre">s</span></tt></dt>
<dd>The start vertex must be the same in every process.</dd>
<dt>OUT: <tt class="docutils literal"><span class="pre">predecessor_map(PredecessorMap</span> <span class="pre">p_map)</span></tt></dt>
<dd><p class="first">The predecessor map must be a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a> or
<tt class="docutils literal"><span class="pre">dummy_property_map</span></tt>, although only the local portions of the map
will be written.</p>
<p class="last"><strong>Default:</strong> <tt class="docutils literal"><span class="pre">dummy_property_map</span></tt></p>
</dd>
<dt>UTIL/OUT: <tt class="docutils literal"><span class="pre">distance_map(DistanceMap</span> <span class="pre">d_map)</span></tt></dt>
<dd>The distance map must be either a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a> or
<tt class="docutils literal"><span class="pre">dummy_property_map</span></tt>. It will be given the <tt class="docutils literal"><span class="pre">vertex_distance</span></tt>
role.</dd>
<dt>IN: <tt class="docutils literal"><span class="pre">visitor(DijkstraVisitor</span> <span class="pre">vis)</span></tt></dt>
<dd>The visitor must be a distributed Dijkstra visitor. The suble differences
between sequential and distributed Dijkstra visitors are discussed in the
section <a class="reference internal" href="#visitor-event-points">Visitor Event Points</a>.</dd>
<dt>UTIL/OUT: <tt class="docutils literal"><span class="pre">color_map(ColorMap</span> <span class="pre">color)</span></tt></dt>
<dd>The color map must be a <a class="reference external" href="distributed_property_map.html">Distributed Property Map</a> with the same
process group as the graph <tt class="docutils literal"><span class="pre">g</span></tt> whose colors must monotonically
darken (white -&gt; gray -&gt; black). The default value is a distributed
<tt class="docutils literal"><span class="pre">iterator_property_map</span></tt> created from a <tt class="docutils literal"><span class="pre">std::vector</span></tt> of
<tt class="docutils literal"><span class="pre">default_color_type</span></tt>.</dd>
</dl>
<p>IN: <tt class="docutils literal"><span class="pre">lookahead(distance_type</span> <span class="pre">look)</span></tt></p>
<blockquote>
<p>When this parameter is supplied, the implementation will use the
<a class="reference internal" href="#eager-dijkstra-s-algorithm">Eager Dijkstra's algorithm</a> with the given lookahead value.
Lookahead permits distributed Dijkstra's algorithm to speculatively
process vertices whose shortest distance from the source may not
have been found yet. When the distance found is the shortest
distance, parallelism is improved and the algorithm may terminate
more quickly. However, if the distance is not the shortest distance,
the vertex will need to be reprocessed later, resulting in more
work.</p>
<p>The type <tt class="docutils literal"><span class="pre">distance_type</span></tt> is the value type of the <tt class="docutils literal"><span class="pre">DistanceMap</span></tt>
property map. It is a nonnegative value specifying how far ahead
Dijkstra's algorithm may process values.</p>
<p><strong>Default:</strong> no value (lookahead is not employed; uses <a class="reference internal" href="#crauser-et-al-s-algorithm">Crauser et
al.'s algorithm</a>).</p>
</blockquote>
</div>
<div class="section" id="visitor-event-points">
<h1><a class="toc-backref" href="#id12">Visitor Event Points</a></h1>
<p>The <a class="reference external" href="http://www.boost.org/libs/graph/doc/DijkstraVisitor.html">Dijkstra Visitor</a> concept defines 7 event points that will be
triggered by the <a class="reference external" href="http://www.boost.org/libs/graph/doc/dijkstra_shortest_paths.html">sequential Dijkstra implementation</a>. The distributed
Dijkstra retains these event points, but the sequence of events
triggered and the process in which each event occurs will change
depending on the distribution of the graph, lookahead, and edge
weights.</p>
<dl class="docutils">
<dt><tt class="docutils literal"><span class="pre">initialize_vertex(s,</span> <span class="pre">g)</span></tt></dt>
<dd>This will be invoked by every process for each local vertex.</dd>
<dt><tt class="docutils literal"><span class="pre">discover_vertex(u,</span> <span class="pre">g)</span></tt></dt>
<dd>This will be invoked each type a process discovers a new vertex
<tt class="docutils literal"><span class="pre">u</span></tt>. Due to incomplete information in distributed property maps,
this event may be triggered many times for the same vertex <tt class="docutils literal"><span class="pre">u</span></tt>.</dd>
<dt><tt class="docutils literal"><span class="pre">examine_vertex(u,</span> <span class="pre">g)</span></tt></dt>
<dd>This will be invoked by the process owning the vertex <tt class="docutils literal"><span class="pre">u</span></tt>. This
event may be invoked multiple times for the same vertex when the
graph contains negative edges or lookahead is employed.</dd>
<dt><tt class="docutils literal"><span class="pre">examine_edge(e,</span> <span class="pre">g)</span></tt></dt>
<dd>This will be invoked by the process owning the source vertex of
<tt class="docutils literal"><span class="pre">e</span></tt>. As with <tt class="docutils literal"><span class="pre">examine_vertex</span></tt>, this event may be invoked
multiple times for the same edge.</dd>
<dt><tt class="docutils literal"><span class="pre">edge_relaxed(e,</span> <span class="pre">g)</span></tt></dt>
<dd>Similar to <tt class="docutils literal"><span class="pre">examine_edge</span></tt>, this will be invoked by the process
owning the source vertex and may be invoked multiple times (even
without lookahead or negative edges).</dd>
<dt><tt class="docutils literal"><span class="pre">edge_not_relaxed(e,</span> <span class="pre">g)</span></tt></dt>
<dd>Similar to <tt class="docutils literal"><span class="pre">edge_relaxed</span></tt>. Some <tt class="docutils literal"><span class="pre">edge_not_relaxed</span></tt> events that
would be triggered by sequential Dijkstra's will become
<tt class="docutils literal"><span class="pre">edge_relaxed</span></tt> events in distributed Dijkstra's algorithm.</dd>
<dt><tt class="docutils literal"><span class="pre">finish_vertex(e,</span> <span class="pre">g)</span></tt></dt>
<dd>See documentation for <tt class="docutils literal"><span class="pre">examine_vertex</span></tt>. Note that a &quot;finished&quot;
vertex is not necessarily finished if lookahead is permitted or
negative edges exist in the graph.</dd>
</dl>
</div>
<div class="section" id="crauser-et-al-s-algorithm">
<h1><a class="toc-backref" href="#id13">Crauser et al.'s algorithm</a></h1>
<pre class="literal-block">
namespace graph {
template&lt;typename DistributedGraph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap, typename WeightMap,
typename IndexMap, typename ColorMap, typename Compare,
typename Combine, typename DistInf, typename DistZero&gt;
void
crauser_et_al_shortest_paths
(const DistributedGraph&amp; g,
typename graph_traits&lt;DistributedGraph&gt;::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map, ColorMap color_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis);
template&lt;typename DistributedGraph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap, typename WeightMap&gt;
void
crauser_et_al_shortest_paths
(const DistributedGraph&amp; g,
typename graph_traits&lt;DistributedGraph&gt;::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight);
template&lt;typename DistributedGraph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap&gt;
void
crauser_et_al_shortest_paths
(const DistributedGraph&amp; g,
typename graph_traits&lt;DistributedGraph&gt;::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance);
}
</pre>
<p>The formulation of Dijkstra's algorithm by Crauser, Mehlhorn, Meyer,
and Sanders <a class="citation-reference" href="#cmms98a" id="id1">[CMMS98a]</a> improves the scalability of parallel Dijkstra's
algorithm by increasing the number of vertices that can be processed
in a given superstep. This algorithm adapts well to various graph
types, and is a simple algorithm to use, requiring no additional user
input to achieve reasonable performance. The disadvantage of this
algorithm is that the implementation is required to manage three
priority queues, which creates a large amount of work at each node.</p>
<p>This algorithm is used by default in distributed
<tt class="docutils literal"><span class="pre">dijkstra_shortest_paths()</span></tt>.</p>
<div class="section" id="id2">
<h2><a class="toc-backref" href="#id14">Where Defined</a></h2>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/distributed/crauser_et_al_shortest_paths.hpp</span></tt>&gt;</p>
</div>
<div class="section" id="complexity">
<h2><a class="toc-backref" href="#id15">Complexity</a></h2>
<p>This algorithm performs <em>O(V log V)</em> work in <em>d + 1</em> BSP supersteps,
where <em>d</em> is at most <em>O(V)</em> but is generally much smaller. On directed
Erdos-Renyi graphs with edge weights in [0, 1), the expected number of
supersteps <em>d</em> is <em>O(n^(1/3))</em> with high probability.</p>
</div>
<div class="section" id="performance">
<h2><a class="toc-backref" href="#id16">Performance</a></h2>
<p>The following charts illustrate the performance of the Parallel BGL implementation of Crauser et al.'s
algorithm on graphs with edge weights uniformly selected from the
range <em>[0, 1)</em>.</p>
<img align="left" alt="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeSparse_columns_4.png" class="align-left" src="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeSparse_columns_4.png" />
<img alt="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeSparse_columns_4_speedup_1.png" src="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeSparse_columns_4_speedup_1.png" />
<img align="left" alt="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeDense_columns_4.png" class="align-left" src="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeDense_columns_4.png" />
<img alt="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeDense_columns_4_speedup_1.png" src="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeDense_columns_4_speedup_1.png" />
</div>
</div>
<div class="section" id="eager-dijkstra-s-algorithm">
<h1><a class="toc-backref" href="#id17">Eager Dijkstra's algorithm</a></h1>
<pre class="literal-block">
namespace graph {
template&lt;typename DistributedGraph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap, typename WeightMap,
typename IndexMap, typename ColorMap, typename Compare,
typename Combine, typename DistInf, typename DistZero&gt;
void
eager_dijkstra_shortest_paths
(const DistributedGraph&amp; g,
typename graph_traits&lt;DistributedGraph&gt;::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance,
typename property_traits&lt;DistanceMap&gt;::value_type lookahead,
WeightMap weight, IndexMap index_map, ColorMap color_map,
Compare compare, Combine combine, DistInf inf, DistZero zero,
DijkstraVisitor vis);
template&lt;typename DistributedGraph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap, typename WeightMap&gt;
void
eager_dijkstra_shortest_paths
(const DistributedGraph&amp; g,
typename graph_traits&lt;DistributedGraph&gt;::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance,
typename property_traits&lt;DistanceMap&gt;::value_type lookahead,
WeightMap weight);
template&lt;typename DistributedGraph, typename DijkstraVisitor,
typename PredecessorMap, typename DistanceMap&gt;
void
eager_dijkstra_shortest_paths
(const DistributedGraph&amp; g,
typename graph_traits&lt;DistributedGraph&gt;::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance,
typename property_traits&lt;DistanceMap&gt;::value_type lookahead);
}
</pre>
<p>In each superstep, parallel Dijkstra's algorithm typically only
processes nodes whose distances equivalent to the global minimum
distance, because these distances are guaranteed to be correct. This
variation on the algorithm allows the algorithm to process all
vertices whose distances are within some constant value of the
minimum distance. The value is called the &quot;lookahead&quot; value and is
provided by the user as the fifth parameter to the function. Small
values of the lookahead parameter will likely result in limited
parallelization opportunities, whereas large values will expose more
parallelism but may introduce (non-infinite) looping and result in
extra work. The optimal value for the lookahead parameter depends on
the input graph; see <a class="citation-reference" href="#cmms98b" id="id3">[CMMS98b]</a> and <a class="citation-reference" href="#ms98" id="id4">[MS98]</a>.</p>
<p>This algorithm will be used by <tt class="docutils literal"><span class="pre">dijkstra_shortest_paths()</span></tt> when it
is provided with a lookahead value.</p>
<div class="section" id="id5">
<h2><a class="toc-backref" href="#id18">Where Defined</a></h2>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/distributed/eager_dijkstra_shortest_paths.hpp</span></tt>&gt;</p>
</div>
<div class="section" id="id6">
<h2><a class="toc-backref" href="#id19">Complexity</a></h2>
<p>This algorithm performs <em>O(V log V)</em> work in <em>d
+ 1</em> BSP supersteps, where <em>d</em> is at most <em>O(V)</em> but may be smaller
depending on the lookahead value. the algorithm may perform more work
when a large lookahead is provided, because vertices will be
reprocessed.</p>
</div>
<div class="section" id="id7">
<h2><a class="toc-backref" href="#id20">Performance</a></h2>
<p>The performance of the eager Dijkstra's algorithm varies greatly
depending on the lookahead value. The following charts illustrate the
performance of the Parallel BGL on graphs with edge weights uniformly
selected from the range <em>[0, 1)</em> and a constant lookahead of 0.1.</p>
<img align="left" alt="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeSparse_columns_5.png" class="align-left" src="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeSparse_columns_5.png" />
<img alt="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeSparse_columns_5_speedup_1.png" src="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeSparse_columns_5_speedup_1.png" />
<img align="left" alt="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeDense_columns_5.png" class="align-left" src="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeDense_columns_5.png" />
<img alt="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeDense_columns_5_speedup_1.png" src="chart_php_cluster_Odin_generator_ER_SF_SW_dataset_TimeDense_columns_5_speedup_1.png" />
</div>
</div>
<div class="section" id="delta-stepping-algorithm">
<h1><a class="toc-backref" href="#id21">Delta-Stepping algorithm</a></h1>
<pre class="literal-block">
namespace boost { namespace graph { namespace distributed {
template &lt;typename Graph, typename PredecessorMap,
typename DistanceMap, typename WeightMap&gt;
void delta_stepping_shortest_paths
(const Graph&amp; g,
typename graph_traits&lt;Graph&gt;::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
typename property_traits&lt;WeightMap&gt;::value_type delta)
template &lt;typename Graph, typename PredecessorMap,
typename DistanceMap, typename WeightMap&gt;
void delta_stepping_shortest_paths
(const Graph&amp; g,
typename graph_traits&lt;Graph&gt;::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight)
}
} } }
</pre>
<p>The delta-stepping algorithm <a class="citation-reference" href="#ms98" id="id8">[MS98]</a> is another variant of the parallel
Dijkstra algorithm. Like the eager Dijkstra algorithm, it employs a
lookahead (<tt class="docutils literal"><span class="pre">delta</span></tt>) value that allows processors to process vertices
before we are guaranteed to find their minimum distances, permitting
more parallelism than a conservative strategy. Delta-stepping also
introduces a multi-level bucket data structure that provides more
relaxed ordering constraints than the priority queues employed by the
other Dijkstra variants, reducing the complexity of insertions,
relaxations, and removals from the central data structure. The
delta-stepping algorithm is the best-performing of the Dijkstra
variants.</p>
<p>The lookahead value <tt class="docutils literal"><span class="pre">delta</span></tt> determines how large each of the
&quot;buckets&quot; within the delta-stepping queue will be, where the ith
bucket contains edges within tentative distances between <tt class="docutils literal"><span class="pre">delta``*i</span>
<span class="pre">and</span> <span class="pre">``delta``*(i+1).</span> <span class="pre">``delta</span></tt> must be a positive value. When omitted,
<tt class="docutils literal"><span class="pre">delta</span></tt> will be set to the maximum edge weight divided by the
maximum degree.</p>
<div class="section" id="id9">
<h2><a class="toc-backref" href="#id22">Where Defined</a></h2>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/distributed/delta_stepping_shortest_paths.hpp</span></tt>&gt;</p>
</div>
</div>
<div class="section" id="example">
<h1><a class="toc-backref" href="#id23">Example</a></h1>
<p>See the separate <a class="reference external" href="dijkstra_example.html">Dijkstra example</a>.</p>
</div>
<div class="section" id="bibliography">
<h1><a class="toc-backref" href="#id24">Bibliography</a></h1>
<table class="docutils citation" frame="void" id="cmms98a" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id1">[CMMS98a]</a></td><td>Andreas Crauser, Kurt Mehlhorn, Ulrich Meyer, and Peter Sanders. A
Parallelization of Dijkstra's Shortest Path Algorithm. In
<em>Mathematical Foundations of Computer Science (MFCS)</em>, volume 1450 of
Lecture Notes in Computer Science, pages 722--731, 1998. Springer.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="cmms98b" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label"><a class="fn-backref" href="#id3">[CMMS98b]</a></td><td>Andreas Crauser, Kurt Mehlhorn, Ulrich Meyer, and Peter
Sanders. Parallelizing Dijkstra's shortest path algorithm. Technical
report, MPI-Informatik, 1998.</td></tr>
</tbody>
</table>
<table class="docutils citation" frame="void" id="ms98" rules="none">
<colgroup><col class="label" /><col /></colgroup>
<tbody valign="top">
<tr><td class="label">[MS98]</td><td><em>(<a class="fn-backref" href="#id4">1</a>, <a class="fn-backref" href="#id8">2</a>)</em> Ulrich Meyer and Peter Sanders. Delta-stepping: A parallel
shortest path algorithm. In <em>6th ESA</em>, LNCS. Springer, 1998.</td></tr>
</tbody>
</table>
<hr class="docutils" />
<p>Copyright (C) 2004, 2005, 2006, 2007, 2008 The Trustees of Indiana University.</p>
<p>Authors: Douglas Gregor and Andrew Lumsdaine</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:21 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>distributedS Distribution Selector</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="distributeds-distribution-selector">
<h1 class="title"><tt class="docutils literal"><span class="pre">distributedS</span></tt> Distribution Selector</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<p>The Boost Graph Library's class template <a class="reference external" href="http://www.boost.org/libs/graph/doc/adjacency_list.html">adjacency_list</a> supports
several selectors that indicate what data structure should be used for
the storage of edges or vertices. The selector <tt class="docutils literal"><span class="pre">vecS</span></tt>, for instance,
indicates storage in a <tt class="docutils literal"><span class="pre">std::vector</span></tt> whereas <tt class="docutils literal"><span class="pre">listS</span></tt> indicates
storage in a <tt class="docutils literal"><span class="pre">std::list</span></tt>. The Parallel BGL's <a class="reference external" href="distributed_adjacency_list.html">distributed
adjacency list</a> supports an additional selector, <tt class="docutils literal"><span class="pre">distributedS</span></tt>,
that indicates that the storage should be distributed across multiple
processes. This selector can transform a sequential adjacency list
into a distributed adjacency list.</p>
<pre class="literal-block">
template&lt;typename ProcessGroup, typename LocalSelector = vecS&gt;
struct distributedS;
</pre>
<div class="section" id="template-parameters">
<h1>Template parameters</h1>
<dl class="docutils">
<dt><strong>ProcessGroup</strong>:</dt>
<dd>The type of the process group over which the property map is
distributed and also the medium for communication. This type must
model the <a class="reference external" href="process_group.html">Process Group</a> concept, but certain data structures may
place additional requirements on this parameter.</dd>
<dt><strong>LocalSelector</strong>:</dt>
<dd>A selector type (e.g., <tt class="docutils literal"><span class="pre">vecS</span></tt>) that indicates how vertices or
edges should be stored in each process.</dd>
</dl>
<hr class="docutils" />
<p>Copyright (C) 2005 The Trustees of Indiana University.</p>
<p>Authors: Douglas Gregor and Andrew Lumsdaine</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:22 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,804 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Distributed Adjacency List</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-distributed-adjacency-list">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Distributed Adjacency List</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#introduction" id="id1">Introduction</a><ul>
<li><a class="reference internal" href="#defining-a-distributed-adjacency-list" id="id2">Defining a Distributed Adjacency List</a></li>
<li><a class="reference internal" href="#distributed-vertex-and-edge-properties" id="id3">Distributed Vertex and Edge Properties</a></li>
<li><a class="reference internal" href="#named-vertices" id="id4">Named Vertices</a></li>
<li><a class="reference internal" href="#building-a-distributed-graph" id="id5">Building a Distributed Graph</a></li>
<li><a class="reference internal" href="#graph-concepts" id="id6">Graph Concepts</a></li>
</ul>
</li>
<li><a class="reference internal" href="#reference" id="id7">Reference</a><ul>
<li><a class="reference internal" href="#where-defined" id="id8">Where Defined</a></li>
<li><a class="reference internal" href="#associated-types" id="id9">Associated Types</a></li>
<li><a class="reference internal" href="#member-functions" id="id10">Member Functions</a></li>
<li><a class="reference internal" href="#non-member-functions" id="id11">Non-Member Functions</a></li>
<li><a class="reference internal" href="#structure-modification" id="id12">Structure Modification</a></li>
<li><a class="reference internal" href="#property-map-accessors" id="id13">Property Map Accessors</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="introduction">
<h1><a class="toc-backref" href="#id1">Introduction</a></h1>
<p>The distributed adjacency list implements a graph data structure using
an adjacency list representation. Its interface and behavior are
roughly equivalent to the Boost Graph Library's <a class="reference external" href="http://www.boost.org/libs/graph/doc/adjacency_list.html">adjacency_list</a>
class template. However, the distributed adjacency list partitions the
vertices of the graph across several processes (which need not share
an address space). Edges outgoing from any vertex stored by a process
are also stored on that process, except in the case of undirected
graphs, where either the source or the target may store the edge.</p>
<pre class="literal-block">
template&lt;typename OutEdgeListS, typename ProcessGroup, typename VertexListS,
typename DirectedS, typename VertexProperty, typename EdgeProperty,
typename GraphProperty, typename EdgeListS&gt;
class adjacency_list&lt;OutEdgeListS,
distributedS&lt;ProcessGroup, VertexListS&gt;,
DirectedS, VertexProperty,
EdgeProperty, GraphProperty, EdgeListS&gt;;
</pre>
<div class="section" id="defining-a-distributed-adjacency-list">
<h2><a class="toc-backref" href="#id2">Defining a Distributed Adjacency List</a></h2>
<p>To create a distributed adjacency list, first determine the
representation of the graph in a single address space using these
<a class="reference external" href="http://www.boost.org/libs/graph/doc/using_adjacency_list.html">guidelines</a>. Next, replace the vertex list selector (<tt class="docutils literal"><span class="pre">VertexListS</span></tt>)
with an instantiation of <a class="reference external" href="distributedS.html">distributedS</a>, which includes:</p>
<ul class="simple">
<li>Selecting a <a class="reference external" href="process_group.html">process group</a> type that represents the various
coordinating processes that will store the distributed graph. For
example, the <a class="reference external" href="process_group.html">MPI process group</a>.</li>
<li>A selector indicating how the vertex lists in each process will be
stored. Only the <tt class="docutils literal"><span class="pre">vecS</span></tt> and <tt class="docutils literal"><span class="pre">listS</span></tt> selectors are well-supported
at this time.</li>
</ul>
<p>The following <tt class="docutils literal"><span class="pre">typedef</span></tt> defines a distributed adjacency list
containing directed edges. The vertices in the graph will be
distributed over several processes, using the MPI process group
for communication. In each process, the vertices and outgoing edges
will be stored in STL vectors. There are no properties attached to the
vertices or edges of the graph.</p>
<pre class="literal-block">
using namespace boost;
typedef adjacency_list&lt;vecS,
distributedS&lt;parallel::mpi::bsp_process_group, vecS&gt;,
directedS&gt;
Graph;
</pre>
</div>
<div class="section" id="distributed-vertex-and-edge-properties">
<h2><a class="toc-backref" href="#id3">Distributed Vertex and Edge Properties</a></h2>
<p>Vertex and edge properties for distributed graphs mirror their
counterparts for non-distributed graphs. With a distributed graph,
however, vertex and edge properties are stored only in the process
that owns the vertex or edge.</p>
<p>The most direct way to attach properties to a distributed graph is to
create a structure that will be attached to each of the vertices and
edges of the graph. For example, if we wish to model a simplistic map
of the United States interstate highway system, we might state that
the vertices of the graph are cities and the edges are highways, then
define the information that we maintain for each city and highway:</p>
<pre class="literal-block">
struct City {
City() { }
City(const std::string&amp; name, const std::string&amp; mayor = &quot;Unknown&quot;, int population = 0)
: name(name), mayor(mayor), population(population) { }
std::string name;
std::string mayor;
int population;
// Serialization support is required!
template&lt;typename Archiver&gt;
void serialize(Archiver&amp; ar, const unsigned int /*version*/) {
ar &amp; name &amp; mayor &amp; population;
}
};
struct Highway {
Highway() { }
Highway(const std::string&amp; name, int lanes, int miles_per_hour, int length)
: name(name), lanes(lanes), miles_per_hour(miles_per_hour), length(length) { }
std::string name;
int lanes;
int miles_per_hour;
int length;
// Serialization support is required!
template&lt;typename Archiver&gt;
void serialize(Archiver&amp; ar, const unsigned int /*version*/) {
ar &amp; name &amp; lanes &amp; miles_per_hour &amp; length;
}
};
</pre>
<p>To create a distributed graph for a road map, we supply <tt class="docutils literal"><span class="pre">City</span></tt> and
<tt class="docutils literal"><span class="pre">Highway</span></tt> as the fourth and fifth parameters to <tt class="docutils literal"><span class="pre">adjacency_list</span></tt>,
respectively:</p>
<pre class="literal-block">
typedef adjacency_list&lt;vecS,
distributedS&lt;parallel::mpi::bsp_process_group, vecS&gt;,
directedS,
City, Highway&gt;
RoadMap;
</pre>
<p>Property maps for internal properties retain their behavior with
distributed graphs via <a class="reference external" href="distributed_property_map.html">distributed property maps</a>, which automate
communication among processes so that <tt class="docutils literal"><span class="pre">put</span></tt> and <tt class="docutils literal"><span class="pre">get</span></tt> operations
may be applied to non-local vertices and edges. However, for
distributed adjacency lists that store vertices in a vector
(<tt class="docutils literal"><span class="pre">VertexListS</span></tt> is <tt class="docutils literal"><span class="pre">vecS</span></tt>), the automatic <tt class="docutils literal"><span class="pre">vertex_index</span></tt>
property map restricts the domain of <tt class="docutils literal"><span class="pre">put</span></tt> and <tt class="docutils literal"><span class="pre">get</span></tt> operations
to vertices local to the process executing the operation. For example,
we can create a property map that accesses the length of each highway
as follows:</p>
<pre class="literal-block">
RoadMap map; // distributed graph instance
typedef property_map&lt;RoadMap, int Highway::*&gt;::type
road_length = get(&amp;Highway::length, map);
</pre>
<p>Now, one can access the length of any given road based on its edge
descriptor <tt class="docutils literal"><span class="pre">e</span></tt> with the expression <tt class="docutils literal"><span class="pre">get(road_length,</span> <span class="pre">e)</span></tt>,
regardless of which process stores the edge <tt class="docutils literal"><span class="pre">e</span></tt>.</p>
</div>
<div class="section" id="named-vertices">
<h2><a class="toc-backref" href="#id4">Named Vertices</a></h2>
<p>The vertices of a graph typically correspond to named entities within
the application domain. In the road map example from the previous
section, the vertices in the graph represent cities. The distributed
adjacency list supports named vertices, which provides an implicit
mapping from the names of the vertices in the application domain
(e.g., the name of a city, such as &quot;Bloomington&quot;) to the actual vertex
descriptor stored within the distributed graph (e.g., the third vertex
on processor 1). By enabling support for named vertices, one can refer
to vertices by name when manipulating the graph. For example, one can
add a highway from Indianapolis to Chicago:</p>
<pre class="literal-block">
add_edge(&quot;Indianapolis&quot;, &quot;Chicago&quot;, Highway(&quot;I-65&quot;, 4, 65, 151), map);
</pre>
<p>The distributed adjacency list will find vertices associated with the
names &quot;Indianapolis&quot; and &quot;Chicago&quot;, then add an edge between these
vertices that represents I-65. The vertices may be stored on any
processor, local or remote.</p>
<p>To enable named vertices, specialize the <tt class="docutils literal"><span class="pre">internal_vertex_name</span></tt>
property for the structure attached to the vertices in your
graph. <tt class="docutils literal"><span class="pre">internal_vertex_name</span></tt> contains a single member, <tt class="docutils literal"><span class="pre">type</span></tt>,
which is the type of a function object that accepts a vertex property
and returns the name stored within that vertex property. In the case
of our road map, the <tt class="docutils literal"><span class="pre">name</span></tt> field contains the name of each city, so
we use the <tt class="docutils literal"><span class="pre">member</span></tt> function object from the <a class="reference external" href="http://www.boost.org/libs/multi_index/doc/index.html">Boost.MultiIndex</a>
library to extract the name, e.g.,</p>
<pre class="literal-block">
namespace boost { namespace graph {
template&lt;&gt;
struct internal_vertex_name&lt;City&gt;
{
typedef multi_index::member&lt;City, std::string, &amp;City::name&gt; type;
};
} }
</pre>
<p>That's it! One can now refer to vertices by name when interacting with
the distributed adjacency list.</p>
<p>What happens when one uses the name of a vertex that does not exist?
For example, in our <tt class="docutils literal"><span class="pre">add_edge</span></tt> call above, what happens if the
vertex named &quot;Indianapolis&quot; has not yet been added to the graph? By
default, the distributed adjacency list will throw an exception if a
named vertex does not yet exist. However, one can customize this
behavior by specifying a function object that constructs an instance
of the vertex property (e.g., <tt class="docutils literal"><span class="pre">City</span></tt>) from just the name of the
vertex. This customization occurs via the
<tt class="docutils literal"><span class="pre">internal_vertex_constructor</span></tt> trait. For example, using the
<tt class="docutils literal"><span class="pre">vertex_from_name</span></tt> template (provided with the Parallel BGL), we can
state that a <tt class="docutils literal"><span class="pre">City</span></tt> can be constructed directly from the name of the
city using its second constructor:</p>
<pre class="literal-block">
namespace boost { namespace graph {
template&lt;&gt;
struct internal_vertex_constructor&lt;City&gt;
{
typedef vertex_from_name&lt;City&gt; type;
};
} }
</pre>
<p>Now, one can add edges by vertex name freely, without worrying about
the explicit addition of vertices. The <tt class="docutils literal"><span class="pre">mayor</span></tt> and <tt class="docutils literal"><span class="pre">population</span></tt>
fields will have default values, but the graph structure will be
correct.</p>
</div>
<div class="section" id="building-a-distributed-graph">
<h2><a class="toc-backref" href="#id5">Building a Distributed Graph</a></h2>
<p>Once you have determined the layout of your graph type, including the
specific data structures and properties, it is time to construct an
instance of the graph by adding the appropriate vertices and
edges. Construction of distributed graphs can be slightly more
complicated than construction of normal, non-distributed graph data
structures, because one must account for both the distribution of the
vertices and edges and the multiple processes executing
concurrently. There are three main ways to construct distributed
graphs:</p>
<p>1. <em>Sequence constructors</em>: if your data can easily be generated by a
pair of iterators that produce (source, target) pairs, you can use the
sequence constructors to build the distributed graph in parallel. This
method is often preferred when creating benchmarks, because random
graph generators like the <a class="reference external" href="http://www.boost.org/libs/graph/doc/sorted_erdos_renyi_gen.html">sorted_erdos_renyi_iterator</a> create the
appropriate input sequence. Note that one must provide the same input
iterator sequence on all processes. This method has the advantage that
the sequential graph-building code is identical to the parallel
graph-building code. An example constructing a random graph this way:</p>
<blockquote>
<pre class="literal-block">
typedef boost::sorted_erdos_renyi_iterator&lt;boost::minstd_rand, Graph&gt; ERIter;
boost::minstd_rand gen;
unsigned long n = 1000000; // 1M vertices
Graph g(ERIter(gen, n, 0.00005), ERIter(), n);
</pre>
</blockquote>
<p>2. <em>Adding edges by vertex number</em>: if you are able to map your
vertices into values in the random [0, <em>n</em>), where <em>n</em> is the number
of vertices in the distributed graph. Use this method rather than the
sequence constructors when your algorithm cannot easily be moved into
input iterators, or if you can't replicate the input sequence. For
example, you might be reading the graph from an input file:</p>
<blockquote>
<pre class="literal-block">
Graph g(n); // initialize with the total number of vertices, n
if (process_id(g.process_group()) == 0) {
// Only process 0 loads the graph, which is distributed automatically
int source, target;
for (std::cin &gt;&gt; source &gt;&gt; target)
add_edge(vertex(source, g), vertex(target, g), g);
}
// All processes synchronize at this point, then the graph is complete
synchronize(g.process_group());
</pre>
</blockquote>
<p>3. <em>Adding edges by name</em>: if you are using named vertices, you can
construct your graph just by calling <tt class="docutils literal"><span class="pre">add_edge</span></tt> with the names of
the source and target vertices. Be careful to make sure that each edge
is added by only one process (it doesn't matter which process it is),
otherwise you will end up with multiple edges. For example, in the
following program we read edges from the standard input of process 0,
adding those edges by name. Vertices and edges will be created and
distributed automatically.</p>
<blockquote>
<pre class="literal-block">
Graph g;
if (process_id(g.process_group()) == 0) {
// Only process 0 loads the graph, which is distributed automatically
std:string source, target;
for(std::cin &gt;&gt; source &gt;&gt; target)
add_edge(source, target, g);
}
// All processes synchronize at this point, then the graph is complete
synchronize(g.process_group());
</pre>
</blockquote>
</div>
<div class="section" id="graph-concepts">
<h2><a class="toc-backref" href="#id6">Graph Concepts</a></h2>
<p>The distributed adjacency list models the <a class="reference external" href="http://www.boost.org/libs/graph/doc/Graph.html">Graph</a> concept, and in
particular the <a class="reference external" href="DistributedGraph.html">Distributed Graph</a> concept. It also models the
<a class="reference external" href="http://www.boost.org/libs/graph/doc/IncidenceGraph.html">Incidence Graph</a> and <a class="reference external" href="http://www.boost.org/libs/graph/doc/AdjacencyGraph.html">Adjacency Graph</a> concept, but restricts the
input domain of the operations to correspond to local vertices
only. For instance, a process may only access the outgoing edges of a
vertex if that vertex is stored in that process. Undirected and
bidirectional distributed adjacency lists model the <a class="reference external" href="http://www.boost.org/libs/graph/doc/BidirectionalGraph.html">Bidirectional
Graph</a> concept, with the same domain restrictions. Distributed
adjacency lists also model the <a class="reference external" href="http://www.boost.org/libs/graph/doc/MutableGraph.html">Mutable Graph</a> concept (with domain
restrictions; see the <a class="reference internal" href="#reference">Reference</a> section), <a class="reference external" href="http://www.boost.org/libs/graph/doc/PropertyGraph.html">Property Graph</a> concept,
and <a class="reference external" href="http://www.boost.org/libs/graph/doc/MutablePropertyGraph.html">Mutable Property Graph</a> concept.</p>
<p>Unlike its non-distributed counterpart, the distributed adjacency
list does <strong>not</strong> model the <a class="reference external" href="http://www.boost.org/libs/graph/doc/VertexListGraph.html">Vertex List Graph</a> or <a class="reference external" href="http://www.boost.org/libs/graph/doc/EdgeListGraph.html">Edge List
Graph</a> concepts, because one cannot enumerate all vertices or edges
within a distributed graph. Instead, it models the weaker
<a class="reference external" href="DistributedVertexListGraph.html">Distributed Vertex List Graph</a> and <a class="reference external" href="DistributedEdgeListGraph.html">Distributed Edge List Graph</a>
concepts, which permit access to the local edges and vertices on each
processor. Note that if all processes within the process group over
which the graph is distributed iterator over their respective vertex
or edge lists, all vertices and edges will be covered once.</p>
</div>
</div>
<div class="section" id="reference">
<h1><a class="toc-backref" href="#id7">Reference</a></h1>
<p>Since the distributed adjacency list closely follows the
non-distributed <a class="reference external" href="http://www.boost.org/libs/graph/doc/adjacency_list.html">adjacency_list</a>, this reference documentation
only describes where the two implementations differ.</p>
<div class="section" id="where-defined">
<h2><a class="toc-backref" href="#id8">Where Defined</a></h2>
<p>&lt;boost/graph/distributed/adjacency_list.hpp&gt;</p>
</div>
<div class="section" id="associated-types">
<h2><a class="toc-backref" href="#id9">Associated Types</a></h2>
<pre class="literal-block">
adjacency_list::process_group_type
</pre>
<p>The type of the process group over which the graph will be
distributed.</p>
<hr class="docutils" />
<blockquote>
adjacency_list::distribution_type</blockquote>
<p>The type of distribution used to partition vertices in the graph.</p>
<hr class="docutils" />
<blockquote>
adjacency_list::vertex_name_type</blockquote>
<p>If the graph supports named vertices, this is the type used to name
vertices. Otherwise, this type is not present within the distributed
adjacency list.</p>
</div>
<div class="section" id="member-functions">
<h2><a class="toc-backref" href="#id10">Member Functions</a></h2>
<pre class="literal-block">
adjacency_list(const ProcessGroup&amp; pg = ProcessGroup());
adjacency_list(const GraphProperty&amp; g,
const ProcessGroup&amp; pg = ProcessGroup());
</pre>
<p>Construct an empty distributed adjacency list with the given process
group (or default) and graph property (or default).</p>
<hr class="docutils" />
<pre class="literal-block">
adjacency_list(vertices_size_type n, const GraphProperty&amp; p,
const ProcessGroup&amp; pg, const Distribution&amp; distribution);
adjacency_list(vertices_size_type n, const ProcessGroup&amp; pg,
const Distribution&amp; distribution);
adjacency_list(vertices_size_type n, const GraphProperty&amp; p,
const ProcessGroup&amp; pg = ProcessGroup());
adjacency_list(vertices_size_type n,
const ProcessGroup&amp; pg = ProcessGroup());
</pre>
<p>Construct a distributed adjacency list with <tt class="docutils literal"><span class="pre">n</span></tt> vertices,
optionally providing the graph property, process group, or
distribution. The <tt class="docutils literal"><span class="pre">n</span></tt> vertices will be distributed via the given
(or default-constructed) distribution. This operation is collective,
requiring all processes with the process group to execute it
concurrently.</p>
<hr class="docutils" />
<pre class="literal-block">
template &lt;class EdgeIterator&gt;
adjacency_list(EdgeIterator first, EdgeIterator last,
vertices_size_type n,
const ProcessGroup&amp; pg = ProcessGroup(),
const GraphProperty&amp; p = GraphProperty());
template &lt;class EdgeIterator, class EdgePropertyIterator&gt;
adjacency_list(EdgeIterator first, EdgeIterator last,
EdgePropertyIterator ep_iter,
vertices_size_type n,
const ProcessGroup&amp; pg = ProcessGroup(),
const GraphProperty&amp; p = GraphProperty());
template &lt;class EdgeIterator&gt;
adjacency_list(EdgeIterator first, EdgeIterator last,
vertices_size_type n,
const ProcessGroup&amp; process_group,
const Distribution&amp; distribution,
const GraphProperty&amp; p = GraphProperty());
template &lt;class EdgeIterator, class EdgePropertyIterator&gt;
adjacency_list(EdgeIterator first, EdgeIterator last,
EdgePropertyIterator ep_iter,
vertices_size_type n,
const ProcessGroup&amp; process_group,
const Distribution&amp; distribution,
const GraphProperty&amp; p = GraphProperty());
</pre>
<p>Construct a distributed adjacency list with <tt class="docutils literal"><span class="pre">n</span></tt> vertices and with
edges specified in the edge list given by the range <tt class="docutils literal"><span class="pre">[first,</span> <span class="pre">last)</span></tt>. The
<tt class="docutils literal"><span class="pre">EdgeIterator</span></tt> must be a model of <a class="reference external" href="http://www.boost.org/doc/html/InputIterator.html">InputIterator</a>. The value type of the
<tt class="docutils literal"><span class="pre">EdgeIterator</span></tt> must be a <tt class="docutils literal"><span class="pre">std::pair</span></tt>, where the type in the pair is an
integer type. The integers will correspond to vertices, and they must
all fall in the range of <tt class="docutils literal"><span class="pre">[0,</span> <span class="pre">n)</span></tt>. When provided, <tt class="docutils literal"><span class="pre">ep_iter</span></tt>
refers to an edge property list <tt class="docutils literal"><span class="pre">[ep_iter,</span> <span class="pre">ep_iter</span> <span class="pre">+</span> <span class="pre">m)</span></tt> contains
properties for each of the edges.</p>
<p>This constructor is a collective operation and must be executed
concurrently by each process with the same argument list. Most
importantly, the edge lists provided to the constructor in each process
should be equivalent. The vertices will be partitioned among the
processes according to the <tt class="docutils literal"><span class="pre">distribution</span></tt>, with edges placed on the
process owning the source of the edge. Note that this behavior
permits sequential graph construction code to be parallelized
automatically, regardless of the underlying distribution.</p>
<hr class="docutils" />
<pre class="literal-block">
void clear()
</pre>
<p>Removes all of the edges and vertices from the local graph. To
eliminate all vertices and edges from the graph, this routine must be
executed in all processes.</p>
<hr class="docutils" />
<pre class="literal-block">
process_group_type&amp; process_group();
const process_group_type&amp; process_group() const;
</pre>
<p>Returns the process group over which this graph is distributed.</p>
<hr class="docutils" />
<pre class="literal-block">
distribution_type&amp; distribution();
const distribution_type&amp; distribution() const;
</pre>
<p>Returns the distribution used for initial placement of vertices.</p>
<hr class="docutils" />
<pre class="literal-block">
template&lt;typename VertexProcessorMap&gt;
void redistribute(VertexProcessorMap vertex_to_processor);
</pre>
<p>Redistributes the vertices (and, therefore, the edges) of the
graph. The property map <tt class="docutils literal"><span class="pre">vertex_to_processor</span></tt> provides, for each
vertex, the process identifier indicating where the vertex should be
moved. Once this collective routine has completed, the distributed
graph will reflect the new distribution. All vertex and edge
descsriptors and internal and external property maps are invalidated
by this operation.</p>
<hr class="docutils" />
<pre class="literal-block">
template&lt;typename OStreamConstructibleArchive&gt;
void save(std::string const&amp; filename) const;
template&lt;typename IStreamConstructibleArchive&gt;
void load(std::string const&amp; filename);
</pre>
<p>Serializes the graph to a Boost.Serialization archive.
<tt class="docutils literal"><span class="pre">OStreamConstructibleArchive</span></tt> and <tt class="docutils literal"><span class="pre">IStreamConstructibleArchive</span></tt>
are models of Boost.Serialization <em>Archive</em> with the extra
requirement that they can be constructed from a <tt class="docutils literal"><span class="pre">std::ostream</span></tt>
and <tt class="docutils literal"><span class="pre">std::istream</span></tt>.
<tt class="docutils literal"><span class="pre">filename</span></tt> names a directory that will hold files for
the different processes.</p>
</div>
<div class="section" id="non-member-functions">
<h2><a class="toc-backref" href="#id11">Non-Member Functions</a></h2>
<pre class="literal-block">
std::pair&lt;vertex_iterator, vertex_iterator&gt;
vertices(const adjacency_list&amp; g);
</pre>
<p>Returns an iterator-range providing access to the vertex set of graph
<tt class="docutils literal"><span class="pre">g</span></tt> stored in this process. Each of the processes that contain <tt class="docutils literal"><span class="pre">g</span></tt>
will get disjoint sets of vertices.</p>
<hr class="docutils" />
<pre class="literal-block">
std::pair&lt;edge_iterator, edge_iterator&gt;
edges(const adjacency_list&amp; g);
</pre>
<p>Returns an iterator-range providing access to the edge set of graph
<tt class="docutils literal"><span class="pre">g</span></tt> stored in this process.</p>
<hr class="docutils" />
<pre class="literal-block">
std::pair&lt;adjacency_iterator, adjacency_iterator&gt;
adjacent_vertices(vertex_descriptor u, const adjacency_list&amp; g);
</pre>
<p>Returns an iterator-range providing access to the vertices adjacent to
vertex <tt class="docutils literal"><span class="pre">u</span></tt> in graph <tt class="docutils literal"><span class="pre">g</span></tt>. The vertex <tt class="docutils literal"><span class="pre">u</span></tt> must be local to this process.</p>
<hr class="docutils" />
<pre class="literal-block">
std::pair&lt;out_edge_iterator, out_edge_iterator&gt;
out_edges(vertex_descriptor u, const adjacency_list&amp; g);
</pre>
<p>Returns an iterator-range providing access to the out-edges of vertex
<tt class="docutils literal"><span class="pre">u</span></tt> in graph <tt class="docutils literal"><span class="pre">g</span></tt>. If the graph is undirected, this iterator-range
provides access to all edges incident on vertex <tt class="docutils literal"><span class="pre">u</span></tt>. For both
directed and undirected graphs, for an out-edge <tt class="docutils literal"><span class="pre">e</span></tt>, <tt class="docutils literal"><span class="pre">source(e,</span> <span class="pre">g)</span>
<span class="pre">==</span> <span class="pre">u</span></tt> and <tt class="docutils literal"><span class="pre">target(e,</span> <span class="pre">g)</span> <span class="pre">==</span> <span class="pre">v</span></tt> where <tt class="docutils literal"><span class="pre">v</span></tt> is a vertex adjacent to
<tt class="docutils literal"><span class="pre">u</span></tt>. The vertex <tt class="docutils literal"><span class="pre">u</span></tt> must be local to this process.</p>
<hr class="docutils" />
<pre class="literal-block">
std::pair&lt;in_edge_iterator, in_edge_iterator&gt;
in_edges(vertex_descriptor v, const adjacency_list&amp; g);
</pre>
<p>Returns an iterator-range providing access to the in-edges of vertex
<tt class="docutils literal"><span class="pre">v</span></tt> in graph <tt class="docutils literal"><span class="pre">g</span></tt>. This operation is only available if
<tt class="docutils literal"><span class="pre">bidirectionalS</span></tt> was specified for the <tt class="docutils literal"><span class="pre">Directed</span></tt> template
parameter. For an in-edge <tt class="docutils literal"><span class="pre">e</span></tt>, <tt class="docutils literal"><span class="pre">target(e,</span> <span class="pre">g)</span> <span class="pre">==</span> <span class="pre">v</span></tt> and <tt class="docutils literal"><span class="pre">source(e,</span>
<span class="pre">g)</span> <span class="pre">==</span> <span class="pre">u</span></tt> for some vertex <tt class="docutils literal"><span class="pre">u</span></tt> that is adjacent to <tt class="docutils literal"><span class="pre">v</span></tt>, whether the
graph is directed or undirected. The vertex <tt class="docutils literal"><span class="pre">v</span></tt> must be local to
this process.</p>
<hr class="docutils" />
<pre class="literal-block">
degree_size_type
out_degree(vertex_descriptor u, const adjacency_list&amp; g);
</pre>
<p>Returns the number of edges leaving vertex <tt class="docutils literal"><span class="pre">u</span></tt>. Vertex <tt class="docutils literal"><span class="pre">u</span></tt> must
be local to the executing process.</p>
<hr class="docutils" />
<pre class="literal-block">
degree_size_type
in_degree(vertex_descriptor u, const adjacency_list&amp; g);
</pre>
<p>Returns the number of edges entering vertex <tt class="docutils literal"><span class="pre">u</span></tt>. This operation is
only available if <tt class="docutils literal"><span class="pre">bidirectionalS</span></tt> was specified for the
<tt class="docutils literal"><span class="pre">Directed</span></tt> template parameter. Vertex <tt class="docutils literal"><span class="pre">u</span></tt> must be local to the
executing process.</p>
<hr class="docutils" />
<pre class="literal-block">
vertices_size_type
num_vertices(const adjacency_list&amp; g);
</pre>
<p>Returns the number of vertices in the graph <tt class="docutils literal"><span class="pre">g</span></tt> that are stored in
the executing process.</p>
<hr class="docutils" />
<pre class="literal-block">
edges_size_type
num_edges(const adjacency_list&amp; g);
</pre>
<p>Returns the number of edges in the graph <tt class="docutils literal"><span class="pre">g</span></tt> that are stored in the
executing process.</p>
<hr class="docutils" />
<pre class="literal-block">
vertex_descriptor
vertex(vertices_size_type n, const adjacency_list&amp; g);
</pre>
<p>Returns the <tt class="docutils literal"><span class="pre">n``th</span> <span class="pre">vertex</span> <span class="pre">in</span> <span class="pre">the</span> <span class="pre">graph's</span> <span class="pre">vertex</span> <span class="pre">list,</span> <span class="pre">according</span> <span class="pre">to</span> <span class="pre">the</span>
<span class="pre">distribution</span> <span class="pre">used</span> <span class="pre">to</span> <span class="pre">partition</span> <span class="pre">the</span> <span class="pre">graph.</span> <span class="pre">``n</span></tt> must be a value
between zero and the sum of <tt class="docutils literal"><span class="pre">num_vertices(g)</span></tt> in each process (minus
one). Note that it is not necessarily the case that <tt class="docutils literal"><span class="pre">vertex(0,</span> <span class="pre">g)</span> <span class="pre">==</span>
<span class="pre">*num_vertices(g).first</span></tt>. This function is only guaranteed to be
accurate when no vertices have been added to or removed from the
graph after its initial construction.</p>
<hr class="docutils" />
<pre class="literal-block">
std::pair&lt;edge_descriptor, bool&gt;
edge(vertex_descriptor u, vertex_descriptor v,
const adjacency_list&amp; g);
</pre>
<p>Returns an edge connecting vertex <tt class="docutils literal"><span class="pre">u</span></tt> to vertex <tt class="docutils literal"><span class="pre">v</span></tt> in graph
<tt class="docutils literal"><span class="pre">g</span></tt>. For bidirectional and undirected graphs, either vertex <tt class="docutils literal"><span class="pre">u</span></tt> or
vertex <tt class="docutils literal"><span class="pre">v</span></tt> must be local; for directed graphs, vertex <tt class="docutils literal"><span class="pre">u</span></tt> must be
local.</p>
<hr class="docutils" />
<pre class="literal-block">
std::pair&lt;out_edge_iterator, out_edge_iterator&gt;
edge_range(vertex_descriptor u, vertex_descriptor v,
const adjacency_list&amp; g);
</pre>
<p>TODO: Not implemented. Returns a pair of out-edge iterators that give
the range for all the parallel edges from <tt class="docutils literal"><span class="pre">u</span></tt> to <tt class="docutils literal"><span class="pre">v</span></tt>. This function only
works when the <tt class="docutils literal"><span class="pre">OutEdgeList</span></tt> for the <tt class="docutils literal"><span class="pre">adjacency_list</span></tt> is a container that
sorts the out edges according to target vertex, and allows for
parallel edges. The <tt class="docutils literal"><span class="pre">multisetS</span></tt> selector chooses such a
container. Vertex <tt class="docutils literal"><span class="pre">u</span></tt> must be stored in the executing process.</p>
</div>
<div class="section" id="structure-modification">
<h2><a class="toc-backref" href="#id12">Structure Modification</a></h2>
<pre class="literal-block">
unspecified add_edge(vertex_descriptor u, vertex_descriptor v, adjacency_list&amp; g);
unspecified add_edge(vertex_name_type u, vertex_descriptor v, adjacency_list&amp; g);
unspecified add_edge(vertex_descriptor u, vertex_name_type v, adjacency_list&amp; g);
unspecified add_edge(vertex_name_type u, vertex_name_type v, adjacency_list&amp; g);
</pre>
<p>Adds edge <tt class="docutils literal"><span class="pre">(u,v)</span></tt> to the graph. The return type itself is
unspecified, but the type can be copy-constructed and implicitly
converted into a <tt class="docutils literal"><span class="pre">std::pair&lt;edge_descriptor,bool&gt;</span></tt>. The edge
descriptor describes the added (or found) edge. For graphs that do not
allow parallel edges, if the edge
is already in the graph then a duplicate will not be added and the
<tt class="docutils literal"><span class="pre">bool</span></tt> flag will be <tt class="docutils literal"><span class="pre">false</span></tt>. Also, if u and v are descriptors for
the same vertex (creating a self loop) and the graph is undirected,
then the edge will not be added and the flag will be <tt class="docutils literal"><span class="pre">false</span></tt>. When
the flag is <tt class="docutils literal"><span class="pre">false</span></tt>, the returned edge descriptor points to the
already existing edge.</p>
<p>The parameters <tt class="docutils literal"><span class="pre">u</span></tt> and <tt class="docutils literal"><span class="pre">v</span></tt> can be either vertex descriptors or, if
the graph uses named vertices, the names of vertices. If no vertex
with the given name exists, the internal vertex constructor will be
invoked to create a new vertex property and a vertex with that
property will be added to the graph implicitly. The default internal
vertex constructor throws an exception.</p>
<hr class="docutils" />
<pre class="literal-block">
unspecified add_edge(vertex_descriptor u, vertex_descriptor v, const EdgeProperties&amp; p, adjacency_list&amp; g);
unspecified add_edge(vertex_name_type u, vertex_descriptor v, const EdgeProperties&amp; p, adjacency_list&amp; g);
unspecified add_edge(vertex_descriptor u, vertex_name_type v, const EdgeProperties&amp; p, adjacency_list&amp; g);
unspecified add_edge(vertex_name_type u, vertex_name_type v, const EdgeProperties&amp; p, adjacency_list&amp; g);
</pre>
<p>Adds edge <tt class="docutils literal"><span class="pre">(u,v)</span></tt> to the graph and attaches <tt class="docutils literal"><span class="pre">p</span></tt> as the value of the edge's
internal property storage. See the previous <tt class="docutils literal"><span class="pre">add_edge()</span></tt> member
function for more details.</p>
<hr class="docutils" />
<pre class="literal-block">
void
remove_edge(vertex_descriptor u, vertex_descriptor v,
adjacency_list&amp; g);
</pre>
<p>Removes the edge <tt class="docutils literal"><span class="pre">(u,v)</span></tt> from the graph. If the directed selector is
<tt class="docutils literal"><span class="pre">bidirectionalS</span></tt> or <tt class="docutils literal"><span class="pre">undirectedS</span></tt>, either the source or target
vertex of the graph must be local. If the directed selector is
<tt class="docutils literal"><span class="pre">directedS</span></tt>, then the source vertex must be local.</p>
<hr class="docutils" />
<pre class="literal-block">
void
remove_edge(edge_descriptor e, adjacency_list&amp; g);
</pre>
<p>Removes the edge <tt class="docutils literal"><span class="pre">e</span></tt> from the graph. If the directed selector is
<tt class="docutils literal"><span class="pre">bidirectionalS</span></tt> or <tt class="docutils literal"><span class="pre">undirectedS</span></tt>, either the source or target
vertex of the graph must be local. If the directed selector is
<tt class="docutils literal"><span class="pre">directedS</span></tt>, then the source vertex must be local.</p>
<hr class="docutils" />
<pre class="literal-block">
void remove_edge(out_edge_iterator iter, adjacency_list&amp; g);
</pre>
<p>This has the same effect as <tt class="docutils literal"><span class="pre">remove_edge(*iter,</span> <span class="pre">g)</span></tt>. For directed
(but not bidirectional) graphs, this will be more efficient than
<tt class="docutils literal"><span class="pre">remove_edge(*iter,</span> <span class="pre">g)</span></tt>.</p>
<hr class="docutils" />
<pre class="literal-block">
template &lt;class Predicate &gt;
void remove_out_edge_if(vertex_descriptor u, Predicate predicate,
adjacency_list&amp; g);
</pre>
<p>Removes all out-edges of vertex <tt class="docutils literal"><span class="pre">u</span></tt> from the graph that satisfy the
predicate. That is, if the predicate returns <tt class="docutils literal"><span class="pre">true</span></tt> when applied to an
edge descriptor, then the edge is removed. The vertex <tt class="docutils literal"><span class="pre">u</span></tt> must be local.</p>
<p>The affect on descriptor and iterator stability is the same as that of
invoking remove_edge() on each of the removed edges.</p>
<hr class="docutils" />
<pre class="literal-block">
template &lt;class Predicate &gt;
void remove_in_edge_if(vertex_descriptor v, Predicate predicate,
adjacency_list&amp; g);
</pre>
<p>Removes all in-edges of vertex <tt class="docutils literal"><span class="pre">v</span></tt> from the graph that satisfy the
predicate. That is, if the predicate returns true when applied to an
edge descriptor, then the edge is removed. The vertex <tt class="docutils literal"><span class="pre">v</span></tt> must be local.</p>
<p>The affect on descriptor and iterator stability is the same as that of
invoking <tt class="docutils literal"><span class="pre">remove_edge()</span></tt> on each of the removed edges.</p>
<p>This operation is available for undirected and bidirectional
adjacency_list graphs, but not for directed.</p>
<hr class="docutils" />
<pre class="literal-block">
template &lt;class Predicate&gt;
void remove_edge_if(Predicate predicate, adjacency_list&amp; g);
</pre>
<p>Removes all edges from the graph that satisfy the predicate. That is,
if the predicate returns true when applied to an edge descriptor, then
the edge is removed.</p>
<p>The affect on descriptor and iterator stability is the same as that
of invoking <tt class="docutils literal"><span class="pre">remove_edge()</span></tt> on each of the removed edges.</p>
<hr class="docutils" />
<pre class="literal-block">
vertex_descriptor add_vertex(adjacency_list&amp; g);
</pre>
<p>Adds a vertex to the graph and returns the vertex descriptor for the
new vertex. The vertex will be stored in the local process. This
function is not available when using named vertices.</p>
<hr class="docutils" />
<pre class="literal-block">
unspecified add_vertex(const VertexProperties&amp; p, adjacency_list&amp; g);
unspecified add_vertex(const vertex_name_type&amp; p, adjacency_list&amp; g);
</pre>
<p>Adds a vertex to the graph with the specified properties. If the graph
is using vertex names, the vertex will be added on whichever process
&quot;owns&quot; that name. Otherwise, the vertex will be stored in the local
process. Note that the second constructor will invoke the
user-customizable internal vertex constructor, which (by default)
throws an exception when it sees an unknown vertex.</p>
<p>The return type is of unspecified type, but can be copy-constructed
and can be implicitly converted into a vertex descriptor.</p>
<hr class="docutils" />
<pre class="literal-block">
void clear_vertex(vertex_descriptor u, adjacency_list&amp; g);
</pre>
<p>Removes all edges to and from vertex <tt class="docutils literal"><span class="pre">u</span></tt>. The vertex still appears
in the vertex set of the graph.</p>
<p>The affect on descriptor and iterator stability is the same as that of
invoking <tt class="docutils literal"><span class="pre">remove_edge()</span></tt> for all of the edges that have <tt class="docutils literal"><span class="pre">u</span></tt> as the source
or target.</p>
<p>This operation is not applicable to directed graphs, because the
incoming edges to vertex <tt class="docutils literal"><span class="pre">u</span></tt> are not known.</p>
<hr class="docutils" />
<pre class="literal-block">
void clear_out_edges(vertex_descriptor u, adjacency_list&amp; g);
</pre>
<p>Removes all out-edges from vertex <tt class="docutils literal"><span class="pre">u</span></tt>. The vertex still appears in
the vertex set of the graph.</p>
<p>The affect on descriptor and iterator stability is the same as that of
invoking <tt class="docutils literal"><span class="pre">remove_edge()</span></tt> for all of the edges that have <tt class="docutils literal"><span class="pre">u</span></tt> as the
source.</p>
<p>This operation is not applicable to undirected graphs (use
<tt class="docutils literal"><span class="pre">clear_vertex()</span></tt> instead).</p>
<hr class="docutils" />
<pre class="literal-block">
void clear_in_edges(vertex_descriptor u, adjacency_list&amp; g);
</pre>
<p>Removes all in-edges from vertex <tt class="docutils literal"><span class="pre">u</span></tt>. The vertex still appears in
the vertex set of the graph.</p>
<p>The affect on descriptor and iterator stability is the same as that of
invoking <tt class="docutils literal"><span class="pre">remove_edge()</span></tt> for all of the edges that have <tt class="docutils literal"><span class="pre">u</span></tt> as the
target.</p>
<p>This operation is only applicable to bidirectional graphs.</p>
<hr class="docutils" />
<pre class="literal-block">
void remove_vertex(vertex_descriptor u, adjacency_list&amp; g);
</pre>
<p>Remove vertex <tt class="docutils literal"><span class="pre">u</span></tt> from the vertex set of the graph. It is assumed
that there are no edges to or from vertex <tt class="docutils literal"><span class="pre">u</span></tt> when it is
removed. One way to make sure of this is to invoke <tt class="docutils literal"><span class="pre">clear_vertex()</span></tt>
beforehand. The vertex <tt class="docutils literal"><span class="pre">u</span></tt> must be stored locally.</p>
</div>
<div class="section" id="property-map-accessors">
<h2><a class="toc-backref" href="#id13">Property Map Accessors</a></h2>
<pre class="literal-block">
template &lt;class PropertyTag&gt;
property_map&lt;adjacency_list, PropertyTag&gt;::type
get(PropertyTag, adjacency_list&amp; g);
template &lt;class PropertyTag&gt;
property_map&lt;adjacency_list, Tag&gt;::const_type
get(PropertyTag, const adjacency_list&amp; g);
</pre>
<p>Returns the property map object for the vertex property specified by
<tt class="docutils literal"><span class="pre">PropertyTag</span></tt>. The <tt class="docutils literal"><span class="pre">PropertyTag</span></tt> must match one of the properties
specified in the graph's <tt class="docutils literal"><span class="pre">VertexProperty</span></tt> template argument. The
returned property map will be a <a class="reference external" href="distributed_property_map.html">distributed property map</a>.</p>
<hr class="docutils" />
<pre class="literal-block">
template &lt;class PropertyTag , class X&gt;
typename property_traits&lt;property_map&lt;adjacency_list, PropertyTag&gt;::const_type&gt;::value_type
get(PropertyTag, const adjacency_list&amp; g, X x);
</pre>
<p>This returns the property value for <tt class="docutils literal"><span class="pre">x</span></tt>, where <tt class="docutils literal"><span class="pre">x</span></tt> is either a vertex or
edge descriptor. The entity referred to by descriptor <tt class="docutils literal"><span class="pre">x</span></tt> must be
stored in the local process.</p>
<hr class="docutils" />
<pre class="literal-block">
template &lt;class PropertyTag , class X, class Value&gt;
void put(PropertyTag, const adjacency_list&amp; g, X x, const Value&amp; value);
</pre>
<p>This sets the property value for <tt class="docutils literal"><span class="pre">x</span></tt> to value. <tt class="docutils literal"><span class="pre">x</span></tt> is either a
vertex or edge descriptor. <tt class="docutils literal"><span class="pre">Value</span></tt> must be convertible to <tt class="docutils literal"><span class="pre">typename</span>
<span class="pre">property_traits&lt;property_map&lt;adjacency_list,</span>
<span class="pre">PropertyTag&gt;::type&gt;::value_type</span></tt>.</p>
<hr class="docutils" />
<pre class="literal-block">
template &lt;class GraphProperties, class GraphPropertyTag&gt;
typename graph_property&lt;adjacency_list, GraphPropertyTag&gt;::type&amp;
get_property(adjacency_list&amp; g, GraphPropertyTag);
template &lt;class GraphProperties, class GraphPropertyTag &gt;
const typename graph_property&lt;adjacency_list, GraphPropertyTag&gt;::type&amp;
get_property(const adjacency_list&amp; g, GraphPropertyTag);
</pre>
<p>TODO: not implemented.</p>
<p>Return the property specified by <tt class="docutils literal"><span class="pre">GraphPropertyTag</span></tt> that is attached
to the graph object <tt class="docutils literal"><span class="pre">g</span></tt>. The <tt class="docutils literal"><span class="pre">graph_property</span></tt> traits class is
defined in <tt class="docutils literal"><span class="pre">boost/graph/adjacency_list.hpp</span></tt>.</p>
<hr class="docutils" />
<p>Copyright (C) 2004 The Trustees of Indiana University.</p>
<p>Copyright (C) 2007 Douglas Gregor</p>
<p>Authors: Douglas Gregor and Andrew Lumsdaine</p>
</div>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:21 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,649 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Distributed Property Map</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-distributed-property-map">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Distributed Property Map</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<p>A distributed property map adaptor is a property map whose stored
values are distributed across multiple non-overlapping memory spaces
on different processes. Values local to the current process are stored
within a local property map and may be immediately accessed via
<tt class="docutils literal"><span class="pre">get</span></tt> and <tt class="docutils literal"><span class="pre">put</span></tt>. Values stored on remote processes may also be
accessed via <tt class="docutils literal"><span class="pre">get</span></tt> and <tt class="docutils literal"><span class="pre">put</span></tt>, but the behavior differs slightly:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">put</span></tt> operations update a local ghost cell and send a &quot;put&quot;
message to the process that owns the value. The owner is free to
update its own &quot;official&quot; value or may ignore the put request.</li>
<li><tt class="docutils literal"><span class="pre">get</span></tt> operations returns the contents of the local ghost
cell. If no ghost cell is available, one is created using a
(customizable) default value.</li>
</ul>
</blockquote>
<p>Using distributed property maps requires a bit more care than using
local, sequential property maps. While the syntax and semantics are
similar, distributed property maps may contain out-of-date
information that can only be guaranteed to be synchronized by
calling the <tt class="docutils literal"><span class="pre">synchronize</span></tt> function in all processes.</p>
<p>To address the issue of out-of-date values, distributed property
maps support multiple <a class="reference internal" href="#consistency-models">consistency models</a> and may be supplied with a
<a class="reference internal" href="#reduction-operation">reduction operation</a>.</p>
<p>Distributed property maps meet the requirements of the <a class="reference external" href="http://www.boost.org/libs/property_map/ReadablePropertyMap.html">Readable
Property Map</a> and, potentially, the <a class="reference external" href="http://www.boost.org/libs/property_map/WritablePropertyMap.html">Writable Property Map</a> and
<a class="reference external" href="http://www.boost.org/libs/property_map/ReadWritePropertyMap.html">Read/Write Property Map</a> concepts. Distributed property maps do
<em>not</em>, however, meet the requirements of the <a class="reference external" href="http://www.boost.org/libs/property_map/LvaluePropertyMap.html">Lvalue Property Map</a>
concept, because elements residing in another process are not
directly addressible. There are several forms of distributed property
maps:</p>
<blockquote>
<ul class="simple">
<li><a class="reference internal" href="#distributed-property-map-adaptor">Distributed property map adaptor</a></li>
<li><a class="reference internal" href="#distributed-iterator-property-map">Distributed iterator property map</a></li>
<li><a class="reference internal" href="#distributed-safe-iterator-property-map">Distributed safe iterator property map</a></li>
<li><a class="reference internal" href="#local-property-map">Local property map</a></li>
</ul>
</blockquote>
<div class="section" id="consistency-models">
<h1>Consistency models</h1>
<p>Distributed property maps offer many consistency models, which affect
how the values read from and written to remote keys relate to the
&quot;official&quot; value for that key stored in the owning process. The
consistency model of a distributed property map can be set with the
member function <tt class="docutils literal"><span class="pre">set_consistency_model</span></tt> to a bitwise-OR of the
flags in the <tt class="docutils literal"><span class="pre">boost::parallel::consistency_model</span></tt> enumeration. The
individual flags are:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">cm_forward</span></tt>: The default consistency model, which propagates
values forward from <tt class="docutils literal"><span class="pre">put</span></tt> operations on remote processors to
the owner of the value being changed.</li>
<li><tt class="docutils literal"><span class="pre">cm_backward</span></tt>: After all values have been forwarded or flushed
to the owning processes, each process receives updates values for
each of its ghost cells. After synchronization, the values in
ghost cells are guaranteed to match the values stored on the
owning processor.</li>
<li><tt class="docutils literal"><span class="pre">cm_bidirectional</span></tt>: A combination of both <tt class="docutils literal"><span class="pre">cm_forward</span></tt> and
<tt class="docutils literal"><span class="pre">cm_backward</span></tt>.</li>
<li><tt class="docutils literal"><span class="pre">cm_flush</span></tt>: At the beginning of synchronization, all of the
values stored locally in ghost cells are sent to their owning
processors.</li>
<li><tt class="docutils literal"><span class="pre">cm_reset</span></tt>: Executes a <tt class="docutils literal"><span class="pre">reset()</span></tt> operation after
synchronization, setting the values in each ghost cell to their
default value.</li>
<li><tt class="docutils literal"><span class="pre">cm_clear</span></tt>: Executes a <tt class="docutils literal"><span class="pre">clear()</span></tt> operation after
synchronizing, eliminating all ghost cells.</li>
</ul>
</blockquote>
<p>There are several common combinations of flags that result in
interesting consistency models. Some of these combinations are:</p>
<blockquote>
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">cm_forward</span></tt>: By itself, the forward consistency model enables
algorithms such as <a class="reference external" href="dijkstra_shortest_paths.html">Dijkstra's shortest paths</a> and
<a class="reference external" href="breadth_first_search.html">Breadth-First Search</a> to operate correctly.</li>
<li><tt class="docutils literal"><span class="pre">cm_flush</span> <span class="pre">&amp;</span> <span class="pre">cm_reset</span></tt>: All updates values are queued locally,
then flushed during the synchronization step. Once the flush has
occurred, the ghost cells are restored to their default
values. This consistency model is used by the <a class="reference external" href="page_rank.html">PageRank</a>
implementation to locally accumulate rank for each node.</li>
</ul>
</blockquote>
</div>
<div class="section" id="reduction-operation">
<h1>Reduction operation</h1>
<p>The reduction operation maintains consistency by determining how
multiple writes to a property map are resolved and what the property
map should do if unknown values are requested. More specifically, a
reduction operation is used in two cases:</p>
<blockquote>
<ol class="arabic simple">
<li>When a value is needed for a remote key but no value is
immediately available, the reduction operation provides a
suitable default. For instance, a distributed property map
storing distances may have a reduction operation that returns
an infinite value as the default, whereas a distributed
property map for vertex colors may return white as the
default.</li>
<li>When a value is received from a remote process, the process
owning the key associated with that value must determine which
value---the locally stored value, the value received from a
remote process, or some combination of the two---will be
stored as the &quot;official&quot; value in the property map. The
reduction operation transforms the local and remote values
into the &quot;official&quot; value to be stored.</li>
</ol>
</blockquote>
<p>The reduction operation of a distributed property map can be set with
the <tt class="docutils literal"><span class="pre">set_reduce</span></tt> method of <tt class="docutils literal"><span class="pre">distributed_property_map</span></tt>. The reduce
operation is a function object with two signatures. The first
signature takes a (remote) key and returns a default value for it,
whereas the second signatures takes a key and two values (local first,
then remote) and will return the combined value that will be stored in
the local property map. Reduction operations must also contain a
static constant <tt class="docutils literal"><span class="pre">non_default_resolver&quot;,</span> <span class="pre">which</span> <span class="pre">states</span> <span class="pre">whether</span> <span class="pre">the</span>
<span class="pre">reduction</span> <span class="pre">operation's</span> <span class="pre">default</span> <span class="pre">value</span> <span class="pre">actually</span> <span class="pre">acts</span> <span class="pre">like</span> <span class="pre">a</span> <span class="pre">default</span>
<span class="pre">value.</span> <span class="pre">It</span> <span class="pre">should</span> <span class="pre">be</span> <span class="pre">``true</span></tt> when the default is meaningful (e.g.,
infinity for a distance) and <tt class="docutils literal"><span class="pre">false</span></tt> when the default should not be
used.</p>
<p>The following reduction operation is used by the distributed PageRank
algorithm. The default rank for a remote node is 0. Rank is
accumulated locally, and then the reduction operation combines local
and remote values by adding them. Combined with a consistency model
that flushes all values to the owner and then resets the values
locally in each step, the resulting property map will compute partial
sums on each processor and then accumulate the results on the owning
processor. The PageRank reduction operation is defined as follows.</p>
<pre class="literal-block">
template&lt;typename T&gt;
struct rank_accumulate_reducer {
static const bool non_default_resolver = true;
// The default rank of an unknown node
template&lt;typename K&gt;
T operator()(const K&amp;) const { return T(0); }
template&lt;typename K&gt;
T operator()(const K&amp;, const T&amp; x, const T&amp; y) const { return x + y; }
};
</pre>
</div>
<div class="section" id="distributed-property-map-adaptor">
<h1>Distributed property map adaptor</h1>
<p>The distributed property map adaptor creates a distributed property
map from a local property map, a <a class="reference external" href="process_group.html">process group</a> over which
distribution should occur, and a <a class="reference external" href="GlobalDescriptor.html">global descriptor</a> type that
indexes the distributed property map.</p>
<div class="section" id="synopsis">
<h2>Synopsis</h2>
<pre class="literal-block">
template&lt;typename ProcessGroup, typename LocalPropertyMap, typename Key,
typename GhostCellS = gc_mapS&gt;
class distributed_property_map
{
public:
typedef ... ghost_regions_type;
distributed_property_map();
distributed_property_map(const ProcessGroup&amp; pg,
const LocalPropertyMap&amp; pm);
template&lt;typename Reduce&gt;
distributed_property_map(const ProcessGroup&amp; pg,
const LocalPropertyMap&amp; pm,
const Reduce&amp; reduce);
template&lt;typename Reduce&gt; void set_reduce(const Reduce&amp; reduce);
void set_consistency_model(int model);
void flush();
void reset();
void clear();
};
reference get(distributed_property_map pm, const key_type&amp; key);
void
put(distributed_property_map pm, const key_type&amp; key, const value_type&amp; value);
local_put(distributed_property_map pm, const key_type&amp; key, const value_type&amp; value);
void request(distributed_property_map pm, const key_type&amp; key);
void synchronize(distributed_property_map&amp; pm);
template&lt;typename Key, typename ProcessGroup, typename LocalPropertyMap&gt;
distributed_property_map&lt;ProcessGroup, LocalPropertyMap, Key&gt;
make_distributed_property_map(const ProcessGroup&amp; pg, LocalPropertyMap pmap);
template&lt;typename Key, typename ProcessGroup, typename LocalPropertyMap,
typename Reduce&gt;
distributed_property_map&lt;ProcessGroup, LocalPropertyMap, Key&gt;
make_distributed_property_map(const ProcessGroup&amp; pg, LocalPropertyMap pmap,
Reduce reduce);
</pre>
</div>
<div class="section" id="template-parameters">
<h2>Template parameters</h2>
<dl class="docutils">
<dt><strong>ProcessGroup</strong>:</dt>
<dd>The type of the process group over which the
property map is distributed and is also the medium for
communication.</dd>
<dt><strong>LocalPropertyMap</strong>:</dt>
<dd>The type of the property map that will store values
for keys local to this processor. The <tt class="docutils literal"><span class="pre">value_type</span></tt> of this
property map will become the <tt class="docutils literal"><span class="pre">value_type</span></tt> of the distributed
property map. The distributed property map models the same property
map concepts as the <tt class="docutils literal"><span class="pre">LocalPropertyMap</span></tt>, with one exception: a
distributed property map cannot be an <a class="reference external" href="http://www.boost.org/libs/property_map/LvaluePropertyMap.html">Lvalue Property Map</a>
(because remote values are not addressable), and is therefore
limited to <a class="reference external" href="http://www.boost.org/libs/property_map/ReadWritePropertyMap.html">Read/Write Property Map</a>.</dd>
<dt><strong>Key</strong>:</dt>
<dd>The <tt class="docutils literal"><span class="pre">key_type</span></tt> of the distributed property map, which
must model the <a class="reference external" href="GlobalDescriptor.html">Global Descriptor</a> concept. The process ID type of
the <tt class="docutils literal"><span class="pre">Key</span></tt> parameter must match the process ID type of the
<tt class="docutils literal"><span class="pre">ProcessGroup</span></tt>, and the local descriptor type of the <tt class="docutils literal"><span class="pre">Key</span></tt> must
be convertible to the <tt class="docutils literal"><span class="pre">key_type</span></tt> of the <tt class="docutils literal"><span class="pre">LocalPropertyMap</span></tt>.</dd>
<dt><strong>GhostCellS</strong>:</dt>
<dd><p class="first">A selector type that indicates how ghost cells should be stored in
the distributed property map. There are either two or three
options, depending on your compiler:</p>
<blockquote class="last">
<ul class="simple">
<li><tt class="docutils literal"><span class="pre">boost::parallel::gc_mapS</span></tt> (default): Uses an STL <tt class="docutils literal"><span class="pre">map</span></tt> to
store the ghost cells for each process.</li>
<li><tt class="docutils literal"><span class="pre">boost::parallel::gc_vector_mapS</span></tt>: Uses a sorted STL
<tt class="docutils literal"><span class="pre">vector</span></tt> to store the ghost cells for each process. This
option works well when there are likely to be few insertions
into the ghost cells; for instance, if the only ghost cells used
are for neighboring vertices, the property map can be
initialized with cells for each neighboring vertex, providing
faster lookups than a <tt class="docutils literal"><span class="pre">map</span></tt> and using less space.</li>
<li><tt class="docutils literal"><span class="pre">boost::parallel::gc_hash_mapS</span></tt>: Uses the GCC <tt class="docutils literal"><span class="pre">hash_map</span></tt> to
store ghost cells. This option may improve performance over
<tt class="docutils literal"><span class="pre">map</span></tt> for large problems sizes, where the set of ghost cells
cannot be predetermined.</li>
</ul>
</blockquote>
</dd>
</dl>
</div>
<div class="section" id="member-functions">
<h2>Member functions</h2>
<pre class="literal-block">
distributed_property_map();
</pre>
<p>Default-construct a distributed property map. The property map is in
an invalid state, and may only be used if it is reassigned to a valid
property map.</p>
<hr class="docutils" />
<pre class="literal-block">
distributed_property_map(const ProcessGroup&amp; pg,
const LocalPropertyMap&amp; pm);
template&lt;typename Reduce&gt;
distributed_property_map(const ProcessGroup&amp; pg,
const LocalPropertyMap&amp; pm,
const Reduce&amp; reduce);
</pre>
<p>Construct a property map from a process group and a local property
map. If a <tt class="docutils literal"><span class="pre">reduce</span></tt> operation is not supplied, a default of
<tt class="docutils literal"><span class="pre">basic_reduce&lt;value_type&gt;</span></tt> will be used.</p>
<hr class="docutils" />
<pre class="literal-block">
template&lt;typename Reduce&gt; void set_reduce(const Reduce&amp; reduce);
</pre>
<p>Replace the current reduction operation with the new operation
<tt class="docutils literal"><span class="pre">reduce</span></tt>.</p>
<hr class="docutils" />
<pre class="literal-block">
void set_consistency_model(int model);
</pre>
<p>Sets the consistency model of the distributed property map, which will
take effect on the next synchronization step. See the section
<a class="reference internal" href="#consistency-models">Consistency models</a> for a description of the effect of various
consistency model flags.</p>
<hr class="docutils" />
<pre class="literal-block">
void flush();
</pre>
<p>Emits a message sending the contents of all local ghost cells to the
owners of those cells.</p>
<hr class="docutils" />
<pre class="literal-block">
void reset();
</pre>
<p>Replaces the values stored in each of the ghost cells with the default
value generated by the reduction operation.</p>
<hr class="docutils" />
<pre class="literal-block">
void clear();
</pre>
<p>Removes all ghost cells from the property map.</p>
</div>
<div class="section" id="free-functions">
<h2>Free functions</h2>
<pre class="literal-block">
reference get(distributed_property_map pm, const key_type&amp; key);
</pre>
<p>Retrieves the element in <tt class="docutils literal"><span class="pre">pm</span></tt> associated with the given <tt class="docutils literal"><span class="pre">key</span></tt>. If
the key refers to data stored locally, returns the actual value
associated with the key. If the key refers to nonlocal data, returns
the value of the ghost cell. If no ghost cell exists, the behavior
depends on the current reduction operation: if a reduction operation
has been set and has <tt class="docutils literal"><span class="pre">non_default_resolver</span></tt> set <tt class="docutils literal"><span class="pre">true</span></tt>, then a
ghost cell will be created according to the default value provided by
the reduction operation. Otherwise, the call to <tt class="docutils literal"><span class="pre">get</span></tt> will abort
because no value exists for this remote cell. To avoid this problem,
either set a reduction operation that generates default values,
<tt class="docutils literal"><span class="pre">request()</span></tt> the value and then perform a synchronization step, or
<tt class="docutils literal"><span class="pre">put</span></tt> a value into the cell before reading it.</p>
<hr class="docutils" />
<pre class="literal-block">
void
put(distributed_property_map pm, const key_type&amp; key, const value_type&amp; value);
</pre>
<p>Places the given <tt class="docutils literal"><span class="pre">value</span></tt> associated with <tt class="docutils literal"><span class="pre">key</span></tt> into property map
<tt class="docutils literal"><span class="pre">pm</span></tt>. If the key refers to data stored locally, the value is
immediately updates. If the key refers to data stored in a remote
process, updates (or creates) a local ghost cell containing this
value for the key and sends the new value to the owning process. Note
that the owning process may reject this value based on the reduction
operation, but this will not be detected until the next
synchronization step.</p>
<hr class="docutils" />
<pre class="literal-block">
void
local_put(distributed_property_map pm, const key_type&amp; key, const value_type&amp; value);
</pre>
<p>Equivalent to <tt class="docutils literal"><span class="pre">put(pm,</span> <span class="pre">key,</span> <span class="pre">value)</span></tt>, except that no message is sent
to the owning process when the value is changed for a nonlocal key.</p>
<hr class="docutils" />
<pre class="literal-block">
void synchronize(distributed_property_map&amp; pm);
</pre>
<p>Synchronize the values stored in the distributed property maps. Each
process much execute <tt class="docutils literal"><span class="pre">synchronize</span></tt> at the same time, after which
the ghost cells in every process will reflect the actual value stored
in the owning process.</p>
<hr class="docutils" />
<pre class="literal-block">
void request(distributed_property_map pm, const key_type&amp; key);
</pre>
<p>Request that the element &quot;key&quot; be available after the next
synchronization step. For a non-local key, this means establishing a
ghost cell and requesting.</p>
<hr class="docutils" />
<pre class="literal-block">
template&lt;typename Key, typename ProcessGroup, typename LocalPropertyMap&gt;
distributed_property_map&lt;ProcessGroup, LocalPropertyMap, Key&gt;
make_distributed_property_map(const ProcessGroup&amp; pg, LocalPropertyMap pmap);
template&lt;typename Key, typename ProcessGroup, typename LocalPropertyMap,
typename Reduce&gt;
distributed_property_map&lt;ProcessGroup, LocalPropertyMap, Key&gt;
make_distributed_property_map(const ProcessGroup&amp; pg, LocalPropertyMap pmap,
Reduce reduce);
</pre>
<p>Create a distributed property map over process group <tt class="docutils literal"><span class="pre">pg</span></tt> and local
property map <tt class="docutils literal"><span class="pre">pmap</span></tt>. A default reduction operation will be generated
if it is not provided.</p>
</div>
</div>
<div class="section" id="distributed-iterator-property-map">
<h1>Distributed iterator property map</h1>
<p>The distributed iterator property map adaptor permits the creation of
distributed property maps from random access iterators using the same
syntax as non-distributed iterator property maps. The specialization
is based on a <a class="reference internal" href="#local-property-map">local property map</a>, which contains the
indices for local descriptors and is typically returned to describe
the vertex indices of a distributed graph.</p>
<div class="section" id="id1">
<h2>Synopsis</h2>
<pre class="literal-block">
template&lt;typename RandomAccessIterator, typename ProcessGroup,
typename GlobalKey, typename LocalMap, typename ValueType,
typename Reference&gt;
class iterator_property_map&lt;RandomAccessIterator,
local_property_map&lt;ProcessGroup, GlobalKey, LocalMap&gt;,
ValueType, Reference&gt;
{
public:
typedef local_property_map&lt;ProcessGroup, GlobalKey, LocalMap&gt; index_map_type;
iterator_property_map();
iterator_property_map(RandomAccessIterator iter, const index_map_type&amp; id);
};
reference get(iterator_property_map pm, const key_type&amp; key);
void put(iterator_property_map pm, const key_type&amp; key, const value_type&amp; value);
template&lt;typename RandomAccessIterator, typename ProcessGroup,
typename GlobalKey, typename LocalMap&gt;
iterator_property_map&lt;RandomAccessIterator,
local_property_map&lt;ProcessGroup, GlobalKey, LocalMap&gt; &gt;
make_iterator_property_map(RandomAccessIterator iter,
local_property_map&lt;ProcessGroup, GlobalKey, LocalMap&gt; id);
</pre>
</div>
<div class="section" id="id2">
<h2>Member functions</h2>
<pre class="literal-block">
iterator_property_map();
</pre>
<p>Default-constructs a distributed iterator property map. The property
map is in an invalid state, and must be reassigned before it may be
used.</p>
<hr class="docutils" />
<pre class="literal-block">
iterator_property_map(RandomAccessIterator iter, const index_map_type&amp; id);
</pre>
<p>Constructs a distributed iterator property map using the property map
<tt class="docutils literal"><span class="pre">id</span></tt> to map global descriptors to local indices. The random access
iterator sequence <tt class="docutils literal"><span class="pre">[iter,</span> <span class="pre">iter</span> <span class="pre">+</span> <span class="pre">n)</span></tt> must be a valid range, where
<tt class="docutils literal"><span class="pre">[0,</span> <span class="pre">n)</span></tt> is the range of local indices.</p>
</div>
<div class="section" id="id3">
<h2>Free functions</h2>
<pre class="literal-block">
reference get(iterator_property_map pm, const key_type&amp; key);
</pre>
<p>Returns the value associated with the given <tt class="docutils literal"><span class="pre">key</span></tt> from the
distributed property map.</p>
<hr class="docutils" />
<pre class="literal-block">
void put(iterator_property_map pm, const key_type&amp; key, const value_type&amp; value);
</pre>
<p>Associates the value with the given key in the distributed property map.</p>
<hr class="docutils" />
<pre class="literal-block">
template&lt;typename RandomAccessIterator, typename ProcessGroup,
typename GlobalKey, typename LocalMap, typename ValueType,
typename Reference&gt;
iterator_property_map&lt;RandomAccessIterator,
local_property_map&lt;ProcessGroup, GlobalKey, LocalMap&gt;,
ValueType, Reference&gt;
make_iterator_property_map(RandomAccessIterator iter,
local_property_map&lt;ProcessGroup, GlobalKey, LocalMap&gt;,
ValueType, Reference&gt; id);
</pre>
<p>Creates a distributed iterator property map using the given iterator
<tt class="docutils literal"><span class="pre">iter</span></tt> and local index property map <tt class="docutils literal"><span class="pre">id</span></tt>.</p>
</div>
</div>
<div class="section" id="distributed-safe-iterator-property-map">
<h1>Distributed safe iterator property map</h1>
<p>The distributed safe iterator property map adaptor permits the
creation of distributed property maps from random access iterators
using the same syntax as non-distributed safe iterator property
maps. The specialization is based on a <a class="reference internal" href="#local-property-map">local property map</a>, which
contains the indices for local descriptors and is typically returned
to describe the vertex indices of a distributed graph. Safe iterator
property maps check the indices of accesses to ensure that they are
not out-of-bounds before attempting to access an value.</p>
<div class="section" id="id4">
<h2>Synopsis</h2>
<pre class="literal-block">
template&lt;typename RandomAccessIterator, typename ProcessGroup,
typename GlobalKey, typename LocalMap, typename ValueType,
typename Reference&gt;
class safe_iterator_property_map&lt;RandomAccessIterator,
local_property_map&lt;ProcessGroup, GlobalKey, LocalMap&gt;,
ValueType, Reference&gt;
{
public:
typedef local_property_map&lt;ProcessGroup, GlobalKey, LocalMap&gt; index_map_type;
safe_iterator_property_map();
safe_iterator_property_map(RandomAccessIterator iter, std::size_t n,
const index_map_type&amp; id);
};
reference get(safe_iterator_property_map pm, const key_type&amp; key);
void put(safe_iterator_property_map pm, const key_type&amp; key, const value_type&amp; value);
template&lt;typename RandomAccessIterator, typename ProcessGroup,
typename GlobalKey, typename LocalMap, typename ValueType,
typename Reference&gt;
safe_iterator_property_map&lt;RandomAccessIterator,
local_property_map&lt;ProcessGroup, GlobalKey, LocalMap&gt;,
ValueType, Reference&gt;
make_safe_iterator_property_map(RandomAccessIterator iter,
std::size_t n,
local_property_map&lt;ProcessGroup, GlobalKey, LocalMap&gt;,
ValueType, Reference&gt; id);
</pre>
</div>
<div class="section" id="id5">
<h2>Member functions</h2>
<pre class="literal-block">
safe_iterator_property_map();
</pre>
<p>Default-constructs a distributed safe iterator property map. The property
map is in an invalid state, and must be reassigned before it may be
used.</p>
<hr class="docutils" />
<pre class="literal-block">
safe_iterator_property_map(RandomAccessIterator iter, std::size_t n,
const index_map_type&amp; id);
</pre>
<p>Constructs a distributed safe iterator property map using the property map
<tt class="docutils literal"><span class="pre">id</span></tt> to map global descriptors to local indices. The random access
iterator sequence <tt class="docutils literal"><span class="pre">[iter,</span> <span class="pre">iter</span> <span class="pre">+</span> <span class="pre">n)</span></tt>.</p>
</div>
<div class="section" id="id6">
<h2>Free functions</h2>
<pre class="literal-block">
reference get(safe_iterator_property_map pm, const key_type&amp; key);
</pre>
<p>Returns the value associated with the given <tt class="docutils literal"><span class="pre">key</span></tt> from the
distributed property map.</p>
<hr class="docutils" />
<pre class="literal-block">
void put(safe_iterator_property_map pm, const key_type&amp; key, const value_type&amp; value);
</pre>
<p>Associates the value with the given key in the distributed property map.</p>
<hr class="docutils" />
<pre class="literal-block">
template&lt;typename RandomAccessIterator, typename ProcessGroup,
typename GlobalKey, typename LocalMap, typename ValueType,
typename Reference&gt;
safe_iterator_property_map&lt;RandomAccessIterator,
local_property_map&lt;ProcessGroup, GlobalKey, LocalMap&gt;,
ValueType, Reference&gt;
make_safe_iterator_property_map(RandomAccessIterator iter,
std::size_t n,
local_property_map&lt;ProcessGroup, GlobalKey, LocalMap&gt;,
ValueType, Reference&gt; id);
</pre>
<p>Creates a distributed safe iterator property map using the given iterator
<tt class="docutils literal"><span class="pre">iter</span></tt> and local index property map <tt class="docutils literal"><span class="pre">id</span></tt>. The indices in <tt class="docutils literal"><span class="pre">id</span></tt> must</p>
</div>
</div>
<div class="section" id="local-property-map">
<h1>Local property map</h1>
<p>A property map adaptor that accesses an underlying property map whose
key type is the local part of the <tt class="docutils literal"><span class="pre">Key</span></tt> type for the local subset
of keys. Local property maps are typically used by distributed graph
types for vertex index properties.</p>
<div class="section" id="id7">
<h2>Synopsis</h2>
<pre class="literal-block">
template&lt;typename ProcessGroup, typename GlobalKey, typename LocalMap&gt;
class local_property_map
{
public:
typedef typename property_traits&lt;LocalMap&gt;::value_type value_type;
typedef GlobalKey key_type;
typedef typename property_traits&lt;LocalMap&gt;::reference reference;
typedef typename property_traits&lt;LocalMap&gt;::category category;
explicit
local_property_map(const ProcessGroup&amp; process_group = ProcessGroup(),
const LocalMap&amp; local_map = LocalMap());
reference operator[](const key_type&amp; key);
};
reference get(const local_property_map&amp; pm, key_type key);
void put(local_property_map pm, const key_type&amp; key, const value_type&amp; value);
</pre>
</div>
<div class="section" id="id8">
<h2>Template parameters</h2>
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">ProcessGroup:</th><td class="field-body">the type of the process group over which the global
keys are distributed.</td>
</tr>
<tr class="field"><th class="field-name">GlobalKey:</th><td class="field-body">The <tt class="docutils literal"><span class="pre">key_type</span></tt> of the local property map, which
must model the <a class="reference external" href="GlobalDescriptor.html">Global Descriptor</a> concept. The process ID type of
the <tt class="docutils literal"><span class="pre">GlobalKey</span></tt> parameter must match the process ID type of the
<tt class="docutils literal"><span class="pre">ProcessGroup</span></tt>, and the local descriptor type of the <tt class="docutils literal"><span class="pre">GlobalKey</span></tt>
must be convertible to the <tt class="docutils literal"><span class="pre">key_type</span></tt> of the <tt class="docutils literal"><span class="pre">LocalMap</span></tt>.</td>
</tr>
<tr class="field"><th class="field-name">LocalMap:</th><td class="field-body">the type of the property map that will store values
for keys local to this processor. The <tt class="docutils literal"><span class="pre">value_type</span></tt> of this
property map will become the <tt class="docutils literal"><span class="pre">value_type</span></tt> of the local
property map. The local property map models the same property
map concepts as the <tt class="docutils literal"><span class="pre">LocalMap</span></tt>.</td>
</tr>
</tbody>
</table>
</div>
<div class="section" id="id9">
<h2>Member functions</h2>
<pre class="literal-block">
explicit
local_property_map(const ProcessGroup&amp; process_group = ProcessGroup(),
const LocalMap&amp; local_map = LocalMap());
</pre>
<p>Constructs a local property map whose keys are distributed across the
given process group and which accesses the given local map.</p>
<hr class="docutils" />
<pre class="literal-block">
reference operator[](const key_type&amp; key);
</pre>
<p>Access the value associated with the given key, which must be local
to this process.</p>
</div>
<div class="section" id="id10">
<h2>Free functions</h2>
<pre class="literal-block">
reference get(const local_property_map&amp; pm, key_type key);
</pre>
<p>Return the value associated with the given key, which must be local
to this process.</p>
<hr class="docutils" />
<pre class="literal-block">
void put(local_property_map pm, const key_type&amp; key, const value_type&amp; value);
</pre>
<p>Set the value associated with the given key, which must be local to
this process.</p>
<hr class="docutils" />
<p>Copyright (C) 2004, 2005 The Trustees of Indiana University.</p>
<p>Authors: Douglas Gregor and Andrew Lumsdaine</p>
</div>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:22 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,181 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Distributed queue adaptor</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-distributed-queue-adaptor">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Distributed queue adaptor</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<pre class="literal-block">
template&lt;typename ProcessGroup, typename Buffer&gt;
class distributed_queue
{
public:
typedef ProcessGroup process_group_type;
typedef Buffer buffer_type;
typedef typename buffer_type::value_type value_type;
typedef typename buffer_type::size_type size_type;
explicit
distributed_queue(const ProcessGroup&amp; process_group = ProcessGroup(),
const Buffer&amp; buffer = Buffer(),
bool polling = false);
distributed_queue(const ProcessGroup&amp; process_group, bool polling);
void push(const value_type&amp; x);
void pop();
value_type&amp; top();
const value_type&amp; top() const;
bool empty() const;
size_type size() const;
};
template&lt;typename ProcessGroup, typename Buffer&gt;
inline distributed_queue&lt;ProcessGroup, Buffer&gt;
make_distributed_queue(const ProcessGroup&amp; process_group, const Buffer&amp; buffer,
bool polling = false);
</pre>
<p>Class template <tt class="docutils literal"><span class="pre">distributed_queue</span></tt> implements a distributed queue
across a process group. The distributed queue is an adaptor over an
existing (local) queue, which must model the <a class="reference external" href="http://www.boost.org/libs/graph/doc/Buffer.html">Buffer</a> concept. Each
process stores a distinct copy of the local queue, from which it draws
or removes elements via the <tt class="docutils literal"><span class="pre">pop</span></tt> and <tt class="docutils literal"><span class="pre">top</span></tt> members.</p>
<p>The value type of the local queue must be a model of the
<a class="reference external" href="GlobalDescriptor.html">Global Descriptor</a> concept. The <tt class="docutils literal"><span class="pre">push</span></tt> operation of the
distributed queue passes (via a message) the value to its owning
processor. Thus, the elements within a particular local queue are
guaranteed to have the process owning that local queue as an owner.</p>
<p>Synchronization of distributed queues occurs in the <tt class="docutils literal"><span class="pre">empty</span></tt> and
<tt class="docutils literal"><span class="pre">size</span></tt> functions, which will only return &quot;empty&quot; values (true or 0,
respectively) when the entire distributed queue is empty. If the local
queue is empty but the distributed queue is not, the operation will
block until either condition changes. When the <tt class="docutils literal"><span class="pre">size</span></tt> function of a
nonempty queue returns, it returns the size of the local queue. These
semantics were selected so that sequential code that processes
elements in the queue via the following idiom can be parallelized via
introduction of a distributed queue:</p>
<pre class="literal-block">
distributed_queue&lt;...&gt; Q;
Q.push(x);
while (!Q.empty()) {
// do something, that may push a value onto Q
}
</pre>
<p>In the parallel version, the initial <tt class="docutils literal"><span class="pre">push</span></tt> operation will place
the value <tt class="docutils literal"><span class="pre">x</span></tt> onto its owner's queue. All processes will
synchronize at the call to empty, and only the process owning <tt class="docutils literal"><span class="pre">x</span></tt>
will be allowed to execute the loop (<tt class="docutils literal"><span class="pre">Q.empty()</span></tt> returns
false). This iteration may in turn push values onto other remote
queues, so when that process finishes execution of the loop body
and all processes synchronize again in <tt class="docutils literal"><span class="pre">empty</span></tt>, more processes
may have nonempty local queues to execute. Once all local queues
are empty, <tt class="docutils literal"><span class="pre">Q.empty()</span></tt> returns <tt class="docutils literal"><span class="pre">false</span></tt> for all processes.</p>
<p>The distributed queue can receive messages at two different times:
during synchronization and when polling <tt class="docutils literal"><span class="pre">empty</span></tt>. Messages are
always received during synchronization, to ensure that accurate
local queue sizes can be determines. However, whether <tt class="docutils literal"><span class="pre">empty</span></tt>
should poll for messages is specified as an option to the
constructor. Polling may be desired when the order in which
elements in the queue are processed is not important, because it
permits fewer synchronization steps and less communication
overhead. However, when more strict ordering guarantees are
required, polling may be semantically incorrect. By disabling
polling, one ensures that parallel execution using the idiom above
will not process an element at a later &quot;level&quot; before an earlier
&quot;level&quot;.</p>
<p>The distributed queue nearly models the <a class="reference external" href="http://www.boost.org/libs/graph/doc/Buffer.html">Buffer</a>
concept. However, the <tt class="docutils literal"><span class="pre">push</span></tt> routine does not necessarily
increase the result of <tt class="docutils literal"><span class="pre">size()</span></tt> by one (although the size of the
global queue does increase by one).</p>
<div class="section" id="member-functions">
<h1>Member Functions</h1>
<pre class="literal-block">
explicit
distributed_queue(const ProcessGroup&amp; process_group = ProcessGroup(),
const Buffer&amp; buffer = Buffer(),
bool polling = false);
</pre>
<p>Build a new distributed queue that communicates over the given
<tt class="docutils literal"><span class="pre">process_group</span></tt>, whose local queue is initialized via <tt class="docutils literal"><span class="pre">buffer</span></tt> and
which may or may not poll for messages.</p>
<hr class="docutils" />
<pre class="literal-block">
distributed_queue(const ProcessGroup&amp; process_group, bool polling);
</pre>
<p>Build a new distributed queue that communicates over the given
<tt class="docutils literal"><span class="pre">process_group</span></tt>, whose local queue is default-initalized and which
may or may not poll for messages.</p>
<hr class="docutils" />
<pre class="literal-block">
void push(const value_type&amp; x);
</pre>
<p>Push an element onto the distributed queue.</p>
<p>The element will be sent to its owner process to be added to that
process's local queue. If polling is enabled for this queue and
the owner process is the current process, the value will be
immediately pushed onto the local queue.</p>
<p>Complexity: O(1) messages of size O(<tt class="docutils literal"><span class="pre">sizeof(value_type)</span></tt>) will be
transmitted.</p>
<hr class="docutils" />
<pre class="literal-block">
void pop();
</pre>
<p>Pop an element off the local queue. The queue must not be <tt class="docutils literal"><span class="pre">empty()</span></tt>.</p>
<hr class="docutils" />
<pre class="literal-block">
value_type&amp; top();
const value_type&amp; top();
</pre>
<p>Returns the top element in the local queue. The queue must not be
<tt class="docutils literal"><span class="pre">empty()</span></tt>.</p>
<hr class="docutils" />
<pre class="literal-block">
bool empty() const;
</pre>
<p>Determines if the queue is empty.</p>
<p>When the local queue is nonempty, returns true. If the local queue is
empty, synchronizes with all other processes in the process group
until either (1) the local queue is nonempty (returns true) (2) the
entire distributed queue is empty (returns false).</p>
<hr class="docutils" />
<pre class="literal-block">
size_type size() const;
</pre>
<p>Determines the size of the local queue.</p>
<p>The behavior of this routine is equivalent to the behavior of
<tt class="docutils literal"><span class="pre">empty</span></tt>, except that when <tt class="docutils literal"><span class="pre">empty</span></tt> returns true this
function returns the size of the local queue and when <tt class="docutils literal"><span class="pre">empty</span></tt>
returns false this function returns zero.</p>
</div>
<div class="section" id="free-functions">
<h1>Free Functions</h1>
<pre class="literal-block">
template&lt;typename ProcessGroup, typename Buffer&gt;
inline distributed_queue&lt;ProcessGroup, Buffer&gt;
make_distributed_queue(const ProcessGroup&amp; process_group, const Buffer&amp; buffer,
bool polling = false);
</pre>
<p>Constructs a distributed queue.</p>
<hr class="docutils" />
<p>Copyright (C) 2004, 2005 The Trustees of Indiana University.</p>
<p>Authors: Douglas Gregor and Andrew Lumsdaine</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:22 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Fruchterman Reingold</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-fruchterman-reingold">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Fruchterman Reingold</h1>
<!-- Copyright (C) 2004-2009 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<pre class="literal-block">
namespace graph { namespace distributed {
template&lt;typename Graph, typename PositionMap,
typename AttractiveForce, typename RepulsiveForce,
typename ForcePairs, typename Cooling, typename DisplacementMap&gt;
void
fruchterman_reingold_force_directed_layout
(const Graph&amp; g,
PositionMap position,
typename property_traits&lt;PositionMap&gt;::value_type const&amp; origin,
typename property_traits&lt;PositionMap&gt;::value_type const&amp; extent,
AttractiveForce attractive_force,
RepulsiveForce repulsive_force,
ForcePairs force_pairs,
Cooling cool,
DisplacementMap displacement)
template&lt;typename Graph, typename PositionMap,
typename AttractiveForce, typename RepulsiveForce,
typename ForcePairs, typename Cooling, typename DisplacementMap&gt;
void
fruchterman_reingold_force_directed_layout
(const Graph&amp; g,
PositionMap position,
typename property_traits&lt;PositionMap&gt;::value_type const&amp; origin,
typename property_traits&lt;PositionMap&gt;::value_type const&amp; extent,
AttractiveForce attractive_force,
RepulsiveForce repulsive_force,
ForcePairs force_pairs,
Cooling cool,
DisplacementMap displacement,
simple_tiling tiling)
} }
</pre>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<ul class="simple">
<li><a class="reference internal" href="#where-defined" id="id1">Where Defined</a></li>
<li><a class="reference internal" href="#parameters" id="id2">Parameters</a></li>
</ul>
</div>
<div class="section" id="where-defined">
<h1><a class="toc-backref" href="#id1">Where Defined</a></h1>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/distributed/fruchterman_reingold.hpp</span></tt>&gt;</p>
<p>also accessible from</p>
<p>&lt;<tt class="docutils literal"><span class="pre">boost/graph/fruchterman_reingold.hpp</span></tt>&gt;</p>
</div>
<div class="section" id="parameters">
<h1><a class="toc-backref" href="#id2">Parameters</a></h1>
<dl class="docutils">
<dt>IN: <tt class="docutils literal"><span class="pre">const</span> <span class="pre">Graph&amp;</span> <span class="pre">g</span></tt></dt>
<dd>The graph type must be a model of <a class="reference external" href="DistributedGraph.html">Distributed Graph</a>. The graph
type must also model the <a class="reference external" href="http://www.boost.org/libs/graph/doc/IncidenceGraph.html">Incidence Graph</a>.</dd>
</dl>
<p>OUT: <tt class="docutils literal"><span class="pre">PositionMap</span> <span class="pre">position</span></tt></p>
<p>IN: <tt class="docutils literal"><span class="pre">property_traits&lt;PositionMap&gt;::value_type</span> <span class="pre">origin</span></tt></p>
<p>IN: <tt class="docutils literal"><span class="pre">property_traits&lt;PositionMap&gt;::value_type</span> <span class="pre">extent</span></tt></p>
<p>IN: <tt class="docutils literal"><span class="pre">AttractiveForce</span> <span class="pre">attractive_force</span></tt></p>
<p>IN: <tt class="docutils literal"><span class="pre">RepulsiveForce</span> <span class="pre">repulsive_force</span></tt></p>
<p>IN: <tt class="docutils literal"><span class="pre">ForcePairs</span> <span class="pre">force_pairs</span></tt></p>
<p>IN: <tt class="docutils literal"><span class="pre">Cooling</span> <span class="pre">cool</span></tt></p>
<p>IN: <tt class="docutils literal"><span class="pre">DisplacementMap</span> <span class="pre">displacement</span></tt></p>
<!-- Complexity
- - - - - - - - - - -->
<!-- Algorithm Description
- - - - - - - - - - - - - - - - - - - - - -->
<hr class="docutils" />
<p>Copyright (C) 2009 The Trustees of Indiana University.</p>
<p>Authors: Nick Edmonds and Andrew Lumsdaine</p>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:21 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Parallel Boost Graph Library</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-parallel-boost-graph-library">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Parallel Boost Graph Library</h1>
<h2 class="subtitle" id="overview">Overview</h2>
<!-- Copyright (C) 2004-2009 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<p>The Parallel Boost Graph Library is an extension to the <a class="reference external" href="http://www.boost.org/libs/graph/doc">Boost Graph
Library</a> (BGL) for parallel and distributed computing. It offers
distributed graphs and graph algorithms to exploit coarse-grained
parallelism along with parallel algorithms that exploit fine-grained
parallelism, while retaining the same interfaces as the (sequential)
BGL. Code written using the sequential BGL should be easy to
parallelize with the parallel BGL. Visitors new to the Parallel BGL
should read our <a class="reference external" href="overview.html">architectural overview</a>.</p>
<ol class="arabic simple">
<li><a class="reference external" href="process_group.html">Process groups</a></li>
</ol>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="process_group.html">MPI process group</a></li>
<li><a class="reference external" href="simple_trigger.html">Simple trigger interface</a></li>
</ul>
</blockquote>
<ol class="arabic simple" start="2">
<li>Auxiliary data structures</li>
</ol>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="distributed_queue.html">Distributed queue</a></li>
<li><a class="reference external" href="distributed_property_map.html">Distributed property map</a></li>
</ul>
</blockquote>
<ol class="arabic simple" start="3">
<li>Distributed graph concepts</li>
</ol>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="DistributedGraph.html">Distributed Graph</a></li>
<li><a class="reference external" href="DistributedVertexListGraph.html">Distributed Vertex List Graph</a></li>
<li><a class="reference external" href="DistributedEdgeListGraph.html">Distributed Edge List Graph</a></li>
<li><a class="reference external" href="GlobalDescriptor.html">Global Descriptor</a></li>
</ul>
</blockquote>
<ol class="arabic simple" start="4">
<li>Graph data structures</li>
</ol>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="distributed_adjacency_list.html">Distributed adjacency list</a></li>
</ul>
</blockquote>
<ol class="arabic simple" start="5">
<li>Graph adaptors</li>
</ol>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="local_subgraph.html">Local subgraph adaptor</a></li>
<li><a class="reference external" href="vertex_list_adaptor.html">Vertex list graph adaptor</a></li>
</ul>
</blockquote>
<ol class="arabic simple" start="6">
<li>Graph input/output</li>
</ol>
<blockquote>
<ul class="simple">
<li>Graphviz output</li>
<li><a class="reference external" href="metis.html">METIS input</a></li>
</ul>
</blockquote>
<ol class="arabic simple" start="7">
<li>Synthetic data generators</li>
</ol>
<blockquote>
<ul class="simple">
<li><a class="reference external" href="rmat_generator.html">R-MAT generator</a></li>
<li><a class="reference external" href="sorted_rmat_generator.html">Sorted R-MAT generator</a></li>
<li><a class="reference external" href="sorted_unique_rmat_generator.html">Sorted unique R-MAT generator</a></li>
<li><a class="reference external" href="unique_rmat_generator.html">Unique R-MAT generator</a></li>
<li><a class="reference external" href="scalable_rmat_generator.html">Scalable R-MAT generator</a></li>
<li><a class="reference external" href="http://www.boost.org/libs/graph/doc/erdos_renyi_generator.html">Erdos-Renyi generator</a></li>
<li><a class="reference external" href="http://www.boost.org/libs/graph/doc/sorted_erdos_renyi_gen.html">Sorted Erdos-Renyi generator</a></li>
<li><a class="reference external" href="http://www.boost.org/libs/graph/doc/small_world_generator.html">Small world generator</a></li>
<li><a class="reference external" href="ssca_generator.html">SSCA generator</a></li>
<li><a class="reference external" href="mesh_generator.html">Mesh generator</a></li>
</ul>
</blockquote>
<ol class="arabic simple" start="8">
<li>Algorithms</li>
</ol>
<blockquote>
<ul class="simple">
<li>Distributed algorithms<ul>
<li><a class="reference external" href="breadth_first_search.html">Breadth-first search</a></li>
<li><a class="reference external" href="dijkstra_shortest_paths.html">Dijkstra's single-source shortest paths</a><ul>
<li><a class="reference external" href="dijkstra_shortest_paths.html#eager-dijkstra-s-algorithm">Eager Dijkstra shortest paths</a></li>
<li><a class="reference external" href="dijkstra_shortest_paths.html#crauser-et-al-s-algorithm">Crauser et al. Dijkstra shortest paths</a></li>
<li><a class="reference external" href="dijkstra_shortest_paths.html#delta-stepping-algorithm">Delta-Stepping shortest paths</a></li>
</ul>
</li>
<li><a class="reference external" href="tsin_depth_first_visit.html">Depth-first search</a></li>
<li><a class="reference external" href="dehne_gotz_min_spanning_tree.html">Minimum spanning tree</a><ul>
<li><a class="reference external" href="dehne_gotz_min_spanning_tree.html#dense-boruvka-minimum-spanning-tree">Boruvka's minimum spanning tree</a></li>
<li><a class="reference external" href="dehne_gotz_min_spanning_tree.html#merge-local-minimum-spanning-trees">Merging local minimum spanning forests</a></li>
<li><a class="reference external" href="dehne_gotz_min_spanning_tree.html#boruvka-then-merge">Boruvka-then-merge</a></li>
<li><a class="reference external" href="dehne_gotz_min_spanning_tree.html#boruvka-mixed-merge">Boruvka-mixed-merge</a></li>
</ul>
</li>
<li>Connected components<ul>
<li><a class="reference external" href="connected_components.html">Connected components</a></li>
<li><a class="reference external" href="connected_components_parallel_search.html">Connected components parallel search</a></li>
<li><a class="reference external" href="strong_components.html">Strongly-connected components</a></li>
</ul>
</li>
<li><a class="reference external" href="page_rank.html">PageRank</a></li>
<li><a class="reference external" href="boman_et_al_graph_coloring.html">Boman et al. Graph coloring</a></li>
<li><a class="reference external" href="fruchterman_reingold.html">Fruchterman Reingold force-directed layout</a></li>
<li><a class="reference external" href="st_connected.html">s-t connectivity</a></li>
<li><a class="reference external" href="betweenness_centrality.html">Betweenness centrality</a></li>
<li><a class="reference external" href="non_distributed_betweenness_centrality.html">Non-distributed betweenness centrality</a></li>
</ul>
</li>
</ul>
</blockquote>
<hr class="docutils" />
<p>Copyright (C) 2005-2009 The Trustees of Indiana University.</p>
<p>Authors: Nick Edmonds, Douglas Gregor, and Andrew Lumsdaine</p>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:21 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Local Subgraph Adaptor</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-local-subgraph-adaptor">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Local Subgraph Adaptor</h1>
<!-- Copyright (C) 2004-2008 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<p>The local subgraph adaptor takes an existing <cite>Distributed Graph</cite> and
filters out all of the nonlocal edges and vertices, presenting only
the local portion of the distributed graph to the user. The behavior
is equivalent to (and implemented with) a <a class="reference external" href="http://www.boost.org/libs/graph/doc/filtered_graph.html">filtered graph</a>, and is a
noncopying view into the graph itself. Changes made through the
filtered graph will be reflected in the original graph and vice-versa.</p>
<pre class="literal-block">
template&lt;typename DistributedGraph&gt; class local_subgraph;
template&lt;typename DistributedGraph&gt;
local_subgraph&lt;DistributedGraph&gt; make_local_subgraph(DistributedGraph&amp; g);
</pre>
<div class="section" id="where-defined">
<h1>Where Defined</h1>
<p>&lt;boost/graph/distributed/local_subgraph.hpp&gt;</p>
</div>
<div class="section" id="reference">
<h1>Reference</h1>
<p>The local subgraph adaptor adapts and forwards all operations of
distributed graphs, the signatures of which will be omitted. Only
operations unique to the local subgraph adaptor are presented.</p>
<div class="section" id="member-functions">
<h2>Member Functions</h2>
<pre class="literal-block">
local_subgraph(DistributedGraph&amp; g);
</pre>
<p>Constructs a local subgraph presenting the local portion of the
distributed graph <tt class="docutils literal"><span class="pre">g</span></tt>.</p>
<hr class="docutils" />
<pre class="literal-block">
DistributedGraph&amp; base() { return g; }
const DistributedGraph&amp; base() const { return g; }
</pre>
<p>Returns the underlying distributed graph.</p>
</div>
<div class="section" id="free-functions">
<h2>Free Functions</h2>
<pre class="literal-block">
template&lt;typename DistributedGraph&gt;
local_subgraph&lt;DistributedGraph&gt; make_local_subgraph(DistributedGraph&amp; g);
</pre>
<p>Constructs a local subgraph presenting the local portion of the
distributed graph <tt class="docutils literal"><span class="pre">g</span></tt>.</p>
</div>
</div>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:22 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.6: http://docutils.sourceforge.net/" />
<title>Parallel BGL Mesh Generator</title>
<link rel="stylesheet" href="../../../../rst.css" type="text/css" />
</head>
<body>
<div class="document" id="logo-mesh-generator">
<h1 class="title"><a class="reference external" href="http://www.osl.iu.edu/research/pbgl"><img align="middle" alt="Parallel BGL" class="align-middle" src="pbgl-logo.png" /></a> Mesh Generator</h1>
<!-- Copyright (C) 2004-2009 The Trustees of Indiana University.
Use, modification and distribution is 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) -->
<hr class="docutils" />
<p>Copyright (C) 2009 The Trustees of Indiana University.</p>
<p>Authors: Nick Edmonds and Andrew Lumsdaine</p>
</div>
<div class="footer">
<hr class="footer" />
Generated on: 2009-05-31 00:21 UTC.
Generated by <a class="reference external" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference external" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
</div>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More