Soumya Kanti Naskar
Soumya Kanti Naskar

Reputation: 1081

Fibonacci Series using Dynamic Programming

Let us consider the implementation of Fibonacci series using dynamic programming.

// Fibonacci Series using Dynamic Programming
class fibonacci
{
static int fib(int n)
{
    /* Declare an array to store Fibonacci numbers. */
int f[] = new int[n+1];
int i;

/* 0th and 1st number of the series are 0 and 1*/
f[0] = 0;
f[1] = 1;

for (i = 2; i <= n; i++)
{
   /* Add the previous 2 numbers in the series
     and store it */
    f[i] = f[i-1] + f[i-2];
}

return f[n];
}

public static void main (String args[])
{
    int n = 9;
    System.out.println(fib(n));
}
} 

We use the dynamic programming so that the repetition of the recursive work does not occur. But here when every time the function has been called,a new array will be generated. So how could this algorithm is said to be more optimized ?

Upvotes: 2

Views: 11830

Answers (2)

atul sachan
atul sachan

Reputation: 617

We use Memoization to prevent further recursion with Dynamic Programming. Memoization is the way to store already calculated values ex - let say fib(m) for index m is calculated and stored in memoization table. Further in upcoming recursions if fib(m) reoccur for calculation, then we take it from memoization table instead of doing again fib(m-1)+fib(m-2) i.e. avoid unnecessary recursions...Note - this will keep the complexity linear i.e. O(n).

We can implement this memoization in many ways for faster search. However here for Fibonacci we can implement memoization as array. And yes memoization table will be initialized just once. Below code is illustration for above explanation -

Note - we have taken a variable "complexity" which will incremented whenever we cant find value in memoization table i.e. whenever we go for recursion..

package com.company.dynamicProgramming;

import java.math.BigInteger;

public class FibonacciByBigDecimal {


    static int complexity = 0;

    public static void main(String ...args) {

        int n = 200;
        BigInteger[] memoization = new BigInteger[n + 1];

        System.out.println("fibonacci of "+ n + " is : " + fibByDivCon(n, memoization));
        System.out.println("Complexity is "+complexity);

    }


    static BigInteger fibByDivCon(int n, BigInteger[] memoization){

        if(memoization[n]!=null){
            return memoization[n];
        }

        complexity++;      

        if (n == 1 || n== 2){
            memoization[n] = BigInteger.ONE;
            return BigInteger.ONE;
        }

        // creates 2 further entries in stack
        BigInteger fibOfn = fibByDivCon(n-1, memoization).add( fibByDivCon(n-2, memoization)) ;

        memoization[n] = fibOfn;

        return fibOfn;

    }

}

Above i am calculating Fibonacci number at index 200. When I ran above code the result is : -

fibonacci of 200 is : 280571172992510140037611932413038677189525
Complexity is 200

Process finished with exit code 0

Upvotes: 2

Thomas
Thomas

Reputation: 2259

one optimization would be only save the last 2 values instead of all results. You don't need to store all your results.

you also can write the fibonacci series recursively in O(n):

int fib(int n1, int n2, int counter)
{
    if(counter == 0)
    {
        return n2;
    }
    else
    {
        return fib(n2,n2 + n1,counter-1);
    }
}

//to start:
int result = fib(0,1,100); //gives you the 100 fibonacci value

This code runs recursively and is easy to read. You don't have to initialize an array or other stuff.

alternatively you can use the nonrecursive option:

int fib(int number)
{
    int n1 = 0;
    int n2 = 1;
    int temp;
    for(int i = 0; i< number;i++)
    {
        temp = n1 + n2;
        n1 = n2;
        n2 = temp;
    }
    return n2;
}

If you want to store your results, you have to initialize the array outside of your fib function:

// Fibonacci Series using Dynamic Programming
class fibonacci
{
    /* Declare an array to store Fibonacci numbers. */
    int f[];

    static void init(int n)
    {    /* 0th and 1st number of the series are 0 and 1*/
        f = new int[n+1];            
        f[0] = 0;
        f[1] = 1;
    }

    static int fib(int n)
    {
        int i;

        for (i = 2; i <= n; i++)
        {
           /* Add the previous 2 numbers in the series
             and store it */
            f[i] = f[i-1] + f[i-2];
        }

        return f[n];
    }

    public static void main (String args[])
    {
        int n = 9;
        init(n);
        System.out.println(fib(n));
    }
} 

Upvotes: 3

Related Questions