Hilbert_R-Tree.h

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2007  A.N. Yzelman
00003  *  Released under LGPL, see license.txt
00004  *
00005  *  Last modified at 11th of May, 2007, by A.N. Yzelman
00006  *
00007  *  Hilbert_R-Tree.h: Definition of a Hilbert R-tree.
00008  *
00009  */
00010 
00011 #ifndef _H_HILBERT_R_TREE
00012 #define _H_HILBERT_R_TREE
00013  
00014 #include "r-tree.h"
00015 #include "orderings.h"
00016 #include <limits>
00017 
00018 #define Sfrom 2
00019 
00020 //#define _DEBUG
00021 
00026 class Hilbert_R_tree : public R_tree< Hilbert_R_tree > {
00027 
00028   private:
00029    
00031         double LHV;
00032         
00033   protected:
00034 
00042         Hilbert_R_tree* buildNode( vector< Hilbert_R_tree* > &input, BB_type *newMbr ) const;
00043         
00051         Hilbert_R_tree* buildNode( vector< BB_container* > &input, BB_type *newMbr ) const;
00052 
00053   
00057         class HilbertTreeOrdering: public Ordering< Hilbert_R_tree > {
00058                 protected:
00059                         virtual double getVal( const Hilbert_R_tree * const inp ) const {
00060                                 return inp->LHV;
00061                         }
00062         };
00063     
00072         Hilbert_R_tree *chooseLeaf( const double h );
00073         
00078         void handleOverflow();
00079         
00084         void handleRootOverflow();
00085         
00090         void handleUnderflow();
00091         
00098         void insert( BB_container* element, double h );
00099         
00112         void removeElement( BB_container* element );
00113 
00118         void updateLHVLocal();
00119         
00125         void updateLHV();
00126         
00133         void setChildren( vector< Hilbert_R_tree* > newChildren, BB_type *newMbr );
00134         
00135   public:
00136    
00138    Hilbert_R_tree() : R_tree< Hilbert_R_tree >() { LHV = 0; }
00139 
00141    Hilbert_R_tree( R_tree_props *props ) : R_tree< Hilbert_R_tree >( props ) { LHV = 0; }
00142         
00146    virtual ~Hilbert_R_tree() {}
00147  
00149    virtual void postBulkLoad() { getRoot()->updateLHV(); }
00150 
00157    int compareLHV( const Hilbert_R_tree* b ) const;
00158    
00165    void visualiseTree( const int level, Hilbert_R_tree *ref );
00166    
00172    Hilbert_R_tree* getRoot();
00173                 
00180         virtual Hilbert_R_tree*insert( BB_container *element );
00181         
00187         virtual Hilbert_R_tree* remove( BB_container* element );
00188 
00194         virtual Hilbert_R_tree* search( BB_container* element );
00195 
00196 };
00197 
00205 int compare_hilbert_trees( const void* a, const void* b );
00206 
00214 int compare_containers( const void* a, const void* b );
00215 
00216 
00217 /*************************************************************
00218  *                    PROTECTED FUNCTIONS                    *
00219  *************************************************************/ 
00220 
00221 
00222 void Hilbert_R_tree::setChildren( vector< Hilbert_R_tree* > newChildren, BB_type *newMbr ) {
00223 
00224         if ( newChildren.size() == 1 ) {
00225                 if ( newChildren[0]->isLeaf() )
00226                         this->setElements( newChildren[0]->elements, &( newChildren[0]->mbr ) );
00227                 else
00228                         this->setChildren( newChildren[0]->children, &( newChildren[0]->mbr ) );
00229                 LHV = newChildren[0]->LHV;
00230                 newChildren[0]->children.clear();
00231                 newChildren[0]->elements.clear();
00232                 delete newChildren[0];
00233                 return;
00234         }
00235 
00236         this->children.clear();
00237         
00238         childIterator it = newChildren.begin();
00239 
00240         for( ; it!=newChildren.end(); it++ ) {
00241 
00242                 (*it)->parent = this;
00243 
00244                 this->children.push_back( (*it) );
00245 
00246         }
00247                 
00248         this->elements.clear();
00249         if ( newMbr != 0 )
00250                 mbr = BB_type( newMbr );
00251 }
00252 
00253 Hilbert_R_tree* Hilbert_R_tree::buildNode( vector< Hilbert_R_tree* > &input, BB_type *newMbr ) const {
00254         
00255 #ifdef _DEBUG
00256         cout << "Entering buildNode, the R-tree node version" << endl; fflush( stdout );
00257 #endif
00258 
00259         Hilbert_R_tree *ret = new Hilbert_R_tree( properties );
00260                 
00261         //ret.children.add( input.begin(), input.end() );
00262         for ( unsigned int i=0; i<input.size(); i++ ) {
00263                 ret->children.push_back(  input[ i ] );
00264                 ret->children[ i ]->parent = ret;
00265         }
00266         
00267         ret->mbr = BB_type( newMbr );
00268 
00269 #ifdef _DEBUG
00270         cout << "Exitting buildNode, the R-tree node version" << endl; fflush( stdout );
00271 #endif
00272 
00273         return ret;
00274 }
00275 
00276 Hilbert_R_tree* Hilbert_R_tree::buildNode( vector< BB_container* > &input, BB_type *newMbr ) const {
00277         
00278 #ifdef _DEBUG
00279         cout << "Entering buildNode, the polytope version" << endl; fflush( stdout );
00280 #endif
00281 
00282         Hilbert_R_tree *ret = new Hilbert_R_tree( properties );
00283         
00284         vector< BB_container* >::iterator it = input.begin();
00285         for( ; it!=input.end(); it++ ) {
00286                 ret->elements.push_back( *it );
00287         }
00288         
00289         ret->mbr = BB_type( newMbr );
00290                 
00291 #ifdef _DEBUG
00292         cout << "Exitting buildNode, the polytope version" << endl; fflush( stdout );
00293 #endif
00294 
00295         return ret;
00296 }
00297 
00298 void Hilbert_R_tree::updateLHVLocal() {
00299 
00300         if ( isLeaf() ) {
00301                 vector< BB_container* >::iterator it = elements.begin();
00302 
00303 #ifdef _DEBUG   
00304                 if ( elements.size() == 0 ) {
00305                         cout << "Element size is zero? (Hilbert_R_tree::updateLHV)" << endl;
00306                         fflush( stdout );
00307                 }       
00308 #endif          
00309 
00310                 //init
00311                 vector< double > center;
00312                 (*it)->getCenterCoordinate( &center );
00313                 LHV = HilbertCoordinateMapper::toHilbert3D( &center );
00314                 
00315                 //find max (cannot use HilbertOrdering3D, because explicit ordering
00316                 //value is needed here).
00317                 for( ; it!=elements.end(); it++ ) {
00318                         vector< double > center;
00319                         (*it)->getCenterCoordinate( &center );
00320                         const double curLHV = HilbertCoordinateMapper::toHilbert3D( &center );
00321                         if ( curLHV > LHV )
00322                                 LHV = curLHV;
00323                 }
00324         } else {
00325                 vector< Hilbert_R_tree* >::iterator it = children.begin();
00326                 
00327                 //init
00328                 if ( (*it)->LHV == 0 )
00329                         (*it)->updateLHVLocal();
00330                 else
00331                         LHV = (*it)->LHV;
00332                 
00333                 //loop to find max
00334                 for( ; it!=children.end(); it++ )
00335                         if ( (*it)->LHV > LHV )
00336                                 LHV = (*it)->LHV;
00337         }
00338 }
00339 
00340 void Hilbert_R_tree::updateLHV() {
00341         updateLHVLocal();
00342 
00343         //if not root, recurse upwards
00344         if ( !isRoot() )
00345                 parent->updateLHV();
00346 }
00347 
00348 Hilbert_R_tree *Hilbert_R_tree::chooseLeaf( const double h ) {
00349         if ( isLeaf() )
00350                 return this;
00351 
00352         vector< Hilbert_R_tree* >::iterator it = children.begin();
00353         
00354         double curLHV = (*it)->LHV;
00355         Hilbert_R_tree *ret = *it;
00356         it++;
00357         
00358         //find one which is larger than h
00359         for( ; it!=children.end() && curLHV<h; it++ ) {
00360                 const double cur = (*it)->LHV;
00361                 if ( cur > curLHV ) {
00362                         curLHV = cur;
00363                         ret = *it;
00364                 }
00365         }
00366         
00367         //find the minimum one which is larger than h
00368         for( ; it!=children.end(); it++ ) {
00369                 const double cur = (*it)->LHV;
00370                 if ( cur < curLHV && cur > h ) {
00371                         curLHV = cur;
00372                         ret = *it;
00373                 }
00374         }
00375         
00376         return ret->chooseLeaf( h );
00377 }
00378 
00379 void Hilbert_R_tree::handleOverflow() {
00380         if ( isRoot() ) {
00381 #ifdef _DEBUG
00382                 cout << "Root overflow detected, heightening tree..." << endl;
00383 #endif          
00384         
00385                 //root overflow
00386                 Hilbert_R_tree *childOne = new Hilbert_R_tree( properties );
00387                 childOne->parent = this;
00388                 
00389                 //child one is a clone of current node
00390                 childOne->children.assign( children.begin(), children.end() );
00391                 childOne->elements.assign( elements.begin(), elements.end() );
00392                 childOne->LHV = LHV;
00393                 childOne->updateMBRLocal();
00394                 
00395                 //the children of child one should have child one as parent
00396                 vector< Hilbert_R_tree * >::iterator it = childOne->children.begin();
00397                 for( ; it!=childOne->children.end(); it++ )
00398                         (*it)->parent = childOne;
00399                 
00400                 //current node is the father of the new node
00401                 children.clear();
00402                 elements.clear();
00403                 children.push_back( childOne );
00404 #ifdef _DEBUG
00405                 cout << "Recursing on child" << endl;
00406 #endif
00407                 //now, the situation of root overflow is reduced to non-root overflow
00408                 //so call handleOverflow on the overflowing child
00409                 childOne->handleOverflow();
00410         } else {
00411                 //non-root overflow
00412                 //get all siblings, including ourselves
00413                 vector< Hilbert_R_tree * > siblings;
00414                 vector< Hilbert_R_tree * >::iterator it = parent->children.begin();
00415                 
00416 #ifdef _DEBUG
00417                 bool check = false;
00418 #endif          
00419                 for ( ; it!=parent->children.end(); it++ ) {
00420                         siblings.push_back( *it );
00421 #ifdef _DEBUG
00422                         if ( *it == this )
00423                                 check = true;
00424 #endif          
00425                 }
00426 #ifdef _DEBUG           
00427                 if ( !check )
00428                         cout << "Im not a child of my parent!!" << endl;
00429 #endif          
00430                 
00431                 //we should have a total of s siblings or less
00432                 while ( siblings.size() > Sfrom ) {
00433                         it = siblings.begin();
00434                         if ( (*it) == this )
00435                                 it++;
00436                         double max = fabs( (*it)->LHV - LHV );
00437                         vector< Hilbert_R_tree * >::iterator maxElem = it;
00438                         it++;
00439                         for( it=siblings.begin(); it!=siblings.end(); it++ ) {
00440                                 const double curmax = fabs( (*it)->LHV - LHV );
00441                                 if ( curmax > max && (*it) != this ) {
00442                                         maxElem = it;
00443                                         max = curmax;
00444                                 }
00445                         }
00446                         siblings.erase( maxElem );
00447                 }
00448 #ifdef _DEBUG           
00449                 cout << "Number of siblings: " << siblings.size() << endl;
00450 #endif          
00451                 
00452                 //now we have exactly s siblings, or less
00453                 //we have an s to s+1 splitting policy
00454                 //so we should defer splitting as long
00455                 //as possible.
00456                 unsigned int roomInSiblings = 0;
00457                 unsigned int numberOfElemts = 0;
00458                 it = siblings.begin();
00459                 for( ; it!=siblings.end(); it++ ) {
00460                         roomInSiblings += properties->maximum;
00461                         if ( isLeaf() )
00462                                 numberOfElemts += (*it)->elements.size();
00463                         else
00464                                 numberOfElemts += (*it)->children.size();
00465                 }
00466 #ifdef _DEBUG
00467                 cout << "Room in siblings: " << roomInSiblings << endl;
00468                 cout << "Number of elemts: " << numberOfElemts << endl;
00469 #endif          
00470                 if ( numberOfElemts > roomInSiblings ) {
00471                         //at this point, we need to create a new sibling
00472                         Hilbert_R_tree *newSibling = new Hilbert_R_tree( properties );
00473                         newSibling->parent = parent;
00474                         parent->children.push_back( newSibling );
00475                         siblings.push_back( newSibling );
00476                         roomInSiblings += properties->maximum;
00477 #ifdef _DEBUG
00478                         cout << "Created and added new child to siblings;" << endl;
00479                         cout << "Number of children of parent: " << parent->children.size() << endl;
00480                         cout << "Room in siblings: " << roomInSiblings << endl;
00481                         cout << "Number of elemts: " << numberOfElemts << endl;
00482 #endif          
00483                 }
00484                 
00485                 if ( numberOfElemts <= roomInSiblings ) {
00486                         //determine number of elements per sibling
00487                         const unsigned int numberOfElemsPerSibling = (const unsigned int) ( (double) numberOfElemts / (double) siblings.size() );
00488 #ifdef _DEBUG                   
00489                         cout << numberOfElemts << "/" << siblings.size() << "=" << numberOfElemsPerSibling << endl;
00490 #endif                  
00491                         //redistribute elements
00492                         if ( isLeaf() ) {
00493                                 //get leaf elements
00494                                 vector< BB_container * > toReDist;
00495                                 it = siblings.begin();
00496                                 for ( ; it!=siblings.end(); it++ )
00497                                         toReDist.insert( toReDist.end(), (*it)->elements.begin(), (*it)->elements.end() );
00498                                 
00499 #ifdef _DEBUG
00500                                 cout << "Redist size: " << toReDist.size() << endl;
00501 #endif
00502 
00503                                 //sort them according to LHVs
00504                                 HilbertOrdering3D< BB_container > ordering;
00505                                 ordering.sort( &toReDist );
00506                                 
00507                                 //redistribute
00508                                 it = siblings.begin();
00509                                 for( unsigned int i=0; i<( siblings.size() - 1 ); i++ ) {
00510                                         const unsigned int start = i * numberOfElemsPerSibling;
00511                                         const unsigned int end = start + numberOfElemsPerSibling;
00512                                         (*it)->elements.assign( toReDist.begin() + start, toReDist.begin() + end );
00513 #ifdef _DEBUG
00514                                         cout << (*it)->elements.size() << " elements assigned." << endl;
00515 #endif
00516                                         it++;
00517                                 }
00518                                 //add the remaining items (could be 1 more than numberOfElemsPerSibling)
00519                                 const unsigned int start = numberOfElemsPerSibling * ( siblings.size() - 1 );
00520                                 (*it)->elements.assign( toReDist.begin() + start, toReDist.end() );
00521 #ifdef _DEBUG
00522                                 cout << (*it)->elements.size() << " elements assigned." << endl;
00523 #endif
00524                         } else {
00525                                 //get sibling children
00526                                 vector< Hilbert_R_tree * > toReDist;
00527                                 it = siblings.begin();
00528                                 for( ; it!=siblings.end(); it++ )
00529                                         toReDist.insert( toReDist.end(), (*it)->children.begin(), (*it)->children.end() );
00530                                 
00531 #ifdef _DEBUG
00532                                 cout << "Redist size: " << toReDist.size() << endl;
00533 #endif
00534                                 
00535                                 //sort them according to LHVs
00536                                 HilbertTreeOrdering ordering;
00537                                 ordering.sort( &toReDist );
00538                                 
00539                                 //redistribute
00540                                 it = siblings.begin();
00541                                 for( unsigned int i=0; i<( siblings.size() - 1 ); i++ ){ 
00542                                         const unsigned int start = i * numberOfElemsPerSibling;
00543                                         const unsigned int end = start + numberOfElemsPerSibling;
00544                                         
00545                                         //assign children
00546                                         (*it)->children.assign( toReDist.begin() + start, toReDist.begin() + end );
00547                                         
00548                                         //parent of children should point to *it
00549                                         vector< Hilbert_R_tree * >::iterator childit = (*it)->children.begin();
00550                                         for ( ; childit!=(*it)->children.end(); childit++ )
00551                                                 (*childit)->parent = (*it);
00552 #ifdef _DEBUG
00553                                         cout << (*it)->children.size() << " elements assigned." << endl;
00554 #endif
00555                                         it++;
00556                                 }
00557                                 //add the remaining items (could be 1 more than numberOfElemsPerSibling)
00558                                 const unsigned int start = numberOfElemsPerSibling * ( siblings.size() - 1 );
00559                                 (*it)->children.assign( toReDist.begin() + start, toReDist.end() );
00560                                 //parent of children should point to *it
00561                                 vector< Hilbert_R_tree * >::iterator childit = (*it)->children.begin();
00562                                 for ( ; childit!=(*it)->children.end(); childit++ )
00563                                         (*childit)->parent = (*it);
00564 #ifdef _DEBUG
00565                                 cout << (*it)->children.size() << " elements assigned." << endl;
00566 #endif
00567                         }
00568                         
00569                         //update LHVs and such
00570                         //first local in siblings
00571                         it = siblings.begin();
00572                         for( ; it!=siblings.end(); it++ ) {
00573                                 (*it)->updateMBRLocal();
00574                                 (*it)->updateLHVLocal();
00575                         }
00576                         //then propagate upwards from parent
00577                         parent->updateMBR();
00578                         parent->updateLHV();
00579                 } else {
00580                         //this should be impossible
00581                         cerr << "Fatal error; Hilbert_R_tree::handleOverflow() in invalid state." << endl;
00582                         exit( 1 );
00583                 }
00584                 
00585                 if ( parent->children.size() > properties->maximum ) {
00586 #ifdef _DEBUG
00587                         cout << "Parent has overflowed, recursing..." << endl;
00588 #endif          
00589                         parent->handleOverflow();
00590                 } else {
00591 #ifdef _DEBUG
00592                         cout << "Overflow handling finished" << endl;
00593 #endif          
00594                 }
00595 #ifdef _DEBUG
00596                 getRoot()->visualiseTree( 0, 0 );
00597 #endif
00598         }
00599 }
00600 
00601 /* //Compares two BB_containers using their LHVs, for use with qsort
00602 int compare_containers( const void* a, const void* b ) {
00603    BB_container* arg1 = (BB_container*) a;
00604    BB_container* arg2 = (BB_container*) b;
00605    vector< double > centera = arg1->getCenterCoordinate();
00606    vector< double > centerb = arg2->getCenterCoordinate();
00607    const double ha = HilbertCoordinateMapper::toHilbert3D( &centera );
00608    const double hb = HilbertCoordinateMapper::toHilbert3D( &centerb );
00609    if( ha < hb ) return -1;
00610    else if( ha == hb ) return 0;
00611    else return 1;
00612 }
00613 
00614 // Compares two Hilbert R-trees using their LHVs
00615 int compare_hilbert_trees( const void* a, const void* b ) {
00616    Hilbert_R_tree* arg1 = (Hilbert_R_tree*) a;
00617    Hilbert_R_tree* arg2 = (Hilbert_R_tree*) b;
00618    return arg1->compareLHV( arg2 );
00619 }*/
00620 
00621 int Hilbert_R_tree::compareLHV( const Hilbert_R_tree* b ) const {
00622    if( LHV < b->LHV ) return -1;
00623    else if( LHV == b->LHV ) return 0;
00624    else return 1;
00625 }
00626  
00627 void Hilbert_R_tree::insert( BB_container* element, const double h ) {
00628         //push it back, regardless of overflows
00629         elements.push_back( element );
00630         
00631         //do 'late' overflow checking
00632         if( elements.size() > properties->maximum ) {
00633 #ifdef _DEBUG
00634                 cout << elements.size() << " > " << properties->maximum << "; calling handleOverflow()" << endl;
00635 #endif          
00636                 handleOverflow();
00637                 if( elements.size() > properties->maximum ) {
00638                         cerr << "handleOverflow did not reslove overflow!" << endl;
00639                         exit( 1 );
00640                 }
00641         } else {
00642                 //updates; note that handleOverflows handles updates also
00643                 updateMBR();
00644                 updateLHV();
00645         }
00646 }
00647 
00648 void Hilbert_R_tree::handleUnderflow() {}
00649 
00650 void Hilbert_R_tree::removeElement( BB_container* element ) {}
00651 
00652 void Hilbert_R_tree::visualiseTree( const int level, Hilbert_R_tree *ref ) {
00653         for( int i=0; i<level; i++ )
00654                 cout << "  ";
00655         if ( parent != ref )
00656                 cout << "|*" << endl;
00657         else if ( children.size() > properties->maximum || elements.size() > properties->maximum )
00658                 cout << "|O" << endl;
00659         else
00660                 cout << "|-" << endl;
00661         if ( !isLeaf() ) {
00662                 vector< Hilbert_R_tree * >::iterator it = children.begin();
00663                 for( ; it!=children.end(); it++ )
00664                         (*it)->visualiseTree( level + 1, this );
00665         }
00666 }
00667 
00668 
00669 /*************************************************************
00670  *                    PUBLIC FUNCTIONS                       *
00671  *************************************************************/ 
00672 
00673 Hilbert_R_tree* Hilbert_R_tree::insert( BB_container *element ) {
00674         //get hilbert value of data element
00675         vector< double > p;
00676         element->getCenterCoordinate( &p );
00677         double curLHV = HilbertCoordinateMapper::toHilbert3D( &p );
00678         
00679         //choose the correct leaf
00680         Hilbert_R_tree* toInsertAt = chooseLeaf( curLHV );
00681         
00682         //do the actual insertion at that leaf
00683         toInsertAt->insert( element, curLHV );
00684         
00685         //root has not changed
00686         return this;
00687 }
00688 
00689 Hilbert_R_tree* Hilbert_R_tree::remove( BB_container* element ) {
00690         cerr << "Element removal not yet implemented!" << endl; exit( 1 ); //TODO
00691 }
00692 
00693 Hilbert_R_tree* Hilbert_R_tree::search( BB_container* element ) {
00694         cerr << "Element search not yet implemented!" << endl; exit( 1 ); //TODO
00695 }
00696 
00697 Hilbert_R_tree* Hilbert_R_tree::getRoot() {
00698         if ( isRoot() )
00699                 return this;
00700         else
00701                 return parent->getRoot();
00702 }
00703 
00704 #endif

Generated on Sat Oct 13 17:34:42 2007 for R-Tree by  doxygen 1.5.2