算法设计和复杂性理论学习笔记_3(分治策略算法)

来源:互联网 发布:淘宝运营工资一般多少 编辑:程序博客网 时间:2024/06/06 06:48

一些笔记:

1.分治算法的主要思想:将原问题划分成若干的子问题,分而治之,最后将若干个子问题的解合并得到原问题的解。常常含有二分、递归的方法在里面

2.分析分治算法的工具——递归方程;

3.每次划分的时候子问题的规模尽量接近:连续划分 平衡原则;

4.通常两类递归方程:

1) T(n)= \sum{i=1}_{n-1} T(n-i)+g(n);

2) T(n)=a*f(n/b)+ d(n);

5.通常用主定理(MasterTheorem)、递归树解决此类方程或者得到阶的估计;

6.优化分治算法的两个途径(根据主定理得出):

1) 在n^(logb(a)-eps) = BIGOMEGA(d(n)) 时,算法的复杂度由n^logb(a)决定,所以尽量减小logb(a)而通常问题的划分,比如二分的情况是已经不能改变了的,所以可以通过子问题之间的关系,考虑减少子问题的个数;

2) 在的d(N) = BIGOMEGA(n^(logb(a)+eps))  时,算法的复杂度由d(n)决定,此时我们可以考虑通过适当的预处理减少迭代内部的复杂度从而降低总的复杂度;


例子两个:

分治算法的思想很简单,但是要想灵活运用还是得理解深刻才行,多见见一些例子是很有帮助的。老师在课上举了大量的例子,每一个都讲得很细,便于我们理解。我选择其中两例回顾一下:

例1:(芯片检测)

题设是这样的,有n个芯片,其中好芯片比坏芯片的个数至少多一个。现有检测方式是这样的:任取两块芯片互测,好芯片会准确测得对面芯片的好坏,而坏芯片测出的结果是不可靠的,可能把好的测成坏的,反之也有可能。

所有可能结果如下:G 代表好芯片 B代表坏芯片

1 2 检测结果

G G 1:G 2:G

B B 1:G 2:G or 1:G 2.:B or 1:B 2:G

G B 1:B 2:B or 1;B 2:G

B G 1;G; 2:B or 1:B 2:B

现在要求设计一种算法选出一块好芯片:


分析:在好芯片多于坏芯片的情况下,从n块芯片中任取一块芯片作为被测芯片,用其他的芯片轮流测这块芯片。1.若被测芯片是一块好芯片,那么剩下的芯片中的好芯片的测试结果一定是G,而坏芯片的测试结果可能会有G,也就是说剩下的n-1块芯片中至少一半的芯片至少一半的芯片会给出G的结果;2.如果被测芯片是一块坏芯片的话,同理,有超过半数的芯片会给出B的结果;因此通过n-1次比较,我么可以测得一块的好坏,因此我们对每一块芯片都这样做的话,最坏的情况下需要比较的次数的为O(n^2)

当然,这是一种不错的算法,但是我们能不能利用分治算法的思想使得算法的复杂度进一步的降低呢?

分治的精髓在递归,在于将问题化成规模较小的子问题。这道题目当中,作为测试者的我们,只能看到三种结果:(G,G)、(G,B)、(B,B)第一个结果说明两个芯片同好同怀,后两种说明两者之中至少有一个坏的。

利用这一点,考虑设计这样的算法,对于n为偶数,我们将所有的芯片两两分为一组,每组芯片进行一次测试。若得到的结果是(G, G)说明两块芯片都是一样的,要么都好,要么都坏,此时留哪一块都一样,我们取一块留下,另一块扔掉,对于n为偶数的情况下,经过这一方法选取留下的好芯片一定多于坏芯片的,因为n为偶数,好芯片至少比坏芯片多2块;而对于(G,B)和(B,B)的结果我们把两块芯片都给丢掉,因为至少有一块坏芯片。这样可以保证,在这一部分扔掉的芯片中,扔掉的坏芯片是多于好芯片的。总的来说我们经过这样一步操作之后,问题被划为一个不超过n/2的子问题。而对于n为奇数的情况,分组会产生一个剩余,这个剩余的芯片怎么办呢?如果n块芯片,好芯片恰好比坏芯片多一块的话,剩下的这块芯片如果是一块好芯片的话,那么以分组的n-1块芯片的测试结果有可能是丢掉了所有芯片(刚好一好一坏搭配),或者留下了相同数量的好芯片和坏芯片,无论哪种情况发生,我们的问题就扥不到解决了。所以我们不能直接将这块芯片丢掉,但是能不能直接将这块芯片留下呢,当然也不行,如果n块芯片好芯片的数量刚好比坏芯片多一块,剩余一块坏芯片,分组的n-1块芯片的测试结果留下的芯片中可能就是刚好好芯片多于坏芯片一片,如果再加入一块坏芯片的话,就会导致两者一样多了。正确的做法是,用前面提过的第一种算法,用分组检测过的芯片留下的芯片取轮流检验这块未分组的芯片,如果这块是好芯片,那么我们的算法结束,如果是坏芯片的话,直接扔掉即可。

算法复杂度的递推方程为,T(n)=T(n/2)+O(n),由master定理,算法的复杂度为O(n).


例2:(一般性元素选择问题)

输入:长度为n的数组A,正整数k,1<=k<=n

输出:第k小的数


通常算法:

先排序O(nlogn),再选择


分治算法:

先将数组元素每五个一组分为ceil(n/5)组元素,将每组元素排序后按照每组中位数的大小从小到大排序,这些中位数中的中位数记为M,若为偶数个,则任取第floor(n/5)或者ceil(n/5)均可,于是形成如下的形状:


用M与图中A、D的元素逐个比较,把A、D中元素可以分到左下或者右上,然后根据k选择合适的集合进行搜索

算法如下:



Reference:北京大学信息科学技术学院  《算法分析与复杂度理论》 课程课件



原创粉丝点击