Example #1
0
 /// <summary>
 /// 从cur节点开始向子树中寻找x的最近邻
 /// </summary>
 /// <param name="cur">开始查找的根节点</param>
 private void Query(KD_TreeNode cur)
 {
     if (cur == null) return;
     //求出目标x到当前节点的距离
     double dist = Dist(cur.data.value, curQuery.value);
     if (check.Contains(cur.data.index)==false && dist<curNearestDist)
     {
         //当前节点未被提取过且dist小于当前最近距离
         curNearestDist = dist;
         curNearestNode = cur.data.index;
     }
     //计算x到分裂平面的距离
     double radius = Math.Pow(curQuery.value[cur.split] - cur.data.value[cur.split], 2);
     //对子区间进行查询
     if (curQuery.value[cur.split]<cur.data.value[cur.split])
     {
         Query(cur.left);
         if (radius <= curNearestDist) Query(cur.right);
     }
     else
     {
         Query(cur.right);
         if (radius <= curNearestDist) Query(cur.left);
     }
 }
Example #2
0
 public KD_Tree(KD_DataType[] s)
 {
     dataset = s;
     dimension = s[0].value.Count();
     root = BuildTree(0, s.Count() - 1);
 }
Example #3
0
        /// <summary>
        /// 对区间head到tail之间的点建树
        /// </summary>
        /// <param name="head"></param>
        /// <param name="tail"></param>
        /// <returns>当前节点</returns>
        private KD_TreeNode BuildTree(int head, int tail)
        {
            if (head > tail) return null;

            //计算每一维上的方差,并找到方差最大的维度
            double maxVariance = 0;
            int bestDimension = 0;
            for (int s = 0; s < dimension; s++)
            {
                double variance = 0;
                double sum = 0;
                for (int i = head; i <= tail; i++) sum += dataset[i].value[s];
                double avr = sum / (double)(tail - head + 1);
                for(int i=head;i<=tail; i++) variance += Math.Pow(dataset[i].value[s] - avr, 2);
                variance /= (double)(tail - head + 1);
                if (variance>maxVariance)
                {
                    maxVariance = variance;
                    bestDimension = s;
                }
            }
            //新节点
            KD_TreeNode newNode = new KD_TreeNode();
            newNode.split = bestDimension;
            //将区间内的点按best dimension排序
            Dictionary<KD_DataType, double> unsort = new Dictionary<KD_DataType, double>();

            for (int i = head; i <= tail; i++)
            {
                unsort.Add(dataset[i], dataset[i].value[bestDimension]);
            }
            var sorted = from pair in unsort
                         orderby pair.Value ascending
                         select pair;
            var arrSorted = sorted.ToArray();
            for(int i = head;i<=tail;i++)
            {
                dataset[i] = arrSorted[i - head].Key;
            }
            //建立左右子树
            //sort(head, tail, bestDimension);
            int mid = head + (tail - head) / 2;
            newNode.data = dataset[mid];
            newNode.left = BuildTree(head, mid - 1);
            newNode.right = BuildTree(mid + 1, tail);
            return newNode;
        }