在 C# 中找到 k 个最近邻 [英] Find k nearest neighbor in C#

查看:20
本文介绍了在 C# 中找到 k 个最近邻的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

仅从一组点中获取作为整数坐标 x 和 y 的点的 h 邻域的点.点"具有整数坐标 x 和 y 的给定点.h"给定点周围的距离.积分"一组给定的点.

类点:

public readonly struct Point : System.IEquatable{公共点(int x,int y){这个.X = x;这个.Y = y;}公共 int X { 得到;}公共 int Y { 得到;}public static bool operator ==(Point left, Point right){返回 left.Equals(right);}public static bool operator !=(Point left, Point right){返回 !(左 == 右);}公共覆盖 int GetHashCode(){返回 this.X.GetHashCode() ^ this.Y.GetHashCode();}公共覆盖 bool 等于(对象 obj){如果(对象为空){返回假;}if (!(obj is Point)){返回假;}如果 (obj.GetType() != this.GetType()){返回假;}点点=(点)obj;返回 this.Equals(point);}public bool Equals(Point other){返回 this.X == other.X &&this.Y == other.Y;}}

方法:

public static Point[] GetNeighbors(Point point, int h, params Point[] points){}

我不知道如何解决这个问题,我尝试使用:

 for (int i = 0; i <= points.Length - 1; i++){PointsCoordinate[i] = Math.Sqrt(Math.Pow(points[i].X, 2) + Math.Pow(points[i].Y, 2));}

之后我将使用列表或等找到点的最近值,但在这种情况下,我必须从数组而不是值中准确返回最近的点,我该如何解决这个问题,mb 我有错误的方法来解决这个问题.我需要将排序的值与数组中的点连接起来,请帮帮我

解决方案

首先,您需要计算与源点"的距离;到您的每个邻居点.您可以使用

<块引用>

腿(a 和 b)上两个正方形的面积之和等于斜边上正方形的面积.

public static double CalculateDistanceBetweenPoints(Point originPoint, Point destinationPoint){返回 Math.Pow(originPoint.X - destinationPoint.X, 2)+ Math.Pow(originPoint.Y - destinationPoint.Y, 2);}

您可以使用LINQ扩展方法Select()来计算每个点的距离:

var pointsWithDistance = 点数.Select(p => new { Point = p, Distance = CalculateDistanceBetweenPoints(point, p) });

然后过滤掉h"之外的邻居.与 Where() 的距离:

var filteredPointsWithDistance = 点数.Select(p => new { Point = p, Distance = CalculateDistanceBetweenPoints(point, p) }).Where(pointAndDistance => pointAndDistance.Distance <= Math.Pow(h, 2));

...并按距离增加排序:

varorderedFilteredPointsWithDistance = 点.Select(p => new { Point = p, Distance = CalculateDistanceBetweenPoints(point, p) }).Where(pointAndDistance => pointAndDistance.Distance <= Math.Pow(h, 2)).OrderBy(pointAndDistance => pointAndDistance.Distance);

不再需要计算出的距离,带回Point,再次使用Select():

var 点数 = 点数.Select(p => new { Point = p, Distance = CalculateDistanceBetweenPoints(point, p) }).Where(pointAndDistance => pointAndDistance.Distance <= Math.Pow(h, 2)).OrderBy(pointAndDistance => pointAndDistance.Distance).Select(pointAndDistance => pointAndDistance.Point);

最后,根据结果序列创建一个数组:

返回点.Select(p => new { Point = p, Distance = CalculateDistanceBetweenPoints(point, p) }).Where(pointAndDistance => pointAndDistance.Distance <= Math.Pow(h, 2)).OrderBy(pointAndDistance => pointAndDistance.Distance).Select(pointAndDistance => pointAndDistance.Point).ToArray();

整个代码和使用示例:

公共静态类程序{public static void Main(){无功h = 10;var sourcePoint = new Point(0, 0);var 邻居 = 新点[]{新点(0, 0),新点(100, 100),新点(10, 0),新点(5, 5),新点(-2,-2),};varnearestNeighbors = GetNeighbors(sourcePoint, h,neighbors);}public static Point[] GetNeighbors(Point point, int h, params Point[] points){返回点.Select(p => new { Point = p, Distance = CalculateDistanceBetweenPoints(point, p) }).Where(pointAndDistance => pointAndDistance.Distance <= Math.Pow(h, 2)).OrderBy(pointAndDistance => pointAndDistance.Distance).Select(pointAndDistance => pointAndDistance.Point).ToArray();}public static double CalculateDistanceBetweenPoints(Point originPoint, Point destinationPoint){返回 Math.Pow(originPoint.X - destinationPoint.X, 2)+ Math.Pow(originPoint.Y - destinationPoint.Y, 2);}}

Gets from a set of points only points that are h-neighbors for a point with integer coordinates x and y. "point" Given point with integer coordinates x and y. "h" Distance around a given point. "points" A given set of points.

