123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- #ifndef BOOST_INCREMENTAL_COMPONENTS_HPP
- #define BOOST_INCREMENTAL_COMPONENTS_HPP
- #include <boost/tuple/tuple.hpp>
- #include <boost/graph/detail/incremental_components.hpp>
- #include <boost/iterator/counting_iterator.hpp>
- #include <boost/smart_ptr/make_shared.hpp>
- #include <boost/pending/disjoint_sets.hpp>
- #include <iterator>
- namespace boost
- {
- template < class EdgeListGraph, class DisjointSets >
- void incremental_components(EdgeListGraph& g, DisjointSets& ds)
- {
- typename graph_traits< EdgeListGraph >::edge_iterator e, end;
- for (boost::tie(e, end) = edges(g); e != end; ++e)
- ds.union_set(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 std::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;
- }
- 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 (boost::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);
- }
- template < typename IndexType > class component_index
- {
- private:
- typedef std::vector< IndexType > IndexContainer;
- public:
- typedef counting_iterator< IndexType > iterator;
- typedef iterator const_iterator;
- typedef IndexType value_type;
- typedef IndexType size_type;
- typedef detail::component_index_iterator<
- typename IndexContainer::iterator >
- component_iterator;
- public:
- template < typename ParentIterator, typename ElementIndexMap >
- component_index(ParentIterator parent_start, ParentIterator parent_end,
- const ElementIndexMap& index_map)
- : m_num_elements(std::distance(parent_start, parent_end))
- , m_components(make_shared< IndexContainer >())
- , m_index_list(make_shared< IndexContainer >(m_num_elements))
- {
- build_index_lists(parent_start, index_map);
- }
- template < typename ParentIterator >
- component_index(ParentIterator parent_start, ParentIterator parent_end)
- : m_num_elements(std::distance(parent_start, parent_end))
- , m_components(make_shared< IndexContainer >())
- , m_index_list(make_shared< IndexContainer >(m_num_elements))
- {
- build_index_lists(parent_start, boost::identity_property_map());
- }
-
- inline std::size_t size() const { return (m_components->size()); }
-
- iterator begin() const { return (iterator(0)); }
-
- iterator end() const { return (iterator(this->size())); }
-
-
- std::pair< component_iterator, component_iterator > operator[](
- IndexType component_index) const
- {
- IndexType first_index = (*m_components)[component_index];
- return (std::make_pair(
- component_iterator(m_index_list->begin(), first_index),
- component_iterator(m_num_elements)));
- }
- private:
- template < typename ParentIterator, typename ElementIndexMap >
- void build_index_lists(
- ParentIterator parent_start, const ElementIndexMap& index_map)
- {
- typedef
- typename std::iterator_traits< ParentIterator >::value_type Element;
- typename IndexContainer::iterator index_list = m_index_list->begin();
-
- for (IndexType element_index = 0; element_index < m_num_elements;
- ++element_index)
- {
- Element parent_element = parent_start[element_index];
- IndexType parent_index = get(index_map, parent_element);
- if (element_index != parent_index)
- {
- index_list[element_index] = parent_index;
- }
- else
- {
- m_components->push_back(element_index);
-
- index_list[element_index] = m_num_elements;
- }
- }
-
- for (IndexType element_index = 0; element_index < m_num_elements;
- ++element_index)
- {
- Element parent_element = parent_start[element_index];
- IndexType parent_index = get(index_map, parent_element);
- if (element_index != parent_index)
- {
-
- while (index_list[parent_index] != m_num_elements)
- {
- parent_index = index_list[parent_index];
- }
-
- index_list[element_index] = index_list[parent_index];
- index_list[parent_index] = element_index;
- }
- }
- }
- protected:
- IndexType m_num_elements;
- shared_ptr< IndexContainer > m_components, m_index_list;
- };
- }
- #endif
|