减治原理 Decrease and Conquer
原始问题划分为若干子问题,将原始计算问题转化为其中某一个子问题的计算问题。
譬如:折半查找 T(n)=T([n/2])+1 有序数组中间数据与目标数据比较一次后即可转到一半的有序数组中继续查找。
非常有效的一种方法,通常用于解决优化问题。
分治原理需要递归求解每一个子问题,通过合并各个子问题的解来得到母问题的解;而减治原理仅仅只需要求解某一个子问题的解即可得到母问题的解。
2.Selection Problem
The i th order statistic problem指给出一个无重复的集合以及i的值如何求解出这个序列中第i小的数的查找问题。
直接求解方法:对这n个输入进行排序,于排序后的序列直接进行查找。
平均时间复杂度:O(nlogn)
Algorithm of Selection Problem:
使用一种新算法进行查找:
个人理解:查找第n小的数并不需要所有的输入都在它应在的位置上,想要求的是具有这个相对位置的元素。因此我们也不需要对所有元素都排序,拿出一个元素,根据这个元素对所有输入进行排序得到的就是各个元素的相对位置。这样就能够运用减治原理,在一个相对较小的集合里进行查找。
那么,我们如何选择p呢?
如果p是中位数的话该算法将得到较好的性能。我们在这里选用组中位数作为p。
(为什么选用5这个数字进行分组在后面说明。)
那么,我们的算法步骤变为:
S1、S2、S4都会线性地把输入扫一遍,显然O(n)。S3是递归地调用算法,计算中位数和Selection本质上是一个问题,且为了方便,我们在这里约定如果输出为even的,取较小的那个中位数。
S5的复杂度呢?
将所有经过了S1-S4的输入摆成如图的阵列,每一列的5个元素都是sorted的,黄色元素为每一列的中位数,红色元素即为组中位数。对p来说,如果要找比它大的元素,除去本列和最后一列这样的特殊列(只有2个元素比p大),可以看出大概有|S|/4个元素符合条件。找比p小的元素同理。
据此我们可以分析出Step5的worst情况即为T(3n/4)。
算法复杂性分析:
T(n)=T(3n/4)+T(n/5) + O(n) 我们观察两个子问题的系数发现它是一定能到达O(n)级别的。c>=d/(1-a-b)即可。(c为待求系数,d为原式中O(n)系数)也就是对所有T(n)=T(an)+T(bn) + O(n)都右=有这样的结论。
事实上,我们能找到S5更精确的复杂性估计。
从图中可以看出,在x的右边,每一个包含五个元素的列中有3个元素大于x;同理在x左边也有这样多的元素小于x(都去掉本列和边界列)。
这个东西最外层是向上取整很好理解,如果除不开(odd个组)的话把本组也算上再减二。
据此有至少这么多个元素大于(小于)x,就可以用n减去它算出递归子区间最坏的长度。
subroutine意为“子程序”。S4的意思是使用x对输入进行分组(类似快排的Partiton函数),然后将分组前一段的元素个数作为k,方便进行第5步的递归。
140是为了舍入随便取的。递归方程在有限输入的时候总会得到有限输出啦,所以在n取常数级别的时候输出就将达到θ(1),相比于具体啥时候不再是θ(1),我们更关心n充分大的情况。
介绍一个有趣的办法求解这个算法的时间复杂性:
为了能把两个子问题合起来,所以采取多项式表示的方式。
为什么我们可以让T(n)直接和一个多项式对等,就因为我们假设它是多项式界限的,就这么简单。最后求出来的很可能不是紧界,所以也只是作为一个猜界的方法。
对于本问题嘛,还真不如直接套结论或者画递归树。不过如果是对于T(n)=O(n^k)(k>=2)的问题也许是一种好方法。