[Algorithm]分治法 Divide and Conquer 与 主定理 Master Theorem
警:此文是理论深度文,如果想从这里找源代码或者“神马是归并排序”之类的东西的话,提前放弃吧。这文的来源主要是MIT的算法导论。
主定理 Master Theorem
这中文名字十分蛋疼(其实英文名字也十分蛋疼),我感觉确切地应该叫做递归复杂度判定定理,不过姑且就这么用吧。
分治法 Divide and Conquer
分治法分为三步:分、治、合(Divide, Conquer, Combine)。
分是递归的,不是说分一次就结束了,分后的子问题,被看做一个完整的问题,再进行分的过程,否则,算法的复杂度是不会降低的。
分治法的时间复杂度计算
使用公式:
然后套用主定理求解,PS:不适用主定理时,就悲剧鸟~
分治法举例
归并排序 Merge Sort
too simple, something naive了,简单说下就是:分成子队列、子队列排序、合并子队列。这一过程迭代执行
公式:
套用主定理第2种情况,得
二分查找
更加simple:先和队列中点比较,选择结果的位置,然后再从子队列中查找。这一过程迭代执行。队列必须是有序的。
公式:
套用主定理第1种情况,得
求幂值ax
分治法不是唯一的方法,这和前边两个不大一样,确切说小标题应该是“用分治法求幂值”
简单说是先求ax/2,然后再求ax/2*ax/2得出结果,当然,这一步骤也是要递归的。
公式:
套用主定理第1种情况,得
矩阵乘法
正常的算法,套用公式
使用i、j、k三重循环,复杂度为n3
使用分治法,将矩阵分块,进行分块相乘(主方法第一种情况):
是不能降低复杂度的,悲了个摧。
Strassen's Algorithm
http://en.wikipedia.org/wiki/Strassen_algorithm
应用这个算法,可以将复杂度降低一点点……
时间复杂度是
求斐波那契数值 Fibonacci Numbers
多说一句,如果用递归求斐波那契,则
斐波那契无法直接使用分治法求解,不过其计算公式可以使用分治法求值。
这是错误的方法:
斐波那契近似计算公式
其中的幂值计算可以使用分治法,最终复杂度为
不过计算机无法精确计算浮点数,也就是说会存在误差累积的问题~(另外据说大数乘法也不是常数时间,据说而已)
所以不可行。
这是正确的方法,使用了线性代数:
斐波那契计算公式
硬件布线
分治法还可以有神奇的用途,例如计算硬件布线占用的电路板面积:
方案1下的:
目标方案的:
可以反推出
如果有灵感的话,可以得出H布局