• [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布局

  • 相关阅读:
    【转】Visual studio 快捷键大全
    C++ 中的权限控制
    论C++11 中vector的N种遍历方法
    c++ 模板仿函数初探
    OBS (open boardcast server)结构分析
    OpenCV学习笔记:opencv_core模块
    [转]C++ new操作符详解
    进程已经被attach debug,如何解除其debug权限?
    dll 在进程中怎么区分的
    树状数组学习笔记
  • 原文地址:https://www.cnblogs.com/SelaSelah/p/2535271.html
Copyright © 2020-2023  润新知