【问题标题】:Given a set of points, how do I find the two points that are farthest from each other? [duplicate]给定一组点,我如何找到彼此最远的两个点? [复制]
【发布时间】:2010-12-09 18:10:38
【问题描述】:

可能重复:
Greatest linear dimension 2d set of points

我可以计算每个点之间的距离并取最大值,但是当点数很大(> 1000)时,这听起来不是一种非常有效的方法。

注意:这是针对 iPhone 的,所以我没有大量的处理能力。

【问题讨论】:

    标签: c algorithm geometry points


    【解决方案1】:

    请参阅these pages(链接到的以及通过单击“下一步”链接可访问的页面)计算一组点的凸包直径。

    我的快速总结:

    1. 计算凸包中的点集(= O(n log n),唯一得到 O(n) 的时间是如果您首先对列表进行排序,无论如何需要 O(n log n))
    2. 沿边界订购(如果您将Graham scan 用于#1,则可以免费获得)
    3. 使用一种 O(n) 直径算法来扫描具有最大直径的对映点。 Shamos algorithm 对我来说看起来不错,因为它是 rotating calipers 算法之一。

    【讨论】:

      【解决方案2】:

      您要求计算集合的直径。标准技术是首先计算凸包,这将问题简化为找到凸多边形的直径。即使在您不消除任何点的情况下,这些附加信息也正是有效解决问题所需要的。然而,找到凸多边形的直径并非易事。几篇已发表的包含此任务算法的论文被证明是不正确的。

      这是该任务的正确 O(n) 算法的fairly readable discussion(其中 n 是凸包中的点数)。

      另外,请注意 iphone 不受 限制;即使是完全朴素的算法,精心编写的实现也可以在不到十分之一秒的时间内处理 1000 个点。当然,使用正确的算法会让你走得更快 =)

      【讨论】:

      • 只有在找到凸包之后才需要 O(n) ——如果你只是给定一组点,那么首先找到凸包可能是 O(n log n)。
      • @ShreevatsaR:当然。我的回答明确地说“其中 n 是凸包中的点数”,这很清楚您需要先找到凸包。
      • 是的,也许确实如此。清晰在读者眼中。 :-) (问题中任务的算法显然不是 O(n) ,其中 n 是凸包中的点数;正如你所说,这是第二部分。)无论如何,我认为值得一提,只是为了完整性:人们可能会在多年后通过搜索引擎获得这些答案,可能不会仔细阅读,并且可能会感到困惑,等等。
      • pdf 链接失效,谷歌快速搜索失败,有人有副本吗?
      • @Thomas:该算法被称为“旋转卡尺”,ShreevatsaR 在他对另一个问题的回答中给出了很好的非正式描述(stackoverflow.com/a/322409/142434
      【解决方案3】:

      为什么不只计算点的convex hull?根据您使用的algorithm,它会花费O(n)O(n log n) 时间,并从考虑中消除所有内部点。然后,只检查这些最外面的点,找到最远的两个。

      【讨论】:

      • 这并没有让事情变得更容易。如果凸包中的点数为 O(n),则复杂度保持不变。
      • 非常正确。但希望是,如果有 >1000 个点,那么其中许多点将位于凸包内。
      • 很好的答案。我正要说这个。从 Akl-Toussaint 启发式开始,在找到凸包之前抛出尽可能多的点。
      • 您已将复杂度度量从 O(n^2) 降低。在最坏的情况下,所有点都在凸包上,但在许多情况下,您会大大减少实际工作量。
      • @Pavel(和@Chris)凸包上的预期点数是O(log n),因此检查这些点的预期运行时间是O(log^2 n)
      【解决方案4】:

      从 x 坐标最低的点开始。 (称之为 X 点) 构建“边界点”集 从点 x 开始,垂直线穿过该点,PointX 左侧应该没有其他点)通过顺时针(或逆时针)缓慢旋转线找到边界中的下一个点,直到线接触其他点,(见下文)。将该点添加到集合中并重复下一个点以获得下一个点,直到您最终回到原始点 x。您 npw 有一组点构成完整集的边界。比较此缩减集中每对之间的距离,以找到相距最远的一对。

      要“旋转线”(找到每个连续的边界点),取与用于最后一个边界点的线垂直的方向上“最远”的点,并在最后一个边界点之间构造一条新线还有那个“下一个”点。然后验证在由该新线形成的新垂直方向上没有其他点。如果在与这条线或最后一条线垂直的方向上没有其他点“进一步向外”,那么这是下一个边界点的正确选择,如果有这样的点,切换到那个点并重新测试。

      【讨论】:

      • 与克里斯相同的评论。如果在外部边界上没有更少的点,你不会让任何事情变得更容易。
      • 这听起来像是一种计算复杂船体的昂贵方法,接下来是 Chris Bunch 的其余答案。
      • 我不知道这有一个技术术语...(凸壳),但它是一个橡皮筋边界。我将检查其他算法来计算它......关于点数,对于任何随机点集合,边界中的点数应该小于总点数 O(n)。 (边界是界定二维区域的一维线。)
      猜你喜欢
      • 2023-03-27
      • 2010-10-03
      • 1970-01-01
      • 2021-02-09
      • 2019-06-06
      • 2022-11-01
      • 2011-02-13
      • 2019-11-19
      相关资源
      最近更新 更多