示例#1
0
        internal void BuildTree(List<VectorData> points)
        {
            if (!points.Any())
            {
                return;
            }

            DimensionCount = points.First().Data.Count();

            root = GenerateNode(0, points, 0, points.Count() - 1);
        }
示例#2
0
        void FindPointsWithinRadius(KDNode node, VectorData targetPoint, List<VectorData> result, double radius)
        {
            if (node.Values != targetPoint)
            {
                TryToSaveRadius(node, targetPoint, result, radius);
            }

            var dMinus1 = node.Dimension - 1;
            if (dMinus1 < 0)
            {
                dMinus1 = DimensionCount - 1;
            }

            var perpendicularDistance = Math.Abs(node.Values.Data.Skip(node.Dimension).First() - targetPoint.Data.Skip(dMinus1).First());
            if (perpendicularDistance < radius || node.Values == targetPoint)
            {
                if (node.Above != null)
                {
                    FindPointsWithinRadius(node.Above, targetPoint, result, radius);
                }
                if (node.Below != null)
                {
                    FindPointsWithinRadius(node.Below, targetPoint, result, radius);
                }
            }
            else
            {
                if (targetPoint.Data.Skip(dMinus1).First() < node.Values.Data.Skip(node.Dimension).First())
                {
                    if (node.Below != null)
                    {
                        FindPointsWithinRadius(node.Below, targetPoint, result, radius);
                    }
                }
                else
                {
                    if (node.Above != null)
                    {
                        FindPointsWithinRadius(node.Above, targetPoint, result, radius);
                    }
                }
            }
        }
示例#3
0
        void TryToSaveRadius(KDNode node, VectorData target, List<VectorData> result, double radius)
        {
            if (node == null)
            {
                return;
            }

            var distance = AbstractDistanceFunction.CalculateDistance(target, node.Values);
            if (radius < distance)
            {
                return;
            }

            result.Add(node.Values);
        }
示例#4
0
 void TryToSaveRadiusWithDistance(KDNode node, VectorData target, List<KNNPoint> result, double radius)
 {
     if (node == null)
     {
         return;
     }
     double distance = AbstractDistanceFunction.CalculateDistance(target, node.Values);
     if (radius < distance)
     {
         return;
     }
     result.Add(new KNNPoint(node.Values, distance));
 }
示例#5
0
        KDNode GenerateNode(int currentD, List<VectorData> points, int left, int right)
        {
            if (right < left)
            {
                return null;
            }

            if (right == left)
            {
                return new KDNode(points[left], currentD);
            }

            var m = (right - left) / 2;

            var medianNode = RandomizedSelect(points, m, left, right, currentD);

            var node = new KDNode(medianNode, currentD);
            currentD++;
            if (currentD == DimensionCount)
            {
                currentD = 0;
            }

            node.Below = GenerateNode(currentD, points, left, left + m - 1);
            node.Above = GenerateNode(currentD, points, left + m + 1, right);
            return node;
        }