|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r53835 - in trunk: boost/graph libs/graph/doc libs/graph/test
From: jewillco_at_[hidden]
Date: 2009-06-12 16:56:54
Author: jewillco
Date: 2009-06-12 16:56:54 EDT (Fri, 12 Jun 2009)
New Revision: 53835
URL: http://svn.boost.org/trac/boost/changeset/53835
Log:
Added constructors from unsorted single-pass ranges for CSR graph by caching data in vectors; refs #3134
Text files modified:
trunk/boost/graph/compressed_sparse_row_graph.hpp | 97 +++++++++++++++++++++++++++++++++++----
trunk/libs/graph/doc/compressed_sparse_row.html | 86 ++++++++++++++++++++++++++++++++--
trunk/libs/graph/test/csr_graph_test.cpp | 5 ++
3 files changed, 171 insertions(+), 17 deletions(-)
Modified: trunk/boost/graph/compressed_sparse_row_graph.hpp
==============================================================================
--- trunk/boost/graph/compressed_sparse_row_graph.hpp (original)
+++ trunk/boost/graph/compressed_sparse_row_graph.hpp 2009-06-12 16:56:54 EDT (Fri, 12 Jun 2009)
@@ -65,9 +65,16 @@
#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.
+// 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 (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
@@ -105,14 +112,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
@@ -237,7 +263,7 @@
#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,
+ compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
MultiPassInputIterator edge_begin,
MultiPassInputIterator edge_end,
vertices_size_type numverts,
@@ -273,7 +299,7 @@
// 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,
+ compressed_sparse_row_graph(edges_are_unsorted_multi_pass_t,
MultiPassInputIterator edge_begin,
MultiPassInputIterator edge_end,
EdgePropertyIterator ep_iter,
@@ -551,6 +577,55 @@
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());
+ }
+
// 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.
Modified: trunk/libs/graph/doc/compressed_sparse_row.html
==============================================================================
--- trunk/libs/graph/doc/compressed_sparse_row.html (original)
+++ trunk/libs/graph/doc/compressed_sparse_row.html 2009-06-12 16:56:54 EDT (Fri, 12 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,
@@ -401,8 +414,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 +490,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 +504,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 +522,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>
Modified: trunk/libs/graph/test/csr_graph_test.cpp
==============================================================================
--- trunk/libs/graph/test/csr_graph_test.cpp (original)
+++ trunk/libs/graph/test/csr_graph_test.cpp 2009-06-12 16:56:54 EDT (Fri, 12 Jun 2009)
@@ -481,7 +481,12 @@
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());
}
#endif // BOOST_GRAPH_USE_NEW_CSR_INTERFACE
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