예제 #1
0
void rnnsearch(TREENODE *subroot, VECTOR *vp, int level, int n, 
		VECTOR **bestn, NUMBER *min_nd, int *max_id, int *cnt){

    NUMBER rootdist;  /* the distance from the root */
    int numdims;

    numdims = vp->len;

    if( subroot == NULL){ return; } /* empty tree */

    rootdist = myvecdist2( vp, subroot->pvec);
    #ifdef DEBUG
    printf("rootdist %g nth mindist %g\n", rootdist, *min_nd);
    #endif

	if(rootdist < *min_nd && !subroot->fetched) {
		int i;
		bestn[*max_id] = subroot->pvec;
		*min_nd = myvecdist2(vp, bestn[0]);
		*max_id = 0;
		for(i = 1; i < n; i++) {
			if (myvecdist2(vp, bestn[i]) > *min_nd) {
				*min_nd = myvecdist2(vp, bestn[i]);
				*max_id = i;
			}
		}
	}

    /* check the subtrees - start from the most promising first */
    if( (vp->vec)[level] > ((subroot->pvec)->vec)[level]){
	/* the right subtree is more promising */
	rnnsearch( subroot->right, vp,  (level+1)% numdims, n, 
		bestn, min_nd, max_id, cnt);

	/* now check the left subtree */
	if( (*cnt) < n || (vp->vec)[level] <= ( ((subroot->pvec)->vec)[level] + (*min_nd) ) ){
	    /* only then is the left subtree promising */
	    /* notice that we use the UPDATED mindist */
	    rnnsearch( subroot->left, vp, (level+1)% numdims, n,
		bestn, min_nd, max_id, cnt);
        }
    }else{
	/* the left subtree is more promising */
	rnnsearch( subroot->left, vp, (level+1)% numdims, n,
		bestn, min_nd, max_id, cnt);

	/* now check the right subtree */
	if( (*cnt) < n || ( (vp->vec)[level] + (*min_nd)) > ((subroot->pvec)->vec)[level] ){
	    rnnsearch( subroot->right, vp, (level+1)%numdims, n,
		bestn, min_nd, max_id, cnt);
	}
    }

    return;
}
예제 #2
0
파일: kdtree.c 프로젝트: SunnyQ/15826
/* 'level'		is the current level of the tree */
VECTOR *rnnsearch(TREENODE *subroot, VECTOR *vp, VECTOR *best, int level, VECTOR** bests, int count){
    NUMBER mindist;  /* the current best distance */
    NUMBER rootdist;  /* the distance from the root */
    int numdims;

    numdims = vp->len;

    if(subroot == NULL){
        return(best); 
    } /* empty tree */

    rootdist = myvecdist2( vp, subroot->pvec);
    mindist = myvecdist2( vp, best);
    #ifdef DEBUG
    printf("rootdist %g mindist %g\n", rootdist, mindist);
    #endif

    /* vecprint(subroot->pvec); */
    save_knn(subroot->pvec, bests, count, vp);
    if(rootdist < mindist){
    	best = subroot->pvec;
    	mindist = rootdist;
    }

    /* check the subtrees - start from the most promising first */
    if( (vp->vec)[level] > ((subroot->pvec)->vec)[level]){
    	/* the right subtree is more promising */
    	best = rnnsearch( subroot->right, vp, best, (level+1)% numdims, bests, count);
    	mindist = myvecdist2(vp, best);

        /* now check the left subtree */
    	if( (vp->vec)[level] <= ( ((subroot->pvec)->vec)[level] + mindist ) ){
    	    /* only then is the left subtree promising */
    	    /* notice that we use the UPDATED mindist */
    	    best = rnnsearch( subroot->left, vp, best, (level+1)% numdims, bests, count);
        }
    }
    else {
    	/* the left subtree is more promising */
    	best = rnnsearch( subroot->left, vp, best, (level+1)% numdims, bests, count);
    	mindist = myvecdist2(vp, best);

    	/* now check the right subtree */
    	if( ( (vp->vec)[level] + mindist) > ((subroot->pvec)->vec)[level] ){
    	    best = rnnsearch( subroot->right, vp, best, (level+1)%numdims, bests, count);
    	}
    }

    return(best);
}
예제 #3
0
void getNNode(TREENODE *subroot, VECTOR *vp, int count,
		VECTOR **bestn, NUMBER *min_nd, int *max_id, int *cnt){
	if ((*cnt) < count && subroot) {
		(*cnt)++;
		if ((*cnt) <= count ) {
			bestn[*cnt-1] = subroot->pvec;	
			subroot->fetched = 1;
			if (*cnt == 1) {
				*max_id = 0;
				*min_nd = myvecdist2(vp, bestn[*cnt-1]);
			}
			else {
				if ((*min_nd) < myvecdist2(vp, bestn[*cnt-1])) {
					*max_id = *cnt-1;
					*min_nd = myvecdist2(vp, bestn[*cnt-1]);
				}
			}
		}
		getNNode(subroot->left, vp, count, bestn, min_nd, max_id, cnt);
		getNNode(subroot->right, vp, count, bestn, min_nd, max_id, cnt);
	}
}
예제 #4
0
파일: kdtree.c 프로젝트: SunnyQ/15826
/* Added: runyunz - Fall 2013 */
void save_knn(VECTOR* best, VECTOR** bests, int count, VECTOR* vp){
    int i, j;
    if(vp != NULL && bests != NULL) {

        if(bests[count-1] != NULL)
        {
            if(myvecdist2(vp, bests[count-1]) <= myvecdist2(vp, best)){
                return;
            }
        }

        for(i=0; bests[i]!=NULL; i++)
        {
            if(myvecdist2(vp, best) < myvecdist2(vp, bests[i])){
                for(j=count-1; j>i; j--){
                    bests[j] = bests[j-1];
                }
                break;
            }
        }
        bests[i] = best;
        return;
    }
}
예제 #5
0
void rknnsearch(TREENODE *subroot, VECTOR *vp, heap *hp, NUMBER radius, int level) {
  NUMBER rootdist;  /* the distance from the root */
  NUMBER max_dist_from_heap;
  int numdims;

  numdims = vp->len;

  if (subroot == NULL) {
    return;
  }

  rootdist = myvecdist2(vp, subroot->pvec);
  max_dist_from_heap = heap_max_dis(hp);

  if(max_dist_from_heap > rootdist && radius > rootdist) {
    heap_insert(hp, rootdist, subroot->pvec);
  }

  /* check the subtrees - start from the most promising first */
  if( (vp->vec)[level] > ((subroot->pvec)->vec)[level]){
    /* the right subtree is more promising */
    rknnsearch(subroot->right, vp, hp, radius, (level+1)% numdims);

    max_dist_from_heap = heap_max_dis(hp);
    /* now check the left subtree */
    if( (vp->vec)[level] <= ( ((subroot->pvec)->vec)[level] + max_dist_from_heap )
      && (vp->vec)[level] <= (((subroot->pvec)->vec)[level] + radius)) {
      /* only then is the left subtree promising */
      /* notice that we use the UPDATED mindist */
      rknnsearch(subroot->left, vp, hp, radius, (level+1)% numdims);
    }
  }else{
    /* the left subtree is more promising */
    rknnsearch(subroot->left, vp, hp, radius, (level+1)% numdims);

    max_dist_from_heap = heap_max_dis(hp);
    /* now check the right subtree */
    if( (vp->vec)[level] + max_dist_from_heap > (subroot->pvec->vec)[level] &&
      (vp->vec)[level] + radius > ((subroot->pvec)->vec)[level]) {
      rknnsearch( subroot->right, vp, hp, radius, (level+1)%numdims);
    }
  }
}
예제 #6
0
void nnsearch(TREENODE *subroot, VECTOR *vp, int count){

    VECTOR **bestn = (VECTOR**)malloc(sizeof(VECTOR*) * count);
    NUMBER *bestn_d = (NUMBER*)malloc(sizeof(NUMBER) * count);
    NUMBER min_nd = HUGE;
    int max_id = 0;
    int cnt = 0;
    int i = 0;

    #ifdef DEBUG
    printf("nn tree search was called with \n");
    vecprint(vp);
    #endif


    /* fetch count tree nodes first in case that there're less than count nodes */    
    getNNode(subroot, vp, count, bestn, &min_nd, &max_id, &cnt);

    rnnsearch(subroot, vp, 0, count, 
		bestn, &min_nd, &max_id, &cnt);

    while(i < cnt) {
	bestn_d[i] = myvecdist2(vp, bestn[i]);
	i++;
    }

    if (cnt == 0) {
	printf("empty tree\n");
    }else if(cnt < count) {
	printf("Only %d nodes found\n",cnt);
    }
    
    mergeSort(bestn, bestn_d, cnt);
    
    printf("nearest %d neighbors:\n",cnt);
    for(i = 0; i < cnt; i++){
	vecprint(bestn[i]);
	printf("distance: %f\n", bestn_d[i]);
    }


}