Quantcast
Channel: roman10 » Data Structure & Algorithms
Viewing all articles
Browse latest Browse all 15

Computing Fibonacci Numbers

$
0
0

Fibonacci series is a number sequence of 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 44, … It can be expressed by the formula below,

1

Fibonacci series grows almost as fast as the power of 2. Fn ~= 2^(0.694n).

Computation of Fibonacci Numbers
The naive approach to compute Fibonacci numbers is to recursion according to the formula of Fabonacci numbers. A C implementation is given below,

/*

a naive approach of computing fibonacci series, the computation time also satisfy fabonacci series, since

fabonacci series grows almost as fast as power of 2, the computation is expoential time

*/

#include <stdio.h>

#include <stdlib.h>

 

unsigned long fibo(int n) {

    if (n == 0) {

       return 0;

    } else if (n == 1) {

       return 1;

    } else {

       return fibo(n-1) + fibo(n-2);

    }

}

 

int main(int argc, char **argv) {

    int n;

    unsigned long res;

    struct timeval stTime, edTime;

    n = atoi(argv[1]);

    gettimeofday(&stTime, NULL);

    res = fibo(n);

    gettimeofday(&edTime, NULL);

    printf("%lu, time takes (%u:%u)\n", res, (unsigned int)(edTime.tv_sec - stTime.tv_sec), (unsigned int)(edTime.tv_usec - stTime.tv_usec));

}

Suppose the time takes to compute fibo(n-1) and fibo(n-2) are O(n-1) and O(n-2) respectively, then the time complexity of computing fibo(n) is O(n) = O(n-1) + O(n-2). The time complexity itself follows the Fibonacci series. Since we know Fn~= 2^(0.694n), then O(n) ~=2^(0.694n). The computation is exponential. And since O(n)~=(2^0.694)^n ~=1.62^n, compute the Fn+1 takes around 1.6 times longer than computing Fn.

Compile the code using the command,

gcc -o fibo fibo.c

Below is a sample run of the program,

Figure 1. Execution of Recursive Version Program

It is not easy to observe that a Fibonacci number depends on its two previous numbers. The computation above computes some small Fibonacci numbers for many times. We can use an array to remember the previous computation. A C implementation is shown as below,

/*

use dynamic programming to remember previous computation results

this computation runs in linear time

*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

int main(int argc, char **argv) {

    int n;

    int i;

    struct timeval stTime, edTime;

    unsigned long* fibo;

    n = atoi(argv[1]);

    fibo = (unsigned long*) malloc((n+1)*sizeof(unsigned long));

    memset(fibo, 0x00, sizeof(unsigned long)*n);

    fibo[1] = 1;

    gettimeofday(&stTime, NULL);

    for (i = 2; i <= n; ++i) {

        fibo[i] = fibo[i-1] + fibo[i-2];

    }

    gettimeofday(&edTime, NULL);

    printf("%lu, time takes (%u:%u)\n", fibo[n], (unsigned int)(edTime.tv_sec - stTime.tv_sec), (unsigned int)(edTime.tv_usec - stTime.tv_usec));

}

Compile the code using the command below,

gcc -o fibo1 fibo1.c

A sample run is as below,

Figure 2. Execution of Dynamic Programming Version

It is not difficult to tell the code above runs in linear time. However, the code takes a lot of memory space and if we’re to compute a Fibonacci number Fn for a very large n, then we may run out of memory space.
To compute Fn, we only need values for Fn-1 and Fn-2, this leads to the code below,

/*

use dynamic programming to remember previous computation results

this computation runs in linear time

*/

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

int main(int argc, char **argv) {

    int n;

    int i;

    struct timeval stTime, edTime;

    unsigned long fibo[2];

    n = atoi(argv[1]);

    fibo[0] = 0;

    fibo[1] = 1;

    gettimeofday(&stTime, NULL);

    for (i = 2; i <= n; ++i) {

        fibo[i%2] = fibo[0] + fibo[1];

    }

    gettimeofday(&edTime, NULL);

    if (n&0x01) {

        printf("%lu, time takes (%u:%u)\n", fibo[1], (unsigned int)(edTime.tv_sec - stTime.tv_sec), (unsigned int)(edTime.tv_usec - stTime.tv_usec));

    } else {

        printf("%lu, time takes (%u:%u)\n", fibo[0], (unsigned int)(edTime.tv_sec - stTime.tv_sec), (unsigned int)(edTime.tv_usec - stTime.tv_usec));

    }

}

Compile the code using the command below,

gcc -o fibo2 fibo2.c

A sample run is as below,

Figure 3. Execution of Dynamic Programming Version Improved

References:
1. Algorithms. Dasgupta, C.H. Papadimitriou, and U. V. Vazirani, 2006
2. Wikipedia Fibonacci Number: http://en.wikipedia.org/wiki/Fibonacci_number


Viewing all articles
Browse latest Browse all 15

Trending Articles