【问题标题】:Closest point to a given point到给定点的最近点
【发布时间】:2009-12-14 14:10:52
【问题描述】:

我在 2D 图像中有一组随机选择的像素 K。对于图像中的每个其他像素,我需要找出 K 集中的哪个像素最接近它(使用标准的 sqrt(dx^2 + dy^2) 距离度量)。我知道每个像素可能有多个解决方案。显然,它可以通过对集合中的每个像素的蛮力来完成,但我宁愿避免这样做,因为它效率不高。还有什么好的建议吗?

干杯。

【问题讨论】:

    标签: algorithm 2d points


    【解决方案1】:

    别忘了你不需要考虑平方根。

    如果您只想找到最近的(而不是实际距离),只需使用dx^2 + dy^2,它会为您提供与每个项目的距离平方,这同样有用。

    如果您没有将这个像素列表包装起来的数据结构,您只需针对它们进行测试。

    如果您有一定的灵活性,有很多好方法可以减少工作量。创建Quadtree,或保留像素的排序列表(按 x 排序并按 y 排序)以更快地缩小搜索范围。

    【讨论】:

    • 好主意!对于大型数据集,这将大大减少运行时间。
    • 由于您正在处理像素,这也意味着您可以降级到整数数学,这是另一个巨大的速度奖励
    • @rikh 即使您确实需要距离,一旦您知道哪个点最近,您也可以随时使用sqrt
    • 推广四叉树来对 n 维向量进行搜索是个好主意吗?
    【解决方案2】:

    我将不得不同意 jk 和 Ewan 制作 Voronoi Diagram。这会将空间划分为多边形。 K 中的每个点都会有一个多边形来描述最接近它的所有点。 现在,当您查询某个点时,您需要找到它位于哪个多边形中。这个问题称为Point Location,可以通过构造Trapezoidal Map 来解决。

    jk 已经链接到使用 Fortune's algorithm 创建 Voronoi Diagram,这需要 O(n log n) 计算步骤并花费 O(n) 空间。 This website 教你如何制作梯形图以及如何查询。您还可以在那里找到一些界限:
    预期创建时间:O(n log n)
    预期空间复杂度:O(n)

    但最重要的是,预期的查询时间:O(log n)。这(理论上)比 kD-tree 的 O(√n) 更好。

    我的来源(除了上面的链接)是:Computational Geometry: algorithms and applications,第六章和第七章。

    您将在此处找到有关这两种数据结构的详细信息(包括详细证明)。 Google 图书版本只有您需要的一部分,但其他链接应该足以满足您的目的。如果您对这类事情感兴趣,就买这本书(这是一本好书)。

    【讨论】:

      【解决方案3】:

      将这些点放在 KD 树中,之后可以非常快地找到最近的邻居。有关详细信息,请参阅维基百科上的 this 文章。

      【讨论】:

        【解决方案4】:

        Voronoi Diagrams 的构造是Computational Geometry 的一个分支。 Delaunay Triangulations 的构造涉及类似的考虑。您可以调整以下Delaunay algorithms 之一以满足您的需求。

        • 翻转算法
        • 增量
        • 分而治之
        • 扫描线

        【讨论】:

          【解决方案5】:

          这称为最近邻搜索。 Donald Knuth 称之为邮局问题。

          有许多解决方案:线性搜索、局部敏感散列、向量近似文件和空间分区。

          谷歌搜索应该会有所帮助。

          【讨论】:

            【解决方案6】:

            您要做的是构造一个voronoi diagram,这可以使用plane sweep 在O(n log n) 中完成

            【讨论】:

              【解决方案7】:

              另一个提示:距离总是大于等于每个坐标差,并且总是小于等于它们的和,即

              d >= dx, d >= dy, d <= dx + dy.
              

              这可能会帮助您更有效地进行排序。

              【讨论】:

                【解决方案8】:

                根据该图形填充像素的密集程度,您最好从原始像素向外搜索。

                我为图形终端仿真编写了类似的程序。我最终做的是编写一个从中心点长出来的方形螺旋形状的搜索模式,我让它一直增长直到它碰到什么东西。即使在旧 CPU 上,这也足够快。

                【讨论】:

                • 就单点而言,我的算法“足够好”。对于一大群人来说,Voronoi 听起来像是赢家。我会收回我的答案,除非一些未来的读者可能有单点要求。
                猜你喜欢
                • 1970-01-01
                • 2018-08-28
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2020-12-28
                • 1970-01-01
                • 2021-12-24
                • 1970-01-01
                相关资源
                最近更新 更多