将基坐标与 n 个坐标列表进行比较并确定最接近的 m 个坐标的最佳算法?

发布于 2024-09-30 04:23:55 字数 950 浏览 5 评论 0原文

我现在有一些代码正在执行此操作。它适用于中小型列表,但是当我有一个大小为 n > 的列表时,它可以正常工作。 5000 那么我的算法在移动设备上运行大约需要 1 分钟。我基本上将 Java 中的坐标对象与坐标对象列表(向量)进行比较。

这是我的基本算法:

  • 遍历列表 nx 中的每个元素,
  • 如果“10 个最接近”列表中的项目少于 10 个,则将 nx 添加到列表中 如果“10 最接近”列表已经有 10 个项目,则转到下一个元素
  • ,然后计算 nx 与底座之间的距离 则坐标
  • 如果距离小于“10 个最近距离”中的最远距离, list”,然后删除最远的项目 从该列表中并将其替换为 nx

我一直在关注这个,并试图找到一种更有效的方法来做到这一点。这有点像排序算法问题,所以必须有更好的方法。

这是我的距离计算方法:

public static double distance(double lat1, double lon1, double lat2, double lon2, char unit) {

  double theta = lon1 - lon2;

  double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));

  dist = acos(dist);

  dist = rad2deg(dist);

  dist = dist * 60 * 1.1515;

  if (unit == 'K') {

    dist = dist * 1.609344;

  } else if (unit == 'N') {

    dist = dist * 0.8684;

    }

  return (dist);

}

I have some code doing this right now. It works fine with small to medium sized lists, but when I have a list of size n > 5000 then the my algorithm can take almost 1 minute on a mobile device to run. I'm basically comparing a Coordinate object in Java to a list (Vector) of Coordinate objects.

Here's my basic algorithm:

  • traverse each element in the list nx
  • if there is less 10 items in the "10 closest" list then add nx to the list
    and go to the next element
  • if the "10 closest" list has 10 items already, then calculate the
    distance between nx and the base
    Coordinates
  • if the distance is less than furthest distance in the "10 closest
    list" then remove the furthest item
    from that list and replace it with nx

I keep looking at this and am trying to find a more efficient way of doing this. It's sort of like a sorting algorithm problem so there must be a better way.

Here is my distance calculation method:

public static double distance(double lat1, double lon1, double lat2, double lon2, char unit) {

  double theta = lon1 - lon2;

  double dist = Math.sin(deg2rad(lat1)) * Math.sin(deg2rad(lat2)) + Math.cos(deg2rad(lat1)) * Math.cos(deg2rad(lat2)) * Math.cos(deg2rad(theta));

  dist = acos(dist);

  dist = rad2deg(dist);

  dist = dist * 60 * 1.1515;

  if (unit == 'K') {

    dist = dist * 1.609344;

  } else if (unit == 'N') {

    dist = dist * 0.8684;

    }

  return (dist);

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

喜爱皱眉﹌ 2024-10-07 04:23:55

您可以将坐标存储在某个空间分区树中。

或者,对于更简单的方法,您可以使用二维存储桶数组,并首先检查最近的存储桶,直到找到足够的最近邻居。仅当坐标分布均匀时,此方法才有效。

编辑:要比较距离,您可以预先计算球体上的 3D 坐标,并在比较中使用欧几里得距离的平方:

dx * dx + dy * dy + dz * dz

You could store your coordinates in some space partitioning tree.

Or, for a simpler approach, you could use a two-dimensional array of buckets, and check the closest buckets first, until you found enough nearest neighbors. This only works well if the coordinates are distributed evenly.

Edit: To compare the distances you could precompute 3D coordinates on the sphere and use the square of the Euclidean distance in the comparisons:

dx * dx + dy * dy + dz * dz
水波映月 2024-10-07 04:23:55

好吧,也许用数组来做这件事会更快。您可以比较距离的平方而不是距离,这意味着您不必使用平方根。

最好有实际的代码。

Well, maybe it would be faster to do this with arrays. And you could compare the square of the distance instead of the distance, which means that you don't have to work with square roots.

It would be good to have the actual code.

顾北清歌寒 2024-10-07 04:23:55

您也许可以使用类似于此网站的方法来限制实际需要您计算的点数距离。

该网站展示了如何计算点和给定距离的纬度、经度边界坐标。这与您遇到的问题不完全相同,但它可以充当过滤器。在你的例子中,你显然试图找到距离给定点最近的 10 个(或 n 个)点。您可以应用以下算法来查找 10 个(或 n 个)最近的点:

对于前 n 个点,您可以完成完整的距离
您进行的计算,保存沿每个点的距离。

保存总的最长距离。计算纬度、经度边界
框如上面网站所示。

继续你的其余观点。

如果任何点位于纬度、经度边界框之外,则不能将其
比当前 10 个最近点中的任何一个都更近。如果是在里面的话
边界框,计算距离。

丢弃前一组 10 个“最近”点中最远的一个。

根据新的最远点重新计算经纬度边界框。

重复此操作,直到处理完所有点。

这种方法的好处是您可以避免对大量点进行繁重的计算。根据点的分布,您仍然可能会遇到性能不佳的问题,例如,如果点被排序,使得它们与目标点的距离逐渐减小(点 [0] 是最远的,点 [N]是最接近的))。

You might be able use something like the approach at this website to restrict the number of points that actually require you to compute the distance.

The website shows how to compute the lat, lon bounding coordinates for a point and a given distance. That is not exactly the same problem that you have, but it could serve as a filter. In your case you are apparently trying to find the 10 (or n) closest points to a given point. You could apply the following algorithm to find the 10 (or n) closest points:

For the first n points, you could go through the full-blown distance
calculation that you have, saving the distance along each point.

Save the overall longest distance. Compute the lat, lon bounding
box as illustrated on the website above.

Continue through the rest of your points.

If any point is outside of the lat, lon bounding box, it cannot be
closer than any of the current 10 closest points. If it is inside
the bounding box, calculate the distance.

Discard the farthest of the previous set of 10 "closest" points.

Recompute the lat, lon bounding box based on the new farthest point.

Repeat until all points processed.

The benefit of this approach is that you might be able to avoid heavy calculations for a large number of your points. Depending on the distribution of your points, you could still suffer from poor performance, such as if the points turn out to be ordered such that they are in decreasing distance from your target points (point[0] is the farthest and point[N] is the closest)).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文