basic-r-tree.h

Go to the documentation of this file.
00001 
00011 #ifndef _H_BASIC_R_TREE
00012 #define _H_BASIC_R_TREE
00013 
00014 #include "r-tree.h"
00015 
00019 //template < typename bb_type > Pending...
00020 class Basic_R_tree : public R_tree< Basic_R_tree > {
00021 
00022   protected:
00023 
00025         typedef vector< Basic_R_tree* >::const_iterator childIterator;
00026         
00028         typedef vector< BB_container* >::const_iterator elemIterator;
00029         
00038         Basic_R_tree *chooseLeaf( Basic_R_tree *v, const BB_type bb ) const;
00039 
00057         Basic_R_tree *handleOverflow( Basic_R_tree *node, BB_container *element );
00058 
00073         void linearSplitElements( vector< BB_container* > oldItems, BB_container *newItem, vector< BB_container* > *set_one, vector< BB_container* > *set_two, BB_type *mbr_one, BB_type *mbr_two, int dimension );
00074 
00089         void linearSplitNodes( vector< Basic_R_tree * > oldItems, Basic_R_tree *newItem, vector< Basic_R_tree* > *set_one, vector< Basic_R_tree* > *set_two, BB_type *mbr_one, BB_type *mbr_two, int dimension );
00090 
00105         void quadraticSplitElements( vector< BB_container* > oldItems, BB_container *newItem, vector< BB_container* > *set_one, vector< BB_container* > *set_two, BB_type *mbr_one, BB_type *mbr_two, int dimension );
00106 
00121         void quadraticSplitNodes( vector< Basic_R_tree* > oldItems, Basic_R_tree *newItem, vector< Basic_R_tree* > *set_one, vector< Basic_R_tree* > *set_two, BB_type *mbr_one, BB_type *mbr_two, int dimension );
00122 
00131         Basic_R_tree *insert( Basic_R_tree *node );
00132 
00140         Basic_R_tree *buildNode( vector< BB_container* > input, BB_type *newMbr ) const;
00141         
00149         Basic_R_tree *buildNode( vector< Basic_R_tree* > input, BB_type *newMbr ) const;
00150 
00157         void reinsert( vector< Basic_R_tree* > s );
00158         
00165         void reinsert( Basic_R_tree* walk, Basic_R_tree* at );
00166 
00176         Basic_R_tree *handleOverflow( Basic_R_tree *node );
00177 
00185         Basic_R_tree *makeNewRoot( Basic_R_tree *child );
00186 
00193         void setChildren( vector< Basic_R_tree* > newChildren, BB_type *newMbr );
00194         
00195         /*
00196          *  Sets a collection of bb_containers to be the elements of this node.
00197          *
00198          *  @param newElements The collection of new elements.
00199          *  @param newMbr The minimum bounding rectangle of newElements
00200          *
00201          */
00202         //void setElements( vector< BB_container* > newElements, BB_type *newMbr );
00203 
00209         void removeChild( Basic_R_tree *toRemove );
00210 
00220         Basic_R_tree *remove( Basic_R_tree *node, BB_container *element );
00221 
00222 
00223   public:
00224 
00229         Basic_R_tree() : R_tree< Basic_R_tree >() {}
00230         
00236         Basic_R_tree( R_tree_props *props ) : R_tree< Basic_R_tree >( props ) {}
00237                 
00246         virtual Basic_R_tree *remove( BB_container *element );
00247 
00253         virtual Basic_R_tree *getRoot();
00254 
00261         virtual const Basic_R_tree *getRoot() const;
00262 
00269         virtual Basic_R_tree *insert( BB_container *element );
00270 
00278         virtual Basic_R_tree *search( BB_container *element );
00279 
00280 };
00281 
00282 
00283 Basic_R_tree *Basic_R_tree::remove( Basic_R_tree *node, BB_container *element ) {
00284 #ifdef _DEBUG
00285         cout << "Entering remove(node, element)" << endl; fflush( stdout );
00286 #endif
00287         vector< BB_container* >::iterator it = node->elements.begin();
00288         vector< Basic_R_tree* > s;
00289                 
00290         //first erase the element
00291         for ( ; it!=node->elements.end(); it++ ) {
00292                 if ( (*it)->getID() == element->getID() ) {
00293                         node->elements.erase( it );
00294                 }
00295         }
00296                 
00297         //check for underflows
00298         Basic_R_tree *walk = node;
00299         while ( !( walk->isRoot() ) ) {
00300                 Basic_R_tree *par = walk->parent;
00301         
00302                 if ( walk->isLeaf() ) {
00303                         if ( walk->elements.size() < properties->minimum ) {
00304                                 //underflow detected, store node
00305                                 s.push_back( walk );
00306                                 //remove node
00307                                 par->removeChild( walk );
00308                                 //update MBR
00309                                 par->updateMBRNode();
00310                         }
00311                 } else {
00312                         if ( walk->children.size() < properties->minimum ) {
00313                                 s.push_back( walk );
00314                                 par->removeChild( walk );
00315                                 par->updateMBRNode();
00316                         }
00317                 }
00318                         
00319                 //check parent
00320                 walk = par;
00321         }
00322                 
00323         //re-insert all at root
00324         walk->reinsert( s );
00325 
00326 #ifdef _DEBUG
00327         cout << "Almost exitting remove(node, element) -- rootcheck" << endl; fflush( stdout );
00328 #endif
00329         //check for degenerate root
00330         if ( walk->children.size() == 1 ) {
00331 
00332                 Basic_R_tree *temp = walk->children[0];
00333                 walk->elements = temp->elements;
00334                 walk->children = temp->children;
00335                 walk->mbr = temp->mbr;
00336                 walk->properties = temp->properties; //actually kind of useless
00337                 delete temp;
00338         
00339 #ifdef _DEBUG
00340                 cout << "Exitting remove(node, element) -- root fixed" << endl; fflush( stdout );
00341 #endif
00342 
00343                 return walk;
00344         }
00345 #ifdef _DEBUG
00346         cout << "Exitting remove(node, element) -- no degenerate root" << endl; fflush( stdout );
00347 #endif
00348 
00349         return walk;
00350 }
00351 
00352 void Basic_R_tree::removeChild( Basic_R_tree *toRemove ) {
00353 
00354 #ifdef _DEBUG
00355         cout << "Entering removeChild" << endl; fflush( stdout );
00356 #endif
00357 
00358         vector< Basic_R_tree* >::iterator it = this->children.begin();
00359         for ( ; it!=this->children.end(); it++ ) {
00360                 if ( ( *it ) == toRemove )
00361                         this->children.erase( it );
00362         }
00363         
00364 #ifdef _DEBUG
00365         cout << "Exitting removeChild" << endl; fflush( stdout );
00366 #endif
00367 
00368 }
00369 
00370 void Basic_R_tree::setChildren( vector< Basic_R_tree* > newChildren, BB_type *newMbr ) {
00371 
00372         if ( newChildren.size() == 1 ) {
00373                 if ( newChildren[0]->isLeaf() )
00374                         this->setElements( newChildren[0]->elements, &( newChildren[0]->mbr ) );
00375                 else
00376                         this->setChildren( newChildren[0]->children, &( newChildren[0]->mbr ) );
00377                 newChildren[0]->children.clear();
00378                 newChildren[0]->elements.clear();
00379                 delete newChildren[0];
00380                 return;
00381         }
00382 
00383 #ifdef _DEBUG
00384         cout << "Entering setChildren; replacing with " << newChildren.size() << " children." << endl; fflush( stdout );
00385         cout << "\tClearing old children..." << endl; fflush( stdout );
00386 #endif
00387 
00388         this->children.clear();
00389                 
00390 #ifdef _DEBUG
00391         cout << "\tInitialising iterator..." << endl; fflush( stdout );
00392 #endif
00393 
00394         childIterator it = newChildren.begin();
00395 
00396 #ifdef _DEBUG
00397         cout << "\tLooping..." << endl; fflush( stdout );
00398 #endif
00399 
00400         for( ; it!=newChildren.end(); it++ ) {
00401 
00402 #ifdef _DEBUG
00403                 cout << "\tSetting parent..." << endl; fflush( stdout );
00404 #endif
00405 
00406                 (*it)->parent = this;
00407 
00408 #ifdef _DEBUG
00409                 cout << "\t" << this->children.size() << " Children, pushing back another child..." << endl; fflush( stdout );
00410                 cout << "\tChild mbr: " << (*(*it)).mbr << endl; fflush( stdout );
00411                 cout << "\tChild adress: " << (*it) << endl; fflush( stdout );
00412 #endif
00413 
00414                 this->children.push_back( (*it) );
00415                         
00416 #ifdef _DEBUG
00417                 cout << "\tPush back successful" << endl; fflush( stdout );
00418 #endif
00419 
00420         }
00421 
00422 #ifdef _DEBUG
00423         cout << "\tClearing elements..." << endl; fflush( stdout );
00424 #endif
00425                 
00426         this->elements.clear();
00427         
00428 #ifdef _GREATER_CHECK
00429  #ifdef _DEBUG
00430         cout << "\tLocal height estimate: " << getLocalHeightEstimate() << endl;
00431  #endif
00432 #endif
00433 
00434 #ifdef _DEBUG
00435         cout << "\tSetting MBR..." << endl; fflush( stdout );
00436 #endif
00437 
00438         if ( newMbr != 0 )
00439                 mbr = BB_type( newMbr );
00440 
00441 #ifdef _DEBUG
00442         cout << "Exitting setChildren" << endl; fflush( stdout );
00443 #endif
00444 
00445 }
00446 
00447 /*void Basic_R_tree::setElements( vector< BB_container* > newElements, BB_type *newMbr ) {
00448 
00449 #ifdef _DEBUG
00450         cout << "Entering setElements" << endl; fflush( stdout );
00451 #endif
00452 
00453         this->elements.clear();
00454         vector< BB_container* >::iterator it = newElements.begin();
00455         for( ; it!=newElements.end(); it++ ) {
00456 #ifdef _DEBUG
00457                 cout << "Adding element " << endl << *(*it) << endl; fflush( stdout );
00458 #endif
00459                 this->elements.push_back( *it );
00460         }
00461         
00462         this->children.clear();
00463         
00464         mbr = BB_type( newMbr );
00465 
00466 #ifdef _GREATER_CHECK
00467         checkInvariants();
00468 #endif
00469         
00470 #ifdef _DEBUG
00471         cout << "Exitting setElements" << endl; fflush( stdout );
00472 #endif
00473 
00474 }*/
00475 
00476 Basic_R_tree *Basic_R_tree::makeNewRoot( Basic_R_tree *child ) {
00477         
00478 #ifdef _DEBUG
00479         cout << "Entering makeNewRoot" << endl; fflush( stdout );
00480 #endif
00481 
00482 #ifndef _HP
00483         if (!this->isRoot()) {
00484                 cerr << "makeNewRoot called on non-root node!" << endl;
00485                 exit(1);
00486         }
00487 #endif
00488 
00489         Basic_R_tree *newRoot = new Basic_R_tree( properties );
00490 
00491 #ifdef _GREATER_CHECK
00492  #ifdef _DEBUG
00493         cout << "\tLocal children depth: " << getLocalHeightEstimate() << endl;
00494         cout << "\tReal depth: " << getHeightEstimate() << endl;
00495  #endif
00496 #endif
00497 
00498         newRoot->children.push_back( this );
00499 
00500 #ifdef _GREATER_CHECK
00501  #ifdef _DEBUG
00502         cout << "\tNew child children depth: " << child->getLocalHeightEstimate() << endl;
00503         cout << "\tReal depth: " << child->getHeightEstimate() << endl;
00504  #endif
00505 #endif
00506 
00507         newRoot->children.push_back( child );
00508         this->parent = newRoot;
00509         child->parent = newRoot;
00510         newRoot->updateMBRLocal();
00511 
00512 #ifdef _GREATER_CHECK
00513  #ifdef _DEBUG
00514         cout << "\tRoot check: " << endl; fflush( stdout );
00515  #endif
00516         newRoot->checkInvariants();
00517 #endif
00518 
00519 #ifdef _DEBUG
00520         cout << "Exitting makeNewRoot" << endl; fflush( stdout );
00521 #endif
00522 
00523         return newRoot;
00524 }
00525         
00526 void Basic_R_tree::reinsert( vector< Basic_R_tree* > s ) {
00527 
00528 #ifdef _DEBUG
00529         cout << "Entering re-insert" << endl; fflush( stdout );
00530 #endif
00531 
00532         childIterator it = s.begin();
00533         for ( ; it!=s.end(); it++ ) {
00534                 
00535                 Basic_R_tree *node = *it;
00536                 if ( node->isLeaf() ) {
00537                         vector< BB_container* >::iterator itp = node->elements.begin();
00538                         for( ; itp != node->elements.end(); itp++ )
00539                                 insert( *itp );
00540                 } else {
00541                         //non leaf. take the naive approach (for now), and just reinsert
00542                         //all stored elements instead of adding the internal node at some
00543                         //position at the appropiate height, as in [GUT84], page 51.
00544                         
00545                         Basic_R_tree* walk = (*it);
00546                         reinsert( walk, this );
00547                         
00548                         /*Basic_R_tree::Iterator itr = node->begin();
00549                         for ( ; itr != node->end(); ++itr )
00550                                 insert( *itr );*/
00551                 }
00552                         
00553         }
00554         
00555 #ifdef _DEBUG
00556         cout << "Exitting re-insert" << endl; fflush( stdout );
00557 #endif
00558 
00559 }
00560 
00561 void Basic_R_tree::reinsert( Basic_R_tree* walk, Basic_R_tree* at ) {
00562         if ( walk->isLeaf() ) {
00563                 elemIterator it = this->elements.begin();
00564                 for( ; it!=this->elements.end(); it++ )
00565                         at->insert( *it );
00566         } else {
00567                 childIterator it = this->children.begin();
00568                 for( ; it!=this->children.end(); it++ )
00569                         reinsert( *it, at );
00570         }
00571 }
00572 
00573 Basic_R_tree *Basic_R_tree::buildNode( vector< BB_container* > input, BB_type *newMbr ) const {
00574         
00575 #ifdef _DEBUG
00576         cout << "Entering buildNode, the polytope version" << endl; fflush( stdout );
00577 #endif
00578 
00579         Basic_R_tree *ret = new Basic_R_tree( properties );
00580         
00581         vector< BB_container* >::iterator it = input.begin();
00582         for( ; it!=input.end(); it++ ) {
00583                 ret->elements.push_back( *it );
00584         }
00585         
00586         ret->mbr = BB_type( newMbr );
00587                 
00588 #ifdef _DEBUG
00589         cout << "Exitting buildNode, the polytope version" << endl; fflush( stdout );
00590 #endif
00591 
00592         return ret;
00593 }
00594 
00595 Basic_R_tree *Basic_R_tree::buildNode( vector< Basic_R_tree* > input, BB_type *newMbr ) const {
00596         
00597 #ifdef _DEBUG
00598         cout << "Entering buildNode, the R-tree node version" << endl; fflush( stdout );
00599 #endif
00600 
00601         Basic_R_tree *ret = new Basic_R_tree( properties );
00602                 
00603         //ret.children.add( input.begin(), input.end() );
00604         for ( unsigned int i=0; i<input.size(); i++ ) {
00605                 ret->children.push_back(  input[ i ] );
00606                 ret->children[ i ]->parent = ret;
00607         }
00608         
00609         if ( newMbr!= 0 )
00610                 ret->mbr = BB_type( newMbr );
00611 
00612 #ifdef _DEBUG
00613         cout << "Exitting buildNode, the R-tree node version" << endl; fflush( stdout );
00614 #endif
00615 
00616         return ret;
00617 }
00618 
00619 Basic_R_tree *Basic_R_tree::handleOverflow( Basic_R_tree *node ) {
00620 #ifdef _DEBUG
00621         cout << "Entering handleOverflow, the Basic_R_tree node version" << endl; fflush( stdout );
00622 #endif
00623 
00624         //set splits
00625         vector< Basic_R_tree* > set_one;
00626         vector< Basic_R_tree* > set_two;
00627         BB_type *mbr_one = new BB_type();
00628         BB_type *mbr_two = new BB_type();
00629 
00630         //build item nodes
00631         vector< Basic_R_tree* > oldItems;
00632 
00633 #ifdef _DEBUG
00634         cout << "\tCurrent node at: " << this << ", children are at: ";
00635 #endif
00636 
00637         for( unsigned int i=0; i<this->children.size(); i++ ) {
00638 
00639 #ifdef _DEBUG
00640                 cout << this->children[i] << " ";
00641 #endif
00642 
00643                 oldItems.push_back( this->children[ i ] );
00644         }
00645 
00646 #ifdef _DEBUG
00647         cout << endl;
00648 #endif
00649         
00650         this->children.clear();
00651                 
00652         //actual splitting
00653         switch( SPLIT_STRATEGY ) {
00654                 case LINEAR_SPLIT:
00655                         linearSplitNodes( oldItems, node, &set_one, &set_two, mbr_one, mbr_two, node->mbr.getDimension() ); 
00656                         break;
00657                 case QUADRATIC_SPLIT:
00658                         quadraticSplitNodes( oldItems, node, &set_one, &set_two, mbr_one, mbr_two, node->mbr.getDimension() ); 
00659                         break;
00660                 case EXPONENTIAL_SPLIT:
00661                         cerr << "x^Split not yet implemented! " << endl; exit(1);
00662                         break;
00663                 default:
00664                         cerr << "No valid split strategy selected! (r-tree.h)" << endl;
00665                         exit(1);
00666         }
00667                 
00668         //node building
00669         Basic_R_tree *child_one = buildNode( set_one, mbr_one ); //note this takes into account mbr
00670 
00671 #ifdef _GREATER_CHECK
00672  #ifdef _DEBUG
00673         cout << "child_one local depth: " << child_one->getLocalHeightEstimate() << endl;
00674  #endif
00675 #endif
00676 
00677         setChildren( set_two, mbr_two ); //note this takes into account mbr
00678 
00679         //delete temporary mbrs
00680         delete mbr_one;
00681         delete mbr_two;
00682 
00683         //insert the new node
00684         if ( this->isRoot() ) {
00685 
00686 #ifdef _DEBUG
00687         cout << "Exitting handleOverflow, the Basic_R_tree node version, calling makeNewRoot" << endl; fflush( stdout );
00688 #endif
00689 
00690                 return makeNewRoot( child_one ); //takes into account MBR
00691 
00692         } else {
00693 
00694 #ifdef _DEBUG
00695         cout << "Exitting handleOverflow, the Basic_R_tree node version, calling parent->insert" << endl; fflush( stdout );
00696 #endif
00697 
00698                 return this->parent->insert( child_one ); //takes into account MBR
00699         }
00700 }
00701 
00702 Basic_R_tree *Basic_R_tree::insert( Basic_R_tree *node ) {
00703 
00704 #ifdef _DEBUG
00705         cout << "Entering insert, the R-tree node version" << endl; fflush( stdout );
00706         cout << "Inserting " << node << " at " << this << endl;
00707 #endif
00708 
00709 #ifndef _HP
00710         if ( this->isLeaf() ) {
00711                 cerr << "\tTrying to add internal node to a leaf node!" << endl;
00712                 exit(1);
00713         }
00714 #endif
00715                 
00716         if ( full() ) {
00717 
00718 #ifdef _DEBUG
00719         cout << "Exitting insert, the R-tree node version; calling handleOverflow( node )" << endl; fflush( stdout );
00720 #endif
00721 
00722                 return handleOverflow( node ); //should also handle MBR updates
00723 
00724         } else {
00725 
00726                 this->children.push_back( node );
00727                 node->parent = this;
00728 
00729 #ifdef _DEBUG
00730                 cout << "Exitting insert, the R-tree node version" << endl; fflush( stdout );
00731 #endif
00732 #ifdef _GREATER_CHECK
00733                 updateMBR();
00734  #ifdef _DEBUG
00735                 cout << "\tChecking current subtree" << endl; fflush( stdout );
00736  #endif
00737                 checkEntireTreeRecursive();
00738 
00739                 if ( this->isRoot() ) {
00740  #ifdef _DEBUG
00741                         cout << "\tNOT checking parent tree recursively; we are at root." << endl; fflush( stdout );
00742  #endif
00743                 } else {
00744  #ifdef _DEBUG
00745                         cout << "\tOK, checking parents' " << this->parent << " subtree" << endl; fflush( stdout );
00746  #endif
00747                         this->parent->checkEntireTreeRecursive();
00748                 }
00749  #ifdef _DEBUG
00750                 cout << "\tOK, checking entire tree" << endl; fflush( stdout );
00751  #endif
00752                 checkEntireTree();
00753  #ifdef _DEBUG
00754                 cout << "Even exitted with entire tree check" << endl; fflush( stdout );
00755  #endif
00756 #else
00757                 updateMBR(); //propagates upward
00758 #endif
00759                 return getRoot();
00760         }
00761 }
00762 
00763 void Basic_R_tree::quadraticSplitElements( vector< BB_container* > oldItems, BB_container *newItem, vector< BB_container* > *set_one, vector< BB_container* > *set_two, BB_type *mbr_one, BB_type *mbr_two, int dimension ) {
00764         
00765         //add new item to the back of the old ones
00766         oldItems.push_back( newItem );
00767 
00768 #ifndef _HP
00769         if( oldItems.size() < 2 ) {
00770                 cerr << "Too few elements passed to quadraticSplit!" << endl;
00771                 exit(1);
00772         }
00773 #endif
00774         
00775         //find largest dead space combo
00776         unsigned int i = 0;
00777         unsigned int j = 1;
00778         unsigned int a = i;
00779         unsigned int b = j;
00780         double dead = deadSpace( *oldItems[i], *oldItems[j] );
00781         
00782         for ( ; i<oldItems.size(); i++ ) {
00783                 for ( ; j<oldItems.size(); j++ ) {
00784                         if ( i!=j ) {
00785                                 double tempdead = deadSpace( *oldItems[i], *oldItems[j] );
00786                                 if ( dead < tempdead ) {
00787                                         dead = tempdead;
00788                                         a = i;
00789                                         b = j;
00790                                 }
00791                         }
00792                 }
00793         }
00794         
00795         //add those two to two different sets and erase them from oldItems
00796         BB_type *set_one_mbr = new BB_type( oldItems[a] );
00797         BB_type *set_two_mbr = new BB_type( oldItems[b] );
00798         set_one->push_back( oldItems[a] );
00799         set_two->push_back( oldItems[b] );
00800         
00801         if ( b > a ) {
00802                 oldItems.erase( oldItems.begin() + b );
00803                 oldItems.erase( oldItems.begin() + a );
00804         } else {
00805                 oldItems.erase( oldItems.begin() + a );
00806                 oldItems.erase( oldItems.begin() + b );
00807         }
00808 
00809         //remember the volume used in set one
00810         double volumeInOne = Current_Metric::Volume( *set_one_mbr );
00811         double volumeInTwo = Current_Metric::Volume( *set_two_mbr );
00812         
00813         //add the remaining objects
00814         while ( !oldItems.empty() ) {
00815         
00816                 //check for minimum constraint
00817                 if ( properties->minimum - set_one->size() == oldItems.size() ) {
00818                         //all remaining entries must be added to set one, otherwise the min
00819                         //requirement will not be met.
00820                         for ( unsigned int i=0 ; i<oldItems.size(); i++ ) {
00821                                 set_one->push_back( oldItems[ i ] );
00822                                 (*set_one_mbr).unite( oldItems[ i ] );
00823                                 //*set_one_mbr = set_one_mbr->unite( *oldItems[ i ] );
00824                                 
00825 #ifdef _DEBUG_LINEAR_SPLIT
00826                                 cout << "\t Adding to set one (forced): " << oldItems[ i ] << endl; fflush( stdout );
00827 #endif
00828 
00829                         }
00830                         break;
00831                 } else if ( oldItems.size() == properties->minimum - set_two->size() ) {
00832                         //likewise for set two
00833                         for ( unsigned int i=0 ; i<oldItems.size(); i++ ) {
00834                                 set_two->push_back( oldItems[ i ] );
00835                                 (*set_two_mbr).unite( oldItems[ i ] ); 
00836                                 //*set_two_mbr = set_two_mbr->unite( *oldItems[ i ] );
00837 
00838 #ifdef _DEBUG_LINEAR_SPLIT
00839                                 cout << "\t Adding to set two (forced): " << oldItems[ i ] << endl; fflush( stdout );
00840 #endif
00841 
00842                         }
00843                         break;                  
00844                 }
00845         
00846         
00847                 for ( unsigned int k=0; k<oldItems.size(); k++ ) {
00848                 
00849                         //calculate dead spaces
00850                         double curVol = Current_Metric::Volume( *( oldItems[ k ] ) );
00851                         double da = Current_Metric::Volume( set_one_mbr->unionWith( *(oldItems[ k ]) ) ) - volumeInOne - curVol;
00852                         double db = Current_Metric::Volume( set_two_mbr->unionWith( *(oldItems[ k ]) ) ) - volumeInTwo - curVol;
00853                         double p = -1;
00854                 
00855                         if ( db < da ) {
00856                                 double diff = da - db;
00857                                 if ( diff > p ) {
00858                                         p = diff;
00859                                         a = k;
00860                                         b = k;
00861                                 }
00862                         } else {
00863                                 double diff = db - da;
00864                                 if ( diff > p ) {
00865                                         p = diff;
00866                                         a = k;
00867                                         b = k+1;
00868                                 }
00869                         }
00870                 }
00871                 
00872                 //now we have at a the elements which would cause the largest MBR difference
00873                 //add this element to the appropiate set
00874                 if ( a == b ) {
00875                         //only the case if db < da for element a
00876                         //so add a to set two
00877                         volumeInTwo += Current_Metric::Volume( *oldItems[ a ] );
00878                         set_two->push_back( oldItems[a] );
00879                         (*set_two_mbr).unite( oldItems[ a ] );
00880                         //*set_two_mbr = set_two_mbr->unite( *oldItems[a] );
00881                 } else {
00882                         //add to set one
00883                         volumeInOne += Current_Metric::Volume( *oldItems[ a ] );
00884                         set_one->push_back( oldItems[ a ] );
00885                         (*set_one_mbr).unite( oldItems[ a ] );
00886                         //*set_one_mbr = set_one_mbr->unite( *oldItems[a] );
00887                 }
00888 
00889                 //erase item
00890                 oldItems.erase( oldItems.begin() + a );
00891         }
00892         
00893         mbr_one->become( set_one_mbr ); delete set_one_mbr;
00894         mbr_two->become( set_two_mbr ); delete set_two_mbr;
00895         
00896 }
00897 
00898 void Basic_R_tree::quadraticSplitNodes( vector< Basic_R_tree* > oldItems, Basic_R_tree *newItem, vector< Basic_R_tree* > *set_one, vector< Basic_R_tree* > *set_two, BB_type *mbr_one, BB_type *mbr_two, int dimension ) {
00899         
00900         //add new item to the back of the old ones
00901         oldItems.push_back( newItem );
00902 
00903 #ifndef _HP
00904         if( oldItems.size() < 2 ) {
00905                 cerr << "Too few elements passed to quadraticSplit!" << endl;
00906                 exit(1);
00907         }
00908 #endif
00909         
00910         //find largest dead space combo
00911         unsigned int i = 0;
00912         unsigned int j = 1;
00913         unsigned int a = i;
00914         unsigned int b = j;
00915         double dead = deadSpace( oldItems[i]->mbr, oldItems[j]->mbr );
00916         
00917         for ( ; i<oldItems.size(); i++ ) {
00918                 for ( ; j<oldItems.size(); j++ ) {
00919                         if ( i!=j ) {
00920                                 double tempdead = deadSpace( oldItems[i]->mbr, oldItems[j]->mbr );
00921                                 if ( dead < tempdead ) {
00922                                         dead = tempdead;
00923                                         a = i;
00924                                         b = j;
00925                                 }
00926                         }
00927                 }
00928         }
00929         
00930         //add those two to two different sets and erase them from oldItems
00931         BB_type *set_one_mbr = new BB_type( &( oldItems[a]->mbr ) );
00932         BB_type *set_two_mbr = new BB_type( &( oldItems[b]->mbr ) );
00933         set_one->push_back( oldItems[a] );
00934         set_two->push_back( oldItems[b] );
00935         
00936         if ( b > a ) {
00937                 oldItems.erase( oldItems.begin() + b );
00938                 oldItems.erase( oldItems.begin() + a );
00939         } else {
00940                 oldItems.erase( oldItems.begin() + a );
00941                 oldItems.erase( oldItems.begin() + b );
00942         }
00943 
00944         //remember the volume used in set one
00945         double volumeInOne = Current_Metric::Volume( *set_one_mbr );
00946         double volumeInTwo = Current_Metric::Volume( *set_two_mbr );
00947         
00948         //add the remaining objects
00949         while ( !oldItems.empty() ) {
00950         
00951                 //check for minimum constraint
00952                 if ( properties->minimum - set_one->size() == oldItems.size() ) {
00953                         //all remaining entries must be added to set one, otherwise the min
00954                         //requirement will not be met.
00955                         for ( unsigned int i=0 ; i<oldItems.size(); i++ ) {
00956                                 set_one->push_back( oldItems[ i ] );
00957                                 (*set_one_mbr).unite( &( oldItems[ i ]->mbr ) );
00958                                 //*set_one_mbr = set_one_mbr->unite( oldItems[ i ]->mbr );
00959                                 
00960 #ifdef _DEBUG_LINEAR_SPLIT
00961                                 cout << "\t Adding to set one (forced): " << oldItems[ i ] << endl; fflush( stdout );
00962 #endif
00963 
00964                         }
00965                         break;
00966                 } else if ( oldItems.size() == properties->minimum - set_two->size() ) {
00967                         //likewise for set two
00968                         for ( unsigned int i=0 ; i<oldItems.size(); i++ ) {
00969                                 set_two->push_back( oldItems[ i ] );
00970                                 (*set_two_mbr).unite( &( oldItems[ i ]->mbr ) );
00971                                 //*set_two_mbr = set_two_mbr->unite( oldItems[ i ]->mbr );
00972 
00973 #ifdef _DEBUG_LINEAR_SPLIT
00974                                 cout << "\t Adding to set two (forced): " << oldItems[ i ] << endl; fflush( stdout );
00975 #endif
00976 
00977                         }
00978                         break;
00979                 }
00980         
00981         
00982                 for ( unsigned int k=0; k<oldItems.size(); k++ ) {
00983         
00984                         //calculate dead spaces
00985                         double curVol = Current_Metric::Volume( oldItems[ k ]->mbr );
00986                         double da = Current_Metric::Volume( set_one_mbr->unionWith( oldItems[ k ]->mbr ) ) - volumeInOne - curVol;
00987                         double db = Current_Metric::Volume( set_two_mbr->unionWith( oldItems[ k ]->mbr ) ) - volumeInTwo - curVol;
00988                         double p = -1;
00989                 
00990                         if ( db < da ) {
00991                                 double diff = da - db;
00992                                 if ( diff > p ) {
00993                                         p = diff;
00994                                         a = k;
00995                                         b = k;
00996                                 }
00997                         } else {
00998                                 double diff = db - da;
00999                                 if ( diff > p ) {
01000                                         p = diff;
01001                                         a = k;
01002                                         b = k+1;
01003                                 }
01004                         }
01005                 }
01006 
01007                 //now we have at a the elements which would cause the largest MBR difference
01008                 //add this element to the appropiate set
01009                 if ( a == b ) {
01010                         //only the case if db < da for element a
01011                         //so add a to set two
01012                         volumeInTwo += Current_Metric::Volume( oldItems[ a ]->mbr );
01013                         set_two->push_back( oldItems[ a ] );
01014                         (*set_two_mbr).unite( &( oldItems[ a ]->mbr ) );
01015                         //*set_two_mbr = set_two_mbr->unite( oldItems[ a ]->mbr );
01016                 } else {
01017                         //add to set one
01018                         volumeInOne += Current_Metric::Volume( oldItems[ a ]->mbr );
01019                         set_one->push_back( oldItems[ a ] );
01020                         (*set_one_mbr).unite( &( oldItems[ a ]->mbr ) );
01021                         //*set_one_mbr = set_one_mbr->unite( oldItems[ a ]->mbr );
01022                 }
01023         
01024                 //erase item
01025                 oldItems.erase( oldItems.begin() + a );
01026                                 
01027         }
01028         
01029         mbr_one->become( set_one_mbr ); delete set_one_mbr;
01030         mbr_two->become( set_two_mbr ); delete set_two_mbr;
01031         
01032 }
01033 
01034 void Basic_R_tree::linearSplitNodes( vector< Basic_R_tree* > oldItems, Basic_R_tree *newItem, vector< Basic_R_tree* > *set_one, vector< Basic_R_tree* > *set_two, BB_type *mbr_one, BB_type *mbr_two, int dimension ) {
01035         
01036 #ifdef _DEBUG
01037         cout << "Entering linearSplitNodes" << endl; fflush( stdout );
01038 #endif
01039 
01040 #ifdef _DEBUG_LINEAR_SPLIT
01041         cout << "\t #oldItems = " << oldItems.size() << endl; fflush( stdout );
01042 #endif
01043                 
01044         vector<double> lowerBounds; lowerBounds.resize( dimension );
01045         vector<double> upperBounds; upperBounds.resize( dimension );
01046         vector<int> lowerElements; lowerElements.resize( dimension );
01047         vector<int> upperElements; upperElements.resize( dimension );
01048 
01049 #ifdef _DEBUG_LINEAR_SPLIT
01050         cout << "\t Vectors set, entering dimension loop" << endl; fflush( stdout );
01051 #endif
01052                 
01053         //for each dimension
01054         for ( int i=0; i<dimension; i++ ) {
01055                 //for each object to be stored, find the maximum on that dimension
01056                                                 
01057 #ifdef _DEBUG_LINEAR_SPLIT
01058                 cout << "\t Recording newItem MBR max coordinates" << endl; fflush( stdout );
01059 #endif
01060 
01061                 //note that suddenly, mbrs need to implement mins.. not generic!
01062                 
01063                 //initialise all to newItem
01064                 lowerBounds[ i ] = newItem->mbr._mins[ i ];
01065                 upperBounds[ i ] = newItem->mbr._mins[ i ];
01066 
01067 #ifdef _DEBUG_LINEAR_SPLIT
01068                 cout << "\t Initial lower bounds on current dimension: " << lowerBounds[ i ] << endl; fflush( stdout );
01069                 cout << "\t Initial upper bounds on current dimension: " << upperBounds[ i ] << endl; fflush( stdout );
01070 #endif
01071                 lowerElements[ i ] = oldItems.size(); upperElements[ i ] = oldItems.size();
01072                 
01073                 for ( unsigned int j=0; j<oldItems.size(); j++ ) {
01074                         
01075 #ifdef _DEBUG_LINEAR_SPLIT
01076                         cout << "\t Recording oldItems MBR max coordinates" << endl; fflush( stdout );
01077 #endif
01078                         
01079 #ifdef _DEBUG_LINEAR_SPLIT
01080                         cout << "\t Requesting minimum, j=" << j << "<" << oldItemsMBR.size() << " and i=" << i << endl; fflush( stdout );
01081 #endif
01082 
01083                         double t = oldItems[ j ]->mbr._mins[ i ];
01084 
01085 #ifdef _DEBUG_LINEAR_SPLIT
01086                         cout << "\t Minimum t=" << t << endl; fflush( stdout );
01087                         cout << "\t Done, going for if statement." << endl; fflush( stdout );
01088 #endif
01089 
01090                         if ( t <= lowerBounds[ i ] ) {
01091                                 lowerBounds[ i ] = t;
01092                                 lowerElements[ i ] = j;
01093                         }
01094                                 
01095 #ifdef _DEBUG_LINEAR_SPLIT
01096                         cout << "\t Requesting maximum, j="<<j<<" and i=" << i << endl; fflush( stdout );
01097 #endif
01098                         
01099 #ifdef _DEBUG_LINEAR_SPLIT
01100                         cout << "\t Maximum t=" << t << endl; fflush( stdout );
01101                         cout << "\t Done, going for if statement." << endl; fflush( stdout );
01102 #endif
01103 
01104                         if ( t > upperBounds[ i ] ) {
01105                                 upperBounds[ i ] = t;
01106                                 upperElements[ i ] = j;
01107                         }
01108                 }
01109 
01110 #ifdef _DEBUG_LINEAR_SPLIT
01111                 cout << "\t Calculating difference" << endl; fflush( stdout );
01112 #endif
01113 
01114                 //store only the upper<>lower difference
01115                 lowerBounds[ i ] = upperBounds[ i ] - lowerBounds[ i ];
01116 
01117         }
01118 
01119 #ifdef _DEBUG_LINEAR_SPLIT
01120         cout << "\t Calculating maximum" << endl; fflush( stdout );
01121 #endif
01122 
01123         //the below can be incorporated in the above loop
01124         //altough it shouldnt make that much difference
01125         //select the dimension with max difference
01126         int k=0; double t=lowerBounds[0];
01127         
01128 #ifdef _DEBUG_LINEAR_SPLIT
01129         cout << "\t Max = " << t << endl; fflush( stdout );
01130 #endif
01131 
01132         for ( int i=1; i<dimension; i++ ) {
01133 
01134 #ifdef _DEBUG_LINEAR_SPLIT
01135                 cout << "\t Difference = " << lowerBounds[ i ] << endl; fflush( stdout );
01136 #endif
01137 
01138                 if ( lowerBounds[i] > t ) {
01139                         t=lowerBounds[i];
01140                         k=i;
01141 
01142 #ifdef _DEBUG_LINEAR_SPLIT
01143                         cout << "\t Max = " << k << endl; fflush( stdout );
01144 #endif
01145 
01146                 }
01147         }
01148 
01149 #ifdef _DEBUG_LINEAR_SPLIT
01150         cout << "\t Add everything to a single vector" << endl; fflush( stdout );
01151 #endif
01152 
01153         //put all elements to be stored in a single vector
01154         oldItems.push_back( newItem );
01155 
01156 #ifdef _DEBUG_LINEAR_SPLIT
01157         cout << "\t Add the first two items" << endl; fflush( stdout );
01158 #endif
01159                 
01160         //put the extreme 
01161         set_one->push_back( oldItems[ lowerElements[ k ] ] );
01162         set_two->push_back( oldItems[ upperElements[ k ] ] );
01163         
01164 #ifdef _DEBUG_LINEAR_SPLIT
01165         cout << "\t Construct the two set MBRs" << endl; fflush( stdout );
01166         cout << "\t Initially added extreme objects: " <<  oldItems[ lowerElements[ k ] ] << " and " <<  oldItems[ upperElements[ k ] ] << endl;
01167 #endif
01168 
01169         //remember the MBRs of each set
01170         BB_type *set_one_mbr = new BB_type( &( oldItems[ lowerElements[ k ] ]->mbr ) );
01171         BB_type *set_two_mbr = new BB_type( &( oldItems[ upperElements[ k ] ]->mbr ) );
01172 
01173 #ifdef _DEBUG_LINEAR_SPLIT
01174         cout << "\t Erasing the two already added items" << endl; fflush( stdout );
01175         cout << "\t Going to erase: " << (*(oldItems.begin() + lowerElements[ k ])) << endl;
01176         cout << "\t and: " << (*(oldItems.begin() + upperElements[ k ])) << endl;
01177 #endif
01178 
01179         //erase the already added items
01180         oldItems.erase( oldItems.begin() + lowerElements[ k ] );
01181         
01182 #ifndef _HP
01183         if ( lowerElements[ k ] == upperElements[ k ] ) {
01184                 cerr << "Error: Linear split found two extreme elements to be the same!" << endl;
01185                 cerr << set_one_mbr->toString() << endl;
01186                 cerr << set_two_mbr->toString() << endl;
01187                 exit( 1 );
01188         }
01189 #endif
01190         
01191         if ( lowerElements[ k ] < upperElements[ k ] ) {
01192                 oldItems.erase( oldItems.begin() + ( upperElements[ k ] - 1 ) );
01193         } else {
01194                 oldItems.erase( oldItems.begin() + upperElements[ k ] );
01195         }
01196         
01197 #ifdef _DEBUG_LINEAR_SPLIT
01198         cout << "\t Adding the not yet added elements" << endl; fflush( stdout );
01199 #endif
01200 
01201         //add the remaining entries
01202         while ( !oldItems.empty() ) {
01203         
01204                 //check for minimum constraint
01205                 if ( properties->minimum - set_one->size() == oldItems.size() ) {
01206                         //all remaining entries must be added to set one, otherwise the min
01207                         //requirement will not be met.
01208                         for ( unsigned int i=0 ; i<oldItems.size(); i++ ) {
01209                                 set_one->push_back( oldItems[ i ] );
01210                                 (*set_one_mbr).unite( &( oldItems[ i ]->mbr ) );
01211                                 //*set_one_mbr = set_one_mbr->unite( oldItems[ i ]->mbr );
01212                                 
01213 #ifdef _DEBUG_LINEAR_SPLIT
01214                                 cout << "\t Adding to set one (forced): " << oldItems[ i ] << endl; fflush( stdout );
01215 #endif
01216 
01217                         }
01218                         break;
01219                 } else if ( oldItems.size() == properties->minimum - set_two->size() ) {
01220                         //likewise for set two
01221                         for ( unsigned int i=0 ; i<oldItems.size(); i++ ) {
01222                                 set_two->push_back( oldItems[ i ] );
01223                                 (*set_two_mbr).unite( &( oldItems[ i ]->mbr ) );
01224                                 //*set_two_mbr = set_two_mbr->unite( oldItems[ i ]->mbr );
01225 
01226 #ifdef _DEBUG_LINEAR_SPLIT
01227                                 cout << "\t Adding to set two (forced): " << oldItems[ i ] << endl; fflush( stdout );
01228 #endif
01229 
01230                         }
01231                         break;                  
01232                 }
01233         
01234 #ifdef _DEBUG_LINEAR_SPLIT
01235                 cout << "\t Getting random number" << endl; fflush( stdout );
01236 #endif
01237 
01238                 //select randomly
01239                 double rdm = ((double)rand()) / ((double)RAND_MAX + 1);
01240                 unsigned int i = (int)(rdm * oldItems.size());
01241 
01242 #ifndef _HP
01243                 if ( i>=oldItems.size() ) {
01244                         cerr << "Random index number generated is too large!" << endl;
01245                         exit(1);
01246                 }
01247 #endif
01248 
01249 #ifdef _DEBUG_LINEAR_SPLIT
01250                 cout << "\t Calculating area enlargements" << endl; fflush( stdout );
01251 #endif
01252 
01253                 //calculate area enlargement
01254                 double s = areaEnlargement( *set_one_mbr, oldItems[ i ]->mbr );
01255                 double t = areaEnlargement( *set_two_mbr, oldItems[ i ]->mbr );
01256 
01257 #ifdef _DEBUG_LINEAR_SPLIT
01258                 cout << "\t Going for ifs" << endl; fflush( stdout );
01259 #endif
01260 
01261                 if ( s < t ) {
01262                         set_one->push_back( oldItems[ i ] );
01263 
01264 #ifdef _DEBUG_LINEAR_SPLIT
01265                         cout << "\t Adding to set one: " << oldItems[ i ] << endl; fflush( stdout );
01266 #endif
01267 
01268                         //note the following code duplication, could be optimised
01269                         (*set_one_mbr).unite( &( oldItems[ i ]->mbr ) );
01270                         //*set_one_mbr = set_one_mbr->unite( oldItems[ i ]->mbr );
01271                 } else {
01272                         set_two->push_back( oldItems[ i ] );
01273 
01274 #ifdef _DEBUG_LINEAR_SPLIT
01275                         cout << "\t Adding to set two: " << oldItems[ i ] << endl; fflush( stdout );
01276 #endif
01277 
01278                         //note the following code duplication, could be optimised
01279                         (*set_two_mbr).unite( &( oldItems[ i ]->mbr ) );
01280                         //*set_two_mbr = set_two_mbr->unite( oldItems[ i ]->mbr );
01281                 }       
01282 
01283 #ifdef _DEBUG_LINEAR_SPLIT
01284                 cout << "\t Going for erase" << endl; fflush( stdout );
01285                 cout << "\t Erasing the just now added item" << endl; fflush( stdout );
01286                 cout << "\t Going to erase: " << (*(oldItems.begin() + i )) << endl;
01287 #endif
01288 
01289                 //delete
01290 #ifdef _DEBUG_LINEAR_SPLIT
01291                 cout << "\t Erasing item" << endl; fflush( stdout );
01292 #endif
01293 
01294 
01295                 oldItems.erase( oldItems.begin() + i );
01296                 
01297         }
01298 
01299 #ifdef _DEBUG_LINEAR_SPLIT
01300         cout << "Propagating mbr changes" << endl; fflush( stdout );
01301 #endif          
01302                 
01303         mbr_one->become( set_one_mbr ); delete set_one_mbr;
01304         mbr_two->become( set_two_mbr ); delete set_two_mbr;
01305         
01306 #ifdef _DEBUG_LINEAR_SPLIT
01307         cout << "\tNumber of elements in set 1: " << set_one->size() << endl; fflush( stdout );
01308         cout << "\tSet one MBR: " << endl << set_one_mbr->toString();
01309         cout << "\tNumber of elements in set 2: " << set_two->size() << endl; fflush( stdout );
01310         cout << "\tSet two MBR: " << endl << set_two_mbr->toString();
01311 #endif
01312 
01313 #ifdef _DEBUG
01314         cout << "Exitting linearSplit" << endl; fflush( stdout );
01315 #endif
01316 
01317 
01318 }
01319 
01320 void Basic_R_tree::linearSplitElements( vector< BB_container* > oldItems, BB_container *newItem, vector< BB_container* > *set_one, vector< BB_container* > *set_two, BB_type *mbr_one, BB_type *mbr_two, int dimension ) {
01321 
01322 #ifdef _DEBUG
01323         cout << "Entering linearSplitElements" << endl; fflush( stdout );
01324 #endif
01325 
01326 #ifdef _DEBUG_LINEAR_SPLIT
01327         cout << "\t #oldItems = " << oldItems.size() << endl; fflush( stdout );
01328 #endif
01329                 
01330         vector<double> lowerBounds; lowerBounds.resize( dimension );
01331         vector<double> upperBounds; upperBounds.resize( dimension );
01332         vector<int> lowerElements; lowerElements.resize( dimension );
01333         vector<int> upperElements; upperElements.resize( dimension );
01334 
01335 #ifdef _DEBUG_LINEAR_SPLIT
01336         cout << "\t Vectors set, entering dimension loop" << endl; fflush( stdout );
01337 #endif
01338                 
01339         //for each dimension
01340         for ( int i=0; i<dimension; i++ ) {
01341                 //for each object to be stored, find the maximum on that dimension
01342                                                 
01343 #ifdef _DEBUG_LINEAR_SPLIT
01344                 cout << "\t Recording newItem MBR max coordinates" << endl; fflush( stdout );
01345 #endif
01346 
01347                 //note that suddenly, mbrs need to implement mins.. not generic!
01348                 
01349                 //initialise all to newItem
01350                 lowerBounds[ i ] = newItem->_mins[ i ];
01351                 upperBounds[ i ] = newItem->_mins[ i ];
01352 
01353 #ifdef _DEBUG_LINEAR_SPLIT
01354                 cout << "\t Initial lower bounds on current dimension: " << lowerBounds[ i ] << endl; fflush( stdout );
01355                 cout << "\t Initial upper bounds on current dimension: " << upperBounds[ i ] << endl; fflush( stdout );
01356 #endif
01357                 lowerElements[ i ] = oldItems.size(); upperElements[ i ] = oldItems.size();
01358                 
01359                 for ( unsigned int j=0; j<oldItems.size(); j++ ) {
01360                         
01361 #ifdef _DEBUG_LINEAR_SPLIT
01362                         cout << "\t Recording oldItems MBR max coordinates" << endl; fflush( stdout );
01363 #endif
01364                         
01365 #ifdef _DEBUG_LINEAR_SPLIT
01366                         cout << "\t Requesting minimum, j=" << j << "<" << oldItemsMBR.size() << " and i=" << i << endl; fflush( stdout );
01367 #endif
01368 
01369                         double t = oldItems[ j ]->_mins[ i ];
01370 
01371 #ifdef _DEBUG_LINEAR_SPLIT
01372                         cout << "\t Minimum t=" << t << endl; fflush( stdout );
01373                         cout << "\t Done, going for if statement." << endl; fflush( stdout );
01374 #endif
01375 
01376                         if ( t <= lowerBounds[ i ] ) {
01377                                 lowerBounds[ i ] = t;
01378                                 lowerElements[ i ] = j;
01379                         }
01380                                 
01381 #ifdef _DEBUG_LINEAR_SPLIT
01382                         cout << "\t Requesting maximum, j="<<j<<" and i=" << i << endl; fflush( stdout );
01383 #endif
01384                                 
01385 #ifdef _DEBUG_LINEAR_SPLIT
01386                         cout << "\t Maximum t=" << t << endl; fflush( stdout );
01387                         cout << "\t Done, going for if statement." << endl; fflush( stdout );
01388 #endif
01389 
01390                         if ( t > upperBounds[ i ] ) {
01391                                 upperBounds[ i ] = t;
01392                                 upperElements[ i ] = j;
01393                         }
01394                 }
01395 
01396 #ifdef _DEBUG_LINEAR_SPLIT
01397                 cout << "\t Calculating difference" << endl; fflush( stdout );
01398 #endif
01399 
01400                 //store only the upper<>lower difference
01401                 lowerBounds[ i ] = upperBounds[ i ] - lowerBounds[ i ];
01402 
01403         }
01404 
01405 #ifdef _DEBUG_LINEAR_SPLIT
01406         cout << "\t Calculating maximum" << endl; fflush( stdout );
01407 #endif
01408 
01409         //the below can be incorporated in the above loop
01410         //altough it shouldnt make that much difference
01411         //select the dimension with max difference
01412         int k=0; double t=lowerBounds[0];
01413         
01414 #ifdef _DEBUG_LINEAR_SPLIT
01415         cout << "\t Max = " << t << endl; fflush( stdout );
01416 #endif
01417 
01418         for ( int i=1; i<dimension; i++ ) {
01419 
01420 #ifdef _DEBUG_LINEAR_SPLIT
01421                 cout << "\t Difference = " << lowerBounds[ i ] << endl; fflush( stdout );
01422 #endif
01423 
01424                 if ( lowerBounds[i] > t ) {
01425                         t=lowerBounds[i];
01426                         k=i;
01427 
01428 #ifdef _DEBUG_LINEAR_SPLIT
01429                         cout << "\t Max = " << k << endl; fflush( stdout );
01430 #endif
01431 
01432                 }
01433         }
01434 
01435 #ifdef _DEBUG_LINEAR_SPLIT
01436         cout << "\t Add everything to a single vector" << endl; fflush( stdout );
01437 #endif
01438 
01439         //put all elements to be stored in a single vector
01440         oldItems.push_back( newItem );
01441 
01442 #ifdef _DEBUG_LINEAR_SPLIT
01443         cout << "\t Add the first two items" << endl; fflush( stdout );
01444 #endif
01445                 
01446         //put the extreme 
01447         set_one->push_back( oldItems[ lowerElements[ k ] ] );
01448         set_two->push_back( oldItems[ upperElements[ k ] ] );
01449         
01450 #ifdef _DEBUG_LINEAR_SPLIT
01451         cout << "\t Construct the two set MBRs" << endl; fflush( stdout );
01452         cout << "\t Initially added extreme objects: " <<  oldItems[ lowerElements[ k ] ] << " and " <<  oldItems[ upperElements[ k ] ] << endl;
01453 #endif
01454 
01455         //remember the MBRs of each set
01456         BB_type *set_one_mbr = new BB_type( oldItems[ lowerElements[ k ] ] );
01457         BB_type *set_two_mbr = new BB_type( oldItems[ upperElements[ k ] ] );
01458 
01459 #ifdef _DEBUG_LINEAR_SPLIT
01460         cout << "\t Erasing the two already added items" << endl; fflush( stdout );
01461         cout << "\t Going to erase: " << (*(oldItems.begin() + lowerElements[ k ])) << endl;
01462         cout << "\t and: " << (*(oldItems.begin() + upperElements[ k ])) << endl;
01463 #endif
01464 
01465         //erase the already added items
01466         oldItems.erase( oldItems.begin() + lowerElements[ k ] );
01467         
01468 #ifndef _HP
01469         if ( lowerElements[ k ] == upperElements[ k ] ) {
01470                 cerr << "Error: Linear split found two extreme elements to be the same!" << endl;
01471                 cerr << set_one_mbr->toString() << endl;
01472                 cerr << set_two_mbr->toString() << endl;
01473                 exit( 1 );
01474         }
01475 #endif
01476         
01477         if ( lowerElements[ k ] < upperElements[ k ] ) {
01478                 oldItems.erase( oldItems.begin() + ( upperElements[ k ] - 1 ) );
01479         } else {
01480                 oldItems.erase( oldItems.begin() + upperElements[ k ] );
01481         }
01482         
01483 #ifdef _DEBUG_LINEAR_SPLIT
01484         cout << "\t Adding the not yet added elements" << endl; fflush( stdout );
01485 #endif
01486 
01487         //add the remaining entries
01488         while ( !oldItems.empty() ) {
01489         
01490                 //check for minimum constraint
01491                 if ( properties->minimum - set_one->size() == oldItems.size() ) {
01492                         //all remaining entries must be added to set one, otherwise the min
01493                         //requirement will not be met.
01494                         for ( unsigned int i=0 ; i<oldItems.size(); i++ ) {
01495                                 set_one->push_back( oldItems[ i ] );
01496                                 set_one_mbr->unite( oldItems[ i ] );
01497                                 //*set_one_mbr = set_one_mbr->unite( *oldItems[ i ] );
01498                                 
01499 #ifdef _DEBUG_LINEAR_SPLIT
01500                                 cout << "\t Adding to set one (forced): " << oldItems[ i ] << endl; fflush( stdout );
01501 #endif
01502 
01503                         }
01504                         break;
01505                 } else if ( oldItems.size() == properties->minimum - set_two->size() ) {
01506                         //likewise for set two
01507                         for ( unsigned int i=0 ; i<oldItems.size(); i++ ) {
01508                                 set_two->push_back( oldItems[ i ] );
01509                                 set_two_mbr->unite( oldItems[ i ] );
01510                                 //*set_two_mbr = set_two_mbr->unite( *oldItems[ i ] );
01511 
01512 #ifdef _DEBUG_LINEAR_SPLIT
01513                                 cout << "\t Adding to set two (forced): " << oldItems[ i ] << endl; fflush( stdout );
01514 #endif
01515 
01516                         }
01517                         break;                  
01518                 }
01519         
01520 #ifdef _DEBUG_LINEAR_SPLIT
01521                 cout << "\t Getting random number" << endl; fflush( stdout );
01522 #endif
01523 
01524                 //select randomly
01525                 double rdm = ((double)rand()) / ((double)RAND_MAX + 1);
01526                 unsigned int i = (int)(rdm * oldItems.size());
01527 
01528 #ifndef _HP
01529                 if ( i>=oldItems.size() ) {
01530                         cerr << "Random index number generated is too large!" << endl;
01531                         exit(1);
01532                 }
01533 #endif
01534 
01535 #ifdef _DEBUG_LINEAR_SPLIT
01536                 cout << "\t Calculating area enlargements" << endl; fflush( stdout );
01537 #endif
01538 
01539                 //calculate area enlargement
01540                 double s = areaEnlargement( *set_one_mbr, *oldItems[ i ] );
01541                 double t = areaEnlargement( *set_two_mbr, *oldItems[ i ] );
01542 
01543 #ifdef _DEBUG_LINEAR_SPLIT
01544                 cout << "\t Going for ifs" << endl; fflush( stdout );
01545 #endif
01546 
01547                 if ( s < t ) {
01548                         set_one->push_back( oldItems[ i ] );
01549 
01550 #ifdef _DEBUG_LINEAR_SPLIT
01551                         cout << "\t Adding to set one: " << oldItems[ i ] << endl; fflush( stdout );
01552 #endif
01553 
01554                         //note the following code duplication, could be optimised
01555                         set_one_mbr->unite( oldItems[ i ] );
01556                         //*set_one_mbr = set_one_mbr->unite( *oldItems[ i ] );
01557                 } else {
01558                         set_two->push_back( oldItems[ i ] );
01559 
01560 #ifdef _DEBUG_LINEAR_SPLIT
01561                         cout << "\t Adding to set two: " << oldItems[ i ] << endl; fflush( stdout );
01562 #endif
01563 
01564                         //note the following code duplication, could be optimised
01565                         set_two_mbr->unite( oldItems[ i ] );
01566                         //*set_two_mbr = set_two_mbr->unite( *oldItems[ i ] );
01567                 }       
01568 
01569 #ifdef _DEBUG_LINEAR_SPLIT
01570                 cout << "\t Going for erase" << endl; fflush( stdout );
01571                 cout << "\t Erasing the just now added item" << endl; fflush( stdout );
01572                 cout << "\t Going to erase: " << (*(oldItems.begin() + i )) << endl;
01573 #endif
01574 
01575                 //delete
01576 #ifdef _DEBUG_LINEAR_SPLIT
01577                 cout << "\t Erasing item" << endl; fflush( stdout );
01578 #endif
01579 
01580 
01581                 oldItems.erase( oldItems.begin() + i );
01582                 
01583         }
01584 
01585 #ifdef _DEBUG_LINEAR_SPLIT
01586         cout << "Propagating mbr changes" << endl; fflush( stdout );
01587 #endif          
01588                 
01589         mbr_one->become( set_one_mbr ); delete set_one_mbr;
01590         mbr_two->become( set_two_mbr ); delete set_two_mbr;
01591         
01592 #ifdef _DEBUG_LINEAR_SPLIT
01593         cout << "\tNumber of elements in set 1: " << set_one->size() << endl; fflush( stdout );
01594         cout << "\tSet one MBR: " << endl << set_one_mbr->toString();
01595         cout << "\tNumber of elements in set 2: " << set_two->size() << endl; fflush( stdout );
01596         cout << "\tSet two MBR: " << endl << set_two_mbr->toString();
01597 #endif
01598 
01599 #ifdef _DEBUG
01600         cout << "Exitting linearSplit" << endl; fflush( stdout );
01601 #endif
01602 
01603 
01604 }
01605 
01606 
01607 Basic_R_tree *Basic_R_tree::handleOverflow( Basic_R_tree *node, BB_container *element ) {
01608 #ifdef _DEBUG
01609         cout << "Entering handleOverflow, the node-polytope version" << endl; fflush( stdout );
01610 #endif
01611 #ifdef _GREATER_CHECK
01612         checkEntireTree();
01613  #ifdef _DEBUG
01614         cout << "\tTree is valid." << endl; fflush( stdout );
01615  #endif
01616 #endif
01617 
01618         //set splits
01619         vector< BB_container* > set_one;
01620         vector< BB_container* > set_two;
01621         BB_type *mbr_one;
01622         BB_type *mbr_two;
01623         mbr_one = new BB_type();
01624         mbr_two = new BB_type();
01625         
01626         //build item nodes
01627         vector< BB_container* > oldItems;
01628         for( unsigned int i=0; i<this->elements.size(); i++ ) {
01629                 oldItems.push_back( this->elements[ i ] );
01630         }
01631         
01632         switch( SPLIT_STRATEGY ) {
01633                 case LINEAR_SPLIT:
01634                         linearSplitElements( oldItems, element, &set_one, &set_two, mbr_one, mbr_two, element->getDimension() );
01635                         break;
01636                 case QUADRATIC_SPLIT:
01637                         quadraticSplitElements( oldItems, element, &set_one, &set_two, mbr_one, mbr_two, element->getDimension() ); 
01638                         break;
01639                 case EXPONENTIAL_SPLIT:
01640                         cerr << "x^Split! " << endl; exit(1);
01641                         break;
01642                 default:
01643                         cerr << "No valid split strategy selected! (r-tree.h)" << endl;
01644                         exit(1);
01645         }
01646 
01647 #ifdef _DEBUG
01648         cout << "Set one has " << set_one.size() << " items." << endl; fflush( stdout );
01649         cout << "Set two has " << set_two.size() << " items." << endl; fflush( stdout );
01650 #endif
01651 
01652         // build a node from the first set. Let it have the correct MBR.
01653         Basic_R_tree *child_one = buildNode( set_one, mbr_one );
01654 
01655 #ifdef _DEBUG
01656         cout << "Child one has " << child_one->elements.size() << " elements." << endl; fflush( stdout );
01657 #endif
01658 
01659 #ifdef _GREATER_CHECK
01660  #ifdef _DEBUG
01661                         cout << "\tcheckEntireTree after buildnode" << endl; fflush( stdout );
01662                         checkEntireTree();
01663                         cout << "\tOK" << endl; fflush( stdout );
01664  #endif
01665 #endif
01666 
01667         //let the overflowed node contain the elements of the second set, with the correct MBR.
01668         node->setElements( set_two, mbr_two );
01669 
01670 #ifdef _DEBUG
01671         cout << "Current node has " << node->elements.size() << " elements." << endl; fflush( stdout );
01672 #endif
01673 
01674         //delete temporary mbrs
01675         delete mbr_one;
01676         delete mbr_two;
01677 
01678 #ifdef _GREATER_CHECK
01679  #ifdef _DEBUG
01680         cout << "\tCheck child one subtree invariants: " << endl;
01681  #endif
01682         child_one->checkInvariants();
01683  #ifdef _DEBUG
01684         cout << "\tOK. Check current subtree invariants: " << endl;
01685  #endif
01686         node->checkInvariants();
01687  #ifdef _DEBUG
01688         cout << "\tOK." << endl;
01689  #endif
01690 #endif
01691         
01692         //insert the new node
01693         if ( node->isRoot() ) {
01694 
01695 #ifdef _DEBUG
01696                 cout << "Exitting handleOverflow, the node-polytope version" << endl; fflush( stdout );
01697 #endif
01698 
01699                 //make new root should supply the new root with a valid MBR
01700                 return node->makeNewRoot( child_one );
01701         } else {
01702 
01703 #ifdef _DEBUG
01704                 cout << "Exitting handleOverflow, the node-polytope version" << endl; fflush( stdout );
01705 #endif
01706 
01707                 //node insertion will check for new overflows
01708                 //it will also propagate some MBR updates
01709                 return node->parent->insert( child_one );
01710         }
01711 }
01712 
01713 Basic_R_tree *Basic_R_tree::chooseLeaf( Basic_R_tree *v, const BB_type bb ) const {
01714 #ifdef _DEBUG
01715         cout << "Entering chooseLeaf" << endl; fflush( stdout );
01716 #endif
01717         if ( v->isLeaf() ) {
01718 
01719 #ifdef _DEBUG
01720                 cout << "Exitting chooseLeaf" << endl; fflush( stdout );
01721 #endif
01722                 return v;
01723 
01724         }
01725                 
01726         //v is not leaf, so there is at least one child
01727         double m = areaEnlargement( this->children[0]->mbr, bb );
01728         double c = m;
01729         int j = 0;
01730         
01731         for( unsigned int i=1; i<this->children.size(); i++ ) {
01732                 c = areaEnlargement( this->children[i]->mbr, bb );
01733                 if ( c < m ) {
01734                         m = c;
01735                         j = i;
01736                 } else if ( c == m ) {
01737                         if ( Current_Metric::Volume( this->children[j]->mbr ) > Current_Metric::Volume( this->children[i]->mbr ) ) {
01738                                 m = c;
01739                                 j = i;
01740                         }
01741                 }
01742                 // else if ( c == m )?? TODO
01743         }
01744 
01745 #ifdef _DEBUG
01746         cout << "calling chooseLeaf recursively" << endl; fflush( stdout );
01747 #endif
01748 
01749         return chooseLeaf( this->children[j], bb );
01750 }
01751 
01752 Basic_R_tree *Basic_R_tree::search( BB_container *element ) {
01753 
01754 #ifdef _DEBUG
01755         cout << "Entering search(polytope)" << endl; fflush( stdout );
01756 #endif
01757         
01758         if ( this->isLeaf() ) {
01759                 vector< BB_container* >::iterator it = this->elements.begin();
01760                 for( ; it!=this->elements.end(); it++ )
01761                         if ( (*it)->getID() == element->getID() )
01762                                 return this;
01763                 return 0;
01764         } else {
01765                 childIterator it = this->children.begin();
01766                 for( ; it!=this->children.end(); it++ ) {
01767                         if ( element->intersects( (*it)->mbr ) ) {
01768                                 Basic_R_tree *candidate = (*it)->search( element );
01769                                 if ( candidate != 0 ) {
01770                                         return candidate;
01771                                 }
01772                         }
01773                 }
01774                 
01775 #ifdef _DEBUG
01776                 cout << "Exitting search(polytope) -- nothing found" << endl; fflush( stdout );
01777 #endif
01778                 return 0;
01779         }
01780 }
01781 
01782 #ifdef _OUTPUT_TREE
01783 unsigned int _counter_insertion = 0;
01784 #endif
01785 
01786 Basic_R_tree *Basic_R_tree::insert( BB_container *element ) {
01787 
01788 #ifdef _DEBUG
01789         cout << "Entering insert(element)" << endl; fflush( stdout );
01790 #endif
01791 
01792 #ifdef _GREATER_CHECK
01793  #ifdef _DEBUG
01794         cout << "Going for check at the start of insert( element )" << endl;
01795  #endif
01796         checkEntireTree();
01797  #ifdef _DEBUG
01798         cout << "Check succes!" << endl;
01799  #endif
01800 #endif
01801 
01802         Basic_R_tree *node = chooseLeaf( this, *element );
01803         if ( !( node->full() ) ) {
01804 
01805 #ifndef _HP
01806                 if ( !node->isLeaf() ) {
01807                         cerr << "Attempted to store element at non-leaf node in R-tree!" << endl;
01808                         exit(1);
01809                 }
01810 #endif
01811 
01812                 node->elements.push_back( element );
01813 
01814                 node->updateMBR();
01815 
01816         } else {
01817                 //MBR updating is handled inside handleOverflow
01818                 handleOverflow( node, element );
01819         }
01820 
01821 #ifdef _GREATER_CHECK
01822  #ifdef _DEBUG
01823         cout << "Going for check at the end of insert( element )" << endl;
01824  #endif
01825         checkEntireTree();
01826  #ifdef _DEBUG
01827         cout << "Check succes!" << endl;
01828  #endif
01829 #endif
01830         
01831 #ifdef _DEBUG
01832         cout << "Exitting insert(element)" << endl; fflush( stdout );
01833 #endif
01834 
01835 #ifdef _OUTPUT_TREE
01836         ostringstream oss;
01837         
01838         oss << "debug_tree_out.";
01839         oss << _counter_insertion;
01840 
01841         node->getRoot()->writeTreeToFile( oss.str() );
01842         _counter_insertion++;
01843 #endif
01844 
01845         return node->getRoot();
01846 
01847 }
01848 
01849 const Basic_R_tree *Basic_R_tree::getRoot() const {
01850 
01851 #ifdef _DEBUG
01852         cout << "const getRoot() called in R-tree. Current node has " << this->children.size() << " children and stores " << this->elements.size() << " elements." << endl; fflush( stdout );
01853 #endif
01854 
01855         if ( !this->isRoot() )
01856                 return this->parent->getRoot();
01857         else
01858                 return this;
01859 }
01860 
01861 Basic_R_tree *Basic_R_tree::getRoot() {
01862 
01863 #ifdef _DEBUG
01864         cout << "getRoot() called in R-tree. Current node has " << this->children.size() << " children and stores " << this->elements.size() << " elements." << endl; fflush( stdout );
01865 #endif
01866 
01867         if ( !this->isRoot() )
01868                 return this->parent->getRoot();
01869         else
01870                 return this;
01871 }
01872 
01873 Basic_R_tree *Basic_R_tree::remove( BB_container *element ) {
01874 
01875 #ifdef _DEBUG
01876         cout << "Entering remove(element)" << endl; fflush( stdout );
01877 #endif
01878 
01879         //first search the element
01880         Basic_R_tree *node = this->search( element );
01881         if ( node == 0 )
01882                 cerr << "Warning: to be removed element from R-tree was not found. Ignoring..." << endl;
01883         else
01884                 this->remove( node, element );
01885                 
01886         node->updateMBR();
01887 
01888 #ifdef _GREATER_CHECK
01889         this->checkEntireTree();
01890 #endif
01891                         
01892 #ifdef _DEBUG
01893         cout << "Exitting remove(element)" << endl; fflush( stdout );
01894 #endif
01895 
01896         return getRoot();
01897 }
01898 
01899 #endif

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