x
Yes
No
Do you want to visit DriveHQ English website?
Inicio
Características
Precios
Prueba gratuita
Software cliente
Acerca de nosotros
Servidor de archivos
|
Solución de copias de seguridad
|
Servidor FTP
|
Servidor de correo electrónico
|
Alojamiento web
|
Software cliente
Servidor de archivos
Solución de copia de seguridad
Servidor FTP
Servidor de correo electrónico
Alojamiento web
Software cliente
compressed_sparse_row_graph.hpp - Hosted on DriveHQ Cloud IT Platform
Arriba
Subir
Descargar
Compartir
Publicar
Nueva carpeta
Nuevo archivo
Copiar
Cortar
Eliminar
Pegar
Clasificación
Actualizar
Ruta de la carpeta: \\game3dprogramming\materials\GameFactory\GameFactoryDemo\references\boost_1_35_0\boost\graph\compressed_sparse_row_graph.hpp
Girar
Efecto
Propiedad
Historial
// Copyright 2005-2006 The Trustees of Indiana University. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // Authors: Jeremiah Willcock // Douglas Gregor // Andrew Lumsdaine // Compressed sparse row graph type #ifndef BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP #define BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP #include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef BOOST_GRAPH_NO_BUNDLED_PROPERTIES # error The Compressed Sparse Row graph only supports bundled properties. # error You will need a compiler that conforms better to the C++ standard. #endif namespace boost { // A tag type indicating that the graph in question is a compressed // sparse row graph. This is an internal detail of the BGL. struct csr_graph_tag; /**************************************************************************** * Local helper macros to reduce typing and clutter later on. * ****************************************************************************/ #define BOOST_CSR_GRAPH_TEMPLATE_PARMS \ typename Directed, typename VertexProperty, typename EdgeProperty, \ typename GraphProperty, typename Vertex, typename EdgeIndex #define BOOST_CSR_GRAPH_TYPE \ compressed_sparse_row_graph
// Forward declaration of CSR edge descriptor type, needed to pass to // indexed_edge_properties. template
class csr_edge_descriptor; /** Compressed sparse row graph. * * Vertex and EdgeIndex should be unsigned integral types and should * specialize numeric_limits. */ template
class compressed_sparse_row_graph : public detail::indexed_vertex_properties
, public detail::indexed_edge_properties
> { typedef detail::indexed_vertex_properties
inherited_vertex_properties; typedef detail::indexed_edge_properties
> inherited_edge_properties; public: // For Property Graph typedef GraphProperty graph_property_type; protected: template
void maybe_reserve_edge_list_storage(InputIterator, InputIterator, std::input_iterator_tag) { // Do nothing: we have no idea how much storage to reserve. } template
void maybe_reserve_edge_list_storage(InputIterator first, InputIterator last, std::forward_iterator_tag) { using std::distance; typename std::iterator_traits
::difference_type n = distance(first, last); m_column.reserve(n); inherited_edge_properties::reserve(n); } public: /* At this time, the compressed sparse row graph can only be used to * create a directed graph. In the future, bidirectional and * undirected CSR graphs will also be supported. */ BOOST_STATIC_ASSERT((is_same
::value)); // Concept requirements: // For Graph typedef Vertex vertex_descriptor; typedef csr_edge_descriptor
edge_descriptor; typedef directed_tag directed_category; typedef allow_parallel_edge_tag edge_parallel_category; class traversal_category: public incidence_graph_tag, public adjacency_graph_tag, public vertex_list_graph_tag, public edge_list_graph_tag {}; static vertex_descriptor null_vertex() { return vertex_descriptor(-1); } // For VertexListGraph typedef counting_iterator
vertex_iterator; typedef Vertex vertices_size_type; // For EdgeListGraph typedef EdgeIndex edges_size_type; // For IncidenceGraph class out_edge_iterator; typedef EdgeIndex degree_size_type; // For AdjacencyGraph typedef typename std::vector
::const_iterator adjacency_iterator; // For EdgeListGraph class edge_iterator; // For BidirectionalGraph (not implemented) typedef void in_edge_iterator; // For internal use typedef csr_graph_tag graph_tag; // Constructors // Default constructor: an empty graph. compressed_sparse_row_graph() : m_rowstart(1, EdgeIndex(0)), m_column(0), m_property(), m_last_source(0) {} // From number of vertices and sorted list of edges template
compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end, vertices_size_type numverts, edges_size_type numedges = 0, const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numverts), m_rowstart(numverts + 1), m_column(0), m_property(prop), m_last_source(numverts) { // Reserving storage in advance can save us lots of time and // memory, but it can only be done if we have forward iterators or // the user has supplied the number of edges. if (numedges == 0) { typedef typename std::iterator_traits
::iterator_category category; maybe_reserve_edge_list_storage(edge_begin, edge_end, category()); } else { m_column.reserve(numedges); } EdgeIndex current_edge = 0; Vertex current_vertex_plus_one = 1; m_rowstart[0] = 0; for (InputIterator ei = edge_begin; ei != edge_end; ++ei) { Vertex src = ei->first; Vertex tgt = ei->second; for (; current_vertex_plus_one != src + 1; ++current_vertex_plus_one) m_rowstart[current_vertex_plus_one] = current_edge; m_column.push_back(tgt); ++current_edge; } // The remaining vertices have no edges for (; current_vertex_plus_one != numverts + 1; ++current_vertex_plus_one) m_rowstart[current_vertex_plus_one] = current_edge; // Default-construct properties for edges inherited_edge_properties::resize(m_column.size()); } // From number of vertices and sorted list of edges template
compressed_sparse_row_graph(InputIterator edge_begin, InputIterator edge_end, EdgePropertyIterator ep_iter, vertices_size_type numverts, edges_size_type numedges = 0, const GraphProperty& prop = GraphProperty()) : inherited_vertex_properties(numverts), m_rowstart(numverts + 1), m_column(0), m_property(prop), m_last_source(numverts) { // Reserving storage in advance can save us lots of time and // memory, but it can only be done if we have forward iterators or // the user has supplied the number of edges. if (numedges == 0) { typedef typename std::iterator_traits
::iterator_category category; maybe_reserve_edge_list_storage(edge_begin, edge_end, category()); } else { m_column.reserve(numedges); } EdgeIndex current_edge = 0; Vertex current_vertex_plus_one = 1; m_rowstart[0] = 0; for (InputIterator ei = edge_begin; ei != edge_end; ++ei, ++ep_iter) { Vertex src = ei->first; Vertex tgt = ei->second; for (; current_vertex_plus_one != src + 1; ++current_vertex_plus_one) m_rowstart[current_vertex_plus_one] = current_edge; m_column.push_back(tgt); inherited_edge_properties::push_back(*ep_iter); ++current_edge; } // The remaining vertices have no edges for (; current_vertex_plus_one != numverts + 1; ++current_vertex_plus_one) m_rowstart[current_vertex_plus_one] = current_edge; } // Requires IncidenceGraph, a vertex index map, and a vertex(n, g) function template
compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi, vertices_size_type numverts, edges_size_type numedges) : m_property(), m_last_source(0) { assign(g, vi, numverts, numedges); } // Requires VertexListGraph and EdgeListGraph template
compressed_sparse_row_graph(const Graph& g, const VertexIndexMap& vi) : m_property(), m_last_source(0) { assign(g, vi, num_vertices(g), num_edges(g)); } // Requires vertex index map plus requirements of previous constructor template
explicit compressed_sparse_row_graph(const Graph& g) : m_property(), m_last_source(0) { assign(g, get(vertex_index, g), num_vertices(g), num_edges(g)); } // From any graph (slow and uses a lot of memory) // Requires IncidenceGraph, a vertex index map, and a vertex(n, g) function // Internal helper function template
void assign(const Graph& g, const VertexIndexMap& vi, vertices_size_type numverts, edges_size_type numedges) { inherited_vertex_properties::resize(numverts); m_rowstart.resize(numverts + 1); m_column.resize(numedges); EdgeIndex current_edge = 0; typedef typename boost::graph_traits
::vertex_descriptor g_vertex; typedef typename boost::graph_traits
::edge_descriptor g_edge; typedef typename boost::graph_traits
::out_edge_iterator g_out_edge_iter; for (Vertex i = 0; i != numverts; ++i) { m_rowstart[i] = current_edge; g_vertex v = vertex(i, g); EdgeIndex num_edges_before_this_vertex = current_edge; g_out_edge_iter ei, ei_end; for (tie(ei, ei_end) = out_edges(v, g); ei != ei_end; ++ei) { m_column[current_edge++] = get(vi, target(*ei, g)); } std::sort(m_column.begin() + num_edges_before_this_vertex, m_column.begin() + current_edge); } m_rowstart[numverts] = current_edge; m_last_source = numverts; } // Requires the above, plus VertexListGraph and EdgeListGraph template
void assign(const Graph& g, const VertexIndexMap& vi) { assign(g, vi, num_vertices(g), num_edges(g)); } // Requires the above, plus a vertex_index map. template
void assign(const Graph& g) { assign(g, get(vertex_index, g), num_vertices(g), num_edges(g)); } using inherited_vertex_properties::operator[]; using inherited_edge_properties::operator[]; // private: non-portable, requires friend templates inherited_vertex_properties& vertex_properties() {return *this;} const inherited_vertex_properties& vertex_properties() const {return *this;} inherited_edge_properties& edge_properties() { return *this; } const inherited_edge_properties& edge_properties() const { return *this; } std::vector
m_rowstart; std::vector
m_column; GraphProperty m_property; Vertex m_last_source; // Last source of added edge, plus one }; template
class csr_edge_descriptor { public: Vertex src; EdgeIndex idx; csr_edge_descriptor(Vertex src, EdgeIndex idx): src(src), idx(idx) {} csr_edge_descriptor(): src(0), idx(0) {} bool operator==(const csr_edge_descriptor& e) const {return idx == e.idx;} bool operator!=(const csr_edge_descriptor& e) const {return idx != e.idx;} bool operator<(const csr_edge_descriptor& e) const {return idx < e.idx;} bool operator>(const csr_edge_descriptor& e) const {return idx > e.idx;} bool operator<=(const csr_edge_descriptor& e) const {return idx <= e.idx;} bool operator>=(const csr_edge_descriptor& e) const {return idx >= e.idx;} }; // Construction functions template
inline Vertex add_vertex(BOOST_CSR_GRAPH_TYPE& g) { Vertex old_num_verts_plus_one = g.m_rowstart.size(); g.m_rowstart.push_back(EdgeIndex(0)); g.vertex_properties().resize(num_vertices(g)); return old_num_verts_plus_one - 1; } template
inline Vertex add_vertices(typename BOOST_CSR_GRAPH_TYPE::vertices_size_type count, BOOST_CSR_GRAPH_TYPE& g) { Vertex old_num_verts_plus_one = g.m_rowstart.size(); g.m_rowstart.resize(old_num_verts_plus_one + count, EdgeIndex(0)); g.vertex_properties().resize(num_vertices(g)); return old_num_verts_plus_one - 1; } // This function requires that (src, tgt) be lexicographically at least as // large as the largest edge in the graph so far template
inline typename BOOST_CSR_GRAPH_TYPE::edge_descriptor add_edge(Vertex src, Vertex tgt, BOOST_CSR_GRAPH_TYPE& g) { assert ((g.m_last_source == 0 || src >= g.m_last_source - 1) && src < num_vertices(g)); EdgeIndex num_edges_orig = g.m_column.size(); for (; g.m_last_source <= src; ++g.m_last_source) g.m_rowstart[g.m_last_source] = num_edges_orig; g.m_rowstart[src + 1] = num_edges_orig + 1; g.m_column.push_back(tgt); typedef typename BOOST_CSR_GRAPH_TYPE::edge_push_back_type push_back_type; g.edge_properties().push_back(push_back_type()); return typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(src, num_edges_orig); } // This function requires that (src, tgt) be lexicographically at least as // large as the largest edge in the graph so far template
inline typename BOOST_CSR_GRAPH_TYPE::edge_descriptor add_edge(Vertex src, Vertex tgt, typename BOOST_CSR_GRAPH_TYPE::edge_bundled const& p, BOOST_CSR_GRAPH_TYPE& g) { assert ((g.m_last_source == 0 || src >= g.m_last_source - 1) && src < num_vertices(g)); EdgeIndex num_edges_orig = g.m_column.size(); for (; g.m_last_source <= src; ++g.m_last_source) g.m_rowstart[g.m_last_source] = num_edges_orig; g.m_rowstart[src + 1] = num_edges_orig + 1; g.m_column.push_back(tgt); g.edge_properties().push_back(p); return typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(src, num_edges_orig); } // From VertexListGraph template
inline Vertex num_vertices(const BOOST_CSR_GRAPH_TYPE& g) { return g.m_rowstart.size() - 1; } template
std::pair
, counting_iterator
> inline vertices(const BOOST_CSR_GRAPH_TYPE& g) { return std::make_pair(counting_iterator
(0), counting_iterator
(num_vertices(g))); } // From IncidenceGraph template
class BOOST_CSR_GRAPH_TYPE::out_edge_iterator : public iterator_facade
::fast> { public: typedef typename int_t
::fast difference_type; out_edge_iterator() {} // Implicit copy constructor OK explicit out_edge_iterator(edge_descriptor edge) : m_edge(edge) { } private: // iterator_facade requirements const edge_descriptor& dereference() const { return m_edge; } bool equal(const out_edge_iterator& other) const { return m_edge == other.m_edge; } void increment() { ++m_edge.idx; } void decrement() { ++m_edge.idx; } void advance(difference_type n) { m_edge.idx += n; } difference_type distance_to(const out_edge_iterator& other) const { return other.m_edge.idx - m_edge.idx; } edge_descriptor m_edge; friend class iterator_core_access; }; template
inline Vertex source(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e, const BOOST_CSR_GRAPH_TYPE&) { return e.src; } template
inline Vertex target(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e, const BOOST_CSR_GRAPH_TYPE& g) { return g.m_column[e.idx]; } template
inline std::pair
out_edges(Vertex v, const BOOST_CSR_GRAPH_TYPE& g) { typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor ed; typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator it; EdgeIndex v_row_start = g.m_rowstart[v]; EdgeIndex next_row_start = g.m_rowstart[v + 1]; return std::make_pair(it(ed(v, v_row_start)), it(ed(v, (std::max)(v_row_start, next_row_start)))); } template
inline EdgeIndex out_degree(Vertex v, const BOOST_CSR_GRAPH_TYPE& g) { EdgeIndex v_row_start = g.m_rowstart[v]; EdgeIndex next_row_start = g.m_rowstart[v + 1]; return (std::max)(v_row_start, next_row_start) - v_row_start; } // From AdjacencyGraph template
inline std::pair
adjacent_vertices(Vertex v, const BOOST_CSR_GRAPH_TYPE& g) { EdgeIndex v_row_start = g.m_rowstart[v]; EdgeIndex next_row_start = g.m_rowstart[v + 1]; return std::make_pair(g.m_column.begin() + v_row_start, g.m_column.begin() + (std::max)(v_row_start, next_row_start)); } // Extra, common functions template
inline typename graph_traits
::vertex_descriptor vertex(typename graph_traits
::vertex_descriptor i, const BOOST_CSR_GRAPH_TYPE&) { return i; } // Unlike for an adjacency_matrix, edge_range and edge take lg(out_degree(i)) // time template
inline std::pair
edge_range(Vertex i, Vertex j, const BOOST_CSR_GRAPH_TYPE& g) { typedef typename std::vector
::const_iterator adj_iter; typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter; typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor edge_desc; std::pair
raw_adjacencies = adjacent_vertices(i, g); std::pair
adjacencies = std::equal_range(raw_adjacencies.first, raw_adjacencies.second, j); EdgeIndex idx_begin = adjacencies.first - g.m_column.begin(); EdgeIndex idx_end = adjacencies.second - g.m_column.begin(); return std::make_pair(out_edge_iter(edge_desc(i, idx_begin)), out_edge_iter(edge_desc(i, idx_end))); } template
inline std::pair
edge(Vertex i, Vertex j, const BOOST_CSR_GRAPH_TYPE& g) { typedef typename BOOST_CSR_GRAPH_TYPE::out_edge_iterator out_edge_iter; std::pair
range = edge_range(i, j, g); if (range.first == range.second) return std::make_pair(typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(), false); else return std::make_pair(*range.first, true); } // Find an edge given its index in the graph template
inline typename BOOST_CSR_GRAPH_TYPE::edge_descriptor edge_from_index(EdgeIndex idx, const BOOST_CSR_GRAPH_TYPE& g) { typedef typename std::vector
::const_iterator row_start_iter; assert (idx < num_edges(g)); row_start_iter src_plus_1 = std::upper_bound(g.m_rowstart.begin(), g.m_rowstart.begin() + g.m_last_source + 1, idx); // Get last source whose rowstart is at most idx // upper_bound returns this position plus 1 Vertex src = (src_plus_1 - g.m_rowstart.begin()) - 1; return typename BOOST_CSR_GRAPH_TYPE::edge_descriptor(src, idx); } // From EdgeListGraph template
class BOOST_CSR_GRAPH_TYPE::edge_iterator { public: typedef std::forward_iterator_tag iterator_category; typedef edge_descriptor value_type; typedef const edge_descriptor* pointer; typedef edge_descriptor reference; typedef typename int_t
::fast difference_type; edge_iterator() : rowstart_array(0), current_edge(), end_of_this_vertex(0) {} edge_iterator(const compressed_sparse_row_graph& graph, edge_descriptor current_edge, EdgeIndex end_of_this_vertex) : rowstart_array(&graph.m_rowstart[0]), current_edge(current_edge), end_of_this_vertex(end_of_this_vertex) {} // From InputIterator reference operator*() const { return current_edge; } pointer operator->() const { return ¤t_edge; } bool operator==(const edge_iterator& o) const { return current_edge == o.current_edge; } bool operator!=(const edge_iterator& o) const { return current_edge != o.current_edge; } edge_iterator& operator++() { ++current_edge.idx; while (current_edge.idx == end_of_this_vertex) { ++current_edge.src; end_of_this_vertex = rowstart_array[current_edge.src + 1]; } return *this; } edge_iterator operator++(int) { edge_iterator temp = *this; ++*this; return temp; } private: const EdgeIndex* rowstart_array; edge_descriptor current_edge; EdgeIndex end_of_this_vertex; }; template
inline EdgeIndex num_edges(const BOOST_CSR_GRAPH_TYPE& g) { return g.m_column.size(); } template
std::pair
edges(const BOOST_CSR_GRAPH_TYPE& g) { typedef typename BOOST_CSR_GRAPH_TYPE::edge_iterator ei; typedef typename BOOST_CSR_GRAPH_TYPE::edge_descriptor edgedesc; if (g.m_rowstart.size() == 1 || g.m_column.empty()) { return std::make_pair(ei(), ei()); } else { // Find the first vertex that has outgoing edges Vertex src = 0; while (g.m_rowstart[src + 1] == 0) ++src; return std::make_pair(ei(g, edgedesc(src, 0), g.m_rowstart[src + 1]), ei(g, edgedesc(num_vertices(g), g.m_column.size()), 0)); } } // For Property Graph // Graph properties template
inline void set_property(BOOST_CSR_GRAPH_TYPE& g, Tag, const Value& value) { get_property_value(g.m_property, Tag()) = value; } template
inline typename graph_property
::type& get_property(BOOST_CSR_GRAPH_TYPE& g, Tag) { return get_property_value(g.m_property, Tag()); } template
inline const typename graph_property
::type& get_property(const BOOST_CSR_GRAPH_TYPE& g, Tag) { return get_property_value(g.m_property, Tag()); } // Add edge_index property map template
struct csr_edge_index_map { typedef Index value_type; typedef Index reference; typedef Descriptor key_type; typedef readable_property_map_tag category; }; template
inline Index get(const csr_edge_index_map
&, const typename csr_edge_index_map
::key_type& key) { return key.idx; } // Doing the right thing here (by unifying with vertex_index_t and // edge_index_t) breaks GCC. template
struct property_map
{ private: typedef identity_property_map vertex_index_type; typedef typename graph_traits
::edge_descriptor edge_descriptor; typedef csr_edge_index_map
edge_index_type; typedef typename mpl::if_
, edge_index_type, detail::error_property_not_found>::type edge_or_none; public: typedef typename mpl::if_
, vertex_index_type, edge_or_none>::type type; typedef type const_type; }; template
inline identity_property_map get(vertex_index_t, const BOOST_CSR_GRAPH_TYPE&) { return identity_property_map(); } template
inline Vertex get(vertex_index_t, const BOOST_CSR_GRAPH_TYPE&, Vertex v) { return v; } template
inline typename property_map
::const_type get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&) { typedef typename property_map
::const_type result_type; return result_type(); } template
inline EdgeIndex get(edge_index_t, const BOOST_CSR_GRAPH_TYPE&, typename BOOST_CSR_GRAPH_TYPE::edge_descriptor e) { return e.idx; } // Support for bundled properties template
struct property_map
{ private: typedef graph_traits
traits; typedef VertexProperty vertex_bundled; typedef EdgeProperty edge_bundled; typedef typename mpl::if_c<(detail::is_vertex_bundle
::value), typename traits::vertex_descriptor, typename traits::edge_descriptor>::type descriptor; public: typedef bundle_property_map
type; typedef bundle_property_map
const_type; }; template
inline typename property_map
::type get(T Bundle::* p, BOOST_CSR_GRAPH_TYPE& g) { typedef typename property_map
::type result_type; return result_type(&g, p); } template
inline typename property_map
::const_type get(T Bundle::* p, BOOST_CSR_GRAPH_TYPE const & g) { typedef typename property_map
::const_type result_type; return result_type(&g, p); } template
inline T get(T Bundle::* p, BOOST_CSR_GRAPH_TYPE const & g, const Key& key) { return get(get(p, g), key); } template
inline void put(T Bundle::* p, BOOST_CSR_GRAPH_TYPE& g, const Key& key, const T& value) { put(get(p, g), key, value); } #undef BOOST_CSR_GRAPH_TYPE #undef BOOST_CSR_GRAPH_TEMPLATE_PARMS } // end namespace boost #endif // BOOST_GRAPH_COMPRESSED_SPARSE_ROW_GRAPH_HPP
compressed_sparse_row_graph.hpp
Dirección de la página
Dirección del archivo
Anterior
16/95
Siguiente
Descargar
( 28 KB )
Comments
Total ratings:
0
Average rating:
No clasificado
of 10
Would you like to comment?
Join now
, or
Logon
if you are already a member.