Dynamic Programming

Tabulation vs Memoizatation

There are following two different ways to store the values so that the values of a problem can be reused. Here, will discuss two patterns of solving DP problem:
    1. Tabulation: Bottom Up
    2. Memoization: Top Down
Bottom up vs. Top Down:
  • Bottom Up - I'm going to learn programming. Then, I will start practicing. Then, I will start taking part in contests. Then, I'll practice even more and try to improve. After working hard like crazy, I'll be an amazing coder.
  • Top Down - I will be an amazing coder. How? I will work hard like crazy. How? I'll practice more and try to improve. How? I'll start taking part in contests. Then? I'll practicing. How? I'm going to learn programming.
Not a great example, but I hope I got my point across. In Top Down, you start building the big solution right away by explaining how you build it from smaller solutions. In Bottom Up, you start with the small solutions and then build up.
Another good example:-
  • Version 1: I will study the theory of Dynamic Programming from GeeksforGeeks, then I will practice some problems on classic DP and hence I will master Dynamic Programming.
  • Version 2: To Master Dynamic Programming, I would have to practice Dynamic problems and to practice
TOP of the tree
fib(4)
 fib(3)...................... + fib(2)
  fib(2)......... + fib(1)       fib(1)........... + fib(0)
   fib(1) + fib(0)   fib(1)       fib(1)              fib(0)
    fib(1)   fib(0)
BOTTOM of the tree
  • example: If doing fibonacci, you choose to calculate the numbers in this order: fib(2),fib(3),fib(4)... caching every value so you can compute the next ones more easily. You can also think of it as filling up a table (another form of caching).

Now, it is quite obvious that dp[x+1] = dp[x] * (x+1)
// Tabulated version to find factorial x.
int dp[MAXN];

// base case
int dp[0] = 1;
for (int i = 1; i< =n; i++)
{
    dp[i] = dp[i-1] * i;
}
The above code clearly follows the bottom up approach as it starts its transition from the bottom most base case dp[0] and reaches it destination state dp[n]. Here, we may notice that the dp table is being populated sequentially and we are directly accessing the calculated states from the table itself and hence, we call it tabulation method.
Memoization Method – Top Down Dynamic Programming 
You typically perform a recursive call (or some iterative equivalent) from the root, and either hope you will get close to the optimal evaluation order, or you have a proof that you will get the optimal evaluation order. You ensure that the recursive call never recomputes a subproblem because you cache the results, and thus duplicate sub-trees are not recomputed.

    • example: If you are calculating the Fibonacci sequence fib(100), you would just call this, and it would call fib(100)=fib(99)+fib(98), which would call fib(99)=fib(98)+fib(97), ...etc..., which would call fib(2)=fib(1)+fib(0)=1+0=1. Then it would finally resolve fib(3)=fib(2)+fib(1), but it doesn't need to recalculate fib(2), because we cached it.
    • This starts at the top of the tree, and evaluates the subproblems from the leaves/subtrees back up towards the root.

    // Memoized version to find factorial x.
    // To speed up we store the values
    // of calculated states
    
    // initialized to -1
    int dp[MAXN]
    
    // return fact x!
    int solve(int x)
    {
        if (x==0)
            return 1;
        if (dp[x]!=-1)
            return dp[x];
        return (dp[x] = x * solve(x-1));
    }

    1 comment:

    1. Wonderful Blog to get android updates, I will definitely try to implement this idea to develop an application. Thanks keep motivating.
      Regards:
      Best Android Training institute in Chennai
      Android Training Institutes in Chennai

      ReplyDelete