分治算法定理、平面最近点问题

分:递归解决较小的问题

治:从子问题构建原问题的解

分治算法的时间:

定理1:方程T(N)=aT(N/b)+\Theta (N^k)的解是:

O(N^{log_{b}^{a}}),a>b^{k}

O(N^{k}logN),a=b^{k}

O(N^{k}),a< b^{k}

证明用叠缩求和法

定理2:方程T(N)=aT(N/b)+\Theta (N^{k}log^{p}N)的解是

O(N^{log_{b}^{a}}),a> b^{k}

O(N^{k}log^{p+1}N),a=b^{k}

O(N^{k}log^{p}N),a<b^{k}

定理3:若\sum_{i=1}^{k}a_{i}<1,则方程T(N)=\sum_{i=1}^{k}T(a_{i}N)+O(N)的解是T(N)=O(N)

证明:使用数学归纳法,这个方程的意义是,若将原问题分解成若干不到原问题100%的若干个子问题加上合并子问题的线性时间,那么算法时间是O(N)

最近点问题:输入平面上的点列P,若p_{1}=(x_{1},y_{1})p_{2}=(x_{2},y_{2}),那么两点之间的欧几里得距离是[(x_{1}-x_{2})^2+(y_{1}-y_{2})^2]^{1/2},找出一对最近的点

一种显然的方法是遍历所有点对距离,时间是O(N^2)

若先对x坐标排序,那么花费时间是O(NlogN),对于要证明总时间是O(NlogN),不增加时间界

分解问题如下:在二位坐标系中画一条想象的垂线P,将所有点按照x坐标分成左右两个部分P_{L}P_{R},那么距离最近的点对要么在左边,要么在右边,要么一个在左边一个在右边,这就是一个典型的分治问题,由于想要O(NlogN)解,因此只能用线性附加时间计算横跨左右的这种距离。

\delta =min(d_{L},d_{R}),若d_{c}\delta有改进,那么一定在P左右的\delta的带状区域中,这就减少了需要考虑的横跨左右的点,平均在带状区域中的点的数量是O(\sqrt{N}),因为想象N个点落在一个单位格子中,那么最均匀的分布是,长和宽都是\sqrt{N}个点,从而让两点之间最小值的最大值为O(\frac{1}{\sqrt{N}}),这就是带状区域的宽,其中的点数量就是\sqrt{N}*\frac{1}{\sqrt{N}},即O(\sqrt{N}),因此可以用O(N)时间进行蛮力计算,代码如下:

for (i = 0; i < N; i++)
	for (j = i + 1; j < NumPointsInStrip; i++)
		if (Dist(Pi, Pj) < ans)
			ans = Dist(Pi, Pj);

在最坏的情况下,可能所有点都在带状区域中,就不能保证O(N)时间了,可以改进到最坏O(N)时间,方法是对y坐标排序,代码如下:

for (i = 0; i < NumPointsInStrip; i++)
	for (j = i + 1; j < NumPointsInStrip; j++)
		if (Pj and Pi's coordinates differ by more than ans)
			break;
		else if (Dist(Pi, Pj) < ans)
			ans = Dist(Pi, Pj);

内层循环只有常数个节点需要被考虑,因此是线性时间

猜你喜欢

转载自blog.csdn.net/kdb_viewer/article/details/83049171
今日推荐