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 + -
显示快捷键?