给定一组点,找出三个点中的任何一个是否共线

时间:2010-04-29 01:50:03

标签: algorithm graphics data-structures complexity-theory

如果任何三个点在一组点中共线,那么找出最佳算法是什么?如果不是微不足道,请解释复杂性。

感谢
巴拉

3 个答案:

答案 0 :(得分:15)

如果你能想出一个比O(N ^ 2)更好的算法,你可以发布它!

这个问题是3-SUM Hard,并且对于它是否存在亚二次算法(即,优于O(N ^ 2))是一个开放的问题。许多常见的计算几何问题(包括你的问题)已被证明是3SUM很难,而且这类问题正在增长。与NP-Hardness一样,3SUM-Hardness的概念已被证明可用于证明某些问题的“韧性”。

如果您的问题难以证明3SUM,请参阅此处的优秀评论文章:http://www.cs.mcgill.ca/~jking/papers/3sumhard.pdf

您的问题出现在上面提到的论文中的第3页(通常称为3点在线)。

所以,目前最着名的算法是O(N ^ 2),你已经拥有它了: - )

答案 1 :(得分:6)

一个简单的O(d * N ^ 2)时间和空间算法,其中d是维数,N是点数(可能不是最优):

  • 围绕这组点创建一个边界框(使其足够大,以便边界上没有点)
  • 对于每对点,计算通过它们的线。
  • 对于每一行,使用边界框计算其两个碰撞点。
  • 两个碰撞点定义原始线,因此如果有任何匹配线,它们也会产生相同的两个碰撞点。
  • 使用哈希集来确定是否存在任何重复的碰撞点对。
  • 当且仅当存在重复时,才有3个共线点。

答案 2 :(得分:4)

另一个不使用哈希表的简单(可能甚至是微不足道的)解决方案在O(n 2 log n)时间内运行,并使用O(n)空间:

S成为一组点,我们将描述一种算法,该算法可以确定S是否包含三个共线点。

  1. o中的每个点S执行:
    1. L行与x - 轴平行并通过o
    2. 用其反射替换S下方L中的每个点。 (例如,如果Lx轴,(a,-x)的{​​{1}}将在反映后变为x>0。让新的点集为(a,x)
    3. S'中每个点p的角度是段S'与线po的直角。让我们按角度对L点进行排序。
    4. 浏览S'中的已排序点。如果有两个与S'共线的连续点 - 返回true。
  2. 如果在循环中没有找到共线点 - 返回false。
  3. 循环运行o次,每次迭代执行n步。不难证明,如果一条线上有三个点,它们就会找到,否则我们什么也找不到。