00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GUMA_RKDTREE_H
00021 #define GUMA_RKDTREE_H
00022
00023 namespace guma {
00024
00025
00026
00027 template< class U, class V >
00028 class kdrec : public gul::pool_object
00029 {
00030 public:
00031 const U *m_base;
00032 kdrec( const U *base ) { m_base = base; }
00033 const V& operator[]( size_t i) const { return (*m_base)[i]; }
00034 };
00035
00036
00037 template< class U, class V >
00038 class kdtnode : public gul::pool_object
00039 {
00040 public:
00041 int m_disc;
00042 gul::List< gul::ListNode< kdrec<U,V> > > m_recs;
00043 int m_nelems;
00044
00045 kdtnode *m_left;
00046 kdtnode *m_right;
00047 kdtnode *m_parent;
00048
00049 kdtnode( const kdrec<U,V>& rec, int disc )
00050 {
00051 m_disc = disc;
00052 m_recs.Append( new gul::ListNode< kdrec<U,V> >(rec) );
00053 m_left = m_right = m_parent = 0;
00054 m_nelems = 1;
00055 }
00056 kdtnode( gul::List< gul::ListNode< kdrec<U,V> > >& recs, int disc )
00057 {
00058 m_disc = disc;
00059 m_recs = recs;
00060 m_left = m_right = m_parent = 0;
00061 m_nelems = 1;
00062 }
00063 const V& key() const
00064 {
00065 return m_recs.First()->el[m_disc];
00066 }
00067 void add_rec( const kdrec<U,V>& rec )
00068 {
00069 m_recs.Append( new gul::ListNode< kdrec<U,V> >(rec) );
00070 }
00071 void update()
00072 {
00073 m_nelems = 1;
00074 if( m_left ) m_nelems += m_left->m_nelems;
00075 if( m_right ) m_nelems += m_right->m_nelems;
00076 if( m_parent ) m_parent->update();
00077 }
00078 void set_left( kdtnode *left )
00079 {
00080 m_left = left;
00081 if( m_left ) m_left->m_parent = this;
00082 update();
00083 }
00084 void set_right( kdtnode *right )
00085 {
00086 m_right = right;
00087 if( m_right ) m_right->m_parent = this;
00088 update();
00089 }
00090 void set_childs( kdtnode *left, kdtnode *right )
00091 {
00092 m_left = left;
00093 if( m_left ) m_left->m_parent = this;
00094 m_right = right;
00095 if( m_right ) m_right->m_parent = this;
00096 update();
00097 }
00098 void unlink( kdtnode **left, kdtnode **right,
00099 gul::List< gul::ListNode< kdrec<U,V> > >& L)
00100 {
00101 L += m_recs;
00102
00103 *left = m_left;
00104 if( m_left )
00105 {
00106 m_left->m_parent = 0;
00107 m_left = 0;
00108 }
00109 *right = m_right;
00110 if( m_right )
00111 {
00112 m_right->m_parent = 0;
00113 m_right = 0;
00114 }
00115 if( m_parent )
00116 {
00117 if( m_parent->m_left == this )
00118 m_parent->m_left = 0;
00119 if( m_parent->m_right == this )
00120 m_parent->m_right = 0;
00121 m_parent->update();
00122 m_parent = 0;
00123 }
00124 }
00125 ~kdtnode()
00126 {
00127 if( m_left )
00128 {
00129 m_left->m_parent = 0;
00130 delete m_left;
00131 }
00132 if( m_right )
00133 {
00134 m_right->m_parent = 0;
00135 delete m_right;
00136 }
00137 if( m_parent )
00138 {
00139 if( m_parent->m_left == this )
00140 m_parent->m_left = 0;
00141 if( m_parent->m_right == this )
00142 m_parent->m_right = 0;
00143 m_parent->update();
00144 }
00145 }
00146
00147 void height( int cur_height, int *max_height,
00148 int *avg_count, double *avg_sum );
00149 void dump(int dim,int space);
00150 };
00151
00152
00153 template< class U, class V >
00154 class kdnnrec : public gul::pool_object
00155 {
00156 public:
00157 V m_dist;
00158 gul::List< gul::ListNode< kdrec<U,V> > > m_recs;
00159
00160 kdnnrec() { }
00161
00162 kdnnrec( const V& dist, const kdrec<U,V>& rec )
00163 {
00164 m_dist = dist;
00165 m_recs.Append( new gul::ListNode< kdrec<U,V> >(rec) );
00166 }
00167 kdnnrec<U,V>& operator=( kdnnrec<U,V>& other )
00168 {
00169 if( this == &other ) return *this;
00170
00171 m_dist = other.m_dist;
00172 m_recs = other.m_recs;
00173 return *this;
00174 }
00175
00176 GULAPI void dump( int dim );
00177 };
00178
00179
00180 template< class U, class V >
00181 class kdtsnode : public gul::pool_object
00182 {
00183 public:
00184 const kdtnode<U,V> *m_n;
00185 gul::Ptr<V> m_D;
00186 V m_d;
00187 kdtsnode( const kdtnode<U,V> *n, const gul::Ptr<V>& D, V d )
00188 {
00189 m_n = n;
00190 m_D = D;
00191 m_d = d;
00192 }
00193 };
00194
00195 template< class U, class V >
00196 class kdtsearch : public gul::pool_object
00197 {
00198 public:
00199 int m_dim;
00200 int m_nNeighbors;
00201 V m_maxDist;
00202 gul::Map< kdnnrec<U,V> > m_neighbors;
00203 int m_maxNeighbors;
00204
00205
00206 kdtsearch( int dim, int maxNeighbors )
00207 {
00208 m_dim = dim;
00209 m_nNeighbors = 0;
00210 m_maxNeighbors = maxNeighbors;
00211 }
00212 void scan_records(
00213 const U& P, const gul::List< gul::ListNode< kdrec<U,V> > >& recs );
00214 void process_node( const U& P, const kdtnode<U,V> *n, const gul::Ptr<V>& D, V d,
00215 gul::List< gul::ListNode< kdtsnode<U,V> > >& stack );
00216
00217 static int compare_key_to_node( V *k, kdnnrec<U,V> *r );
00218 V length( const gul::Ptr<V>& P );
00219 };
00220
00221
00222
00223
00224
00225 template< class U, class V >
00226 class rkdtree_base : public gul::pool_object
00227 {
00228 public:
00229 int m_dim;
00230 kdtnode<U,V> *m_root;
00231
00232 rkdtree_base( int dim ) { m_dim = dim; m_root = 0; }
00233 ~rkdtree_base() { delete m_root; }
00234
00235
00236 GULAPI int nearest_neighbors( const U& P, int m, gul::Ptr< kdnnrec<U,V> >& M );
00237
00238 void split_recs(
00239 gul::List< gul::ListNode< kdrec<U,V> > >& recs, const V& key, int i,
00240 gul::List< gul::ListNode< kdrec<U,V> > >& recs1,
00241 gul::List< gul::ListNode< kdrec<U,V> > >& recs2,
00242 gul::List< gul::ListNode< kdrec<U,V> > >& C );
00243 void split_recs(
00244 gul::List< gul::ListNode< kdrec<U,V> > >& recs, const U& X, int i,
00245 gul::List< gul::ListNode< kdrec<U,V> > >& recs1,
00246 gul::List< gul::ListNode< kdrec<U,V> > >& recs2,
00247 gul::List< gul::ListNode< kdrec<U,V> > >& C )
00248 {
00249 split_recs( recs, X[i], i, recs1, recs2, C );
00250 }
00251
00252
00253 GULAPI void dump_statistics();
00254 GULAPI void dump_tree();
00255 };
00256
00257
00258
00259
00260 template< class U, class V, class Rand >
00261 class rkdtree : public rkdtree_base<U,V>
00262 {
00263 public:
00264 rkdtree( int dim ) : rkdtree_base<U,V>(dim) { }
00265 ~rkdtree() { }
00266
00267 void insert( const U *rec ) { m_root = insert(m_root, kdrec<U,V>(rec)); }
00268 void remove( const U *rec, gul::List< gul::ListNode< kdrec<U,V> > >& outrecs )
00269 {
00270 m_root = remove(m_root, kdrec<U,V>(rec), outrecs);
00271 }
00272
00273 GULAPI kdtnode<U,V> *insert( kdtnode<U,V> *T, const kdrec<U,V>& rec );
00274 GULAPI kdtnode<U,V> *remove(
00275 kdtnode<U,V> *T,
00276 const kdrec<U,V>& rec,
00277 gul::List< gul::ListNode< kdrec<U,V> > >& outrecs );
00278
00279 void split( kdtnode<U,V> *T, const V& key, int i,
00280 kdtnode<U,V> **retL, kdtnode<U,V> **retR,
00281 gul::List< gul::ListNode< kdrec<U,V> > >& C );
00282 void split( kdtnode<U,V> *T, const kdrec<U,V>& X, int i,
00283 kdtnode<U,V> **retL, kdtnode<U,V> **retR,
00284 gul::List< gul::ListNode< kdrec<U,V> > >& C )
00285 {
00286 split( T, X[i], i, retL, retR, C );
00287 }
00288
00289 kdtnode<U,V> *join( kdtnode<U,V> *A, kdtnode<U,V> *B, int i );
00290 };
00291
00292 }
00293
00294 #endif
00295