zoukankan      html  css  js  c++  java
  • 递归斐波那契数列时间复杂度

    以前看数据结构与算法分析(C语言描述),作者在讲述算法分析时提到递归计算斐波那契数列,
    Fib(int N)
    {
      if(N <= 1)
        return 1;
      else
        return Fib(N - 1) + Fib(N-2);
    }

    时间复杂度T(N) = T(N-1) + T(N-2);
    作者说归纳法易证得T(N) >= Fib(N);而Fib(N) < (5/3)^(N);类似计算可正得Fib(N)>= (3/2)^(N)
    这个地方作者处理得有些不太彻底,不是吗?翻来覆去没把Fib(N)准确求出,今天我翻看另一本资料,
    更模糊了,它求得2^(N/2) < T(N) < 2^(N)就完事了。
    不过今天我开窍了,T(N) = T(N-1) + T(N-2);这是什么?也许你会说这是一个递推式,但它的学名是
    二阶齐次差分方程,我今天猛然看出这一点:)!
    什么是差分方程?
    以下资料全部来自Introduction to Numerical Analysis,second Edition Translate by
    Bartels,W.Gautsch and C.Witigall,Springer-Verlag,世界图书出版公司,(英文版)

    百度百科:

    数学上,递推关系(recurrence relation),也就是差分方程(difference equation),是一种递推地定义一个序列的方程式:序列的每一项目是定义为前一项的函数。某些简单定义的递推关系式可能会表现出非常复杂的(混沌的)性质,他们属于数学中的非线性分析领域。
    所谓解一个递推关系式,也就是求其解析解,即关于n的非递归函数。
    解法:
    http://jpkc.wyu.edu.cn/xhyxt/kejian/chapter5/5.2.2.htm
     


    这是我大三所用的数值分析教材,目前国内好像还没中文版。

    书上464页说道:
    By a linear homogeneous difference equation of order r one means an equation of the form

    u(j+r) + a(r-1)u(j+4-1) + .... + a(0)u(j) =0;  j=0,1,2...  (7.2.9.1)
    上面那些括号里的数一般是下标,我不好打出来,用括号代替了。

    反正就是说齐次差分方程就是那个式子的形式了。
    接着466页上讲到
    Theorem. let the polynomial 
    Ψ(u) = u^r + a(r-1)u^(r-1) + ... + a(0)
    have the k distinct zeros λ(i) ,i = 1,2,...,k
    with multiplicities σ(i),i = 1,2,...,k
    and let a(0) != 0,then for arbitray polynomials p(i)(t) with deg p(i) < σ(i),i = 1...k;
    the sequence 
    u(j) = p(1)(j)λ(1)^(j) + p(2)(j)λ(2)^(j) +...+ p(k)(j)λ(k)^(j)
    is a solution of the difference eqution (7.2.9.1).Conversely,every solution of
    (7.2.9.1)can be uniquely represented in the form(7.2.9.9).

    这段话又是什么意思呢?一句话:这是个牛逼的定理它导出了齐次差分方程的解并且说明了齐次差分方程
    的所有解的形式。书上证明不是太短。

    接下来举例说明。就拿斐波那契数列来说。
    书上561页提了个问题,问题我就不打了,它问:
    u(j+2) = u(j+1) + u(j)的通项公式是什么?然后它说u(0) = 0,u(1) = 1 即可得Fibonacci sequence
    就是说这个式子从u(0) = 0,u(1) = 1递推即可得斐波那契数列。从其他初始状态的话可得其他数列。

    开始解决问题。
    按照那个牛逼定理,先解方程x^2 - x - 1 = 0;
    这个不难,x1= (1+5^(1/2))/2,x2 = (1-5^(1/2))/2;
    然后套公式u(j) = c1 * x1^(j) + c2 * x2^(j);
    c1,c2为待定常数,利用u(0) = 0,u(1) = 1,得出c1 = 1/(5^(1/2));c2 = -c1;
    这样斐波那契数列的通项就出来了,递归计算斐波那契数列时间复杂度问题也就迎刃而解了。

  • 相关阅读:
    基于Canvas的时钟
    注意A链接的默认行为
    基于Aptana3+Django开发blog的示例
    使用vbscript替换excel文件的内容
    使用Ajax建立的Server Push和Iframe建立的Comet
    ajax和它的超时
    通用SQL分页程序
    简简单单学习ASP.NET之三
    功能很强大的UI封装类
    封装的一些实现图片水印与图片自动结合缩放的类
  • 原文地址:https://www.cnblogs.com/youxin/p/3265393.html
Copyright © 2011-2022 走看看