OpenWalnut  1.5.0dev
WHierarchicalTree.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 <list>
26 #include <vector>
27 
28 #include "WHierarchicalTree.h"
29 
31  m_clusterCount( 0 ),
32  m_leafCount( 0 ),
33  m_maxLevel( 0 ),
34  m_leafesLocked( false )
35 {
36 }
37 
39 {
40 }
41 
42 std::vector< size_t > WHierarchicalTree::findXBiggestClusters( size_t cluster, size_t number ) const
43 {
44  //std::cout << number << " largest clusters for cluster: " << cluster << std::endl;
45 
46  if( number > m_containsLeafes[cluster].size() )
47  {
48  number = m_containsLeafes[cluster].size();
49  }
50 
51  // init
52  std::list<size_t>worklist;
53  worklist.push_back( cluster );
54 
55  while( worklist.size() < number )
56  {
57  size_t current = worklist.front();
58  worklist.pop_front();
59  if( m_containsLeafes[current].size() > 1 )
60  {
61  size_t left = m_children[current].first;
62  size_t right = m_children[current].second;
63  worklist.push_back( left );
64  worklist.push_back( right );
65  }
66  else
67  {
68  worklist.push_back( current );
69  }
70  }
71 
72  worklist.sort( compSize( this ) );
73 
74  bool newSplit = true;
75 
76  while( newSplit )
77  {
78  newSplit = false;
79  size_t current = worklist.front();
80 
81  if( m_containsLeafes[current].size() > 1 )
82  {
83  size_t left = m_children[current].first;
84  size_t right = m_children[current].second;
85  size_t last = worklist.back();
86 
87  if( m_containsLeafes[left].size() > m_containsLeafes[last].size() )
88  {
89  worklist.pop_front();
90  worklist.push_back( left );
91  worklist.sort( compSize( this ) );
92  newSplit = true;
93  }
94 
95  last = worklist.back();
96  if( m_containsLeafes[right].size() > m_containsLeafes[last].size() )
97  {
98  if( !newSplit )
99  {
100  worklist.pop_front();
101  }
102  if( worklist.size() == number )
103  {
104  worklist.pop_back();
105  }
106  worklist.push_back( right );
107  worklist.sort( compSize( this ) );
108  newSplit = true;
109  }
110  }
111  }
112 
113  std::vector<size_t>returnVector;
114  std::list<size_t>::iterator it;
115  for( it = worklist.begin(); it != worklist.end(); ++it )
116  {
117  size_t current = *it;
118  //std::cout << "cluster:" << current << " size:" << m_containsLeafes[current].size() << std::endl;
119  returnVector.push_back( current );
120  }
121 
122  return returnVector;
123 }
124 
125 std::vector< size_t > WHierarchicalTree::downXLevelsFromTop( size_t level, bool hideOutliers ) const
126 {
127  if( level > m_maxLevel )
128  {
129  level = m_maxLevel -1;
130  }
131 
132  std::vector< size_t > returnVector;
133 
134  std::list< size_t > worklist;
135  worklist.push_back( m_clusterCount - 1 );
136 
137  for( size_t i = 0; i < level; ++i )
138  {
139  std::list<size_t>newChildList;
140  while( !worklist.empty() )
141  {
142  size_t current = worklist.front();
143  worklist.pop_front();
144  if( m_containsLeafes[current].size() > 1 )
145  {
146  size_t left = m_children[current].first;
147  size_t right = m_children[current].second;
148 
149  if( hideOutliers )
150  {
151  if( m_containsLeafes[left].size() > 1 )
152  {
153  newChildList.push_back( left );
154  }
155  if( m_containsLeafes[right].size() > 1 )
156  {
157  newChildList.push_back( right );
158  }
159  }
160  else
161  {
162  newChildList.push_back( left );
163  newChildList.push_back( right );
164  }
165  }
166  }
167  worklist = newChildList;
168  }
169 
170  worklist.sort( compSize( this ) );
171 
172  std::list<size_t>::iterator it;
173  for( it = worklist.begin(); it != worklist.end(); ++it )
174  {
175  size_t current = *it;
176  returnVector.push_back( current );
177  }
178 
179  return returnVector;
180 }
181 
182 void WHierarchicalTree::colorCluster( size_t cluster, WColor color )
183 {
184  m_colors[cluster] = color;
185  if( m_containsLeafes[cluster].size() > 1 )
186  {
187  colorCluster( m_children[cluster].first, color );
188  colorCluster( m_children[cluster].second, color );
189  }
190 }
191 
size_t size(size_t cluster) const
getter
std::vector< WColor > m_colors
a color value for each cluster
size_t m_clusterCount
overall number of cluster, counts both leafes ( clusters of size one ) and real clusters
std::vector< std::pair< size_t, size_t > > m_children
vector that stores the 2 children of each cluster, contains an empty pair for leafes
std::vector< size_t > downXLevelsFromTop(size_t level, bool hideOutliers=false) const
returns a number of clusters at a certain level down from top cluster
void colorCluster(size_t cluster, WColor color)
sets the color for a selected cluster and all sub clusters
size_t m_maxLevel
the maximum level, naturally the level of the root node
std::vector< size_t > findXBiggestClusters(size_t cluster, size_t number=10) const
finds the X biggest clusters for a given cluster
virtual ~WHierarchicalTree()
destructor
std::vector< std::vector< size_t > > m_containsLeafes
vector that stores the leaf id's for each cluster, this is quite memory intensive but speeds up selec...
WHierarchicalTree()
standard constructor
implements a compare operator for clusters, depending on leaf count