示例#1
0
        private KDTreeNode CreateTreeNode(List <KD_Point> pointList)
        {
            if (pointList.Count > 0)
            {
                // 计算方差
                double xObtainVariance = ObtainVariance(CreateXList(pointList));
                double yObtainVariance = ObtainVariance(CreateYList(pointList));

                // 根据方差确定分裂维度
                EnumDivisionType divisionType = SortListByXOrYVariances(xObtainVariance, yObtainVariance, ref pointList);

                // 获得中位数
                KD_Point medianPoint = ObtainMedian(pointList);
                int      medianIndex = pointList.Count / 2;

                // 构建节点
                KDTreeNode treeNode = new KDTreeNode()
                {
                    DivisionPoint = medianPoint,
                    DivisionType  = divisionType,
                    LeftChild     = CreateTreeNode(pointList.Take(medianIndex).ToList()),
                    RightChild    = CreateTreeNode(pointList.Skip(medianIndex + 1).ToList())
                };
                return(treeNode);
            }
            else
            {
                return(null);
            }
        }
示例#2
0
        public List <KD_Point> K_Nearest(KD_Point position, int K)
        {
            KDTreeNodeCollection collection = new KDTreeNodeCollection(K, position);

            collection = K_Nearest(this.rootNode, position, collection);
            return(collection.GetPoints());
        }
示例#3
0
 //回溯搜索
 private KD_Point BacktrcakSearch(KD_Point searchPoint, KD_Point nearestPoint)
 {
     if (backtrackStack.IsEmpty())
     {
         return(nearestPoint);
     }
     else
     {
         KDTreeNode trackNode            = backtrackStack.Pop();
         double     backtrackDistance    = ObtainDistanFromTwoPoint(searchPoint, trackNode.DivisionPoint);
         double     nearestPointDistance = ObtainDistanFromTwoPoint(searchPoint, nearestPoint);
         if (backtrackDistance < nearestPointDistance)
         {
             KDTreeNode searchNode = new KDTreeNode()
             {
                 DivisionPoint = trackNode.DivisionPoint,
                 DivisionType  = trackNode.DivisionType,
                 LeftChild     = trackNode.LeftChild,
                 RightChild    = trackNode.RightChild
             };
             nearestPoint = DFSBackTrackingSearch(searchNode, searchPoint);
         }
         return(BacktrcakSearch(searchPoint, nearestPoint));
     }
 }
示例#4
0
 //向右节点搜寻
 private KD_Point DFSRightSearch(KDTreeNode node, KD_Point searchPoint)
 {
     if (node.RightChild != null)
     {
         return(DFSSearch(node.RightChild, searchPoint));
     }
     else
     {
         return(node.DivisionPoint);
     }
 }
示例#5
0
 //按照Y节点搜寻
 private KD_Point DFSYsearch(KDTreeNode node, KD_Point searchPoint)
 {
     if (node.DivisionPoint.Y > searchPoint.Y)
     {
         return(DFSLeftSearch(node, searchPoint));
     }
     else
     {
         return(DFSRightSearch(node, searchPoint));
     }
 }
示例#6
0
 //向左节点回溯搜寻
 private KD_Point DFSBackTrackLeftSearch(KDTreeNode node, KD_Point searchPoint)
 {
     if (node.LeftChild != null)
     {
         return(DFSSearch(node.LeftChild, searchPoint, false));
     }
     else
     {
         return(node.DivisionPoint);
     }
 }
示例#7
0
        //向上回溯搜索
        private KD_Point DFSBackTrackingSearch(KDTreeNode node, KD_Point searchPoint)
        {
            backtrackStack.Push(node);

            if (node.DivisionType == EnumDivisionType.X)
            {
                return(DFSBackTrackingXsearch(node, searchPoint));
            }
            else
            {
                return(DFSBackTrackingYsearch(node, searchPoint));
            }
        }
