Computational complexity of Fibonacci Sequence

后端 未结 11 1447
慢半拍i
慢半拍i 2020-11-21 10:27

I understand Big-O notation, but I don\'t know how to calculate it for many functions. In particular, I\'ve been trying to figure out the computational complexity of the nai

11条回答
  •  灰色年华
    2020-11-21 10:42

    The naive recursion version of Fibonacci is exponential by design due to repetition in the computation:

    At the root you are computing:

    F(n) depends on F(n-1) and F(n-2)

    F(n-1) depends on F(n-2) again and F(n-3)

    F(n-2) depends on F(n-3) again and F(n-4)

    then you are having at each level 2 recursive calls that are wasting a lot of data in the calculation, the time function will look like this:

    T(n) = T(n-1) + T(n-2) + C, with C constant

    T(n-1) = T(n-2) + T(n-3) > T(n-2) then

    T(n) > 2*T(n-2)

    ...

    T(n) > 2^(n/2) * T(1) = O(2^(n/2))

    This is just a lower bound that for the purpose of your analysis should be enough but the real time function is a factor of a constant by the same Fibonacci formula and the closed form is known to be exponential of the golden ratio.

    In addition, you can find optimized versions of Fibonacci using dynamic programming like this:

    static int fib(int n)
    {
        /* memory */
        int f[] = new int[n+1];
        int i;
    
        /* Init */
        f[0] = 0;
        f[1] = 1;
    
        /* Fill */
        for (i = 2; i <= n; i++)
        {
            f[i] = f[i-1] + f[i-2];
        }
    
        return f[n];
    }
    

    That is optimized and do only n steps but is also exponential.

    Cost functions are defined from Input size to the number of steps to solve the problem. When you see the dynamic version of Fibonacci (n steps to compute the table) or the easiest algorithm to know if a number is prime (sqrt(n) to analyze the valid divisors of the number). you may think that these algorithms are O(n) or O(sqrt(n)) but this is simply not true for the following reason: The input to your algorithm is a number: n, using the binary notation the input size for an integer n is log2(n) then doing a variable change of

    m = log2(n) // your real input size
    

    let find out the number of steps as a function of the input size

    m = log2(n)
    2^m = 2^log2(n) = n
    

    then the cost of your algorithm as a function of the input size is:

    T(m) = n steps = 2^m steps
    

    and this is why the cost is an exponential.

提交回复
热议问题