一组数字的最长算术级数{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也很好,因为我对这些也很熟悉: - )
答案 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。