简体   繁体   English

给定一组点,找出三个点是否共线

[英]Given a set of points, find if any of the three points are collinear

What is the best algorithm to find if any three points are collinear in a set of points say n. 找出一组点中说n的三个点是否共线的最佳算法是什么? Please also explain the complexity if it is not trivial. 如果不是很简单,也请解释一下复杂性。

Thanks 谢谢
Bala 巴拉

If you can come up with a better than O(N^2) algorithm, you can publish it! 如果您能提出优于O(N ^ 2)的算法,则可以发布它!

This problem is 3-SUM Hard , and whether there is a sub-quadratic algorithm (ie better than O(N^2)) for it is an open problem. 这个问题是3-SUM Hard ,是否存在次二次算法(即优于O(N ^ 2))是一个开放问题。 Many common computational geometry problems (including yours) have been shown to be 3SUM hard and this class of problems is growing. 许多常见的计算几何问题(包括您自己的问题)已证明是3SUM难题,并且这类问题正在不断增加。 Like NP-Hardness, the concept of 3SUM-Hardness has proven useful in proving 'toughness' of some problems. 像NP-Hardness一样,3SUM-Hardness的概念已被证明可用于证明某些问题的“韧性”。

For a proof that your problem is 3SUM hard, refer to the excellent surver paper here: http://www.cs.mcgill.ca/~jking/papers/3sumhard.pdf 有关您的问题很难解决3SUM的证明,请参见此处的优秀综合论文: http : //www.cs.mcgill.ca/~jking/papers/3sumhard.pdf

Your problem appears on page 3 (conveniently called 3-POINTS-ON-LINE) in the above mentioned paper. 您的问题出现在上述论文的第3页上(通常称为3-POINTS-ON-LINE)。

So, the currently best known algorithm is O(N^2) and you already have it :-) 因此,当前最知名的算法是O(N ^ 2),您已经拥有它:-)

A simple O(d*N^2) time and space algorithm, where d is the dimensionality and N is the number of points (probably not optimal): 一个简单的O(d * N ^ 2)时空算法,其中d是维数,N是点数(可能不是最优的):

  • Create a bounding box around the set of points (make it big enough so there are no points on the boundary) 在这组点周围创建一个边界框(使其足够大,以便边界上没有点)
  • For each pair of points, compute the line passing through them. 对于每对点,计算通过它们的线。
  • For each line, compute its two collision points with the bounding box. 对于每条线,使用边界框计算其两个碰撞点。
  • The two collision points define the original line, so if there any matching lines they will also produce the same two collision points. 两个碰撞点定义了原始线,因此,如果有任何匹配的线,它们也将产生相同的两个碰撞点。
  • Use a hash set to determine if there are any duplicate collision point pairs. 使用哈希集确定是否有重复的碰撞点对。
  • There are 3 collinear points if and only if there were duplicates. 当且仅当存在重复项时,存在3个共线点。

Another simple (maybe even trivial) solution which doesn't use a hash table, runs in O(n 2 log n) time, and uses O(n) space: 另一个不使用哈希表的简单(甚至是微不足道的)解决方案,运行时间为O(n 2 log n),并使用O(n)空间:

Let S be a set of points, we will describe an algorithm which finds out whether or not S contains some three collinear points. 假设S为一组点,我们将描述一种算法,该算法找出S是否包含三个共线点。

  1. For each point o in S do: 对于S每个点o
    1. Pass a line L parallel to the x -axis through o . 使平行于x轴的直线L通过o
    2. Replace every point in S below L , with its reflection. SL之下的每个点替换为其反射。 (For example if L is the x axis, (a,-x) for x>0 will become (a,x) after the reflection). (例如,如果Lx轴,则x>0 (a,-x)将在反射后变为(a,x) )。) Let the new set of points be S' 让新的点集为S'
    3. The angle of each point p in S' , is the right angle of the segment po with the line L . S'中每个点p的角度是线段po与直线L直角。 Let us sort the points S' by their angles. 让我们按点S'的角度对其排序。
    4. Walk through the sorted points in S' . 遍历S'的排序点。 If there are two consecutive points which are collinear with o - return true. 如果有两个连续的点与o共线-返回true。
  2. If no collinear points were found in the loop - return false. 如果在循环中找不到共线点,则返回false。

The loop runs n times, and each iteration performs nlog n steps. 循环运行n次,每次迭代执行nlog n步骤。 It is not hard to prove that if there're three points on a line they'll be found, and we'll find nothing otherwise. 不难证明,如果一条线上有三个点,就会找到它们,否则我们将一无所获。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM