OpenWalnut  1.5.0dev
WUnionFind.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <algorithm>
26 #include <map>
27 #include <memory>
28 #include <set>
29 #include <string>
30 #include <vector>
31 
32 
33 #include "../exceptions/WOutOfBounds.h"
34 #include "WUnionFind.h"
35 
36 WUnionFind::WUnionFind( size_t size )
37  : m_component( size )
38 {
39  for( size_t i = 0; i < size; ++i )
40  {
41  m_component[i] = i;
42  }
43 }
44 
45 size_t WUnionFind::find( size_t x )
46 {
47  if( x >= m_component.size() )
48  {
49  throw WOutOfBounds( std::string( "Element index in UnionFind greater than overall elements!" ) );
50  }
51  if( m_component[x] == x ) // we are the root
52  {
53  return x;
54  }
55 
56  m_component[x] = find( m_component[x] ); // path compression otherwise
57  return m_component[x];
58 }
59 
60 void WUnionFind::merge( size_t i, size_t j )
61 {
62  if( i >= m_component.size() || j >= m_component.size() )
63  {
64  throw WOutOfBounds( std::string( "Element index in UnionFind greater than overall elements!" ) );
65  }
66  if( i == j )
67  {
68  return;
69  }
70 
71  size_t ci = find( i );
72  size_t cj = find( j );
73 
74  if( ci == cj )
75  {
76  return;
77  }
78 
79  m_component[ ci ] = cj;
80 }
81 
82 std::shared_ptr< std::set< size_t > > WUnionFind::getMaxSet()
83 {
84  std::map< size_t, std::set< size_t > > sets;
85  size_t maxSetSizeSoFar = 0;
86  size_t maxSetElement = 0;
87  for( size_t i = 0; i < m_component.size(); ++i )
88  {
89  size_t cE = find( i ); // canonical Element
90  sets[ cE ].insert( i );
91  if( sets[ cE ].size() > maxSetSizeSoFar )
92  {
93  maxSetSizeSoFar = sets[ cE ].size();
94  maxSetElement = cE;
95  }
96  }
97  return std::shared_ptr< std::set< size_t > >( new std::set< size_t >( sets[ maxSetElement ] ) );
98 }
Indicates invalid element access of a container.
Definition: WOutOfBounds.h:37
std::shared_ptr< std::set< size_t > > getMaxSet()
Computes the set with maximum number of elements.
Definition: WUnionFind.cpp:82
WUnionFind(size_t size)
Creates a new union find datastructure with size elements where each element is initialized as a sing...
Definition: WUnionFind.cpp:36
void merge(size_t i, size_t j)
Merges two components (iow: makes a union) where the given elements are members of.
Definition: WUnionFind.cpp:60
size_t find(size_t x)
Find the canonical element of the given element and do path compression.
Definition: WUnionFind.cpp:45
std::vector< size_t > m_component
Stores for each index its ID.
Definition: WUnionFind.h:120