【问题标题】:Faster ways to search points close to a line更快的方法来搜索靠近一条线的点
【发布时间】:2013-08-17 08:17:28
【问题描述】:

我在二维空间中有一组点和一条线。我需要找到距离线 D 范围内的所有点。有没有办法让我做到这一点,而不必实际计算所有点与直线的距离 di?有没有比线性搜索更好的解决方案?

编辑:我需要多次搜索不同线的同一点集。这些点始终是恒定的,但在每次搜索期间线会有所不同。通常,点集的数量级为数万(~50k)。

【问题讨论】:

  • 积分是静态的吗?您只需要这样做一次还是经常这样做?如果只需要这样做一次,恐怕没有更好的解决方案了。
  • 您可以通过查找与线的距离平方小于 D^2 的点来节省一些时间。
  • 听起来这可能是一个查询,其中您保留同一行但搜索多个点集,或者您保留相同的点集并使用不同的行。 O(N) 是您可以为前者做的最好的事情,而对于后者,您似乎可以做 O(k) 或 O(k log(N)),其中 k 是返回的点数。
  • 如果直线附近有大量点,那么您可以使用包含椭圆的矩形,该椭圆代表距离直线 d 的空间。它需要一些时间来计算,但是任何检查一个点是否在那个矩形内只需要 8 次比较,这可能比计算距离便宜。尽管您可能需要至少数百万甚至数十亿的积分才能物有所值。

标签: algorithm line distance point nearest-neighbor


【解决方案1】:

关于查询:

如果您使用这些点创建一个 kd-tree,并使用线上的几个等距点(可能在 d 附近),您应该能够使用修改后的最近邻查询来查找所有与 d 为 a 的点大致在 O(k + log(N)) 中。 kd-tree 需要 O(N log N) 预处理,因此只有使用相同的点集才会更好(可能略有不同,因为您可以在 O(log N) 中从 kd-tree 添加/删除一个点)和不同的线路。唯一的问题是 kd-tree 并不是真的要与行一起使用。我确信有类似的东西可以更好地工作,但我不熟悉它。

注意:根据事物的排列方式,可能会出现误报和否定,因为您实际上是在查询到直线上某个点的距离,而不是直线上的距离。这在很大程度上取决于线的长度与 d 之间的比率。因此,除非大多数点不在该线附近,否则您将获得相当数量的误报或误报。一般来说,这可能不会成为太大的问题,因为即使有误报,k 与 N 相比也应该相当小,除非 d 相对较大。

经过一番审查,我注意到查询是针对一条线而不是线段。但是,可以通过使线段以最小/最大 x/y 为界来将其转换为 1。我想可能还有一种更有效的方法可以为此使用 kd-tree。

【讨论】:

    【解决方案2】:

    此搜索无法比线性搜索更快地完成,因为输入数据和结果总体具有相同的复杂性。

    【讨论】:

    • 对于实际问题,常数乘数很重要。我通常宁愿运行需要 n 纳秒的东西而不是需要 n 分钟的东西,即使两者都是 O(n)。
    • 如果输出中有 0 个点,理想的查询将采用 O(1),而不是 O(n)。您不能说输入和输出具有相同的(空间)复杂度。对于几乎任何具有不同大小的非常量输出的算法,在指定复杂性时通常会涉及多个变量。对于这个特定的例子,我们可以说总共有n 个点,m 个点表示与线的距离,输入为 O(n) 空间,输出为 O(m) 空间,搜索采用 O(f(m ,n))。
    • @Dukeling:不清楚这是一个查询问题,尽管它可能是。因此,给定一条线和一个点集,在预处理中不超过 O(N) 的情况下,您似乎不会比 O(N) 做得更好。
    • @Dukeling,复杂性不能超过 O(N),因为您必须至少检查每个点。例如复杂性不能比读取和输出更好。阅读复杂度 O(N),如果您知道如何计算复杂度,那么对于输出来说,复杂度将是 O(N),而不是特殊情况下的 O(1)。
    • 我假设有多个查询,每个单独的查询可以少到 O(1),但是,是的,必须至少有 O(n) 预处理。目前尚不清楚问题是否属于这种情况。
    猜你喜欢
    • 2017-05-09
    • 2014-09-23
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多