adjacency_matrix.hpp
来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 1,083 行 · 第 1/3 页
HPP
1,083 行
struct no_edge_bundle {}; public:#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES typedef typename detail::retag_property_list<vertex_bundle_t, VertexProperty>::type vertex_property_type; typedef typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::type edge_property_type; private: typedef typename detail::retag_property_list<vertex_bundle_t, VertexProperty>::retagged maybe_vertex_bundled; typedef typename detail::retag_property_list<edge_bundle_t, EdgeProperty>::retagged maybe_edge_bundled; public: // The types that are actually bundled typedef typename ct_if<(is_same<maybe_vertex_bundled, no_property>::value), no_vertex_bundle, maybe_vertex_bundled>::type vertex_bundled; typedef typename ct_if<(is_same<maybe_edge_bundled, no_property>::value), no_edge_bundle, maybe_edge_bundled>::type edge_bundled;#else typedef EdgeProperty edge_property_type; typedef VertexProperty vertex_property_type; typedef no_vertex_bundle vertex_bundled; typedef no_edge_bundle edge_bundled;#endif public: // should be private typedef typename ct_if_t<typename has_property<edge_property_type>::type, std::pair<bool, edge_property_type>, char>::type StoredEdge;#if (defined(BOOST_MSVC) && BOOST_MSVC <= 1300) || defined(BOOST_NO_STD_ALLOCATOR) typedef std::vector<StoredEdge> Matrix;#else // This causes internal compiler error for MSVC typedef typename Allocator::template rebind<StoredEdge>::other Alloc; typedef std::vector<StoredEdge, Alloc> Matrix;#endif typedef typename Matrix::iterator MatrixIter; typedef typename Matrix::size_type size_type; public: // Graph concept required types typedef typename Traits::vertex_descriptor vertex_descriptor; typedef typename Traits::edge_descriptor edge_descriptor; typedef typename Traits::directed_category directed_category; typedef typename Traits::edge_parallel_category edge_parallel_category; typedef adj_matrix_traversal_tag traversal_category; static vertex_descriptor null_vertex() { return (std::numeric_limits<vertex_descriptor>::max)(); } //private: if friends worked, these would be private typedef detail::dir_adj_matrix_out_edge_iter< vertex_descriptor, MatrixIter, size_type, edge_descriptor > DirOutEdgeIter; typedef detail::undir_adj_matrix_out_edge_iter< vertex_descriptor, MatrixIter, size_type, edge_descriptor > UnDirOutEdgeIter; typedef typename ct_if_t< typename Directed::is_directed_t, DirOutEdgeIter, UnDirOutEdgeIter >::type unfiltered_out_edge_iter; typedef detail::adj_matrix_edge_iter< Directed, MatrixIter, size_type, edge_descriptor > unfiltered_edge_iter; public: // IncidenceGraph concept required types typedef filter_iterator<detail::does_edge_exist, unfiltered_out_edge_iter> out_edge_iterator; typedef size_type degree_size_type; // BidirectionalGraph required types typedef void in_edge_iterator; // AdjacencyGraph required types typedef typename adjacency_iterator_generator<self, vertex_descriptor, out_edge_iterator>::type adjacency_iterator; // VertexListGraph required types typedef size_type vertices_size_type; typedef integer_range<vertex_descriptor> VertexList; typedef typename VertexList::iterator vertex_iterator; // EdgeListGrpah required types typedef size_type edges_size_type; typedef filter_iterator< detail::does_edge_exist, unfiltered_edge_iter > edge_iterator; // PropertyGraph required types typedef adjacency_matrix_class_tag graph_tag; // Constructor required by MutableGraph adjacency_matrix(vertices_size_type n_vertices) : m_matrix(Directed::is_directed ? (n_vertices * n_vertices) : (n_vertices * (n_vertices + 1) / 2)), m_vertex_set(0, n_vertices), m_vertex_properties(n_vertices), m_num_edges(0) { }#ifndef BOOST_GRAPH_NO_BUNDLED_PROPERTIES // Directly access a vertex or edge bundle vertex_bundled& operator[](vertex_descriptor v) { return get(vertex_bundle, *this)[v]; } const vertex_bundled& operator[](vertex_descriptor v) const { return get(vertex_bundle, *this)[v]; } edge_bundled& operator[](edge_descriptor e) { return get(edge_bundle, *this)[e]; } const edge_bundled& operator[](edge_descriptor e) const { return get(edge_bundle, *this)[e]; }#endif //private: if friends worked, these would be private typename Matrix::const_reference get_edge(vertex_descriptor u, vertex_descriptor v) const { if (Directed::is_directed) return m_matrix[u * m_vertex_set.size() + v]; else { if (v > u) std::swap(u, v); return m_matrix[u * (u + 1)/2 + v]; } } typename Matrix::reference get_edge(vertex_descriptor u, vertex_descriptor v) { if (Directed::is_directed) return m_matrix[u * m_vertex_set.size() + v]; else { if (v > u) std::swap(u, v); return m_matrix[u * (u + 1)/2 + v]; } } Matrix m_matrix; VertexList m_vertex_set; std::vector<vertex_property_type> m_vertex_properties; size_type m_num_edges; }; //========================================================================= // Functions required by the AdjacencyMatrix concept template <typename D, typename VP, typename EP, typename GP, typename A> std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor, bool> edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u, typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v, const adjacency_matrix<D,VP,EP,GP,A>& g) { bool exists = detail::get_edge_exists(g.get_edge(u,v), 0); typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor e(exists, u, v, &detail::get_property(g.get_edge(u,v))); return std::make_pair(e, exists); } //========================================================================= // Functions required by the IncidenceGraph concept // O(1) template <typename VP, typename EP, typename GP, typename A> std::pair<typename adjacency_matrix<directedS,VP,EP,GP,A>::out_edge_iterator, typename adjacency_matrix<directedS,VP,EP,GP,A>::out_edge_iterator> out_edges (typename adjacency_matrix<directedS,VP,EP,GP,A>::vertex_descriptor u, const adjacency_matrix<directedS,VP,EP,GP,A>& g_) { typedef adjacency_matrix<directedS,VP,EP,GP,A> Graph; Graph& g = const_cast<Graph&>(g_); typename Graph::vertices_size_type offset = u * g.m_vertex_set.size(); typename Graph::MatrixIter f = g.m_matrix.begin() + offset; typename Graph::MatrixIter l = f + g.m_vertex_set.size(); typename Graph::unfiltered_out_edge_iter first(f, u, g.m_vertex_set.size()) , last(l, u, g.m_vertex_set.size()); detail::does_edge_exist pred; typedef typename Graph::out_edge_iterator out_edge_iterator; return std::make_pair(out_edge_iterator(pred, first, last), out_edge_iterator(pred, last, last)); } // O(1) template <typename VP, typename EP, typename GP, typename A> std::pair< typename adjacency_matrix<undirectedS,VP,EP,GP,A>::out_edge_iterator, typename adjacency_matrix<undirectedS,VP,EP,GP,A>::out_edge_iterator> out_edges (typename adjacency_matrix<undirectedS,VP,EP,GP,A>::vertex_descriptor u, const adjacency_matrix<undirectedS,VP,EP,GP,A>& g_) { typedef adjacency_matrix<undirectedS,VP,EP,GP,A> Graph; Graph& g = const_cast<Graph&>(g_); typename Graph::vertices_size_type offset = u * (u + 1) / 2; typename Graph::MatrixIter f = g.m_matrix.begin() + offset; typename Graph::MatrixIter l = g.m_matrix.end(); typename Graph::unfiltered_out_edge_iter first(f, u, g.m_vertex_set.size()) , last(l, u, g.m_vertex_set.size()); detail::does_edge_exist pred; typedef typename Graph::out_edge_iterator out_edge_iterator; return std::make_pair(out_edge_iterator(pred, first, last), out_edge_iterator(pred, last, last)); } // O(N) template <typename D, typename VP, typename EP, typename GP, typename A> typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type out_degree(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u, const adjacency_matrix<D,VP,EP,GP,A>& g) { typename adjacency_matrix<D,VP,EP,GP,A>::degree_size_type n = 0; typename adjacency_matrix<D,VP,EP,GP,A>::out_edge_iterator f, l; for (tie(f, l) = out_edges(u, g); f != l; ++f) ++n; return n; } // O(1) template <typename D, typename VP, typename EP, typename GP, typename A, typename Dir, typename Vertex> typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor source(const detail::matrix_edge_desc_impl<Dir,Vertex>& e, const adjacency_matrix<D,VP,EP,GP,A>&) { return e.m_source; } // O(1) template <typename D, typename VP, typename EP, typename GP, typename A, typename Dir, typename Vertex> typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor target(const detail::matrix_edge_desc_impl<Dir,Vertex>& e, const adjacency_matrix<D,VP,EP,GP,A>&) { return e.m_target; } //========================================================================= // Functions required by the AdjacencyGraph concept template <typename D, typename VP, typename EP, typename GP, typename A> std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::adjacency_iterator, typename adjacency_matrix<D,VP,EP,GP,A>::adjacency_iterator> adjacent_vertices (typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u, const adjacency_matrix<D,VP,EP,GP,A>& g_) { typedef adjacency_matrix<D,VP,EP,GP,A> Graph; const Graph& cg = static_cast<const Graph&>(g_); Graph& g = const_cast<Graph&>(cg); typedef typename Graph::adjacency_iterator adjacency_iterator; typename Graph::out_edge_iterator first, last; boost::tie(first, last) = out_edges(u, g); return std::make_pair(adjacency_iterator(first, &g), adjacency_iterator(last, &g)); } //========================================================================= // Functions required by the VertexListGraph concept template <typename D, typename VP, typename EP, typename GP, typename A> std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::vertex_iterator, typename adjacency_matrix<D,VP,EP,GP,A>::vertex_iterator> vertices(const adjacency_matrix<D,VP,EP,GP,A>& g_) { typedef adjacency_matrix<D,VP,EP,GP,A> Graph; Graph& g = const_cast<Graph&>(g_); return std::make_pair(g.m_vertex_set.begin(), g.m_vertex_set.end()); } template <typename D, typename VP, typename EP, typename GP, typename A> typename adjacency_matrix<D,VP,EP,GP,A>::vertices_size_type num_vertices(const adjacency_matrix<D,VP,EP,GP,A>& g) { return g.m_vertex_set.size(); } //========================================================================= // Functions required by the EdgeListGraph concept template <typename D, typename VP, typename EP, typename GP, typename A> std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_iterator, typename adjacency_matrix<D,VP,EP,GP,A>::edge_iterator> edges(const adjacency_matrix<D,VP,EP,GP,A>& g_) { typedef adjacency_matrix<D,VP,EP,GP,A> Graph; Graph& g = const_cast<Graph&>(g_); typename Graph::unfiltered_edge_iter first(g.m_matrix.begin(), g.m_matrix.begin(), g.m_vertex_set.size()), last(g.m_matrix.end(), g.m_matrix.begin(), g.m_vertex_set.size()); detail::does_edge_exist pred; typedef typename Graph::edge_iterator edge_iterator; return std::make_pair(edge_iterator(pred, first, last), edge_iterator(pred, last, last)); } // O(1) template <typename D, typename VP, typename EP, typename GP, typename A> typename adjacency_matrix<D,VP,EP,GP,A>::edges_size_type num_edges(const adjacency_matrix<D,VP,EP,GP,A>& g) { return g.m_num_edges; } //========================================================================= // Functions required by the MutableGraph concept // O(1) template <typename D, typename VP, typename EP, typename GP, typename A> std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor, bool> add_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u, typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v, const EP& ep, adjacency_matrix<D,VP,EP,GP,A>& g) { typedef typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor edge_descriptor; if (detail::get_edge_exists(g.get_edge(u,v), 0) == false) { ++(g.m_num_edges); detail::set_property(g.get_edge(u,v), ep, 0); detail::set_edge_exists(g.get_edge(u,v), true, 0); return std::make_pair (edge_descriptor(true, u, v, &detail::get_property(g.get_edge(u,v))), true); } else return std::make_pair (edge_descriptor(true, u, v, &detail::get_property(g.get_edge(u,v))), false); } // O(1) template <typename D, typename VP, typename EP, typename GP, typename A> std::pair<typename adjacency_matrix<D,VP,EP,GP,A>::edge_descriptor, bool> add_edge(typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor u, typename adjacency_matrix<D,VP,EP,GP,A>::vertex_descriptor v, adjacency_matrix<D,VP,EP,GP,A>& g) { EP ep; return add_edge(u, v, ep, g); } // O(1) template <typename D, typename VP, typename EP, typename GP, typename A> void
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?