算法导论复习——CHP4 分治策略

 分支步骤

步骤:

1)分解(Divide):将原问题分为若干个规模较小、相互独立,形式与原 问题一样的子问题;

2)解决(Conquer):若子问题规模较小、可直接求解时则直接解(称基本情况(base case));否则 “递归”地求解各个子问题,即继续将较大子问题分 解为更小的子问题,然后重复上述计算过程。

3)合并(Combine):将子问题的解合并成原问题的解。 

分治实例 

归并排序

  •         应用步骤:

        1)分解(Divide):将原序列分为两个规模为原来一半的子序列

        2)解决(Conquer):当子序列只有1个元素时,满足有序;否则 “递归” 地求解各个子问题。        

        3)合并(Combine):将两个有序的子数组合并成有序的原数组。 

  •         过程描述:

                MERGE-SORT(A,p,r)

                MERGE(A,p,q,r)

  •         时间复杂度分析:

        T(n) = T(n/2)+cn(求解递归式可得:T(n) = nlogn

最大子数组

        已知数组A,在A中寻找和最大的非空连续子数组。

  •        应用步骤:

        1)分解(Divide):将原数组分为两个规模一样的左右两个子数组。

        2)解决(Conquer):分别求解两个子数组的最大的非空连续子数组。

        3)合并(Combine):最终答案要么整体都在左边或右边子数组中,要么横跨左右,这种情况在合并时考虑,时间复杂度O(n)

  •         时间复杂度:

                                        有T(n) = O(nlogn)     

Strassen矩阵乘法           

        减少乘法次数,增加加法次数。

        先考虑两2 × 2 的矩阵相乘:

        令:

        P=(a11+a22 )(b11+b22 )

        Q=(a21+a22 ) b11

        R=a11 (b12-b22 )

        S=a22 (b21-b11 )

        T=(a11 + a12 )b22

        U=(a11 – a21 ) (b11 + b12 )

        V=(a12 – a22 ) (b21 + b22)

        则有:

        c11 = P+S-T+V = (a11+a22 )(b11+b22 ) + a22 (b21-b11 ) -(a11 + a12 )b22+(a12 – a22 ) (b21 + b22 ) ≡ a11b11+a12b21

        c12 = R+T ≡ a11b12+a12b22

        c21 = Q+S ≡ a21b11+a22b21

        c22 = P+R-Q-U ≡ a21b12+a22b 

        现在对于n阶矩阵,采用分块:(设n = 2^k,若不然可通过在A和B中补0使之变成阶是2的幂的方阵),然后采用Strassen乘法。

算法导论复习——CHP4 分治策略_第1张图片

  •          时间复杂度:算法导论复习——CHP4 分治策略_第2张图片

                有:T(n) = n^{log7}\approx n^{2.81} 

        (但实际上,采用Strassen算法作递归运算,需要创建大量的动态二维数组,其中分配堆 内存空间将占用大量计算时间,从而掩盖了Strassen算法的优势。于是对Strassen算法做出改进,设定一个界限。当 n< 界限时,使用普通法计算矩阵,而不继续分治递归。需要合理设置界限,不同环境(硬件配置)下界限不同。矩阵乘法一般意义上还是选择的是朴素的方法,只有当矩阵变稠密,而且矩阵的阶数很大时,才会考虑使用Strassen算法。)

最近点对问题

        可以参考这一题

求解递归式

        用T(n)表示对规模为n的问题进行求解的时间,则规模分别为n1和n2的子问题的求解时间可表示为T(n1 )和T(n2)。

        一般地,T(n) = T(n_1) + T(n_2)+f(n)

        若有n_1 = n_2 \approx n/2,则T(n) = 2T(n/2)+f(n)

        如何化简递归式,得到形式简单的限界函数?

        代换法

        递归树法

        主方法

         预处理:

        1):n为正整数(因为n通常表示数据的个数)

        2):忽略递归式的边界条件。(递归式的解随T(1)值变化的改变不会超过常数因子)

        3):对上取整、下取整运算做合理简化(忽略)。

        代数法

                先猜测解的形式,然后用数学归纳法求出解中的常数,并证明解是正确的。

                必要的时候要做一些技术处理

                1)去掉一个低阶项

                2)变量代换:

                如:

                令m = logn ,有

                再令S(m)=T(n^m),得

                即化为了熟悉的形式,求解出S(m)再回带。

        递归树

        以例子说明:

        如T(n)=3T(n/4)+cn

        递归树演化如下:

              =>          算法导论复习——CHP4 分治策略_第3张图片   =>                      算法导论复习——CHP4 分治策略_第4张图片 =>

算法导论复习——CHP4 分治策略_第5张图片

 所有节点相加:

算法导论复习——CHP4 分治策略_第6张图片

化简得: 

算法导论复习——CHP4 分治策略_第7张图片

 再用代换法证明其正确性:

        算法导论复习——CHP4 分治策略_第8张图片

        要使得T(n)\le dn^2成立,只要d\ge(16/13)c即可,所以猜测成立。 

        主方法

        针对具有如T(n) = aT(n/b)+f(n)形式的递推式,其中a, b为常数,a\ge1b>1,没有考虑n/b的取整问题,即省略了下取整、上取整,因为其本质上不影响对递归式渐近行为的分析。

  1. 若对于某常数\varepsilon>0,有f(n)=O(n^{log_ba-\varepsilon}),则T(n)=\varTheta(n^{log_ba})
  2. f(n)=\varTheta(n^{log_ba}),则T(n)=\varTheta(n^{log_ba}logn)
  3. 若对于某常数\varepsilon>0,有f(n) = \Omega(n^{log_ba+\varepsilon}),且对于某常数c<1,所有足够大的n,有af(n/b)\le cf(n),则T(n)=\Theta(f(n))

你可能感兴趣的:(算法导论,算法)