Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
132 views

Dynamic Programming

Dynamic programming is a technique for solving problems by breaking them down into subproblems and storing the results of subproblems to avoid recomputing them. It relies on two properties: overlapping subproblems and optimal substructure. The document provides examples of using dynamic programming to solve problems like calculating Fibonacci numbers, finding the longest common subsequence of strings, and finding the minimum cost path through a matrix. Dynamic programming works by building up the solution to a problem from optimal solutions to subproblems, storing these solutions in a table to avoid redundant calculations and enable solving the original problem efficiently in a bottom-up manner.

Uploaded by

ganapathi
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
132 views

Dynamic Programming

Dynamic programming is a technique for solving problems by breaking them down into subproblems and storing the results of subproblems to avoid recomputing them. It relies on two properties: overlapping subproblems and optimal substructure. The document provides examples of using dynamic programming to solve problems like calculating Fibonacci numbers, finding the longest common subsequence of strings, and finding the minimum cost path through a matrix. Dynamic programming works by building up the solution to a problem from optimal solutions to subproblems, storing these solutions in a table to avoid redundant calculations and enable solving the original problem efficiently in a bottom-up manner.

Uploaded by

ganapathi
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

Dynamic Programming

Ajith Jose
What is Dynamic Programming?
Dynamic Programming is a programming
technique that solves an algorithmic problem
by breaking it recursively into sub-problems.
The sub-problem results are saved in a tabular
format to avoid duplicate computation. The
problem being solved satisfies two properties

• Overlapping Sub-problems

• Optimal Substructure
Fibonacci Number

nth fibonacci number represented by

f(n) = f(n-1) + f(n-2)


f(0) = 0 and f(1) = 1

int fib(int n){


if(n<=1) return n;
return fib(n-1) + fib(n-2);
}
fib(5)

fib(4) fib(3)

fib(3) fib(2) fib(2) fib(1)

fib(2) fib(1) fib(1) fib(0) fib(1) fib(0)

Overlapping Sub-problems

Solutions of same sub-problems are needed again and again.


Memoization (Top-down Approach)
int[] memo;
void initialize(int n){
memo = new int[n];
for(int i=0;i<memo.length;i++){
memo[i]=-1;
}
}

int fib(int n){


if(memo[n] == -1){
if(n<=1){
memo[n] = n;
}else{
memo[n] = fib(n-1) + fib(n-2);
}
}
return memo[n];
}

public void test(){


initialize(25);
System.out.println("20th fibonacci no. is : "+fib(20));
}
Tabulation (Bottom-up Approach)

int fib(int n){


int[] table = new int[n+1];
table[0] = 0; table[1] = 1;
for(int i=2; i<=n; i++){
table[i] = table[i-1] + table[i-2];
}
return table[n];
}

public void test(){


System.out.println("20th fibonacci no. is : "+fib(20));
}

Dynamic
Programming
Fibonacci Number Optimized

int fib(int n){


int a = 0, b= 1, c;
for(int i=2; i<=n; i++){
c = a + b;
a = b;
b = c;
}
return b;
}
Minimum Cost Path Problem
int minCost(int[][] cost, int m, int n){

if(m<0 || n<0){
1 5 3 return Integer.MAX_VALUE;
}

4 8 2 if(m==0 && n==0){


return cost[0][0];
}
1 2 3 return cost[m][n] +
min(minCost(cost, m-1, n-1), minCost(cost, m, n-1), minCost(cost, m-1, n));
}

minCost(m,n) = cost[m][n] + min( minCost(m-1, n-1), minCost(m-1, n), minCost(m, n-1) )

Optimal Substructure

Optimal solution of the given problem can be obtained by using


optimal solutions of its sub-problems.
cost matrix minCost table

1 5 3 6 10 8

4 8 2 5 9 5

1 2 3 1 3 6

int minCost(int[][] cost, int m, int n){

int[][] table = new int[m+1][n+1];


table[0][0] = cost[0][0];

for(int i=1;i<=m;i++)
table[i][0] = table[i-1][0] + cost[i][0];
for(int j=1;j<=n;j++)
table[0][j] = table[0][j-1] + cost[0][j];

for(int i=1;i<=m;i++)
for(int j=1;j<=n;j++)
table[i][j] = cost[i][j] +
min(table[i-1][j-1], table[i][j-1], table[i-1][j]);

return table[m][n];
}
Longest Common Subsequence (LCS)

String Sequence
ABCDEFG

Subsequences
ABC, ABG, BDF, AEG, ACEFG

Longest Common Subsequences


LCS of ABCDGH and AEDFHR
AD, AH, ADH are common subsequences
ADH is an LCS

LCS of AGGTAB and GXTXAYB


GT, AB, GTA, TAB, GTAB are common subsequences
GTAB is an LCS
LCS in UNIX diff

Version 1
A B C D F G H J Q Z

Version 2
A B C D E F G I J K R X Y Z

LCS
A B C D F G J Z

Deletions (-)
H Q

Additions (+)
E I K R X Y
LCS Recursion

Let S1 & S2 be two sequences with lengths m & n

Length of LCS

Case when last character of both S1 & S2 match


