Dynamic Programming
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
fib(4) fib(3)
Overlapping Sub-problems
Dynamic
Programming
Fibonacci Number Optimized
if(m<0 || n<0){
1 5 3 return Integer.MAX_VALUE;
}
Optimal Substructure
1 5 3 6 10 8
4 8 2 5 9 5
1 2 3 1 3 6
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
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
Length of LCS
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
lcs("AXYT", "AYZX")
LCS( “ABACD”, “ADCDE”, 5, 5 ) int lcs(char[] S1, char[] S2, int m, int n) {
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
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
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
• Overlapping Sub-problems
• Optimal Substructure
Thank You !