incremental_components.hpp
来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 187 行
HPP
187 行
////=======================================================================// Copyright 1997-2001 University of Notre Dame.// Authors: Andrew Lumsdaine, Lie-Quan Lee, Jeremy G. Siek//// This file is part of the Boost Graph Library//// You should have received a copy of the License Agreement for the// Boost Graph Library along with the software; see the file LICENSE.// If not, contact Office of Research, University of Notre Dame, Notre// Dame, IN 46556.//// Permission to modify the code and to distribute modified code is// granted, provided the text of this NOTICE is retained, a notice that// the code was modified is included with the above COPYRIGHT NOTICE and// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE// file is distributed with the modified code.//// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.// By way of example, but not limitation, Licensor MAKES NO// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS// OR OTHER RIGHTS.//=======================================================================//#ifndef BOOST_INCREMENTAL_COMPONENTS_HPP#define BOOST_INCREMENTAL_COMPONENTS_HPP#include <boost/detail/iterator.hpp>#include <boost/graph/detail/incremental_components.hpp>namespace boost { // A connected component algorithm for the case when dynamically // adding (but not removing) edges is common. The // incremental_components() function is a preparing operation. Call // same_component to check whether two vertices are in the same // component, or use disjoint_set::find_set to determine the // representative for a vertex. // This version of connected components does not require a full // Graph. Instead, it just needs an edge list, where the vertices of // each edge need to be of integer type. The edges are assumed to // be undirected. The other difference is that the result is stored in // a container, instead of just a decorator. The container should be // empty before the algorithm is called. It will grow during the // course of the algorithm. The container must be a model of // BackInsertionSequence and RandomAccessContainer // (std::vector is a good choice). After running the algorithm the // index container will map each vertex to the representative // vertex of the component to which it belongs. // // Adapted from an implementation by Alex Stepanov. The disjoint // sets data structure is from Tarjan's "Data Structures and Network // Algorithms", and the application to connected components is // similar to the algorithm described in Ch. 22 of "Intro to // Algorithms" by Cormen, et. all. // // RankContainer is a random accessable container (operator[] is // defined) with a value type that can represent an integer part of // a binary log of the value type of the corresponding // ParentContainer (char is always enough) its size_type is no less // than the size_type of the corresponding ParentContainer // An implementation of disjoint sets can be found in // boost/pending/disjoint_sets.hpp template <class EdgeListGraph, class DisjointSets> void incremental_components(EdgeListGraph& g, DisjointSets& ds) { typename graph_traits<EdgeListGraph>::edge_iterator e, end; for (tie(e,end) = edges(g); e != end; ++e) ds.link(source(*e,g),target(*e,g)); } template <class ParentIterator> void compress_components(ParentIterator first, ParentIterator last) { for (ParentIterator current = first; current != last; ++current) detail::find_representative_with_full_compression(first, current-first); } template <class ParentIterator> typename boost::detail::iterator_traits<ParentIterator>::difference_type component_count(ParentIterator first, ParentIterator last) { std::ptrdiff_t count = 0; for (ParentIterator current = first; current != last; ++current) if (*current == current - first) ++count; return count; } // This algorithm can be applied to the result container of the // connected_components algorithm to normalize // the components. template <class ParentIterator> void normalize_components(ParentIterator first, ParentIterator last) { for (ParentIterator current = first; current != last; ++current) detail::normalize_node(first, current - first); } template <class VertexListGraph, class DisjointSets> void initialize_incremental_components(VertexListGraph& G, DisjointSets& ds) { typename graph_traits<VertexListGraph> ::vertex_iterator v, vend; for (tie(v, vend) = vertices(G); v != vend; ++v) ds.make_set(*v); } template <class Vertex, class DisjointSet> inline bool same_component(Vertex u, Vertex v, DisjointSet& ds) { return ds.find_set(u) == ds.find_set(v); } // considering changing the so that it initializes with a pair of // vertex iterators and a parent PA. template <class IndexT> class component_index { public://protected: (avoid friends for now) typedef std::vector<IndexT> MyIndexContainer; MyIndexContainer header; MyIndexContainer index; typedef typename MyIndexContainer::size_type SizeT; typedef typename MyIndexContainer::const_iterator IndexIter; public: typedef detail::component_iterator<IndexIter, IndexT, SizeT> component_iterator; class component { friend class component_index; protected: IndexT number; const component_index<IndexT>* comp_ind_ptr; component(IndexT i, const component_index<IndexT>* p) : number(i), comp_ind_ptr(p) {} public: typedef component_iterator iterator; typedef component_iterator const_iterator; typedef IndexT value_type; iterator begin() const { return iterator( comp_ind_ptr->index.begin(), (comp_ind_ptr->header)[number] ); } iterator end() const { return iterator( comp_ind_ptr->index.begin(), comp_ind_ptr->index.size() ); } }; typedef SizeT size_type; typedef component value_type; #if defined(BOOST_NO_TEMPLATED_ITERATOR_CONSTRUCTORS) template <class Iterator> component_index(Iterator first, Iterator last) : index(std::distance(first, last)) { std::copy(first, last, index.begin()); detail::construct_component_index(index, header); }#else template <class Iterator> component_index(Iterator first, Iterator last) : index(first, last) { detail::construct_component_index(index, header); }#endif component operator[](IndexT i) const { return component(i, this); } SizeT size() const { return header.size(); } };} // namespace boost#endif // BOOST_INCREMENTAL_COMPONENTS_HPP
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?