class Point:

public readonly struct Point : System.IEquatable<Point>
{
    public Point(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }


    public int X { get; }

    public int Y { get; }
    
    public static bool operator ==(Point left, Point right)
    {
        return left.Equals(right);
    }
    
    public static bool operator !=(Point left, Point right)
    {
        return !(left == right);
    }
    
    public override int GetHashCode()
    {
        return this.X.GetHashCode() ^ this.Y.GetHashCode();
    }
    
    public override bool Equals(object obj)
    {
        if (obj is null)
        {
            return false;
        }

        if (!(obj is Point))
        {
            return false;
        }

        if (obj.GetType() != this.GetType())
        {
            return false;
        }

        Point point = (Point)obj;
        
        return this.Equals(point);
    }
    public bool Equals(Point other)
    {
        return this.X == other.X && this.Y == other.Y;
    }
}

Method:

public static Point[] GetNeighbors(Point point, int h, params Point[] points)
    {
      
    }

I don’t know how to solve this problem, I tried to solve it using:

 for (int i = 0; i <= points.Length - 1; i++)
        {
            PointsCoordinate[i] = Math.Sqrt(Math.Pow(points[i].X, 2) + Math.Pow(points[i].Y, 2));
        }

After that I will find nearest values of point using list or et cetera , but in this case I have to return exactly nearest points from array not values , how can I solve this , mb I have the wrong approach to solving this problem. I need to connect sorted values with Points in array, help me please

解决方案

First you need to calculate the distance from your source "point" to each of your neighbor points. You can do that by using Pythagorean theorem:

The sum of the areas of the two squares on the legs (a and b) equals the area of the square on the hypotenuse.

public static double CalculateDistanceBetweenPoints(Point originPoint, Point destinationPoint)
{
    return Math.Pow(originPoint.X - destinationPoint.X, 2)
        + Math.Pow(originPoint.Y - destinationPoint.Y, 2);
}

You can calculate the distance for each of the points using LINQ extension method Select():

var pointsWithDistance = points
    .Select(p => new { Point = p, Distance = CalculateDistanceBetweenPoints(point, p) });

Then filter out the neighbors that are outside the "h" distance with Where():

var filteredPointsWithDistance = points
    .Select(p => new { Point = p, Distance = CalculateDistanceBetweenPoints(point, p) })
    .Where(pointAndDistance => pointAndDistance.Distance <= Math.Pow(h, 2));

...and order them by growing distance:

var orderedFilteredPointsWithDistance = points
    .Select(p => new { Point = p, Distance = CalculateDistanceBetweenPoints(point, p) })
    .Where(pointAndDistance => pointAndDistance.Distance <= Math.Pow(h, 2))
    .OrderBy(pointAndDistance => pointAndDistance.Distance);

The calculated distance is no longer needed, bring back the Point, use Select() again:

var points = points
    .Select(p => new { Point = p, Distance = CalculateDistanceBetweenPoints(point, p) })
    .Where(pointAndDistance => pointAndDistance.Distance <= Math.Pow(h, 2))
    .OrderBy(pointAndDistance => pointAndDistance.Distance)
    .Select(pointAndDistance => pointAndDistance.Point);

Finally, create an array from the resulted sequence of points:

return points
    .Select(p => new { Point = p, Distance = CalculateDistanceBetweenPoints(point, p) })
    .Where(pointAndDistance => pointAndDistance.Distance <= Math.Pow(h, 2))
    .OrderBy(pointAndDistance => pointAndDistance.Distance)
    .Select(pointAndDistance => pointAndDistance.Point)
    .ToArray();

The whole code and usage example:

public static class Program
{
    public static void Main()
    {
        var h = 10;
        var sourcePoint = new Point(0, 0);
        var neighbors = new Point[]
        {
            new Point(0, 0),
            new Point(100, 100),
            new Point(10, 0),
            new Point(5, 5),
            new Point(-2, -2),
        };
        var nearestNeighbors = GetNeighbors(sourcePoint, h, neighbors);
    }

    public static Point[] GetNeighbors(Point point, int h, params Point[] points)
    {
        return points
            .Select(p => new { Point = p, Distance = CalculateDistanceBetweenPoints(point, p) })
            .Where(pointAndDistance => pointAndDistance.Distance <= Math.Pow(h, 2))
            .OrderBy(pointAndDistance => pointAndDistance.Distance)
            .Select(pointAndDistance => pointAndDistance.Point)
            .ToArray();
    }

    public static double CalculateDistanceBetweenPoints(Point originPoint, Point destinationPoint)
    {
        return Math.Pow(originPoint.X - destinationPoint.X, 2)
            + Math.Pow(originPoint.Y - destinationPoint.Y, 2);
    }
}

这篇关于在 C# 中找到 k 个最近邻的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