分治算法复杂度和递推关系

通过递推关系求解分治算法复杂度

1 引言

分治算法:将一个问题划分成较小规模的同一个问题的一个或多个实例,这些子问题相互独立且与原问题形式相同。我们通过处理这些小规模问题的解找到初始问题的解。其一般的算法设计模式如下:

divide-and-conquer(P){
	if(|P| <= n0)
		adhoc(P);
	divide P into smaller subinstance P1,P2,P3…Pk;
	for(int i = 1;i<=k;i++)
		yi = divide-and-conquer(Pi);
	return merge(y1,y2,y3…,yk);
}

note:其中|P|表示问题P的规模,n0为一阈值,表示问题P规模不超过n0时,问题容易解出,不必继续分解。adhoc§是该分治法中的基本子算法,用于直接解决小规模问题P,当P的规模不超过n0时,直接用adhoc()求解。算法merge(y1,y2…,yk)是该分治算法中的合并子算法。

2 建立分治算法复杂度的递推关系

我们在通过分治算法找其递推关系时往往比较关注问题的如下几个方面,这些方面直接影响了我们设计的算法的效率,在设计算法分析算法好坏中至关重要。

  1. 我们关注我们将原规模为 n n n问题转化为了几个子问题,即 P 1 , P 2 , ⋯ P k P_1,P_2,\cdots P_k P1,P2,Pk中的 k k k.
  2. 我们关注每个子问题的规模,即| P i P_i Pi|
  3. 同时,还应关注在通过已有小规模问题的解求解原问题时,可能会引入一些额外的工作,即 m e r g e ( P 1 , ⋯ &ThinSpace; , P k ) merge(P_1,\cdots,P_k) merge(P1,,Pk)的操作规模。

举例:我们在二分查找的过程中将一个从 n n n个数组成的list[n]数组中查找键值为 a a a的元素。
1.我们将原问题转化为了在其一个子序列中查找对应元素的问题,即 k = 1 k = 1 k=1
2.每个子问题的规模是原问题规模的 1 / 2 1/2 1/2
3.我们引入以下两个额外的步骤:
-------- 计 算 m i d = ( l e f t + r i g h t ) / 2 计算mid = (left+right)/2 mid=(left+right)/2
-------- 比 较 l i s t [ m i d ] 与 a 的 大 小 关 系 比较list[mid]与a的大小关系 list[mid]a

由这些已知条件,我们可以给出一个分之算法的复杂度 f ( n ) f(n) f(n)的递推公式:
我们不妨设一个递归算法吧一个规模为n的问题分成了a个子问题,每个问题的规模是n/b,且设由各个子问题的解组合成原问题的解的处理步骤需要总量为 g(n) 的额外步骤。设 f ( n ) f(n) f(n):解决规模为 n n n的问题的算法复杂度,则有如下 f f f的递推关系:
(1) f ( n ) = a f ( n / b ) + g ( n ) f(n) = af(n/b) + g(n)\tag{1} f(n)=af(n/b)+g(n)(1)

3 使用递推关系求解分治算法复杂度

对于 ( 1 ) (1) (1)类型的递推公式,我们有以下结论来对其阶进行估计:首先我们根据 g ( n ) g(n) g(n)的形式不同分成以下两种不同的情况其中 c , d c,d c,d为常数:

  • g ( n ) = c g(n) = c g(n)=c
  • g ( n ) = c n d g(n) = cn^d g(n)=cnd

3.1首先考虑情况 g ( n ) = c g(n) = c g(n)=c

定理1 设函数 f f f满足这个递推关系: f ( n ) = a f ( n / b ) + c f(n) = af(n/b) + c f(n)=af(n/b)+c的增函数,其中 a ≥ 1 a≥1 a1, b b b

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值