|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r54064 - in branches/release: boost/graph boost/graph/distributed libs/graph/doc libs/graph/test libs/graph_parallel/example libs/graph_parallel/test status
From: jewillco_at_[hidden]
Date: 2009-06-18 15:34:29
Author: jewillco
Date: 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
New Revision: 54064
URL: http://svn.boost.org/trac/boost/changeset/54064
Log:
Merged in commits on trunk mentioned in comments 1-32 of #3134, plus r54059 not listed there; refs #3134
Added:
branches/release/libs/graph_parallel/example/Jamfile.v2
- copied, changed from r53934, /trunk/libs/graph_parallel/example/Jamfile.v2
branches/release/libs/graph_parallel/test/Jamfile.v2
- copied, changed from r53934, /trunk/libs/graph_parallel/test/Jamfile.v2
Text files modified:
branches/release/boost/graph/adj_list_serialize.hpp | 17
branches/release/boost/graph/adjacency_list_io.hpp | 44 ++--
branches/release/boost/graph/astar_search.hpp | 17 -
branches/release/boost/graph/bc_clustering.hpp | 8
branches/release/boost/graph/compressed_sparse_row_graph.hpp | 369 ++++++++++++++++++++++++++++++++++-----
branches/release/boost/graph/cuthill_mckee_ordering.hpp | 5
branches/release/boost/graph/depth_first_search.hpp | 10
branches/release/boost/graph/distributed/adjacency_list.hpp | 2
branches/release/boost/graph/distributed/betweenness_centrality.hpp | 8
branches/release/boost/graph/distributed/connected_components.hpp | 1
branches/release/boost/graph/distributed/eager_dijkstra_shortest_paths.hpp | 12 -
branches/release/boost/graph/edge_connectivity.hpp | 6
branches/release/boost/graph/graph_utility.hpp | 21 ++
branches/release/boost/graph/howard_cycle_ratio.hpp | 3
branches/release/boost/graph/isomorphism.hpp | 10
branches/release/boost/graph/iteration_macros.hpp | 69 ++++---
branches/release/boost/graph/king_ordering.hpp | 5
branches/release/boost/graph/metric_tsp_approx.hpp | 2
branches/release/boost/graph/named_function_params.hpp | 6
branches/release/boost/graph/properties.hpp | 8
branches/release/boost/graph/push_relabel_max_flow.hpp | 43 ++--
branches/release/boost/graph/relax.hpp | 7
branches/release/boost/graph/rmat_graph_generator.hpp | 21 +
branches/release/libs/graph/doc/compressed_sparse_row.html | 112 +++++++++++
branches/release/libs/graph/test/Jamfile.v2 | 2
branches/release/libs/graph/test/betweenness_centrality_test.cpp | 7
branches/release/libs/graph/test/csr_graph_test.cpp | 15 +
branches/release/libs/graph/test/gursoy_atun_layout_test.cpp | 8
branches/release/libs/graph_parallel/example/Jamfile.v2 | 6
branches/release/libs/graph_parallel/example/breadth_first_search.cpp | 2
branches/release/libs/graph_parallel/example/dijkstra_shortest_paths.cpp | 2
branches/release/libs/graph_parallel/test/Jamfile.v2 | 40 ++--
branches/release/libs/graph_parallel/test/distributed_adjacency_list_test.cpp | 6
branches/release/libs/graph_parallel/test/distributed_dfs_test.cpp | 2
branches/release/libs/graph_parallel/test/distributed_property_map_test.cpp | 4
branches/release/status/explicit-failures-markup.xml | 12 +
36 files changed, 671 insertions(+), 241 deletions(-)
Modified: branches/release/boost/graph/adj_list_serialize.hpp
==============================================================================
--- branches/release/boost/graph/adj_list_serialize.hpp (original)
+++ branches/release/boost/graph/adj_list_serialize.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -10,6 +10,7 @@
#define ADJ_LIST_SERIALIZE_HPP
#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/iteration_macros.hpp>
#include <boost/pending/property_serialize.hpp>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
@@ -49,18 +50,16 @@
// assign indices to vertices
std::map<Vertex,int> indices;
int num = 0;
- typename graph_traits<Graph>::vertex_iterator vi;
- for (vi = vertices(graph).first; vi != vertices(graph).second; ++vi) {
- indices[*vi] = num++;
- ar << serialization::make_nvp("vertex_property", get(vertex_all_t(), graph, *vi) );
+ BGL_FORALL_VERTICES_T(v, graph, Graph) {
+ indices[v] = num++;
+ ar << serialization::make_nvp("vertex_property", get(vertex_all_t(), graph, v) );
}
// write edges
- typename graph_traits<Graph>::edge_iterator ei;
- for (ei = edges(graph).first; ei != edges(graph).second; ++ei){
- ar << serialization::make_nvp("u" , indices[source(*ei,graph)]);
- ar << serialization::make_nvp("v" , indices[target(*ei,graph)]);
- ar << serialization::make_nvp("edge_property", get(edge_all_t(), graph, *ei) );
+ BGL_FORALL_EDGES_T(e, graph, Graph) {
+ ar << serialization::make_nvp("u" , indices[source(e,graph)]);
+ ar << serialization::make_nvp("v" , indices[target(e,graph)]);
+ ar << serialization::make_nvp("edge_property", get(edge_all_t(), graph, e) );
}
}
Modified: branches/release/boost/graph/adjacency_list_io.hpp
==============================================================================
--- branches/release/boost/graph/adjacency_list_io.hpp (original)
+++ branches/release/boost/graph/adjacency_list_io.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -12,6 +12,7 @@
#include <iostream>
#include <vector>
#include <boost/graph/adjacency_list.hpp>
+#include <boost/graph/iteration_macros.hpp>
#include <cctype>
// Method read to parse an adjacency list from an input stream. Examples:
@@ -211,13 +212,13 @@
PropertyPrinter( const Graph& g ):graph(&g){}
- template<class Iterator>
- PropertyPrinter& operator () ( std::ostream& out, Iterator it )
+ template<class Val>
+ PropertyPrinter& operator () ( std::ostream& out, const Val& v )
{
typename property_map<Graph,Tag>::type ps = get(Tag(), *graph);
- out << ps[ *it ] <<" ";
+ out << ps[ v ] <<" ";
PropertyPrinter<Graph,Next> print(*graph);
- print(out, it);
+ print(out, v);
return (*this);
}
private:
@@ -229,10 +230,10 @@
{
PropertyPrinter( const Graph& g ):graph(&g){}
- template<class Iterator>
- PropertyPrinter& operator () ( std::ostream& out, Iterator it )
+ template<class Val>
+ PropertyPrinter& operator () ( std::ostream& out, const Val& v )
{
- out << (*graph)[ *it ] <<" ";
+ out << (*graph)[ v ] <<" ";
return (*this);
}
private:
@@ -244,13 +245,13 @@
{
PropertyPrinter( const Graph& g ):graph(&g){}
- template<class Iterator>
- PropertyPrinter& operator () ( std::ostream& out, Iterator it )
+ template<class Val>
+ PropertyPrinter& operator () ( std::ostream& out, const Val& v )
{
typename property_map<Graph,Tag>::type ps = get(Tag(), *graph);
- out << ps[ *it ] <<" ";
+ out << ps[ v ] <<" ";
PropertyPrinter<Graph,Next> print(*graph);
- print(out, it);
+ print(out, v);
return (*this);
}
private:
@@ -263,8 +264,8 @@
{
PropertyPrinter( const Graph& ){}
- template<class Iterator>
- PropertyPrinter& operator () ( std::ostream&, Iterator it ){ return *this; }
+ template<class Val>
+ PropertyPrinter& operator () ( std::ostream&, const Val& ){ return *this; }
};
// property printer
@@ -287,18 +288,16 @@
// assign indices to vertices
std::map<Vertex,int> indices;
int num = 0;
- typename graph_traits<Graph>::vertex_iterator vi;
- for (vi = vertices(graph).first; vi != vertices(graph).second; ++vi){
- indices[*vi] = num++;
+ BGL_FORALL_VERTICES_T(v, graph, Graph) {
+ indices[v] = num++;
}
// write edges
PropertyPrinter<Graph, EdgeProperty> print_Edge(graph);
out << "e" << std::endl;
- typename graph_traits<Graph>::edge_iterator ei;
- for (ei = edges(graph).first; ei != edges(graph).second; ++ei){
- out << indices[source(*ei,graph)] << " " << indices[target(*ei,graph)] << " ";
- print_Edge(out,ei);
+ BGL_FORALL_EDGES_T(e, graph, Graph) {
+ out << indices[source(e,graph)] << " " << indices[target(e,graph)] << " ";
+ print_Edge(out,e);
out << std::endl;
}
out << std::endl;
@@ -322,9 +321,8 @@
{
PropertyPrinter<Graph, V> printNode(this->graph);
out << "v"<<std::endl;
- typename graph_traits<Graph>::vertex_iterator vi;
- for (vi = vertices(this->graph).first; vi != vertices(this->graph).second; ++vi){
- printNode(out,vi);
+ BGL_FORALL_VERTICES_T(v, this->graph, Graph) {
+ printNode(out,v);
out << std::endl;
}
Modified: branches/release/boost/graph/astar_search.hpp
==============================================================================
--- branches/release/boost/graph/astar_search.hpp (original)
+++ branches/release/boost/graph/astar_search.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -172,20 +172,10 @@
template <class Edge, class Graph>
void gray_target(Edge e, Graph& g) {
- distance_type old_distance = get(m_distance, target(e, g));
-
m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
m_combine, m_compare);
- /* On x86 Linux with optimization, we sometimes get into a
- horrible case where m_decreased is true but the distance hasn't
- actually changed. This occurs when the comparison inside
- relax() occurs with the 80-bit precision of the x87 floating
- point unit, but the difference is lost when the resulting
- values are written back to lower-precision memory (e.g., a
- double). With the eager Dijkstra's implementation, this results
- in looping. */
- if(m_decreased && old_distance != get(m_distance, target(e, g))) {
+ if(m_decreased) {
put(m_cost, target(e, g),
m_combine(get(m_distance, target(e, g)),
m_h(target(e, g))));
@@ -198,13 +188,10 @@
template <class Edge, class Graph>
void black_target(Edge e, Graph& g) {
- distance_type old_distance = get(m_distance, target(e, g));
-
m_decreased = relax(e, g, m_weight, m_predecessor, m_distance,
m_combine, m_compare);
- /* See comment in gray_target */
- if(m_decreased && old_distance != get(m_distance, target(e, g))) {
+ if(m_decreased) {
m_vis.edge_relaxed(e, g);
put(m_cost, target(e, g),
m_combine(get(m_distance, target(e, g)),
Modified: branches/release/boost/graph/bc_clustering.hpp
==============================================================================
--- branches/release/boost/graph/bc_clustering.hpp (original)
+++ branches/release/boost/graph/bc_clustering.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -11,6 +11,7 @@
#include <boost/graph/betweenness_centrality.hpp>
#include <boost/graph/graph_traits.hpp>
+#include <boost/graph/graph_utility.hpp>
#include <boost/pending/indirect_cmp.hpp>
#include <algorithm>
#include <vector>
@@ -116,7 +117,7 @@
typedef typename graph_traits<MutableGraph>::vertices_size_type
vertices_size_type;
- if (edges(g).first == edges(g).second) return;
+ if (has_no_edges(g)) return;
// Function object that compares the centrality of edges
indirect_cmp<EdgeCentralityMap, std::less<centrality_type> >
@@ -127,10 +128,11 @@
brandes_betweenness_centrality(g,
edge_centrality_map(edge_centrality)
.vertex_index_map(vertex_index));
- edge_descriptor e = *max_element(edges(g).first, edges(g).second, cmp);
+ std::pair<edge_iterator, edge_iterator> edges_iters = edges(g);
+ edge_descriptor e = *max_element(edges_iters.first, edges_iters.second, cmp);
is_done = done(get(edge_centrality, e), e, g);
if (!is_done) remove_edge(e, g);
- } while (!is_done && edges(g).first != edges(g).second);
+ } while (!is_done && !has_no_edges(g));
}
/**
Modified: branches/release/boost/graph/compressed_sparse_row_graph.hpp
==============================================================================
--- branches/release/boost/graph/compressed_sparse_row_graph.hpp (original)
+++ branches/release/boost/graph/compressed_sparse_row_graph.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -19,9 +19,12 @@
#include <climits>
#include <cassert>
#include <iterator>
-#include <iostream> // FIXME
+#if 0
+#include <iostream> // For some debugging code below
+#endif
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/properties.hpp>
+#include <boost/graph/filtered_graph.hpp> // For keep_all
#include <boost/graph/detail/indexed_properties.hpp>
#include <boost/iterator/counting_iterator.hpp>
#include <boost/property_map/property_map.hpp>
@@ -58,26 +61,35 @@
// A type (edges_are_sorted_t) and a value (edges_are_sorted) used to indicate
// that the edge list passed into the CSR graph is already sorted by source
// vertex.
-struct edges_are_sorted_internal {};
-inline void edges_are_sorted(edges_are_sorted_internal) {}
-typedef void (*edges_are_sorted_t)(edges_are_sorted_internal);
+enum edges_are_sorted_t {edges_are_sorted};
#ifdef BOOST_GRAPH_USE_NEW_CSR_INTERFACE
// A type (edges_are_unsorted_t) and a value (edges_are_unsorted) used to
// indicate that the edge list passed into the CSR graph is not sorted by
-// source vertex.
-struct edges_are_unsorted_internal {};
-inline void edges_are_unsorted(edges_are_unsorted_internal) {}
-typedef void (*edges_are_unsorted_t)(edges_are_unsorted_internal);
+// source vertex. This version caches the edge information in memory, and thus
+// requires only a single pass over the input data.
+enum edges_are_unsorted_t {edges_are_unsorted};
+
+// A type (edges_are_unsorted_multi_pass_t) and a value
+// (edges_are_unsorted_multi_pass) used to indicate that the edge list passed
+// into the CSR graph is not sorted by source vertex. This version uses less
+// memory but requires multi-pass capability on the iterators.
+enum edges_are_unsorted_multi_pass_t {edges_are_unsorted_multi_pass};
+
+// A type (edges_are_unsorted_multi_pass_filtered_t) and a value
+// (edges_are_unsorted_multi_pass_filtered) used to indicate that the edge list
+// passed into the CSR graph is not sorted by source vertex. This version uses
+// less memory but requires multi-pass capability on the iterators. The
+// filtering is done here because it is often faster and it greatly simplifies
+// handling of edge properties.
+enum edges_are_unsorted_multi_pass_filtered_t {edges_are_unsorted_multi_pass_filtered};
// A type (construct_inplace_from_sources_and_targets_t) and a value
// (construct_inplace_from_sources_and_targets) used to indicate that mutable
// vectors of sources and targets (and possibly edge properties) are being used
// to construct the CSR graph. These vectors are sorted in-place and then the
// targets and properties are swapped into the graph data structure.
-struct construct_inplace_from_sources_and_targets_internal {};
-inline void construct_inplace_from_sources_and_targets(construct_inplace_from_sources_and_targets_internal) {}
-typedef void (*construct_inplace_from_sources_and_targets_t)(construct_inplace_from_sources_and_targets_internal);
+enum construct_inplace_from_sources_and_targets_t {construct_inplace_from_sources_and_targets};
// A type (construct_inplace_from_sources_and_targets_global_t) and a value
// (construct_inplace_from_sources_and_targets_global) used to indicate that
@@ -88,9 +100,16 @@
// used, and a map is required to convert those to local indices. This
// constructor is intended for internal use by the various CSR graphs
// (sequential and distributed).
-struct construct_inplace_from_sources_and_targets_global_internal {};
-inline void construct_inplace_from_sources_and_targets_global(construct_inplace_from_sources_and_targets_global_internal) {}
-typedef void (*construct_inplace_from_sources_and_targets_global_t)(construct_inplace_from_sources_and_targets_global_internal);
+enum construct_inplace_from_sources_and_targets_global_t {construct_inplace_from_sources_and_targets_global};
+
+// A type (edges_are_unsorted_for_distributed_graph_t) and a value
+// (edges_are_unsorted_for_distributed_graph) used to indicate that the edge
+// list passed into the CSR graph is not sorted by source vertex. The data is
+// also stored using global vertex indices, and must be filtered to choose only
+// local vertices. This constructor caches the edge information in memory, and
+// thus requires only a single pass over the input data. This constructor is
+// intended for internal use by the distributed CSR constructors.
+enum edges_are_unsorted_for_distributed_graph_t {edges_are_unsorted_for_distributed_graph};
#endif // BOOST_GRAPH_USE_NEW_CSR_INTERFACE
@@ -111,14 +130,33 @@
#ifdef BOOST_GRAPH_USE_NEW_CSR_INTERFACE
namespace detail {
- // Less-than operator for comparing only the first elements of two arbitrary
- // Boost tuples
- struct compare_first_elements_in_tuples {
- template <typename Tuple>
- bool operator()(const Tuple& a, const Tuple& b) const {
- return (a.template get<0>()) < (b.template get<0>());
- }
- };
+ template<typename InputIterator>
+ size_t
+ reserve_count_for_single_pass_helper(InputIterator, InputIterator,
+ std::input_iterator_tag)
+ {
+ // Do nothing: we have no idea how much storage to reserve.
+ return 0;
+ }
+
+ template<typename InputIterator>
+ size_t
+ reserve_count_for_single_pass_helper(InputIterator first, InputIterator last,
+ std::random_access_iterator_tag)
+ {
+ using std::distance;
+ typename std::iterator_traits<InputIterator>::difference_type n =
+ distance(first, last);
+ return (size_t)n;
+ }
+
+ template<typename InputIterator>
+ size_t
+ reserve_count_for_single_pass(InputIterator first, InputIterator last) {
+ typedef typename std::iterator_traits<InputIterator>::iterator_category
+ category;
+ return reserve_count_for_single_pass_helper(first, last, category());
+ }
}
#endif // BOOST_GRAPH_USE_NEW_CSR_INTERFACE
@@ -241,19 +279,20 @@
}
#ifdef BOOST_GRAPH_USE_NEW_CSR_INTERFACE
- // From number of vertices and unsorted list of edges
- template <typename MultiPassInputIterator>
- compressed_sparse_row_graph(edges_are_unsorted_t,
- MultiPassInputIterator edge_begin,
- MultiPassInputIterator edge_end,
- vertices_size_type numverts,
- const GraphProperty& prop = GraphProperty())
- : inherited_vertex_properties(numverts), m_rowstart(numverts + 1),
- m_column(0), m_property(prop)
- {
+ // Rebuild graph from number of vertices and multi-pass unsorted list of
+ // edges (filtered using edge_pred)
+ template <typename MultiPassInputIterator, typename EdgePred>
+ void
+ assign_unsorted_multi_pass_edges(MultiPassInputIterator edge_begin,
+ MultiPassInputIterator edge_end,
+ vertices_size_type numverts,
+ const EdgePred& edge_pred) {
+ m_rowstart.clear();
+ m_rowstart.resize(numverts + 1, 0);
// Put the degree of each vertex v into m_rowstart[v + 1]
for (MultiPassInputIterator i = edge_begin; i != edge_end; ++i)
- ++m_rowstart[i->first + 1];
+ if (edge_pred(*i))
+ ++m_rowstart[i->first + 1];
// Compute the partial sum of the degrees to get the actual values of
// m_rowstart
@@ -271,26 +310,25 @@
std::vector<EdgeIndex>
current_insert_positions(m_rowstart.begin(), m_rowstart.begin() + numverts);
for (; edge_begin != edge_end; ++edge_begin)
- m_column[current_insert_positions[edge_begin->first]++] = edge_begin->second;
-
- // Default-construct properties for edges
- inherited_edge_properties::resize(m_column.size());
+ if (edge_pred(*edge_begin))
+ m_column[current_insert_positions[edge_begin->first]++] = edge_begin->second;
}
- // From number of vertices and unsorted list of edges, plus edge properties
- template <typename MultiPassInputIterator, typename EdgePropertyIterator>
- compressed_sparse_row_graph(edges_are_unsorted_t,
- MultiPassInputIterator edge_begin,
- MultiPassInputIterator edge_end,
- EdgePropertyIterator ep_iter,
- vertices_size_type numverts,
- const GraphProperty& prop = GraphProperty())
- : inherited_vertex_properties(numverts), m_rowstart(numverts + 1),
- m_column(0), m_property(prop)
- {
+ // Rebuild graph from number of vertices and multi-pass unsorted list of
+ // edges and their properties (filtered using edge_pred)
+ template <typename MultiPassInputIterator, typename EdgePropertyIterator, typename EdgePred>
+ void
+ assign_unsorted_multi_pass_edges(MultiPassInputIterator edge_begin,
+ MultiPassInputIterator edge_end,
+ EdgePropertyIterator ep_iter,
+ vertices_size_type numverts,
+ const EdgePred& edge_pred) {
+ m_rowstart.clear();
+ m_rowstart.resize(numverts + 1, 0);
// Put the degree of each vertex v into m_rowstart[v + 1]
for (MultiPassInputIterator i = edge_begin; i != edge_end; ++i)
- ++m_rowstart[i->first + 1];
+ if (edge_pred(*i))
+ ++m_rowstart[i->first + 1];
// Compute the partial sum of the degrees to get the actual values of
// m_rowstart
@@ -309,13 +347,77 @@
std::vector<EdgeIndex>
current_insert_positions(m_rowstart.begin(), m_rowstart.begin() + numverts);
for (; edge_begin != edge_end; ++edge_begin, ++ep_iter) {
- vertices_size_type source = edge_begin->first;
- EdgeIndex insert_pos = current_insert_positions[source];
- ++current_insert_positions[source];
- m_column[insert_pos] = edge_begin->second;
- inherited_edge_properties::write_by_index(insert_pos, *ep_iter);
+ if (edge_pred(*edge_begin)) {
+ vertices_size_type source = edge_begin->first;
+ EdgeIndex insert_pos = current_insert_positions[source];
+ ++current_insert_positions[source];
+ m_column[insert_pos] = edge_begin->second;
+ inherited_edge_properties::write_by_index(insert_pos, *ep_iter);
+ }
}
}
+
+ // From number of vertices and unsorted list of edges
+ template <typename MultiPassInputIterator>
+ compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
+ MultiPassInputIterator edge_begin,
+ MultiPassInputIterator edge_end,
+ vertices_size_type numverts,
+ const GraphProperty& prop = GraphProperty())
+ : inherited_vertex_properties(numverts), m_rowstart(),
+ m_column(0), m_property(prop)
+ {
+ assign_unsorted_multi_pass_edges(edge_begin, edge_end, numverts, keep_all());
+
+ // Default-construct properties for edges
+ inherited_edge_properties::resize(m_column.size());
+ }
+
+ // From number of vertices and unsorted list of edges, plus edge properties
+ template <typename MultiPassInputIterator, typename EdgePropertyIterator>
+ compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
+ MultiPassInputIterator edge_begin,
+ MultiPassInputIterator edge_end,
+ EdgePropertyIterator ep_iter,
+ vertices_size_type numverts,
+ const GraphProperty& prop = GraphProperty())
+ : inherited_vertex_properties(numverts), m_rowstart(),
+ m_column(0), m_property(prop)
+ {
+ assign_unsorted_multi_pass_edges(edge_begin, edge_end, ep_iter, numverts, keep_all());
+ }
+
+ // From number of vertices and unsorted list of edges, with filter
+ template <typename MultiPassInputIterator, typename EdgePred>
+ compressed_sparse_row_graph(edges_are_unsorted_multi_pass_filtered_t,
+ MultiPassInputIterator edge_begin,
+ MultiPassInputIterator edge_end,
+ vertices_size_type numverts,
+ const EdgePred& edge_pred,
+ const GraphProperty& prop = GraphProperty())
+ : inherited_vertex_properties(numverts), m_rowstart(),
+ m_column(0), m_property(prop)
+ {
+ assign_unsorted_multi_pass_edges(edge_begin, edge_end, numverts, edge_pred);
+
+ // Default-construct properties for edges
+ inherited_edge_properties::resize(m_column.size());
+ }
+
+ // From number of vertices and unsorted list of edges, plus edge properties, with filter
+ template <typename MultiPassInputIterator, typename EdgePropertyIterator, typename EdgePred>
+ compressed_sparse_row_graph(edges_are_unsorted_multi_pass_filtered_t,
+ MultiPassInputIterator edge_begin,
+ MultiPassInputIterator edge_end,
+ EdgePropertyIterator ep_iter,
+ vertices_size_type numverts,
+ const EdgePred& edge_pred,
+ const GraphProperty& prop = GraphProperty())
+ : inherited_vertex_properties(numverts), m_rowstart(),
+ m_column(0), m_property(prop)
+ {
+ assign_unsorted_multi_pass_edges(edge_begin, edge_end, ep_iter, numverts, edge_pred);
+ }
#endif // BOOST_GRAPH_USE_NEW_CSR_INTERFACE
#ifdef BOOST_GRAPH_USE_OLD_CSR_INTERFACE
@@ -557,6 +659,106 @@
assign_sources_and_targets_global(sources, targets, edge_props, numlocalverts, global_to_local);
}
+ // From number of vertices and single-pass range of unsorted edges. Data is
+ // cached in coordinate form before creating the actual graph.
+ template<typename InputIterator>
+ compressed_sparse_row_graph(edges_are_unsorted_t,
+ InputIterator edge_begin, InputIterator edge_end,
+ vertices_size_type numverts,
+ const GraphProperty& prop = GraphProperty())
+ : inherited_vertex_properties(numverts), m_rowstart(),
+ m_column(), m_property(prop)
+ {
+ std::vector<vertex_descriptor> sources, targets;
+ size_t reserve_size
+ = detail::reserve_count_for_single_pass(edge_begin, edge_end);
+ sources.reserve(reserve_size);
+ targets.reserve(reserve_size);
+ for (; edge_begin != edge_end; ++edge_begin) {
+ sources.push_back(edge_begin->first);
+ targets.push_back(edge_begin->second);
+ }
+ assign_sources_and_targets_global(sources, targets, numverts, boost::identity_property_map());
+ }
+
+ // From number of vertices and single-pass range of unsorted edges and
+ // single-pass range of edge properties. Data is cached in coordinate form
+ // before creating the actual graph.
+ template<typename InputIterator, typename EdgePropertyIterator>
+ compressed_sparse_row_graph(edges_are_unsorted_t,
+ InputIterator edge_begin, InputIterator edge_end,
+ EdgePropertyIterator ep_iter,
+ vertices_size_type numverts,
+ const GraphProperty& prop = GraphProperty())
+ : inherited_vertex_properties(numverts), m_rowstart(),
+ m_column(), m_property(prop)
+ {
+ std::vector<vertex_descriptor> sources, targets;
+ std::vector<typename inherited_edge_properties::edge_property_type> edge_props;
+ size_t reserve_size
+ = detail::reserve_count_for_single_pass(edge_begin, edge_end);
+ sources.reserve(reserve_size);
+ targets.reserve(reserve_size);
+ edge_props.reserve(reserve_size);
+ for (; edge_begin != edge_end; ++edge_begin, ++ep_iter) {
+ sources.push_back(edge_begin->first);
+ targets.push_back(edge_begin->second);
+ edge_props.push_back(*ep_iter);
+ }
+ assign_sources_and_targets_global(sources, targets, edge_props, numverts, boost::identity_property_map());
+ }
+
+ // From number of vertices and single-pass range of unsorted edges. Data is
+ // cached in coordinate form before creating the actual graph. Edges are
+ // filtered and transformed for use in a distributed graph.
+ template<typename InputIterator, typename GlobalToLocal, typename EdgePred>
+ compressed_sparse_row_graph(edges_are_unsorted_for_distributed_graph_t,
+ InputIterator edge_begin, InputIterator edge_end,
+ vertices_size_type numlocalverts,
+ GlobalToLocal global_to_local,
+ const EdgePred& edge_pred,
+ const GraphProperty& prop = GraphProperty())
+ : inherited_vertex_properties(numlocalverts), m_rowstart(),
+ m_column(), m_property(prop)
+ {
+ std::vector<vertex_descriptor> sources, targets;
+ for (; edge_begin != edge_end; ++edge_begin) {
+ if (edge_pred(*edge_begin)) {
+ sources.push_back(edge_begin->first);
+ targets.push_back(edge_begin->second);
+ }
+ }
+ assign_sources_and_targets_global(sources, targets, numlocalverts, global_to_local);
+ }
+
+ // From number of vertices and single-pass range of unsorted edges and
+ // single-pass range of edge properties. Data is cached in coordinate form
+ // before creating the actual graph. Edges are filtered and transformed for
+ // use in a distributed graph.
+ template<typename InputIterator, typename EdgePropertyIterator,
+ typename GlobalToLocal, typename EdgePred>
+ compressed_sparse_row_graph(edges_are_unsorted_for_distributed_graph_t,
+ InputIterator edge_begin, InputIterator edge_end,
+ EdgePropertyIterator ep_iter,
+ vertices_size_type numlocalverts,
+ GlobalToLocal global_to_local,
+ const EdgePred& edge_pred,
+ const GraphProperty& prop = GraphProperty())
+ : inherited_vertex_properties(numlocalverts), m_rowstart(),
+ m_column(), m_property(prop)
+ {
+ std::vector<vertex_descriptor> sources, targets;
+ std::vector<typename inherited_edge_properties::edge_property_type> edge_props;
+ for (; edge_begin != edge_end; ++edge_begin, ++ep_iter) {
+ if (edge_pred(*edge_begin)) {
+ sources.push_back(edge_begin->first);
+ targets.push_back(edge_begin->second);
+ edge_props.push_back(*ep_iter);
+ }
+ }
+ assign_sources_and_targets_global(sources, targets, edge_props, numlocalverts, global_to_local);
+ }
+
// Replace graph with sources and targets given, sorting them in-place, and
// using the given global-to-local property map to get local indices from
// global ones in the two arrays.
@@ -841,6 +1043,65 @@
}
#endif // BOOST_GRAPH_USE_OLD_CSR_INTERFACE
+#ifdef BOOST_GRAPH_USE_NEW_CSR_INTERFACE
+// Add edges from a range of (source, target) pairs that are unsorted
+template <BOOST_CSR_GRAPH_TEMPLATE_PARMS, typename InputIterator>
+inline void
+add_edges(InputIterator first, InputIterator last, BOOST_CSR_GRAPH_TYPE& g) {
+ typedef BOOST_CSR_GRAPH_TYPE Graph;
+ typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_t;
+ typedef typename boost::graph_traits<Graph>::vertices_size_type vertex_num;
+ typedef typename boost::graph_traits<Graph>::edges_size_type edge_num;
+ typedef std::vector<std::pair<vertex_t, vertex_t> > edge_vector_t;
+ edge_vector_t new_edges(first, last);
+ if (new_edges.empty()) return;
+ std::sort(new_edges.begin(), new_edges.end());
+ edge_num edges_added_before_i = new_edges.size(); // Count increment to add to rowstarts
+ g.m_column.resize(g.m_column.size() + new_edges.size());
+ typename edge_vector_t::const_reverse_iterator
+ current_new_edge = new_edges.rbegin(),
+ prev_new_edge = new_edges.rbegin();
+ for (vertex_num i_plus_1 = num_vertices(g); i_plus_1 > 0; --i_plus_1) {
+ vertex_num i = i_plus_1 - 1;
+ prev_new_edge = current_new_edge;
+ // edges_added_to_this_vertex = #mbrs of new_edges with first == i
+ edge_num edges_added_to_this_vertex = 0;
+ while (current_new_edge !=
+ (typename edge_vector_t::const_reverse_iterator)new_edges.rend()) {
+ if (current_new_edge->first != i) break;
+ ++current_new_edge;
+ ++edges_added_to_this_vertex;
+ }
+ edges_added_before_i -= edges_added_to_this_vertex;
+ // Invariant: edges_added_before_i = #mbrs of new_edges with first < i
+ edge_num old_rowstart = g.m_rowstart[i];
+ edge_num new_rowstart = g.m_rowstart[i] + edges_added_before_i;
+ edge_num old_degree = g.m_rowstart[i + 1] - g.m_rowstart[i];
+ edge_num new_degree = old_degree + edges_added_to_this_vertex;
+ // Move old edges forward (by #new_edges before this i) to make room
+ // new_rowstart > old_rowstart, so use copy_backwards
+ if (old_rowstart != new_rowstart) {
+ std::copy_backward(g.m_column.begin() + old_rowstart,
+ g.m_column.begin() + old_rowstart + old_degree,
+ g.m_column.begin() + new_rowstart + old_degree);
+ }
+ // Add new edges (reversed because current_new_edge is a
+ // const_reverse_iterator)
+ typename edge_vector_t::const_reverse_iterator temp = current_new_edge;
+ for (; temp != prev_new_edge; ++old_degree) {
+ --temp;
+ g.m_column[new_rowstart + old_degree] = temp->second;
+ }
+ g.m_rowstart[i + 1] = new_rowstart + new_degree;
+ if (edges_added_before_i == 0) break; // No more edges inserted before this point
+ // g.m_rowstart[i] will be fixed up on the next iteration (to avoid
+ // changing the degree of vertex i - 1); the last iteration never changes
+ // it (either because of the condition of the break or because
+ // g.m_rowstart[0] is always 0)
+ }
+}
+#endif // BOOST_GRAPH_USE_NEW_CSR_INTERFACE
+
// From VertexListGraph
template<BOOST_CSR_GRAPH_TEMPLATE_PARMS>
inline Vertex
Modified: branches/release/boost/graph/cuthill_mckee_ordering.hpp
==============================================================================
--- branches/release/boost/graph/cuthill_mckee_ordering.hpp (original)
+++ branches/release/boost/graph/cuthill_mckee_ordering.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -13,6 +13,7 @@
#include <boost/config.hpp>
#include <boost/graph/detail/sparse_ordering.hpp>
+#include <boost/graph/graph_utility.hpp>
#include <algorithm>
@@ -132,7 +133,7 @@
cuthill_mckee_ordering(const Graph& G, OutputIterator permutation,
ColorMap color, DegreeMap degree)
{
- if (vertices(G).first == vertices(G).second)
+ if (has_no_vertices(G))
return permutation;
typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
@@ -168,7 +169,7 @@
cuthill_mckee_ordering(const Graph& G, OutputIterator permutation,
VertexIndexMap index_map)
{
- if (vertices(G).first == vertices(G).second)
+ if (has_no_vertices(G))
return permutation;
typedef out_degree_property_map<Graph> DegreeMap;
Modified: branches/release/boost/graph/depth_first_search.hpp
==============================================================================
--- branches/release/boost/graph/depth_first_search.hpp (original)
+++ branches/release/boost/graph/depth_first_search.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -214,10 +214,12 @@
void
depth_first_search(const VertexListGraph& g, DFSVisitor vis, ColorMap color)
{
- if (vertices(g).first == vertices(g).second)
+ typedef typename boost::graph_traits<VertexListGraph>::vertex_iterator vi;
+ std::pair<vi, vi> verts = vertices(g);
+ if (verts.first == verts.second)
return;
- depth_first_search(g, vis, color, *vertices(g).first);
+ depth_first_search(g, vis, color, *verts.first);
}
template <class Visitors = null_visitor>
@@ -284,7 +286,9 @@
depth_first_search(const VertexListGraph& g,
const bgl_named_params<P, T, R>& params)
{
- if (vertices(g).first == vertices(g).second)
+ typedef typename boost::graph_traits<VertexListGraph>::vertex_iterator vi;
+ std::pair<vi, vi> verts = vertices(g);
+ if (verts.first == verts.second)
return;
using namespace boost::graph::keywords;
typedef bgl_named_params<P, T, R> params_type;
Modified: branches/release/boost/graph/distributed/adjacency_list.hpp
==============================================================================
--- branches/release/boost/graph/distributed/adjacency_list.hpp (original)
+++ branches/release/boost/graph/distributed/adjacency_list.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -1417,7 +1417,7 @@
in_edge_iterator;
/// Iterator over the neighbors of a vertex
- typedef adjacency_iterator<
+ typedef boost::adjacency_iterator<
adjacency_list, vertex_descriptor, out_edge_iterator,
typename detail::iterator_traits<base_out_edge_iterator>
::difference_type>
Modified: branches/release/boost/graph/distributed/betweenness_centrality.hpp
==============================================================================
--- branches/release/boost/graph/distributed/betweenness_centrality.hpp (original)
+++ branches/release/boost/graph/distributed/betweenness_centrality.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -295,8 +295,8 @@
#endif
Dist delta)
: g(g),
- distance(distance),
incoming(incoming),
+ distance(distance),
weight(weight),
path_count(path_count),
#ifdef COMPUTE_PATH_COUNTS_INLINE
@@ -1047,7 +1047,7 @@
vertices_size_type n = num_vertices(g);
n = boost::parallel::all_reduce(pg, n, std::plus<vertices_size_type>());
- for (int i = 0; i < n; ++i) {
+ for (vertices_size_type i = 0; i < n; ++i) {
vertex_descriptor v = vertex(i, g);
do_brandes_sssp(g, centrality, edge_centrality_map, incoming, distance,
@@ -1189,7 +1189,7 @@
}
// DO SSSPs
- for(int i = 0; i < local_sources.size(); ++i)
+ for(size_t i = 0; i < local_sources.size(); ++i)
do_sequential_brandes_sssp(g, centrality, edge_centrality_map, incoming,
distance, dependency, path_count, vertex_index,
shortest_paths, ordered_vertices, local_sources[i]);
@@ -1198,7 +1198,7 @@
typedef typename graph_traits<Graph>::vertices_size_type vertices_size_type;
vertices_size_type n = num_vertices(g);
- for (int i = id; i < n; i += p) {
+ for (vertices_size_type i = id; i < n; i += p) {
vertex_descriptor v = vertex(i, g);
do_sequential_brandes_sssp(g, centrality, edge_centrality_map, incoming,
Modified: branches/release/boost/graph/distributed/connected_components.hpp
==============================================================================
--- branches/release/boost/graph/distributed/connected_components.hpp (original)
+++ branches/release/boost/graph/distributed/connected_components.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -409,7 +409,6 @@
#ifdef PBGL_EXPLICIT_SYNCH
synchronize(p);
#endif
- size_t lone_vertex_count = roots.size();
// Lastly, remove roots with no adjacent vertices, this is
// unnecessary but will speed up sparse graphs
Modified: branches/release/boost/graph/distributed/eager_dijkstra_shortest_paths.hpp
==============================================================================
--- branches/release/boost/graph/distributed/eager_dijkstra_shortest_paths.hpp (original)
+++ branches/release/boost/graph/distributed/eager_dijkstra_shortest_paths.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -113,20 +113,10 @@
boost::parallel::caching_property_map<PredecessorMap> c_pred(m_predecessor);
boost::parallel::caching_property_map<DistanceMap> c_dist(m_distance);
- distance_type old_distance = get(c_dist, target(e, g));
-
bool m_decreased = relax(e, g, m_weight, c_pred, c_dist,
m_combine, m_compare);
- /* On x86 Linux with optimization, we sometimes get into a
- horrible case where m_decreased is true but the distance hasn't
- actually changed. This occurs when the comparison inside
- relax() occurs with the 80-bit precision of the x87 floating
- point unit, but the difference is lost when the resulting
- values are written back to lower-precision memory (e.g., a
- double). With the eager Dijkstra's implementation, this results
- in looping. */
- if (m_decreased && old_distance != get(c_dist, target(e, g))) {
+ if (m_decreased) {
m_Q.update(target(e, g));
m_vis.edge_relaxed(e, g);
} else
Modified: branches/release/boost/graph/edge_connectivity.hpp
==============================================================================
--- branches/release/boost/graph/edge_connectivity.hpp (original)
+++ branches/release/boost/graph/edge_connectivity.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -132,7 +132,8 @@
detail::neighbors(g, S.begin(), S.end(),
std::inserter(neighbor_S, neighbor_S.begin()));
- std::set_difference(vertices(g).first, vertices(g).second,
+ tie(vi, vi_end) = vertices(g);
+ std::set_difference(vi, vi_end,
neighbor_S.begin(), neighbor_S.end(),
std::back_inserter(non_neighbor_S));
@@ -153,7 +154,8 @@
neighbor_S.insert(k);
detail::neighbors(g, k, std::inserter(neighbor_S, neighbor_S.begin()));
non_neighbor_S.clear();
- std::set_difference(vertices(g).first, vertices(g).second,
+ tie(vi, vi_end) = vertices(g);
+ std::set_difference(vi, vi_end,
neighbor_S.begin(), neighbor_S.end(),
std::back_inserter(non_neighbor_S));
}
Modified: branches/release/boost/graph/graph_utility.hpp
==============================================================================
--- branches/release/boost/graph/graph_utility.hpp (original)
+++ branches/release/boost/graph/graph_utility.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -445,6 +445,27 @@
add_removed_edge_capacity(Graph& g) : base(get(edge_capacity, g)) {}
};
+ template <typename Graph>
+ bool has_no_vertices(const Graph& g) {
+ typedef typename boost::graph_traits<Graph>::vertex_iterator vi;
+ std::pair<vi, vi> p = vertices(g);
+ return (p.first == p.second);
+ }
+
+ template <typename Graph>
+ bool has_no_edges(const Graph& g) {
+ typedef typename boost::graph_traits<Graph>::edge_iterator ei;
+ std::pair<ei, ei> p = edges(g);
+ return (p.first == p.second);
+ }
+
+ template <typename Graph>
+ bool has_no_out_edges(const typename boost::graph_traits<Graph>::vertex_descriptor& v, const Graph& g) {
+ typedef typename boost::graph_traits<Graph>::out_edge_iterator ei;
+ std::pair<ei, ei> p = out_edges(v, g);
+ return (p.first == p.second);
+ }
+
} // namespace graph
} /* namespace boost */
Modified: branches/release/boost/graph/howard_cycle_ratio.hpp
==============================================================================
--- branches/release/boost/graph/howard_cycle_ratio.hpp (original)
+++ branches/release/boost/graph/howard_cycle_ratio.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -29,6 +29,7 @@
#include <boost/graph/reverse_graph.hpp>
#include <boost/graph/breadth_first_search.hpp>
#include <boost/graph/iteration_macros.hpp>
+#include <boost/graph/graph_utility.hpp>
namespace boost {
namespace detail {
@@ -172,7 +173,7 @@
}
BGL_FORALL_VERTICES_T(vd1, m_g, TGraph)
{
- if (boost::out_edges(vd1, m_g).first == boost::out_edges(vd1, m_g).second) throw bad_graph(m_vim[vd1]);
+ if (boost::graph::has_no_out_edges(vd1, m_g)) throw bad_graph(m_vim[vd1]);
mcr_edge_t ed = *boost::out_edges(vd1, m_g).first;
pi_edge_t pied = boost::add_edge(m_g2pi_g_vm[source(ed, m_g)], m_g2pi_g_vm[target(ed, m_g)], m_pi_g).first;
boost::put(boost::edge_weight, m_pi_g, pied, m_ew1m[ed]);
Modified: branches/release/boost/graph/isomorphism.hpp
==============================================================================
--- branches/release/boost/graph/isomorphism.hpp (original)
+++ branches/release/boost/graph/isomorphism.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -439,13 +439,11 @@
return false;
#endif
- for (typename graph_traits<Graph1>::edge_iterator e1 = edges(g1).first;
- e1 != edges(g1).second; ++e1) {
+ BGL_FORALL_EDGES_T(e1, g1, Graph1) {
bool found_edge = false;
- for (typename graph_traits<Graph2>::edge_iterator e2 = edges(g2).first;
- e2 != edges(g2).second && !found_edge; ++e2) {
- if (source(*e2, g2) == get(iso_map, source(*e1, g1)) &&
- target(*e2, g2) == get(iso_map, target(*e1, g1))) {
+ BGL_FORALL_EDGES_T(e2, g2, Graph2) {
+ if (source(e2, g2) == get(iso_map, source(e1, g1)) &&
+ target(e2, g2) == get(iso_map, target(e1, g1))) {
found_edge = true;
}
}
Modified: branches/release/boost/graph/iteration_macros.hpp
==============================================================================
--- branches/release/boost/graph/iteration_macros.hpp (original)
+++ branches/release/boost/graph/iteration_macros.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -10,9 +10,12 @@
#ifndef BOOST_GRAPH_ITERATION_MACROS_HPP
#define BOOST_GRAPH_ITERATION_MACROS_HPP
+#include <utility>
+
#define BGL_CAT(x,y) x ## y
-#define BGL_FIRST(linenum) BGL_CAT(bgl_first_,linenum)
-#define BGL_LAST(linenum) BGL_CAT(bgl_last_,linenum)
+#define BGL_RANGE(linenum) BGL_CAT(bgl_range_,linenum)
+#define BGL_FIRST(linenum) (BGL_RANGE(linenum).first)
+#define BGL_LAST(linenum) (BGL_RANGE(linenum).second)
/*
BGL_FORALL_VERTICES_T(v, g, graph_t) // This is on line 9
@@ -22,7 +25,7 @@
bgl_first_9 = vertices(g).first, bgl_last_9 = vertices(g).second;
bgl_first_9 != bgl_last_9; bgl_first_9 = bgl_last_9)
for (typename boost::graph_traits<graph_t>::vertex_descriptor v;
- bgl_first_9 != bgl_last ? (v = *bgl_first_9, true) : false;
+ bgl_first_9 != bgl_last_9 ? (v = *bgl_first_9, true) : false;
++bgl_first_9)
The purpose of having two for-loops is just to provide a place to
@@ -37,90 +40,98 @@
Use the _T versions when the graph type is a template parameter or
dependent on a template parameter. Otherwise use the non _T versions.
+ -----------------------
+ 6/9/09 THK
+
+ The above contains two calls to the vertices function. I modified these
+ macros to expand to
+
+ for (std::pair<typename boost::graph_traits<graph_t>::vertex_iterator,
+ typename boost::graph_traits<graph_t>::vertex_iterator> bgl_range_9 = vertices(g);
+ bgl_range_9.first != bgl_range_9.second;
+ bgl_range_9.first = bgl_range_9.second)
+ for (typename boost::graph_traits<graph_t>::vertex_descriptor v;
+ bgl_range_9.first != bgl_range_9.second ? (v = *bgl_range_9.first, true) : false;
+ ++bgl_range_9.first)
+
*/
#define BGL_FORALL_VERTICES_T(VNAME, GNAME, GraphType) \
-for (typename boost::graph_traits<GraphType>::vertex_iterator \
- BGL_FIRST(__LINE__) = vertices(GNAME).first, BGL_LAST(__LINE__) = vertices(GNAME).second; \
+for (std::pair<typename boost::graph_traits<GraphType>::vertex_iterator, \
+ typename boost::graph_traits<GraphType>::vertex_iterator> BGL_RANGE(__LINE__) = vertices(GNAME); \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (typename boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_VERTICES(VNAME, GNAME, GraphType) \
-for (boost::graph_traits<GraphType>::vertex_iterator \
- BGL_FIRST(__LINE__) = vertices(GNAME).first, BGL_LAST(__LINE__) = vertices(GNAME).second; \
+for (std::pair<boost::graph_traits<GraphType>::vertex_iterator, \
+ boost::graph_traits<GraphType>::vertex_iterator> BGL_RANGE(__LINE__) = vertices(GNAME); \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true):false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_EDGES_T(ENAME, GNAME, GraphType) \
-for (typename boost::graph_traits<GraphType>::edge_iterator \
- BGL_FIRST(__LINE__) = edges(GNAME).first, BGL_LAST(__LINE__) = edges(GNAME).second; \
+for (std::pair<typename boost::graph_traits<GraphType>::edge_iterator, \
+ typename boost::graph_traits<GraphType>::edge_iterator> BGL_RANGE(__LINE__) = edges(GNAME); \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (typename boost::graph_traits<GraphType>::edge_descriptor ENAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true):false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_EDGES(ENAME, GNAME, GraphType) \
-for (boost::graph_traits<GraphType>::edge_iterator \
- BGL_FIRST(__LINE__) = edges(GNAME).first, BGL_LAST(__LINE__) = edges(GNAME).second; \
+for (std::pair<boost::graph_traits<GraphType>::edge_iterator, \
+ boost::graph_traits<GraphType>::edge_iterator> BGL_RANGE(__LINE__) = edges(GNAME); \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (boost::graph_traits<GraphType>::edge_descriptor ENAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true):false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_ADJ_T(UNAME, VNAME, GNAME, GraphType) \
-for (typename boost::graph_traits<GraphType>::adjacency_iterator \
- BGL_FIRST(__LINE__) = adjacent_vertices(UNAME, GNAME).first,\
- BGL_LAST(__LINE__) = adjacent_vertices(UNAME, GNAME).second; \
+for (std::pair<typename boost::graph_traits<GraphType>::adjacency_iterator, \
+ typename boost::graph_traits<GraphType>::adjacency_iterator> BGL_RANGE(__LINE__) = adjacent_vertices(UNAME, GNAME); \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (typename boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true) : false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_ADJ(UNAME, VNAME, GNAME, GraphType) \
-for (boost::graph_traits<GraphType>::adjacency_iterator \
- BGL_FIRST(__LINE__) = adjacent_vertices(UNAME, GNAME).first,\
- BGL_LAST(__LINE__) = adjacent_vertices(UNAME, GNAME).second; \
+for (std::pair<boost::graph_traits<GraphType>::adjacency_iterator, \
+ boost::graph_traits<GraphType>::adjacency_iterator> BGL_RANGE(__LINE__) = adjacent_vertices(UNAME, GNAME); \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (boost::graph_traits<GraphType>::vertex_descriptor VNAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (VNAME = *BGL_FIRST(__LINE__), true) : false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_OUTEDGES_T(UNAME, ENAME, GNAME, GraphType) \
-for (typename boost::graph_traits<GraphType>::out_edge_iterator \
- BGL_FIRST(__LINE__) = out_edges(UNAME, GNAME).first,\
- BGL_LAST(__LINE__) = out_edges(UNAME, GNAME).second; \
+for (std::pair<typename boost::graph_traits<GraphType>::out_edge_iterator, \
+ typename boost::graph_traits<GraphType>::out_edge_iterator> BGL_RANGE(__LINE__) = out_edges(UNAME, GNAME); \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (typename boost::graph_traits<GraphType>::edge_descriptor ENAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_OUTEDGES(UNAME, ENAME, GNAME, GraphType) \
-for (boost::graph_traits<GraphType>::out_edge_iterator \
- BGL_FIRST(__LINE__) = out_edges(UNAME, GNAME).first,\
- BGL_LAST(__LINE__) = out_edges(UNAME, GNAME).second; \
+for (std::pair<boost::graph_traits<GraphType>::out_edge_iterator, \
+ boost::graph_traits<GraphType>::out_edge_iterator> BGL_RANGE(__LINE__) = out_edges(UNAME, GNAME); \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (boost::graph_traits<GraphType>::edge_descriptor ENAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_INEDGES_T(UNAME, ENAME, GNAME, GraphType) \
-for (typename boost::graph_traits<GraphType>::in_edge_iterator \
- BGL_FIRST(__LINE__) = in_edges(UNAME, GNAME).first,\
- BGL_LAST(__LINE__) = in_edges(UNAME, GNAME).second; \
+for (std::pair<typename boost::graph_traits<GraphType>::in_edge_iterator, \
+ typename boost::graph_traits<GraphType>::in_edge_iterator> BGL_RANGE(__LINE__) = in_edges(UNAME, GNAME); \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (typename boost::graph_traits<GraphType>::edge_descriptor ENAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
++BGL_FIRST(__LINE__))
#define BGL_FORALL_INEDGES(UNAME, ENAME, GNAME, GraphType) \
-for (boost::graph_traits<GraphType>::in_edge_iterator \
- BGL_FIRST(__LINE__) = in_edges(UNAME, GNAME).first,\
- BGL_LAST(__LINE__) = in_edges(UNAME, GNAME).second; \
+for (std::pair<boost::graph_traits<GraphType>::in_edge_iterator, \
+ boost::graph_traits<GraphType>::in_edge_iterator> BGL_RANGE(__LINE__) = in_edges(UNAME, GNAME); \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__); BGL_FIRST(__LINE__) = BGL_LAST(__LINE__)) \
for (boost::graph_traits<GraphType>::edge_descriptor ENAME; \
BGL_FIRST(__LINE__) != BGL_LAST(__LINE__) ? (ENAME = *BGL_FIRST(__LINE__), true) : false; \
Modified: branches/release/boost/graph/king_ordering.hpp
==============================================================================
--- branches/release/boost/graph/king_ordering.hpp (original)
+++ branches/release/boost/graph/king_ordering.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -13,6 +13,7 @@
#include <boost/config.hpp>
#include <boost/graph/detail/sparse_ordering.hpp>
+#include <boost/graph/graph_utility.hpp>
/*
King Algorithm for matrix reordering
@@ -262,7 +263,7 @@
king_ordering(const Graph& G, OutputIterator permutation,
ColorMap color, DegreeMap degree, VertexIndexMap index_map)
{
- if (vertices(G).first == vertices(G).second)
+ if (has_no_vertices(G))
return permutation;
typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex;
@@ -298,7 +299,7 @@
king_ordering(const Graph& G, OutputIterator permutation,
VertexIndexMap index_map)
{
- if (vertices(G).first == vertices(G).second)
+ if (has_no_vertices(G))
return permutation;
typedef out_degree_property_map<Graph> DegreeMap;
Modified: branches/release/boost/graph/metric_tsp_approx.hpp
==============================================================================
--- branches/release/boost/graph/metric_tsp_approx.hpp (original)
+++ branches/release/boost/graph/metric_tsp_approx.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -310,4 +310,4 @@
} //boost
-#endif // BOOST_GRAPH_METRIC_TSP_APPROX_HPP
\ No newline at end of file
+#endif // BOOST_GRAPH_METRIC_TSP_APPROX_HPP
Modified: branches/release/boost/graph/named_function_params.hpp
==============================================================================
--- branches/release/boost/graph/named_function_params.hpp (original)
+++ branches/release/boost/graph/named_function_params.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -49,6 +49,8 @@
struct iterations_t { };
struct diameter_range_t { };
struct learning_constant_range_t { };
+ struct vertices_equivalent_t { };
+ struct edges_equivalent_t { };
#define BOOST_BGL_DECLARE_NAMED_PARAMS \
BOOST_BGL_ONE_PARAM_CREF(weight_map, edge_weight) \
@@ -94,7 +96,9 @@
BOOST_BGL_ONE_PARAM_CREF(cooling, cooling) \
BOOST_BGL_ONE_PARAM_CREF(iterations, iterations) \
BOOST_BGL_ONE_PARAM_CREF(diameter_range, diameter_range) \
- BOOST_BGL_ONE_PARAM_CREF(learning_constant_range, learning_constant_range)
+ BOOST_BGL_ONE_PARAM_CREF(learning_constant_range, learning_constant_range) \
+ BOOST_BGL_ONE_PARAM_CREF(vertices_equivalent, vertices_equivalent) \
+ BOOST_BGL_ONE_PARAM_CREF(edges_equivalent, edges_equivalent)
template <typename T, typename Tag, typename Base = no_property>
struct bgl_named_params : public Base
Modified: branches/release/boost/graph/properties.hpp
==============================================================================
--- branches/release/boost/graph/properties.hpp (original)
+++ branches/release/boost/graph/properties.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -13,6 +13,7 @@
#include <boost/config.hpp>
#include <cassert>
#include <boost/pending/property.hpp>
+#include <boost/detail/workaround.hpp>
// Include the property map library and extensions in the BGL.
#include <boost/property_map/property_map.hpp>
@@ -357,6 +358,13 @@
# define BOOST_GRAPH_NO_BUNDLED_PROPERTIES
#endif
+#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590)) && !defined (BOOST_GRAPH_NO_BUNDLED_PROPERTIES)
+// This compiler cannot define a partial specialization based on a
+// pointer-to-member type, as seen in boost/graph/subgraph.hpp line 985 (as of
+// trunk r53912)
+# define BOOST_GRAPH_NO_BUNDLED_PROPERTIES
+#endif
+
#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES
template<typename Graph, typename Descriptor, typename Bundle, typename T>
struct bundle_property_map
Modified: branches/release/boost/graph/push_relabel_max_flow.hpp
==============================================================================
--- branches/release/boost/graph/push_relabel_max_flow.hpp (original)
+++ branches/release/boost/graph/push_relabel_max_flow.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -121,7 +121,7 @@
: g(g_), n(num_vertices(g_)), capacity(cap), src(src_), sink(sink_),
index(idx),
excess_flow(num_vertices(g_)),
- current(num_vertices(g_), out_edges(*vertices(g_).first, g_).second),
+ current(num_vertices(g_), out_edges(*vertices(g_).first, g_)),
distance(num_vertices(g_)),
color(num_vertices(g_)),
reverse_edge(rev),
@@ -149,7 +149,7 @@
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
vertex_descriptor u = *u_iter;
excess_flow[u] = 0;
- current[u] = out_edges(u, g).first;
+ current[u] = out_edges(u, g);
}
bool overflow_detected = false;
@@ -240,7 +240,7 @@
&& is_residual_edge(reverse_edge[a])) {
distance[v] = d_v;
color[v] = ColorTraits::gray();
- current[v] = out_edges(v, g).first;
+ current[v] = out_edges(v, g);
max_distance = max BOOST_PREVENT_MACRO_SUBSTITUTION(d_v, max_distance);
if (excess_flow[v] > 0)
@@ -262,8 +262,7 @@
assert(excess_flow[u] > 0);
while (1) {
out_edge_iterator ai, ai_end;
- for (ai = current[u], ai_end = out_edges(u, g).second;
- ai != ai_end; ++ai) {
+ for (tie(ai, ai_end) = current[u]; ai != ai_end; ++ai) {
edge_descriptor a = *ai;
if (is_residual_edge(a)) {
vertex_descriptor v = target(a, g);
@@ -291,7 +290,7 @@
if (distance[u] == n)
break;
} else { // i is no longer active
- current[u] = ai;
+ current[u].first = ai;
add_to_inactive_list(u, layer);
break;
}
@@ -350,7 +349,7 @@
++min_distance;
if (min_distance < n) {
distance[u] = min_distance; // this is the main action
- current[u] = min_edge_iter;
+ current[u].first = min_edge_iter;
max_distance = max BOOST_PREVENT_MACRO_SUBSTITUTION(min_distance, max_distance);
}
return min_distance;
@@ -444,7 +443,7 @@
u = *u_iter;
color[u] = ColorTraits::white();
parent[u] = u;
- current[u] = out_edges(u, g).first;
+ current[u] = out_edges(u, g);
}
// eliminate flow cycles and topologically order the vertices
for (tie(u_iter, u_end) = vertices(g); u_iter != u_end; ++u_iter) {
@@ -455,8 +454,8 @@
r = u;
color[r] = ColorTraits::gray();
while (1) {
- for (; current[u] != out_edges(u, g).second; ++current[u]) {
- edge_descriptor a = *current[u];
+ for (; current[u].first != current[u].second; ++current[u].first) {
+ edge_descriptor a = *current[u].first;
if (capacity[a] == 0 && is_residual_edge(a)) {
vertex_descriptor v = target(a, g);
if (color[v] == ColorTraits::white()) {
@@ -469,16 +468,16 @@
FlowValue delta = residual_capacity[a];
while (1) {
BOOST_USING_STD_MIN();
- delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, residual_capacity[*current[v]]);
+ delta = min BOOST_PREVENT_MACRO_SUBSTITUTION(delta, residual_capacity[*current[v].first]);
if (v == u)
break;
else
- v = target(*current[v], g);
+ v = target(*current[v].first, g);
}
// remove delta flow units
v = u;
while (1) {
- a = *current[v];
+ a = *current[v].first;
residual_capacity[a] -= delta;
residual_capacity[reverse_edge[a]] += delta;
v = target(a, g);
@@ -488,25 +487,25 @@
// back-out of DFS to the first saturated edge
restart = u;
- for (v = target(*current[u], g); v != u; v = target(a, g)){
- a = *current[v];
+ for (v = target(*current[u].first, g); v != u; v = target(a, g)){
+ a = *current[v].first;
if (color[v] == ColorTraits::white()
|| is_saturated(a)) {
- color[target(*current[v], g)] = ColorTraits::white();
+ color[target(*current[v].first, g)] = ColorTraits::white();
if (color[v] != ColorTraits::white())
restart = v;
}
}
if (restart != u) {
u = restart;
- ++current[u];
+ ++current[u].first;
break;
}
} // else if (color[v] == ColorTraits::gray())
} // if (capacity[a] == 0 ...
} // for out_edges(u, g) (though "u" changes during loop)
- if (current[u] == out_edges(u, g).second) {
+ if ( current[u].first == current[u].second ) {
// scan of i is complete
color[u] = ColorTraits::black();
if (u != src) {
@@ -521,7 +520,7 @@
}
if (u != r) {
u = parent[u];
- ++current[u];
+ ++current[u].first;
} else
break;
}
@@ -533,8 +532,8 @@
// note that the sink is not on the stack
if (! bos_null) {
for (u = tos; u != bos; u = topo_next[u]) {
- ai = out_edges(u, g).first;
- while (excess_flow[u] > 0 && ai != out_edges(u, g).second) {
+ tie(ai, a_end) = out_edges(u, g);
+ while (excess_flow[u] > 0 && ai != a_end) {
if (capacity[*ai] == 0 && is_residual_edge(*ai))
push_flow(*ai);
++ai;
@@ -632,7 +631,7 @@
// will need to use random_access_property_map with these
std::vector< FlowValue > excess_flow;
- std::vector< out_edge_iterator > current;
+ std::vector< std::pair<out_edge_iterator, out_edge_iterator> > current;
std::vector< distance_size_type > distance;
std::vector< default_color_type > color;
Modified: branches/release/boost/graph/relax.hpp
==============================================================================
--- branches/release/boost/graph/relax.hpp (original)
+++ branches/release/boost/graph/relax.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -48,14 +48,17 @@
D d_u = get(d, u), d_v = get(d, v);
W w_e = get(w, e);
+ // The redundant gets in the return statements are to ensure that extra
+ // floating-point precision in x87 registers does not lead to relax()
+ // returning true when the distance did not actually change.
if ( compare(combine(d_u, w_e), d_v) ) {
put(d, v, combine(d_u, w_e));
put(p, v, u);
- return true;
+ return compare(get(d, v), d_v);
} else if (is_undirected && compare(combine(d_v, w_e), d_u)) {
put(d, u, combine(d_v, w_e));
put(p, u, v);
- return true;
+ return compare(get(d, u), d_u);
} else
return false;
}
Modified: branches/release/boost/graph/rmat_graph_generator.hpp
==============================================================================
--- branches/release/boost/graph/rmat_graph_generator.hpp (original)
+++ branches/release/boost/graph/rmat_graph_generator.hpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -17,9 +17,11 @@
#include <map>
#include <boost/shared_ptr.hpp>
#include <boost/random/uniform_int.hpp>
+#include <boost/random/uniform_01.hpp>
#include <boost/graph/graph_traits.hpp>
#include <boost/type_traits/is_base_and_derived.hpp>
#include <boost/type_traits/is_same.hpp>
+#include <boost/test/floating_point_comparison.hpp>
using boost::shared_ptr;
using boost::uniform_01;
@@ -103,7 +105,10 @@
double S = a + b + c + d;
- a /= S; b /= S; c /= S; d /= S;
+ a /= S; b /= S; c /= S;
+ // d /= S;
+ // Ensure all values add up to 1, regardless of floating point errors
+ d = 1. - a - b - c;
}
return std::make_pair(u, v);
@@ -150,7 +155,7 @@
{
this->gen.reset(new uniform_01<RandomGenerator>(gen));
- assert(a + b + c + d == 1);
+ assert(boost::test_tools::check_is_close(a + b + c + d, 1., boost::test_tools::fraction_tolerance(1.e-5)));
if (permute_vertices)
generate_permutation_vector(gen, vertexPermutation, n);
@@ -225,9 +230,9 @@
bool operator() (const std::pair<T,T>& x, const std::pair<T,T>& y)
{
if (x.first == y.first)
- return x.second >= y.second;
+ return x.second > y.second;
else
- return x.first >= y.first;
+ return x.first > y.first;
}
};
@@ -260,7 +265,7 @@
values(sort_pair<vertices_size_type>()), done(false)
{
- assert(a + b + c + d == 1);
+ assert(boost::test_tools::check_is_close(a + b + c + d, 1., boost::test_tools::fraction_tolerance(1.e-5)));
this->gen.reset(new uniform_01<RandomGenerator>(gen));
@@ -271,7 +276,7 @@
// TODO: "Clip and flip" if undirected graph
int SCALE = int_log2(n);
- for (int i = 0; i < m; ++i) {
+ for (edges_size_type i = 0; i < m; ++i) {
vertices_size_type u, v;
tie(u, v) = generate_edge(this->gen, n, SCALE, a, b, c, d);
@@ -361,7 +366,7 @@
: gen(), done(false)
{
- assert(a + b + c + d == 1);
+ assert(boost::test_tools::check_is_close(a + b + c + d, 1., boost::test_tools::fraction_tolerance(1.e-5)));
this->gen.reset(new uniform_01<RandomGenerator>(gen));
@@ -474,7 +479,7 @@
values(sort_pair<vertices_size_type>()), done(false)
{
- assert(a + b + c + d == 1);
+ assert(boost::test_tools::check_is_close(a + b + c + d, 1., boost::test_tools::fraction_tolerance(1.e-5)));
this->gen.reset(new uniform_01<RandomGenerator>(gen));
Modified: branches/release/libs/graph/doc/compressed_sparse_row.html
==============================================================================
--- branches/release/libs/graph/doc/compressed_sparse_row.html (original)
+++ branches/release/libs/graph/doc/compressed_sparse_row.html 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -115,14 +115,27 @@
<a href="#default-const">compressed_sparse_row_graph</a>();
<i>// Unsorted edge list constructors <b>(new interface only)</b></i>
- template<typename MultiPassInputIterator>
+ template<typename InputIterator>
<a href="#edge-const">compressed_sparse_row_graph</a>(edges_are_unsorted_t,
+ InputIterator edge_begin, InputIterator edge_end,
+ vertices_size_type numverts,
+ const GraphProperty& prop = GraphProperty());
+
+ template<typename InputIterator, typename EdgePropertyIterator>
+ compressed_sparse_row_graph(edges_are_unsorted_t,
+ InputIterator edge_begin, InputIterator edge_end,
+ EdgePropertyIterator ep_iter,
+ vertices_size_type numverts,
+ const GraphProperty& prop = GraphProperty());
+
+ template<typename MultiPassInputIterator>
+ compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end,
vertices_size_type numverts,
const GraphProperty& prop = GraphProperty());
template<typename MultiPassInputIterator, typename EdgePropertyIterator>
- compressed_sparse_row_graph(edges_are_unsorted_t,
+ compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end,
EdgePropertyIterator ep_iter,
vertices_size_type numverts,
@@ -264,16 +277,23 @@
void set_property(const compressed_sparse_row_graph& g, GraphPropertyTag,
const typename graph_property<compressed_sparse_row_graph, GraphPropertyTag>::type& value);
-<i>// Incremental construction functions (old interface only)</i>
+<i>// Incremental construction functions</i>
+<b>(old interface only)</b>
template<typename Graph>
vertex_descriptor add_vertex(compressed_sparse_row_graph& g);
+<b>(old interface only)</b>
template<typename Graph>
vertex_descriptor add_vertices(vertices_size_type count, compressed_sparse_row_graph& g);
+<b>(old interface only)</b>
template<typename Graph>
edge_descriptor add_edge(vertex_descriptor src, vertex_descriptor tgt, compressed_sparse_row_graph& g);
+<b>(new interface only)</b>
+template<typename InputIterator, typename Graph>
+void add_edges(InputIterator first, InputIterator last, compressed_sparse_row_graph& g);
+
} <i>// end namespace boost</i>
</pre>
@@ -401,8 +421,67 @@
<hr></hr>
<pre><a name="edge-const"></a>
- template<typename MultiPassInputIterator>
+ template<typename InputIterator>
+ compressed_sparse_row_graph(edges_are_unsorted_t,
+ InputIterator edge_begin, InputIterator edge_end,
+ vertices_size_type numverts,
+ const GraphProperty& prop = GraphProperty());
+ </pre>
+
+ <p class="indent">
+ Constructs a graph with <code>numverts</code> vertices whose
+ edges are specified by the iterator range <code>[edge_begin,
+ edge_end)</code>. The <tt>InputIterator</tt> must be a model of
+ <a
+ href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+ whose <code>value_type</code> is an <code>std::pair</code> of
+ integer values. These integer values are the source and target
+ vertices for the edges, and must fall within the range <code>[0,
+ numverts)</code>. The edges in <code>[edge_begin,
+ edge_end)</code> do not need to be sorted. This constructor uses extra
+ memory to save the edge information before adding it to the graph,
+ avoiding the requirement for the iterator to have multi-pass capability.
+ <b>(This function is only provided by the new interface.)</b>
+ </p>
+
+ <p class="indent">
+ The value <code>prop</code> will be used to initialize the graph
+ property.
+ </p>
+
+ <hr></hr>
+
+ <pre><a name="edge-prop-const"></a>
+ template<typename InputIterator, typename EdgePropertyIterator>
compressed_sparse_row_graph(edges_are_unsorted_t,
+ InputIterator edge_begin, InputIterator edge_end,
+ EdgePropertyIterator ep_iter,
+ vertices_size_type numverts,
+ const GraphProperty& prop = GraphProperty());
+ </pre>
+ <p class="indent">
+ This constructor constructs a graph with <code>numverts</code>
+ vertices and the edges provided in the iterator range
+ <code>[edge_begin, edge_end)</code>. Its semantics are identical
+ to the edge range constructor, except
+ that edge properties are also initialized. The type
+ <tt>EdgePropertyIterator</tt> must be a model of the <a
+ href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+ concept whose <tt>value_type</tt> is convertible to
+ <tt>EdgeProperty</tt>. The iterator range <tt>[ep_iter, ep_ter +
+ m)</tt> will be used to initialize the properties on the edges
+ of the graph, where <tt>m</tt> is distance from
+ <tt>edge_begin</tt> to <tt>edge_end</tt>. This constructor uses extra
+ memory to save the edge information before adding it to the graph,
+ avoiding the requirement for the iterator to have multi-pass capability.
+ <b>(This function is only provided by the new interface.)</b>
+ </p>
+
+ <hr></hr>
+
+ <pre><a name="edge-const"></a>
+ template<typename MultiPassInputIterator>
+ compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end,
vertices_size_type numverts,
const GraphProperty& prop = GraphProperty());
@@ -418,7 +497,8 @@
integer values. These integer values are the source and target
vertices for the edges, and must fall within the range <code>[0,
numverts)</code>. The edges in <code>[edge_begin,
- edge_end)</code> do not need to be sorted.
+ edge_end)</code> do not need to be sorted. Multiple passes will be made
+ over the edge range.
<b>(This function is only provided by the new interface.)</b>
</p>
@@ -431,7 +511,7 @@
<pre><a name="edge-prop-const"></a>
template<typename MultiPassInputIterator, typename EdgePropertyIterator>
- compressed_sparse_row_graph(edges_are_unsorted_t,
+ compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
MultiPassInputIterator edge_begin, MultiPassInputIterator edge_end,
EdgePropertyIterator ep_iter,
vertices_size_type numverts,
@@ -449,7 +529,8 @@
<tt>EdgeProperty</tt>. The iterator range <tt>[ep_iter, ep_ter +
m)</tt> will be used to initialize the properties on the edges
of the graph, where <tt>m</tt> is distance from
- <tt>edge_begin</tt> to <tt>edge_end</tt>.
+ <tt>edge_begin</tt> to <tt>edge_end</tt>. Multiple passes will be made
+ over the edge and property ranges.
<b>(This function is only provided by the new interface.)</b>
</p>
@@ -834,6 +915,23 @@
</p>
<hr></hr>
+
+ <pre><a name="add_edges"></a>
+template<typename InputIterator>
+edge_descriptor add_edges(InputIterator first, InputIterator last, compressed_sparse_row_graph& g)
+ </pre>
+
+ <p class="indent">
+ Add a range of edges (from <tt>first</tt> to <tt>last</tt>) to the graph.
+ The <tt>InputIterator</tt> must be a model of <a
+ href="http://www.sgi.com/tech/stl/InputIterator.html">InputIterator</a>
+ whose <code>value_type</code> is an <code>std::pair</code> of integer
+ values. These integer values are the source and target vertices of the
+ new edges. The edges do not need to be sorted.
+ <b>(This function is only provided by the new interface.)</b>
+ </p>
+
+ <hr></hr>
<a name="example"></a><h2>Example</h2>
<br>[<a
Modified: branches/release/libs/graph/test/Jamfile.v2
==============================================================================
--- branches/release/libs/graph/test/Jamfile.v2 (original)
+++ branches/release/libs/graph/test/Jamfile.v2 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -41,7 +41,7 @@
[ run bfs.cpp ../../test/build//boost_test_exec_monitor ]
[ compile bfs_cc.cpp ]
[ run bellman-test.cpp ]
- [ run betweenness_centrality_test.cpp ]
+ [ run betweenness_centrality_test.cpp : 100 ]
[ run bidir_remove_edge.cpp ]
[ run csr_graph_test.cpp : : : : : <variant>release ]
[ run dag_longest_paths.cpp ]
Modified: branches/release/libs/graph/test/betweenness_centrality_test.cpp
==============================================================================
--- branches/release/libs/graph/test/betweenness_centrality_test.cpp (original)
+++ branches/release/libs/graph/test/betweenness_centrality_test.cpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -16,6 +16,7 @@
#include <boost/test/minimal.hpp>
#include <boost/random/uniform_01.hpp>
#include <boost/random/linear_congruential.hpp>
+#include <boost/lexical_cast.hpp>
using namespace boost;
@@ -440,8 +441,10 @@
}
}
-int test_main(int, char*[])
+int test_main(int argc, char* argv[])
{
+ int random_test_num_vertices = 300;
+ if (argc >= 2) random_test_num_vertices = boost::lexical_cast<int>(argv[1]);
typedef adjacency_list<listS, listS, undirectedS,
property<vertex_index_t, int>, EdgeProperties>
Graph;
@@ -512,7 +515,7 @@
run_wheel_test((Graph*)0, 15);
- random_unweighted_test((Graph*)0, 300);
+ random_unweighted_test((Graph*)0, random_test_num_vertices);
return 0;
}
Modified: branches/release/libs/graph/test/csr_graph_test.cpp
==============================================================================
--- branches/release/libs/graph/test/csr_graph_test.cpp (original)
+++ branches/release/libs/graph/test/csr_graph_test.cpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -84,6 +84,7 @@
std::sort(edges1.begin(), edges1.end());
std::sort(edges2.begin(), edges2.end());
if (edges1 != edges2) {
+ std::cerr << "For vertex " << v1 << std::endl;
std::cerr << "edges1:";
for (size_t i = 0; i < edges1.size(); ++i) std::cerr << " " << edges1[i];
std::cerr << std::endl;
@@ -481,7 +482,21 @@
std::cout << "Testing CSR graph built from unsorted edges" << std::endl;
std::pair<int, int> unsorted_edges[] = {std::make_pair(5, 0), std::make_pair(3, 2), std::make_pair(4, 1), std::make_pair(4, 0), std::make_pair(0, 2), std::make_pair(5, 2)};
CSRGraphT g(boost::edges_are_unsorted, unsorted_edges, unsorted_edges + sizeof(unsorted_edges) / sizeof(*unsorted_edges), 6);
+ CSRGraphT g2(boost::edges_are_unsorted_multi_pass, unsorted_edges, unsorted_edges + sizeof(unsorted_edges) / sizeof(*unsorted_edges), 6);
graph_test(g);
+ graph_test(g2);
+ assert_graphs_equal(g, boost::identity_property_map(),
+ g2, boost::identity_property_map(),
+ boost::identity_property_map());
+ std::cout << "Testing CSR graph built using add_edges" << std::endl;
+ // Test building a graph using add_edges on unsorted lists
+ CSRGraphT g3(boost::edges_are_unsorted, unsorted_edges, unsorted_edges, 6); // Empty range
+ add_edges(unsorted_edges, unsorted_edges + 3, g3);
+ add_edges(unsorted_edges + 3, unsorted_edges + 6, g3);
+ graph_test(g3);
+ assert_graphs_equal(g, boost::identity_property_map(),
+ g3, boost::identity_property_map(),
+ boost::identity_property_map());
}
#endif // BOOST_GRAPH_USE_NEW_CSR_INTERFACE
Modified: branches/release/libs/graph/test/gursoy_atun_layout_test.cpp
==============================================================================
--- branches/release/libs/graph/test/gursoy_atun_layout_test.cpp (original)
+++ branches/release/libs/graph/test/gursoy_atun_layout_test.cpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -59,7 +59,7 @@
// Make grid, like Gursoy and Atun used
std::map<int, std::map<int, vertex_descriptor> > verts;
- const int grid_size = 30;
+ const int grid_size = 20;
boost::minstd_rand edge_weight_gen;
boost::uniform_01<boost::minstd_rand> random_edge_weight(edge_weight_gen);
for (int i = 0; i < grid_size; ++i)
@@ -94,7 +94,7 @@
plod_iterator<minstd_rand, graph_type>(),
n);
#else
- int n = 100000;
+ int n = 1000;
int k = 6;
double p = 0.001;
minstd_rand gen;
@@ -120,19 +120,23 @@
boost::gursoy_atun_layout(graph, space, position);
+#if 0
std::cerr << "--------Unweighted layout--------\n";
boost::write_graphviz(std::cout, graph,
position_writer<Position, vertex_descriptor>(position),
boost::default_writer(),
graph_writer());
+#endif
boost::gursoy_atun_layout(graph, space, position,
weight_map(get(boost::edge_weight, graph)));
+#if 0
std::cerr << "--------Weighted layout--------\n";
boost::write_graphviz(std::cout, graph,
position_writer<Position, vertex_descriptor>(position),
boost::default_writer(),
graph_writer());
+#endif
return 0;
}
Copied: branches/release/libs/graph_parallel/example/Jamfile.v2 (from r53934, /trunk/libs/graph_parallel/example/Jamfile.v2)
==============================================================================
--- /trunk/libs/graph_parallel/example/Jamfile.v2 (original)
+++ branches/release/libs/graph_parallel/example/Jamfile.v2 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -1,3 +1,9 @@
+# Copyright 2009 Vladimir Prus.
+#
+# 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)
+
project : requirements <library>../build//boost_graph_parallel
<library>../../system/build//boost_system
Modified: branches/release/libs/graph_parallel/example/breadth_first_search.cpp
==============================================================================
--- branches/release/libs/graph_parallel/example/breadth_first_search.cpp (original)
+++ branches/release/libs/graph_parallel/example/breadth_first_search.cpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -83,7 +83,7 @@
outfile = argv[2];
else {
outfile = filename;
- int i = outfile.rfind('.');
+ size_t i = outfile.rfind('.');
if (i != std::string::npos)
outfile.erase(outfile.begin() + i, outfile.end());
outfile += "-bfs.dot";
Modified: branches/release/libs/graph_parallel/example/dijkstra_shortest_paths.cpp
==============================================================================
--- branches/release/libs/graph_parallel/example/dijkstra_shortest_paths.cpp (original)
+++ branches/release/libs/graph_parallel/example/dijkstra_shortest_paths.cpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -78,7 +78,7 @@
if (argc > 2)
outfile = argv[2];
else {
- int i = outfile.rfind('.');
+ size_t i = outfile.rfind('.');
if (i != std::string::npos)
outfile.erase(outfile.begin() + i, outfile.end());
outfile += "-dijkstra.dot";
Copied: branches/release/libs/graph_parallel/test/Jamfile.v2 (from r53934, /trunk/libs/graph_parallel/test/Jamfile.v2)
==============================================================================
--- /trunk/libs/graph_parallel/test/Jamfile.v2 (original)
+++ branches/release/libs/graph_parallel/test/Jamfile.v2 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -17,30 +17,30 @@
{
test-suite graph_parallel
:
- [ mpi-test distributed_property_map_test ]
- [ mpi-test distributed_queue_test ]
+ [ mpi-test distributed_property_map_test : : : 2 ]
+ [ mpi-test distributed_queue_test : : : 2 ]
[ mpi-test process_group_serialization : : : 2 ]
- [ mpi-test adjlist_build_test ]
- [ mpi-test adjlist_redist_test ]
+ [ mpi-test adjlist_build_test : : : 2 ]
+ [ mpi-test adjlist_redist_test : : : 2 ]
[ mpi-test adjlist_remove_test : : : 2 ]
- [ mpi-test distributed_adjacency_list_test ]
- [ mpi-test distributed_connected_components_test ]
- [ mpi-test distributed_page_rank_test ]
- [ mpi-test distributed_csr_test ]
- [ mpi-test distributed_dfs_test ]
- [ mpi-test distributed_graph_coloring_test ]
- [ mpi-test distributed_mst_test ]
- [ mpi-test distributed_strong_components_test ]
- [ mpi-test hohberg_biconnected_components_test ]
- [ mpi-test mesh_generator_test : : <testing.arg>"1000 1000 1 0" ]
+ [ mpi-test distributed_adjacency_list_test : : : 2 ]
+ [ mpi-test distributed_connected_components_test : : : 2 ]
+ [ mpi-test distributed_page_rank_test : : : 2 ]
+ [ mpi-test distributed_csr_test : : : 2 ]
+ [ mpi-test distributed_dfs_test : : : 2 ]
+ [ mpi-test distributed_graph_coloring_test : : : 2 ]
+ [ mpi-test distributed_mst_test : : : 2 ]
+ [ mpi-test distributed_strong_components_test : : : 2 ]
+ [ mpi-test hohberg_biconnected_components_test : : : 2 ]
+ [ mpi-test mesh_generator_test : : <testing.arg>"1000 1000 1 0" : 2 ]
[ mpi-test named_vertices_seq : : : 1 ]
- [ mpi-test distributed_shortest_paths_test ]
+ [ mpi-test distributed_shortest_paths_test : : : 2 ]
[ mpi-test distributed_csr_algorithm_test : : : 1 ]
- [ mpi-test distributed_betweenness_centrality_test ]
- [ mpi-test distributed_dimacs_reader ]
- [ mpi-test distributed_rmat_cc_ps ]
- [ mpi-test distributed_rmat_cc ]
- [ mpi-test distributed_rmat_pagerank ]
+ [ mpi-test distributed_betweenness_centrality_test : : : 2 ]
+ [ mpi-test distributed_dimacs_reader : : : 2 ]
+ [ mpi-test distributed_rmat_cc_ps : : : 2 ]
+ [ mpi-test distributed_rmat_cc : : : 2 ]
+ [ mpi-test distributed_rmat_pagerank : : : 2 ]
;
}
Modified: branches/release/libs/graph_parallel/test/distributed_adjacency_list_test.cpp
==============================================================================
--- branches/release/libs/graph_parallel/test/distributed_adjacency_list_test.cpp (original)
+++ branches/release/libs/graph_parallel/test/distributed_adjacency_list_test.cpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -198,7 +198,7 @@
in_degree(*v, g3);
}
- int added_edges = 0;
+ graph_traits<Graph3>::vertices_size_type added_edges = 0;
if (num_vertices(g3) >= 2) {
graph_traits<Graph3>::vertex_iterator vi = vertices(g3).first;
graph_traits<Graph3>::vertex_descriptor u = *vi++;
@@ -239,7 +239,7 @@
}
synchronize(g3);
- assert(std::distance(edges(g3).first, edges(g3).second) == added_edges);
+ assert(std::distance(edges(g3).first, edges(g3).second) == (ptrdiff_t)added_edges);
assert(num_edges(g3) == added_edges);
// Verify the remote edges
@@ -250,7 +250,7 @@
int prior_processor = (process_id(pg) + num_processes(pg) - 1)
% num_processes(pg);
const int n = 20;
- int vertices_in_prior = (n / num_processes(pg))
+ graph_traits<Graph3>::vertices_size_type vertices_in_prior = (n / num_processes(pg))
+ (n % num_processes(pg) > prior_processor? 1 : 0);
if (in_degree(u, g3) != vertices_in_prior + 2) {
std::cerr << "#" << process_id(pg) << ": " << in_degree(u, g3)
Modified: branches/release/libs/graph_parallel/test/distributed_dfs_test.cpp
==============================================================================
--- branches/release/libs/graph_parallel/test/distributed_dfs_test.cpp (original)
+++ branches/release/libs/graph_parallel/test/distributed_dfs_test.cpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -139,8 +139,10 @@
make_iterator_property_map(explore.begin(), get(vertex_index, g)),
get(vertex_index, g));
+#if 0
std::size_t correct_parents1[N] = {u, u, y, y, v, w};
std::size_t correct_parents2[N] = {u, u, y, v, x, w};
+#endif
for (std::size_t i = 0; i < N; ++i) {
vertex_descriptor v = vertex(i, g);
Modified: branches/release/libs/graph_parallel/test/distributed_property_map_test.cpp
==============================================================================
--- branches/release/libs/graph_parallel/test/distributed_property_map_test.cpp (original)
+++ branches/release/libs/graph_parallel/test/distributed_property_map_test.cpp 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -182,7 +182,7 @@
bool my_start_value = process_id(pg) % 2;
int next_processor = (process_id(pg) + 1) % num_processes(pg);
- bool next_start_value = !my_start_value;
+ bool next_start_value = ((process_id(pg) + 1) % num_processes(pg)) % 2;
// Initial color map: even-numbered processes are false,
// odd-numbered processes are true
@@ -298,7 +298,7 @@
// check next processor's strings
for (int i = 0; i < n; ++i) {
remote_key k(next_processor, i);
- BOOST_CHECK(get(strings, k) == std::string());
+ BOOST_CHECK(get(strings, k) == (num_processes(pg) == 1 ? my_start_string : std::string()));
}
if (process_id(pg) == 0) std::cerr << "OK.\nSynchronizing...";
Modified: branches/release/status/explicit-failures-markup.xml
==============================================================================
--- branches/release/status/explicit-failures-markup.xml (original)
+++ branches/release/status/explicit-failures-markup.xml 2009-06-18 15:34:25 EDT (Thu, 18 Jun 2009)
@@ -1790,10 +1790,18 @@
<!-- graph -->
<library name="graph">
<mark-unusable>
- <toolset name="borland-5.6*"/>
- <toolset name="borland-5.8*"/>
+ <toolset name="borland-5.*"/>
+ <toolset name="borland-6.*"/>
<toolset name="msvc-6.5*"/>
<toolset name="sunpro-5_3-sunos"/>
+ <!-- Open64 and Pathscale ICE on almost all test cases, often
+ because of http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17327;
+ property type detection fails because it uses enum types as tags.
+ -->
+ <toolset name="gcc-open64"/>
+ <toolset name="pathscale-3.1"/>
+ <!-- vacpp ICEs on many of the tests -->
+ <toolset name="vacpp"/>
</mark-unusable>
<mark-expected-failures>
<test name="adj_matrix_cc"/>
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk