#include <guma_rkdtree.h>
Inheritance diagram for guma::rkdtree::
Public Methods | |
rkdtree (int dim) | |
~rkdtree () | |
void | insert (const U *rec) |
void | remove (const U *rec, gul::List< gul::ListNode< kdrec< U, V > > > &outrecs) |
GULAPI kdtnode< U, V > * | insert (kdtnode< U, V > *T, const kdrec< U, V > &rec) |
GULAPI kdtnode< U, V > * | remove (kdtnode< U, V > *T, const kdrec< U, V > &rec, gul::List< gul::ListNode< kdrec< U, V > > > &outrecs) |
void | split (kdtnode< U, V > *T, const V &key, int i, kdtnode< U, V > **retL, kdtnode< U, V > **retR, gul::List< gul::ListNode< kdrec< U, V > > > &C) |
void | split (kdtnode< U, V > *T, const kdrec< U, V > &X, int i, kdtnode< U, V > **retL, kdtnode< U, V > **retR, gul::List< gul::ListNode< kdrec< U, V > > > &C) |
kdtnode< U, V > * | join (kdtnode< U, V > *A, kdtnode< U, V > *B, int i) |
|
Definition at line 264 of file guma_rkdtree.h. References guma::rkdtree_base::rkdtree_base().
00264 : rkdtree_base<U,V>(dim) { } |
|
Definition at line 265 of file guma_rkdtree.h.
00265 { } |
|
Definition at line 443 of file guma_rkdtree.cpp. References GULAPI, insert(), guma::rkdtree_base::m_dim, and split().
00445 { 00446 int n,sign,k; 00447 double p; 00448 kdtnode<U,V> *L, *R, *root, *S, *Sold; 00449 00450 if( !T ) 00451 { 00452 k = (int)(Rand::Random()*(double)m_dim); 00453 return new kdtnode<U,V>(rec, k); 00454 } 00455 00456 n = T->m_nelems; 00457 p = Rand::Random(); 00458 00459 if( p*((double)(n+1)) < (double)n ) // becomes not root 00460 { 00461 sign = rtr<V>::cmp( rec[T->m_disc], T->key() ); 00462 00463 if( sign < 0 ) 00464 { 00465 if( !T->m_left ) 00466 { 00467 k = (int)(Rand::Random()*(double)m_dim); 00468 T->set_left( new kdtnode<U,V>(rec, k) ); 00469 } 00470 else 00471 { 00472 Sold = T->m_left; 00473 S = insert( T->m_left, rec ); 00474 if( S != Sold ) 00475 T->set_left(S); 00476 } 00477 } 00478 else if( sign > 0 ) 00479 { 00480 if( !T->m_right ) 00481 { 00482 k = (int)(Rand::Random()*(double)m_dim); 00483 T->set_right( new kdtnode<U,V>(rec, k) ); 00484 } 00485 else 00486 { 00487 Sold = T->m_right; 00488 S = insert( T->m_right, rec ); 00489 if( S != Sold ) 00490 T->set_right(S); 00491 } 00492 } 00493 else // collision 00494 { 00495 T->add_rec( rec ); 00496 } 00497 00498 root = T; 00499 } 00500 else 00501 { 00502 k = (int)(Rand::Random()*(double)m_dim); 00503 root = new kdtnode<U,V>(rec, k); 00504 00505 split( T, rec, k, &L, &R, root->m_recs ); 00506 root->set_childs(L, R); 00507 } 00508 00509 return root; 00510 } |
|
Definition at line 267 of file guma_rkdtree.h. References guma::rkdtree_base::m_root. Referenced by insert().
|
|
Definition at line 658 of file guma_rkdtree.cpp. References split(). Referenced by remove(), and split().
00659 { 00660 kdtnode<U,V> *root, *A1, *A2, *B1, *B2; 00661 int n,m,j; 00662 double p; 00663 00664 if( (!A) && (!B) ) return 0; 00665 00666 // note: the trees which shall be joined shouldn't have parents, 00667 // since the parents aren't updated in this function 00668 00669 if( !A ) { B->m_parent = 0; return B; } 00670 if( !B ) { A->m_parent = 0; return A; } 00671 00672 A->m_parent = 0; 00673 B->m_parent = 0; 00674 00675 n = A->m_nelems; 00676 m = B->m_nelems; 00677 p = Rand::Random(); 00678 00679 if( p*((double)(n+m)) < (double)n ) // root of A becomes new root 00680 { 00681 j = A->m_disc; 00682 root = A; 00683 00684 if( j == i ) 00685 { 00686 A2 = join( A->m_right, B, i ); 00687 root->set_right( A2 ); 00688 } 00689 else 00690 { 00691 split( B, A->key(), j, &B1, &B2, A->m_recs ); 00692 A1 = join( A->m_left, B1, i ); 00693 A2 = join( A->m_right, B2, i ); 00694 A->set_childs( A1, A2 ); 00695 } 00696 } 00697 else // root of B becomes new root 00698 { 00699 j = B->m_disc; 00700 root = B; 00701 00702 if( j == i ) 00703 { 00704 B1 = join( A, B->m_left, i ); 00705 root->set_left( B1 ); 00706 } 00707 else 00708 { 00709 split( A, B->key(), j, &A1, &A2, B->m_recs ); 00710 B1 = join( A1, B->m_left, i ); 00711 B2 = join( A2, B->m_right, i ); 00712 B->set_childs( B1, B2 ); 00713 } 00714 } 00715 00716 return root; 00717 } |
|
Definition at line 513 of file guma_rkdtree.cpp. References gul::ListNode::el, GULAPI, join(), guma::rkdtree_base::m_dim, gul::ListNode::next, and remove().
00517 { 00518 int sign,i; 00519 kdtnode<U,V> *L,*Lold,*R,*Rold,*Told; 00520 gul::ListNode< kdrec<U,V> > *r,*r_next; 00521 gul::List< gul::ListNode< kdrec<U,V> > > dummyrecs; 00522 00523 if( !T ) return 0; 00524 00525 // search record which shall be removed 00526 sign = rtr<V>::cmp( rec[T->m_disc], T->key() ); 00527 00528 if( sign < 0 ) 00529 { 00530 Lold = T->m_left; 00531 L = remove(T->m_left,rec,outrecs); 00532 if( L != Lold ) T->set_left(L); 00533 } 00534 else if( sign > 0 ) 00535 { 00536 Rold = T->m_right; 00537 R = remove(T->m_right,rec,outrecs); 00538 if( R != Rold ) T->set_right(R); 00539 } 00540 else // found a node which is identical in its discriminant component 00541 { 00542 // remove records which are completely identical to 'rec' 00543 r = T->m_recs.First(); 00544 while( r ) 00545 { 00546 for( i = 0; i < m_dim; i++ ) 00547 { 00548 sign = rtr<V>::cmp( r->el[i], rec[i] ); 00549 if( sign != 0 ) break; 00550 } 00551 r_next = r->next; 00552 if( sign == 0 ) 00553 { 00554 T->m_recs.Remove(r); 00555 outrecs.Append(r); 00556 } 00557 r = r_next; 00558 } 00559 00560 // remove node if necessary 00561 if( T->m_recs.nElems == 0 ) 00562 { 00563 i = T->m_disc; 00564 Told = T; 00565 T->unlink(&L,&R,dummyrecs); 00566 T = join( L, R, i ); 00567 delete Told; // deleting T now prevents Tnew==Told 00568 } 00569 } 00570 return T; 00571 } |
|
Definition at line 268 of file guma_rkdtree.h. References GULAPI, and guma::rkdtree_base::m_root. Referenced by remove().
|
|
Definition at line 282 of file guma_rkdtree.h. References split().
00285 { 00286 split( T, X[i], i, retL, retR, C ); 00287 } |
|
Definition at line 574 of file guma_rkdtree.cpp. References join(), and guma::rkdtree_base::split_recs(). Referenced by insert(), join(), and split().
00578 { 00579 kdtnode<U,V> *L, *R, *TL, *TR, *L1, *L2, *R1, *R2, *LR, *RL; 00580 List< ListNode< kdrec<U,V> > > recs,recs1,recs2; 00581 int j, sign; 00582 00583 // if T is empty return empty trees 00584 if( !T ) 00585 { 00586 *retL = 0; 00587 *retR = 0; 00588 return; 00589 } 00590 00591 // note: the tree which shall be splitted shouldn't have a parent, 00592 // since the parent isn't updated in this function 00593 T->m_parent = 0; 00594 00595 j = T->m_disc; 00596 00597 // T has the same discriminant j 00598 if( j == i ) 00599 { 00600 sign = rtr<V>::cmp( T->key(), key ); 00601 00602 // Y[j] < X[i] 00603 if( sign < 0 ) 00604 { 00605 L = T; 00606 split( L->m_right, key, i, &LR, &R, C ); 00607 L->set_right(LR); 00608 } 00609 // Y[j] > X[i] 00610 else if( sign > 0 ) 00611 { 00612 R = T; 00613 split( R->m_left, key, i, &L, &RL, C ); 00614 R->set_left(RL); 00615 } 00616 else 00617 { 00618 T->unlink(&L,&R,C); 00619 delete T; 00620 } 00621 } 00622 // T has a different discriminant j 00623 else 00624 { 00625 T->unlink( &TL, &TR, recs ); 00626 split_recs( recs, key, i, recs1, recs2, C ); 00627 split( TL, key, i, &L1, &L2, C ); 00628 split( TR, key, i, &R1, &R2, C ); 00629 00630 if( recs1.nElems ) 00631 { 00632 L = new kdtnode<U,V>( recs1, j ); 00633 L->set_childs( L1, R1 ); 00634 } 00635 else 00636 { 00637 L = join( L1, R1, j ); 00638 } 00639 00640 if( recs2.nElems ) 00641 { 00642 R = new kdtnode<U,V>( recs2, j ); 00643 R->set_childs( L2, R2 ); 00644 } 00645 else 00646 { 00647 R = join( L2, R2, j ); 00648 } 00649 00650 delete T; 00651 } 00652 00653 *retL = L; 00654 *retR = R; 00655 } |