internal void SearchInNode(object q, double radius, VPF_Node V,List<ResultPair> results) { double d_q_c=this.DB.Dist(q,this.DB[V.center]); // check left if ( V.left is VPF_Node ) // left is a node { VPF_Node L=(VPF_Node) V.left; if (/*V.Lmin <= d_q_c+radius &&*/ d_q_c-radius <= V.Lmax ) // Search left { //Console.Write("L "); SearchInNode(q,radius,L,results); } } else { // left is a leaf //Console.WriteLine("V:{0}",V.GetType()); if (/*V.Lmin <= d_q_c+radius &&*/ d_q_c-radius <= V.Lmax ) { VPF_Leaf L=(VPF_Leaf) V.left; //Console.Write("l*"); for(int i=0;i<L.IDs.Length;i++) { if ( d_q_c-radius<= L.dist2center[i] && L.dist2center[i]<=d_q_c+radius) { double d=this.DB.Dist(q,this.DB[L.IDs[i]]); if ( d<=radius ) // left leaf is a result { //Console.WriteLine("F:{0} d:{1}",L.IDs[i],d); results.Add(new ResultPair(L.IDs[i],d) ); } } } } } // check right if ( V.right is VPF_Node ) // right is a node { VPF_Node R=(VPF_Node) V.right; if (V.Rmin <= d_q_c+radius /*&& d_q_c-radius <= V.Rmax*/ ) // Search right { //Console.Write("R "); SearchInNode(q,radius,R,results); } } else { // right is a leaf if (V.Rmin <= d_q_c+radius /*&& d_q_c-radius <= V.Rmax*/ ) { VPF_Leaf R=(VPF_Leaf) V.right; //Console.Write("r*"); for (int i=0;i<R.IDs.Length;i++) { if ( d_q_c-radius<= R.dist2center[i] && R.dist2center[i]<=d_q_c+radius) { double d=this.DB.Dist(q,this.DB[R.IDs[i]]); if ( d<=radius ) // right leaf is a result { //Console.WriteLine("F:{0} d:{1}",R.IDs[i],d); results.Add(new ResultPair(R.IDs[i],d) ); } } } } } }
// Build the Tree!! internal void BuildTree(VPF_Node Node,double[] Distances,int [] Perm,int a,int w) { //int start=Node.start; //int end=Node.end; int a2=0,w2=0,center2=0; int count=Perm.Length; //Console.WriteLine("a:{0},w:{1},total:{2}",a,w,count); double lmin=Distances[0],lmax=Distances[a-1],rmin=Distances[a+w],rmax=Distances[Perm.Length-1]; //double[] Distances=new double[Perm.Length]; //int center=0; //Divide_Interval(count,out a,out w,Node,Distances,Perm); // Mark to Remove middle part if (w>0) { Mark2PersistRange(a,w,Perm); if (Distances[ a+w-1 ]-Distances[ a ]>0) this.Tau=Math.Min(this.Tau,Distances[ a+w-1 ]-Distances[ a ]); } double[] Distances2=new double[a]; int[] Perm2=new int[a]; for (int i=0;i<a;i++) { Perm2[i]=Perm[i]; //Distances2[i]=Distances[i]; } if (Divide_Interval(a,out a2,out w2,out center2,out Distances2,Perm2)) // build left node { Node.Lmin=lmin; Node.Lmax=lmax; Node.left=new VPF_Node( center2 ); BuildTree((VPF_Node)Node.left,Distances2,Perm2,a2,w2); } else // build leaf { Node.Lmin=lmin; Node.Lmax=lmax; leafs+=a; VPF_Leaf L= new VPF_Leaf(a); for (int i=0;i<a;i++) { L.SetValues(this.Remaining[Perm[i]],Distances[i],i); } //Console.WriteLine("TotalLeafs:{0}",a); Node.left=L; //Console.WriteLine("Build Leaf:{0}",L.IDs.Length); } Distances2=new double[Perm.Length-1-(a+w-1)]; Perm2=new int[Perm.Length-1-(a+w-1)]; for (int i=a+w;i<Perm.Length;i++) { Perm2[i-a-w]=Perm[i]; //Distances2[i-a-w]=Distances[i]; } if (Divide_Interval(Perm.Length-1-(a+w-1),out a2,out w2,out center2,out Distances2,Perm2)) // build right node { Node.Rmin=rmin; Node.Rmax=rmax; Node.right=new VPF_Node( center2 ); BuildTree((VPF_Node)Node.right,Distances2,Perm2,a2,w2); } else // build leaf { Node.Rmin=rmin; Node.Rmax=rmax; //Console.Write("L:{0} ",this.Remaining[Perm[a+w]]); leafs+=Perm.Length-1-(a+w-1); VPF_Leaf R=new VPF_Leaf(Perm.Length-1-(a+w-1)); for(int i=0;i<Perm.Length-1-(a+w-1);i++) { R.SetValues(this.Remaining[Perm[a+w+i]],Distances[a+w+i],i); } //Console.WriteLine("Total Leafs:{0}",Perm.Length-1-(a+w-1)); Node.right=R; //Console.WriteLine("Build Leaf:{0}",R.IDs.Length); } }