一组线性点的有效最长算术级数

时间:2011-12-20 12:09:10

标签: c++ python algorithm math geometry

一组数字的最长算术级数{ab 1 ,ab 2 ,ab 3 .... ab n }定义为子集{bb 1 ,bb 2 ,bb 3 .... bb n < / sub>}使得b i + 1 - b i 是常量。

我想将这个问题扩展到一组直线上的二维点。 让我们定义Dist(P 1 ,P 2 )是两个点之间的距离P 1 (X 1 ,一行上的Y 1 )和P 2 (X 2 ,Y 2

Dist(P 1 ,P 2 )= Dist((X 1 ,Y 1 ), (X 2 ,Y 2 ))=(X 2 - X 1 2 +(Y 2 - Y 1 )) 2

现在对于给定的一组点,我需要找到最大的算术级数,使得Dist(P i ,P i + 1 )是常数,假设它们都是躺在同一条线上(m&amp; C是常数)。

我研究了一下但是找不到比O更好的算法(n 2 )。

事实上,目前我正在做的方式是保持一个字典说

DistDict=dict()

并说点在List中定义为

Points = [(X1,Y1),(X2,Y2),....]

然后这就是我正在做的事情

for i,pi in enumerate(Points):
    for pj in Points[i+1:]:
         DistDict.setdefault(dist(pi,pj),set([])).add((pi,pj))

所以我最终得到了一个相等距离的词典。因此,我唯一要做的就是扫描一下,找出最长的set

我只是想知道这应该有一个更好的解决方案,但不知怎的,我无法找出一个。我也看过几个类似的旧SO帖子,但没有一个我能找到比O更有效的东西(n 2 )。这在某种程度上是一个NP Hard问题,我们永远不会有更好的东西,或者如果不能采取什么方法。 请注意,我发现了一篇帖子,声称效率很高divide and conquer algorithm,但不能说出任何头部或尾部。

在这方面有任何帮助吗?

注意***我正在标记这个Python,因为我比Matlab或Ruby更了解Python。 C / C ++ / Java也很好,因为我对这些也很熟悉: - )

3 个答案:

答案 0 :(得分:1)

您可以研究 Fast Fourier Transform 方法for multiplication。O(N log N)

您可能能够对您的问题做类似的事情。

答案 1 :(得分:1)

首先,你对距离的定义是错误的。你必须采取平方根。其次,如果你知道所有的点都在一条直线上,你可以简单地忽略y坐标(除非线是垂直的)或x坐标(除非线是水平的)。然后它减少了你的第一段中的问题。

答案 2 :(得分:1)

总结一下:正如@TonyK指出的那样,如果你假设这些点位于一条直线上,你可以将它减少到已经discussed extensively here的一维情况。该解决方案使用@YochaiTimmer提到的快速傅里叶变换。

补充说明:问题几乎肯定不是NP难的,因为它有一个有效的O(n log n)解决方案,因此这意味着P = NP。