LCS(“AGGTAB”, “GXTXAYB”) = 1 + LCS(“AGGTA”, “GXTXAY”)
LCS(S1, S2, m, n) = 1 + LCS(S1, S2, m-1, n-1)

Otherwise,
LCS(“ABCDGH”, “AEDFHR”) = MAX ( LCS(“ABCDG”, “AEDFHR”),
LCS(“ABCDGH”, “AEDFH”) )
LCS(S1, S2, m, n) = MAX(LCS(S1, S2, m-1, n), LCS(S1, S2, m, n-1))
LCS Naive Recursive Solution

int lcs(char[] S1, char[] S2, int m, int n) {


if(m==0 || n==0){
return 0;
}else if(S1[m-1] == S2[n-1]){
return 1 + lcs(S1, S2, m-1, n-1);
}else{
return max(lcs(S1, S2, m, n-1), lcs(S1, S2, m-1, n));
}
}

lcs("AXYT", "AYZX")

lcs("AXY", "AYZX") lcs("AXYT", "AYZ")

lcs("AX", "AYZX") lcs("AXY", "AYZ") lcs("AXY", "AYZ") lcs("AXYT", "AY")


LCS Dynamic Programming Solution

LCS( “ABACD”, “ADCDE”, 5, 5 ) int lcs(char[] S1, char[] S2, int m, int n) {

int[][] L = new int[m+1][n+1];


D 0 1 1 2 3 3

0 1 1 2 2 2 for(int i=0;i<=m;i++)
C
for(int j=0;j<=n;j++){
A 0 1 1 1 1 1 if(i==0 || j==0){
L[i][j] = 0;
B 0 1 1 1 1 1 }
else if(S1[i-1] == S2[j-1]){
A 0 1 1 1 1 1 L[i][j] = 1 + L[i-1][j-1];
}
0 0 0 0 0 0 else{
L[i][j] = max(L[i-1][j], L[i][j-1]);
A D C D E }
}

return L[m][n];
}
LCS Dynamic Programming Solution

LCS( “ABACD”, “ADCDE”, 5, 5 ) String printLCS(char[] S1, char[] S2, int m, int n){
int lcsLength = lcs(S1, S2, m, n);
char[] lcsChars = new char[lcsLength];
D 0 1 1 2 3 3

0 1 1 2 2 2 int i=m, j=n, l=lcsLength-1;


C
while(i>0 && j>0){
A 0 1 1 1 1 1 if(S1[i-1] == S2[j-1]){
lcsChars[l] = S1[i-1];
B 0 1 1 1 1 1 i--;j--;l--;
}else if( L[i-1][j] > L[i][j-1] ){
A 0 1 1 1 1 1 i--;
}else{
0 0 0 0 0 0 j--;
}
A D C D E }

return new String(lcsChars);


A C D
}
Longest Common Substring

lcSubStr( “TABLE”, “STABS”, 5, 5 ) int lcSubStr(char[] S1, char[] S2, int m, int n)
{
int[][] L = new int[m+1][n+1];
S 0 0 0 0 0 0 int maxLength = 0;
B 0 0 0 3 0 0
for(int i=0;i<=m;i++)
0 for(int j=0;j<=n;j++){
A 0 2 0 0 0
if(i==0 || j==0){
T 0 1 0 0 0 0 L[i][j] = 0;
}else if(S1[i-1] == S2[j-1]){
S 0 0 0 0 0 0 L[i][j] = 1 + L[i-1][j-1];
maxLength = max(L[i][j], maxLength);
0 0 0 0 0 0 }else{
L[i][j] = 0;
T A B L E }
}

return maxLength;
}
Longest Increasing Subsequence
int lis(int[] S, int n) {
1 7 2 12 5 15
int[] L = new int[n];
int max = 0;
Initialization for(int i=0;i<n;i++){
L[i] = 1;
1 1 1 1 1 1 }

for(int i=1;i<n;i++)
LIS Length for(int j=0;j<i;j++){
if(S[i] > S[j] && L[i] <= L[j]){
1 2 2 3 3 4 L[i] = L[j]+1;
if(L[i]>max){
max = L[i];
}
}
}

return max;
}
Where did you use Dynamic Programming?
Time Series Pattern Searching

i i

i i i+2

time time

Any distance (Euclidean, A non-linear (elastic) alignment


Manhattan, …) which aligns produces a more intuitive
the i-th point on one time series similarity measure, allowing
with the i-th point on the other similar shapes to match even if
will produce a poor similarity they are out of phase in the
score. time axis.
Dynamic Time Warping

Time Series A

1 is n
m
To find the best alignment
between A and B one needs to
find the path through the grid
P = p1, … , ps , … , pk
ps = (is , js )
which minimizes the total js
distance between them.
P is called a warping function.
Time Series B 1
Warping Window
Warping Window: |is – js| ≤ r, where r > 0
is the window length.
A good alignment path is unlikely to
wander too far from the diagonal.

i
Guarantees that the alignment does not
try to skip different features and gets
stuck at similar features.
Conclusion & Definition Revisited

Dynamic Programming is a programming


technique that solves an algorithmic problem
by breaking it recursively into sub-problems.
The sub-problem results are saved in a tabular
format to avoid duplicate computation. The
problem being solved satisfies two properties

• Overlapping Sub-problems

• Optimal Substructure
Thank You !

You might also like