示例#8
0
 private KD_Point DFSSearch(KDTreeNode node, KD_Point searchPoint, bool pushStack = true)
 {
     if (pushStack == true)
     {
         backtrackStack.Push(node);
     }
     if (node.DivisionType == EnumDivisionType.X)
     {
         return(DFSXsearch(node, searchPoint));
     }
     else
     {
         return(DFSYsearch(node, searchPoint));
     }
 }
示例#9
0
        public void Add(KDTreeNode currentnode, double d)
        {
            KD_Point current = currentnode.DivisionPoint;

            if (collection.Count == 0)
            {
                collection.Add(current);
                this.max = d;
            }
            else if (collection.Count < this.k)
            {
                if (max < d)
                {
                    this.max = d;
                    location = collection.Count;
                    collection.Add(current);
                }
                else
                {
                    collection.Add(current);
                }
            }
            else
            {
                if (d <= max)
                {
                    collection.RemoveAt(location);
                    collection.Add(current);
                    for (int i = 0; i < k; i++)
                    {
                        if (i == 0)
                        {
                            max      = Math.Sqrt(Math.Pow(thepoint.X - collection[i].X, 2) + Math.Pow(thepoint.Y - collection[i].Y, 2));
                            location = i;
                        }
                        else
                        {
                            double distance = Math.Sqrt(Math.Pow(thepoint.X - collection[i].X, 2) + Math.Pow(thepoint.Y - collection[i].Y, 2));
                            if (distance > max)
                            {
                                max      = distance;
                                location = i;
                            }
                        }
                    }
                }
            }
        }
示例#10
0
 //按照Y节点回溯搜寻
 private KD_Point DFSBackTrackingYsearch(KDTreeNode node, KD_Point searchPoint)
 {
     if (node.DivisionPoint.Y > searchPoint.Y)
     {
         node.LeftChild = null;
         KD_Point rightSearchPoint = DFSBackTrackRightSearch(node, searchPoint);
         node.RightChild = null;
         return(rightSearchPoint);
     }
     else
     {
         node.RightChild = null;
         KD_Point leftSearchPoint = DFSBackTrackLeftSearch(node, searchPoint);
         node.LeftChild = null;
         return(leftSearchPoint);
     }
 }
示例#11
0
        public KDTreeNodeCollection K_Nearest(KDTreeNode current, KD_Point position, KDTreeNodeCollection collection)
        {
            double d = ObtainDistanFromTwoPoint(current.DivisionPoint, position);

            collection.Add(current, d);
            double value;
            double median;

            if (current.DivisionType == EnumDivisionType.X)
            {
                value  = position.X;
                median = current.DivisionPoint.X;
            }
            else
            {
                value  = position.Y;
                median = current.DivisionPoint.Y;
            }
            double u = value - median;

            if (u <= 0)
            {
                if (current.LeftChild != null)
                {
                    K_Nearest(current.LeftChild, position, collection);
                }
                if (current.RightChild != null && Math.Abs(u) <= collection.max)
                {
                    K_Nearest(current.RightChild, position, collection);
                }
            }
            else
            {
                if (current.RightChild != null)
                {
                    K_Nearest(current.RightChild, position, collection);
                }
                if (current.LeftChild != null && Math.Abs(u) <= collection.max)
                {
                    K_Nearest(current.LeftChild, position, collection);
                }
            }
            return(collection);
        }
示例#12
0
 public int k = 0;//k临近值
 //
 public KDTreeNodeCollection(int num, KD_Point point)
 {
     this.k        = num;
     this.thepoint = point;
     collection    = new List <KD_Point>();
 }
示例#13
0
 private double ObtainDistanFromTwoPoint(KD_Point start, KD_Point end)
 {
     return(Math.Sqrt(Math.Pow(start.X - end.X, 2) + Math.Pow(start.Y - end.Y, 2)));
 }
示例#14
0
        //上面是构建KD树
        //下面是寻找最近点
        public KD_Point FindNearest(KD_Point searchPoint)
        {
            KD_Point nearestPoint = DFSSearch(this.rootNode, searchPoint);

            return(BacktrcakSearch(searchPoint, nearestPoint));
        }