我理解如何使用强力解决臭名昭着的“最近对问题”,但是O(n ^ 2)运行时间中可能递归工作的简单算法呢?问题是
Given a set of n points, write the code to find the closest pair of points
什么是可用于解决此问题的简单递归函数?
这是一个测试问题,第一个数字是点数,下面几行包含点数:
6
0 5
1 13
5 9
1 8
3 10
6 10
答案 0 :(得分:2)
此代码使用除法和征服找到A的最近点对,并在O(N ^ 2)时间内运行。有效的算法(你试图理解)替换了以"开头的部分为左边的pL":而不是比较左右两边的每一对点,它最多比较6从左侧的每个点开始点。
这里的closest
函数返回最近对的距离平方以及这对点。这对于min
来说非常方便。
import itertools
def dist2(a, b):
return (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2
def closest(A):
if len(A) <= 3:
return min((dist2(a, b), (a, b)) for a, b in itertools.combinations(A, 2))
pL = A[:len(A)//2]
pR = A[len(A)//2:]
result = min(closest(pL), closest(pR))
for left in pL:
for right in pR:
result = min(result, (dist2(left, right), (left, right)))
return result
test = [map(float, x.split(' ')) for x in '0 5,1 13,5 9,1 8,3 10,6 10'.split(',')]
print closest(test)
答案 1 :(得分:0)
这就是使用C#
递归解决问题的方法double diffL, diffR;
List<double> L, R;
int mid;
public static double DnQ(List<double> P)
{
if(P.Length == 2) //base case
return P[0]-P[1];
mid = P.Length/2; //calculate middle of List of points
L = P.GetRange(0, mid);
R = P.GetRange(mid+1,P.Length - mid);
diffL = DnQ(L); //recursive call on left side
diffR = DnQ(R); //recursive call on right side
if(diffL > diffR) //return differences
return diffR;
else
return diffL;
}