Esempio n. 1
0
Point<Dim> KDTree<Dim>::findNearestNeighbor(const Point<Dim> & query, int lo, int  hi, int  dim) const{
	if(lo >= hi ) return points[lo]; //base case
	
	int mid = (hi+lo)/2;	//calculate the minPoint index
	Point<Dim> temp;				
	Point<Dim> curr = points[mid];	
	dim = dim%Dim; 	
	int direction=0;
	if(smallerDimVal(query, points[mid], dim)){		
		direction = 0;
	 	temp = findNearestNeighbor(query, lo, mid-1, dim+1); //left half
	}
	else{
		direction =1;
		temp = findNearestNeighbor(query, mid+1, hi, dim+1);  //recusively call the function on the left half
	}
	Point<Dim> best;
	if(shouldReplace(query, temp, curr) ) best= curr;
	else best = temp;
	
	int dimD = (curr[dim] - query[dim])*(curr[dim] - query[dim]);
	int bestCurr = squareDistance(best, query);
	if(dimD > bestCurr) return best;
	else{	
		Point<Dim> t;
		if(direction == 0)	
			 t = findNearestNeighbor(query, mid+1, hi, dim+1);
		else t = findNearestNeighbor(query, lo, mid-1,dim+1);
	
		if(shouldReplace(query,t, best)) return best;
		else return t;
	}
		
}
Esempio n. 2
0
Point<Dim> KDTree<Dim>::find(const Point<Dim> & query, int cur, int curDim, int a, int b) const
{
	if(a == b) return points[a];
	else
	{
		Point<Dim> temp;
		double childdist = 0;
		double parentdist2 = ((points[cur])[curDim] - query[curDim])*((points[cur])[curDim] - query[curDim]);
		double parentdist = 0;
		if(smallerDimVal(query, points[cur], curDim))
		{
			if (cur-1 < a) return points[cur];
			else 
			{
				temp = find(query, (a+cur-1)/2, (curDim+1)%Dim, a, cur-1);
				
				for (int i = 0; i < Dim; i++)
				{
					childdist += ((temp[i]-query[i])*(temp[i]-query[i]));
					parentdist += (((points[cur])[i]-query[i])*((points[cur])[i]-query[i]));
				}
				if (parentdist2 <= childdist)
				{
					Point<Dim> temp2;
					if (cur+1 > b) temp2 = points[cur];
					else temp2 = find(query, (cur+1+b)/2, (curDim+1)%Dim, cur+1, b);
					if ((parentdist < childdist)||((parentdist == childdist)&&(points[cur] < temp))) temp = points[cur];
					if (shouldReplace(query, temp, temp2)) return temp2;
					else return temp;
				}
				else return temp;
			}
		}
		else
		{
			if (cur+1 > b) return points[cur];
			else 
			{
				temp = find(query, (cur+1+b)/2, (curDim+1)%Dim, cur+1, b);
				for (int i = 0; i < Dim; i++)
				{
					childdist += ((temp[i]-query[i])*(temp[i]-query[i]));
					parentdist += (((points[cur])[i]-query[i])*((points[cur])[i]-query[i]));
				}
				if (parentdist2 <= childdist)
				{
					Point<Dim> temp2;
					if (cur-1 < a) temp2 = points[cur];
					else temp2 = find(query, (a+cur-1)/2, (curDim+1)%Dim, a, cur-1);
					if ((parentdist < childdist)||((parentdist == childdist)&&(points[cur] < temp))) temp = points[cur];
					if (shouldReplace(query, temp, temp2)) return temp2;
					else return temp;
				}
				else return temp;

			}
		}
	}
}
Esempio n. 3
0
Point<Dim> KDTree<Dim>::walkThrough(const Point<Dim> &target, const Point<Dim> &ret, int lower, int upper, int curDim) const
{
//base case
		if (lower == upper)
    {
        if (shouldReplace(target, ret, points[lower]))
        {
            
            return points[lower];
        }
        return ret;
    }
// other
	int median = (lower + upper)/2;
	Point<Dim> ret2 = ret;
//a recording for which side are we going
	int side = 0;//0:left, 1:right
	if (smallerDimVal(points[median], target, curDim)&&upper>median)
	//why do we have to check upper>median?
		{
		int dim2 = curDim+1;
		if(dim2>=Dim)
        dim2=dim2-Dim;
        ret2 = walkThrough(target, ret, median+1, upper, dim2);
        side=1;
		}
	if (smallerDimVal(target, points[median], curDim)&&lower<median)
		{
		int dim2 = curDim+1;
		if(dim2>=Dim)
        dim2=dim2-Dim;
        ret2 = walkThrough(target, ret, lower, median-1, dim2);
        side=0;
        }
    //Check if current node is closer than obtained above
    if (shouldReplace(target, ret2, points[median]))
        ret2 = points[median];
    //prepare to check the other side
    	Point<Dim> m = points[median];//don't understand why can't point[median][Dim]
    	int distance=0;//distance we have now
    	for(int i=0; i< Dim; i++)
    	distance+= pow(target[i]-ret2[i],2);
    if(pow(m[curDim]-target[curDim],2)<=distance)
    {
    	int dim2 = curDim+1;
		if(dim2>=Dim)
        dim2=dim2-Dim;
   
    if(side==0&&upper>median)//left has been checked, goto right
    ret2 = walkThrough(target, ret2, median+1, upper, dim2 );
    if(side==1&&lower<median)//goto left
    ret2 = walkThrough(target, ret2, lower, median-1, dim2 );
    }
	return ret2;
}
Esempio n. 4
0
Point<Dim> KDTree<Dim>::NearestNeighbor_helper(int curDim, const Point<Dim> &query, int bottom, int top, const Point<Dim> &currentBest) const
{
    Point<Dim> retVal = currentBest;//set a holder (call it return value) equal to currentBest to start
    bool target = true; //initialize our target bool to true

    if(bottom==top)
    {
        //this means were at a leaf
        //we need to check if were wcloser than current best and return the appropriate currnent best
        if(shouldReplace(query, currentBest, points[bottom])==true)
        {
            retVal = points[bottom];//set the return value
            return retVal; //send that thing up!
        }
        retVal = currentBest; //otherwise return the currentBest
        return retVal;

    }


    //declare the middle point
    int middle = (bottom+top)/2;


    //now lets get to work on tricky stuff
    if(smallerDimVal(points[middle], query, curDim) && top > middle)
    {
        //recursive call to set retVal
        retVal = NearestNeighbor_helper((curDim+1)%Dim, query, middle+1, top, currentBest);
        target = false;
    }
    if (smallerDimVal(query, points[middle], curDim) && bottom <middle)
    {
        //recursive call to set retVal
        retVal = NearestNeighbor_helper((curDim+1)%Dim, query, bottom, middle-1, currentBest);
        target = true;
    }

    //look to see if the node were on is closer than what was obtained earlier
    if(shouldReplace(query, retVal, points[middle]))
    {
        retVal = points[middle];//set retVal appropriately
    }


    //lots of TA guidance here this is still a little foggy
    Point <Dim> holder = points[middle];
    if(pow(holder[curDim] - query[curDim], 2) <= distance(query, retVal))
    {

        if(!target && bottom < middle)
        {
            retVal = NearestNeighbor_helper((curDim+1)%Dim, query, bottom, middle-1, retVal);//same as above but replace currentBest with retVal!
        }


        if(target && top > middle)
        {
            //recurisve call
            retVal = NearestNeighbor_helper((curDim+1)%Dim, query, middle+1, top, retVal);//same as above but replace currentBest with retVal!
        }


    }

    //AND FINALLY
    return retVal;

}