用递归求解最近对算法(除法和征服)

时间:2015-03-17 01:29:58

标签: algorithm recursion

我理解如何使用强力解决臭名昭着的“最近对问题”,但是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

2 个答案:

答案 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;
}