一组线性点的有效最长等差数列

Efficient Longest arithmetic progression for a set of linear Points

本文关键字:有效 等差数列 线性 一组      更新时间:2023-10-16

一组数的最长等差数列{ab1,ab2,ab3 ....ab <子> n }{被定义为一个子集bb <子> 1,bb <子> 2 ,bb <子> 3 …Bb n}使得bi+1 - bi是常数。

我想把这个问题推广到一条直线上的二维点的集合。我们定义Dist(P1,P2)是直线上两点P1(X1,Y1)和P2(X2,Y2)之间的距离为

Dist (p <子> 1子>

2 ) = Dist ((X <子> 1,Y <子> 1 ), (X <子> 2 ,<子> 2 )) = 2 (X <子> 1 - X <子>)<一口> 2> - Y <子> 1 )) <一口> 2

现在对于给定的一组点,我需要找到最大的等差数列,使得Dist(p I , p I +1)是常数,假设它们都在同一条线上(m &C是常量)。

我研究了一下,但没有找到比0 (n2)更好的算法。

事实上,目前我所做的是维护一个字典说

DistDict=dict()

和say点在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帖子,但我找不到比0 (n2)更有效的东西。这是不是一个NP困难的问题,我们永远不会有更好的方法,或者如果没有,我们可以采取什么方法。请注意,我看到一个帖子,声称一个有效的分而治之算法,但不能做出任何头或尾。在这方面有什么帮助吗?

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

总结一下:正如@TonyK指出的,如果你假设这些点位于一条直线上,你可以将其简化为一维情况,这里已经广泛讨论过了。该解决方案使用了@YochaiTimmer提到的快速傅里叶变换。

附加注意:这个问题几乎肯定不是NP困难的,因为它有一个有效的O(n log n)解决方案,所以这意味着p =NP。

你可以学习快速傅立叶变换乘法方法。O(N log N)

你也许可以对你的问题做类似的事情。

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