zoukankan      html  css  js  c++  java
  • 算法标记的一点知识

    现在的数据规模越来越大, 因此, 当输入规模大到只有运行时间的量级有关时, 就是在研究算法的 渐进效率. 也就是从极限的角度观察算法的增长.

    大O 记号 : 只有渐进上界时使用.

    Θ 记号 : 同时具有 渐进上界 和下届.

    Ω 记号 : 渐进下届.

    定理 3.1 : 对任意两个函数 f(n) 和 g(n) , f(n) = Θ(g(n)) 当且仅当f(n) = O(g(n)) 和 f(n) = Ω(g(n)) .

    这一章真的令人蛋痛, 全是记号, 表示头晕. 几个渐进函数之间的 各种 关系 : 传递性, 自反性, 对称性, 转置对称性, 三分性 神马的, 果然都是浮云啊, 只理解简单的大O好了, 其他的以后再慢慢研究.

    第三章酱油……………………………………………………….

    第四章:

    这一章主要就是用 三种方法来 分析递归算法的效率~~~

    1. 代换法 : 猜测解的形式, 用数学归纳法 证明之.

    很容易看出, 这是一种归纳假设的方法, 效率很明显, 可以很快得出结论, 但是只能用于解的形式很容易猜的情况. 我们可以用代换法来确定一个递归式的上界 和 下届(p39) .

    尽管代换法很有效, 但是并不存在通用的方法来猜测递归式的正解, 这种猜测需要经验或是创造性的, 所以有时可以用一些试探的方法帮助作出好的猜测 ( 递归树 ). 另一种方法是证明比较宽松的上下界, 然后缩小区间, 降低上界, 提高下届, 直到达到正解.

    对于陌生的递归式, 使用一些简单的代数变换, 可以转变为较熟悉的形式 :

    8GGB~)Z08R[YT9%@U[DA]9A , 可以设 m = lgn, 那么 式子可以变换为 :

    %%$}UK1DSB0424~~)~)[CHJ , 进一步再设 S(m) = T( 2m ) , 得到新的递归式 :

    S ( m ) = 2 S ( m / 2 ) + m , 这个新的递归式的界前面已经知道 : S(m) = O( mlgm )

    最后可以得到 : T ( n ) = T ( 2m ) = S ( m ) = O ( mlgm ) = O ( lgnlglgn )

    2. 递归树方法 : 其实还是猜测……..

    以下引用:

    我们看一个简单的例子:

    T(n) = 2T(n/2) + n2

    迭代2次可以得:

    T(n) = n2 + 2(2T(n/4) + (n/2) 2)

    还可以继续迭代,将其完全展开可得:

    T(n) = n2 + 2((n/2) 2 + 2((n/22)2 + 2((n/23) 2 + 2((n/24) 2 +…

    +2((n/2i) 2 + (n/2i + 1)))…)))) ……(1)

    而当n/2i+1 == 1时,迭代结束。

    将(1)式小括号展开,可得:

    T(n) = n2 + 2(n/2)2 + 22(n/22) 2 + … + 2i(n/2i)2 + 2i+1T(n/2i+1)

    这恰好是一个树形结构,由此可引出递归树法。

    图中的(a)(b)(c)(d)分别是递归树生成的第1,2,3,n步。每一节点中都将当前的自由项n2留在其中,而将两个递归项T(n/2) + T(n/2)分别摊给了他的两个子节点,如此循环。

    图中所有节点之和为:

    [1 + 1/2 + (1/2)2 + (1/2)3 + … + (1/2)i] n2 = 2n2

    可知其时间复杂度为O(n2)

    可以得到递归树的规则为:

    (1) 每层的节点为T(n) = kT(n / m) + f(n)中的f(n)在当前的n/m下的值;

    (2) 每个节点的分支数为k;

    (3)每层的右侧标出当前层中所有节点的和。

    再举个例子:

    T(n) = T(n/3) + T(2n/3) + n

    其递归树如下图所示:

    可见每层的值都为n,从根到叶节点的最长路径是:

    因为最后递归的停止是在(2/3)kn == 1.则

    于是

    即T(n) = O(nlogn)

    总结,利用此方法解递归算法复杂度:

    f(n) = af(n/b) + d(n)

    1.当d(n)为常数时:

    2.当d(n) = cn 时:

    3.当d(n)为其他情况时可用递归树进行分析。

    由第二种情况知,若采用分治法对原算法进行改进,则着重点是采用新的计算方法缩小a值。

    3. 主方法 : 也就是传说中的公式法………….

    书中给出了 形如 T ( n ) = a T ( n / b ) + f ( n ) 的3种一般公式, 我们要做的就是使用这些萎缩的 公式就可以了 =. = ( P43 )

    对于式子 : T ( n ) = a T ( n / b ) + f ( n )

    1.) 若对于某常数 e > 0, 有 Z%LJ, 则

    031%BXXO5GY};

    2.) 若PEM4EBL~)0R25%T3OFFD]9X 则19OBG{QK8L2I_@E6G

    3.) 若对于某常数e>0, 有I%AVP4I3)J, 且对常数c<1与所有足够大的n, 有 af( n / b ) <= cf( n ), 则 T ( n ) = Θ ( f ( n ) ).

    个人建议使用主方法, 主要是比较简单, 也比较容易理解~~~~~~呵呵


    ==============================================================================

    本博客已经废弃,不在维护。新博客地址:http://wenchao.ren


    我喜欢程序员,他们单纯、固执、容易体会到成就感;面对压力,能够挑灯夜战不眠不休;面对困难,能够迎难而上挑战自我。他
    们也会感到困惑与傍徨,但每个程序员的心中都有一个比尔盖茨或是乔布斯的梦想“用智慧开创属于自己的事业”。我想说的是,其
    实我是一个程序员

    ==============================================================================
  • 相关阅读:
    【笔记】Maven使用入门
    【笔记】c++文件
    【笔记】IntelliJ IDEA配置Hibernate
    【HTML5校企公益课】第四天
    【c++习题】【17/4/16】动态分配内存
    C#
    C#
    C#
    C#
    C#
  • 原文地址:https://www.cnblogs.com/rollenholt/p/2073078.html
Copyright © 2011-2022 走看看