⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x_tree.cc

📁 X-tree的C++源码
💻 CC
字号:
#include <math.h>#ifdef S3#include "s3.h"#else#include "x_tree.h"#endif#define CHECK_MBR//////////////////////////////////////////////////////////////////////////////// globals//////////////////////////////////////////////////////////////////////////////int XTDirNode__dimension;void* XTDirNode__my_tree;int XTDataNode__dimension;//////////////////////////////////////////////////////////////////////////////// C-functions//////////////////////////////////////////////////////////////////////////////float area(int dimension, float *mbr)// berechnet Flaeche (Volumen) eines mbr der Dimension dimension{    int i;    float sum;    sum = 1.0;    for (i = 0; i < dimension; i++)	sum *= mbr[2*i+1] - mbr[2*i];    return sum;}float margin(int dimension, float *mbr)// berechnet Umfang eines mbr der Dimension dimension{    int i;    float *ml, *mu, *m_last, sum;    sum = 0.0;    m_last = mbr + 2*dimension;    ml = mbr;    mu = ml + 1;    while (mu < m_last)    {	sum += *mu - *ml;	ml += 2;	mu += 2;    }    return sum;}bool inside(float &p, float &lb, float &ub)// ist ein Skalar in einem Intervall ?{    return (p >= lb && p <= ub);}bool inside(float *v, float *mbr, int dimension)// ist ein Vektor in einer Box ?{    int i;    for (i = 0; i < dimension; i++)	if (!inside(v[i], mbr[2*i], mbr[2*i+1]))	    return FALSE;    return TRUE;}float overlap (int dim, float *q1, float *q2) {      // Bestimmt den Schnittquader   // zwischen q1 und q2      float sum = 1.0;      for (int i = 0; i < dim; i++) {      sum *= min(q1[2*i+1],q2[2*i+1]) - max(q1[2*i],q2[2*i]);      if (sum <= 0) {	 sum = 0;	 break;      }   }   return sum;}/*float overlap(int dimension, float *r1, float *r2)// calcutales the overlapping area of r1 and r2// calculate overlap in every dimension and multiplicate the values{    float sum;    float *r1pos, *r2pos, *r1last, r1_lb, r1_ub, r2_lb, r2_ub;    sum = 1.0;    r1pos = r1; r2pos = r2;    r1last = r1 + 2 * dimension;    while (r1pos < r1last)    {	r1_lb = *(r1pos++);	r1_ub = *(r1pos++);	r2_lb = *(r2pos++);	r2_ub = *(r2pos++);        // calculate overlap in this dimension        if (inside(r1_ub, r2_lb, r2_ub))        // upper bound of r1 is inside r2 	{            if (inside(r1_lb, r2_lb, r2_ub))            // and lower bound of r1 is inside                sum *= (r1_ub - r1_lb);            else                sum *= (r1_ub - r2_lb);	}	else	{            if (inside(r1_lb, r2_lb, r2_ub))	    // and lower bound of r1 is inside		sum *= (r2_ub - r1_lb);	    else 	    {		if (inside(r2_lb, r1_lb, r1_ub) &&		    inside(r2_ub, r1_lb, r1_ub))	        // r1 contains r2		    sum *= (r2_ub - r2_lb);		else		// r1 and r2 do not overlap		    sum = 0.0;	    }	}    }    return sum;}*/ void enlarge(int dimension, float **mbr, float *r1, float *r2)// enlarge r in a way that it contains s{    int i;    *mbr = new float[2*dimension];    for (i = 0; i < 2*dimension; i += 2)    {	(*mbr)[i]   = min(r1[i],   r2[i]);	(*mbr)[i+1] = max(r1[i+1], r2[i+1]);    }#ifdef CHECK_MBR    check_mbr(dimension,*mbr);#endif}bool section(int dimension, float *mbr1, float *mbr2){    int i;    for (i = 0; i < dimension; i++)    {	if (mbr1[2*i]     > mbr2[2*i + 1] ||	    mbr1[2*i + 1] < mbr2[2*i]) 	    return FALSE;    }    return TRUE;}bool section_c(int dimension, float *mbr1, const void *center, float radius){	float r2;	r2 = radius * radius;	if ( (r2 - MINDIST(center,mbr1)) < 1.0e-8)		return TRUE;	else		return FALSE;	}int sort_lower_mbr(const void *d1, const void *d2)// Vergleichsfunktion fuer qsort, sortiert nach unterem Wert der mbr bzgl.// der angegebenen Dimension{    SortMbr *s1, *s2;    float erg;    int dimension;    s1 = (SortMbr *) d1;    s2 = (SortMbr *) d2;    dimension = s1->dimension;    erg = s1->mbr[2*dimension] - s2->mbr[2*dimension];    if (erg < 0.0)	return -1;    else if (erg == 0.0)	return 0;    else 	return 1;}int sort_upper_mbr(const void *d1, const void *d2)// Vergleichsfunktion fuer qsort, sortiert nach oberem Wert der mbr bzgl.// der angegebenen Dimension{    SortMbr *s1, *s2;    float erg;    int dimension;    s1 = (SortMbr *) d1;    s2 = (SortMbr *) d2;    dimension = s1->dimension;    erg = s1->mbr[2*dimension+1] - s2->mbr[2*dimension+1];    if (erg < 0.0)	return -1;    else if (erg == 0.0)	return 0;    else 	return 1;}int sort_center_mbr(const void *d1, const void *d2)// Vergleichsfunktion fuer qsort, sortiert nach center of mbr {    SortMbr *s1, *s2;    int i, dimension;    float d, e1, e2;    s1 = (SortMbr *) d1;    s2 = (SortMbr *) d2;    dimension = s1->dimension;    e1 = e2 = 0.0;    for (i = 0; i < dimension; i++)    {        d = ((s1->mbr[2*i] + s1->mbr[2*i+1]) / 2.0) - s1->center[i];        e1 += d*d;        d = ((s2->mbr[2*i] + s2->mbr[2*i+1]) / 2.0) - s2->center[i];        e2 += d*d;    }    if (e1 < e2)	return -1;    else if (e1 == e2)	return 0;    else 	return 1;}float OBJECT_DIST(const void  *Point1, const void  *Point2){    //    // Berechnet das Quadrat der euklid'schen Metrik.    // (Der tatsaechliche Abstand ist uninteressant, weil    // die anderen Metriken (MINDIST und MINMAXDIST fuer    // die NearestNarborQuery nur relativ nie absolut     // gebraucht werden; nur Aussagen "<" oder ">" sind    // relevant.    //    DataStruct *d1,*d2;    float summe = 0;    int i;        d1 = (DataStruct *) Point1;    d2 = (DataStruct *) Point2;    for( i = 0; i < d1->dimension; i++)	summe += pow(    d1->Data[i] - d2->Data[i], 2 );    //return( sqrt(summe) );    return(summe);}float MINDIST(const void *Point, float *bounces){    //    // Berechne die kuerzeste Entfernung zwischen einem Punkt Point    // und einem MBR bounces (Lotrecht!)    //    DataStruct *p;    float summe = 0.0;    float r;    int i;    p = (DataStruct *) Point;        for(i = 0; i < p->dimension; i++)    {	if (p->Data[i] < bounces[2*i])	    r = bounces[2*i];	else	{	    if (p->Data[i] > bounces[2*i +1])		r = bounces[2*i+1];	    else 		r = p->Data[i];	}    	summe += pow( p->Data[i] - r , 2);    }    return(summe);    }float MINMAXDIST(const void *Point, float *bounces){    // Berechne den kleinsten maximalen Abstand von einem Punkt Point    // zu einem MBR bounces.    // Wird benutzt zur Abschaetzung von Abstaenden bei NearestNarborQuery.    // Kann als Supremum fuer die aktuell kuerzeste Distanz:     // Alle Punkte mit einem Abstand > MINMAXDIST sind keine Kandidaten mehr    // fuer den NearestNarbor    // vgl. Literatur:     // Nearest Narbor Query v. Roussopoulos, Kelley und Vincent,     // University of Maryland        DataStruct *p;        float summe = 0;    float minimum = 1.0e20;    float S = 0;    float rmk, rMi;    int k,i,j;    p = (DataStruct *) Point;        for( i = 0; i < p->dimension; i++)     { 	rMi = (	p->Data[i] >= (bounces[2*i]+bounces[2*i+1])/2 )	    ? bounces[2*i] : bounces[2*i+1];	S += pow( p->Data[i] - rMi , 2 );    }    for( k = 0; k < p->dimension; k++)    {  		rmk = ( p->Data[k] <=  (bounces[2*k]+bounces[2*k+1]) / 2 ) ? 	    bounces[2*k] : bounces[2*k+1];	summe = pow( p->Data[k] - rmk , 2 );			rMi = (	p->Data[k] >= (bounces[2*k]+bounces[2*k+1]) / 2 )	    ? bounces[2*k] : bounces[2*k+1];	summe += S - pow( p->Data[k] - rMi , 2 );		minimum = min( minimum,summe);    }    return(minimum);    }int sort_min_dist(const void *element1, const void *element2){    //    // Vergleichsfunktion fuer die Sortierung der BranchList bei der    // NearestNarborQuery (Sort, Branch and Prune)    //    BranchList *e1,*e2;    e1 = (BranchList *) element1;    e2 = (BranchList *) element2;        if (e1->mindist < e2->mindist) 	return(-1);    else if (e1->mindist > e2->mindist)	return(1);    else	return(0);}int prune_branch_list(float *nearest_distanz, const void *activebrunchList, 		    int n){    // Schneidet im Array BranchList alle Eintraege ab, deren Distanz groesser    // ist als die aktuell naeheste Distanz    //    BranchList *bl;         int i,j,k, aktlast;        bl = (BranchList *) activebrunchList;        // 1. Strategie:    //     // Ist MINDIST(P,M1) > MINMAXDIST(P,M2), so kann der     // NearestNeighbor auf keinen Fall mehr in M1 liegen!    //    aktlast = n;        for( i = 0; i < aktlast ; i++ )    {	if (bl[i].minmaxdist < bl[aktlast-1].mindist)	    for( j = 0; (j < aktlast) ; j++ )		if ((i!=j) && (bl[j].mindist>bl[i].minmaxdist))		{		    aktlast = j;		    break;		}	    }        // 2. Strategie:    //    // nearest_distanz > MINMAXDIST(P,M)    // -> nearest_distanz = MIMMAXDIST(P,M)    //    for( i = 0; i < aktlast; i++)	if (*nearest_distanz > bl[i].minmaxdist)	    *nearest_distanz = bl[i].minmaxdist;        // 3. Strategie:    //     // nearest_distanz < MINDIST(P,M)    //    // in M kann der Nearest-Narbor sicher nicht mehr liegen.    //    for( i = 0; (i < aktlast) && (*nearest_distanz >= bl[i].mindist) ; i++);        aktlast = i;    // printf("n: %d aktlast: %d \n",n,aktlast);       return (aktlast);    }int testBrunchList(const void *abL, const void *sL,		   int n, int last){    // Schneidet im Array BranchList alle Eintr"age ab, deren Distanz gr"o"ser	// ist als die aktuell naeheste Distanz	//	BranchList *activebrunchList, *sectionList; 		int i,number, aktlast;		activebrunchList = (BranchList *) abL;	sectionList      = (BranchList *) sL;	aktlast = last; 	for(i = last; i < n ; i++)	{	    number = activebrunchList[i].entry_number;  	    if (sectionList[number].section)	    {		// obwohl vom Abstand her dieser Eintrag gecanceld werden		// m"usste, wird hier der Eintrag in die ABL wieder		    // aufgenommen, da evtl. ein Treffer der range-Query zu erwarten ist!		    //		    // An der letzten Stelle der Liste kommt der aktuelle Eintrag!		    aktlast++;		    activebrunchList[aktlast].entry_number = activebrunchList[i].entry_number;		    activebrunchList[aktlast].mindist = activebrunchList[i].mindist;		    activebrunchList[aktlast].minmaxdist = activebrunchList[i].minmaxdist;		     }      	 	    	}		return (aktlast);    }void check_mbr(int dimension, float *mbr){}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -