21 #ifndef SNARK_PERCEPTION_EQUIVALENCECLASSES_HEADER_GUARD_
22 #define SNARK_PERCEPTION_EQUIVALENCECLASSES_HEADER_GUARD_
27 #include <boost/unordered_map.hpp>
28 #include <boost/unordered_set.hpp>
29 #include <comma/base/types.h>
34 template <
typename It,
typename N,
typename Tr >
35 inline std::map< comma::uint32, std::list< It > >
equivalence_classes(
const It& begin,
const It& end, comma::uint32 minId )
37 typedef std::list< It > partition_type;
38 typedef std::map< comma::uint32, partition_type > partitions_type;
39 partitions_type partitions;
40 comma::uint32 maxId = minId;
41 for( It it = begin; it != end; ++it )
43 if( Tr::skip( *it ) ) {
continue; }
44 if( !Tr::visited( *it ) )
46 for(
typename N::iterator nit = N::begin( it ); nit != N::end( it ); ++nit )
48 if( Tr::skip( *nit ) ) {
continue; }
49 if( !Tr::visited( *nit ) || !Tr::same( *it, *nit ) ) {
continue; }
50 Tr::set_visited( *it,
true );
51 Tr::set_id( *it, Tr::id( *nit ) );
53 if( !Tr::visited( *it ) )
55 Tr::set_visited( *it,
true );
56 Tr::set_id( *it, maxId++ );
59 comma::uint32
id = Tr::id( *it );
60 partition_type& p( partitions[
id] );
62 for(
typename N::iterator nit = N::begin( it ); nit != N::end( it ); ++nit )
64 if( Tr::skip( *nit ) ) {
continue; }
65 if( !Tr::visited( *nit ) || !Tr::same( *it, *nit ) ||
id == Tr::id( *nit ) ) {
continue; }
66 typename partitions_type::iterator old = partitions.find( Tr::id( *nit ) );
67 for(
typename partition_type::iterator i = old->second.begin(); i != old->second.end(); ++i )
69 Tr::set_id( *It( *i ),
id );
71 p.splice( p.end(), old->second, old->second.begin(), old->second.end() );
72 partitions.erase( old );
80 #endif // SNARK_PERCEPTION_EQUIVALENCECLASSES_HEADER_GUARD_