<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-273616926724373216</id><updated>2012-01-05T13:28:25.952-08:00</updated><category term='Dynamic Programming  Longest Common Subsequence Algorithm Recursion'/><title type='text'>amit shekhar</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://cella-door.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/273616926724373216/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://cella-door.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Cellar Door</name><uri>http://www.blogger.com/profile/08361512500990202557</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-273616926724373216.post-7922614875662828846</id><published>2011-04-18T04:01:00.000-07:00</published><updated>2011-04-18T04:48:46.848-07:00</updated><title type='text'>Longest Increasing Sequence</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;The&amp;nbsp;&lt;b&gt;Longest Increasing Subsequence&lt;/b&gt;&amp;nbsp;problem is to find the longest increasing subsequence of a given sequence.&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-family: sans-serif; font-size: 13px; line-height: 19px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="line-height: 1.5em; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 0.4em;"&gt;Formally, the problem is as follows:&lt;/div&gt;&lt;div style="margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 0.4em;"&gt;&lt;span class="Apple-style-span" style="line-height: 1.5em;"&gt;Given a sequence &lt;/span&gt;&lt;span class="Apple-style-span"&gt;a1, a2, ... an&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 1.5em;"&gt;, find the largest subset such that for every&amp;nbsp;&lt;/span&gt;&lt;span class="texhtml" style="font-family: serif; line-height: 1.5em;"&gt;&lt;i&gt;i&lt;/i&gt;&amp;nbsp;&amp;lt;&amp;nbsp;&lt;i&gt;j&lt;/i&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 1.5em;"&gt;,&amp;nbsp;&lt;/span&gt;&lt;span class="texhtml" style="font-family: serif; line-height: 1.5em;"&gt;&lt;i&gt;a&lt;/i&gt;&lt;sub&gt;&lt;i&gt;i&lt;/i&gt;&lt;/sub&gt;&amp;nbsp;&amp;lt;&amp;nbsp;&lt;i&gt;a&lt;/i&gt;&lt;sub&gt;&lt;i&gt;j&lt;/i&gt;&lt;/sub&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="line-height: 1.5em;"&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 0.4em;"&gt;&lt;span class="Apple-style-span" style="line-height: 1.5em;"&gt;Example:&amp;nbsp;&lt;/span&gt;0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15 # sequence&lt;br /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;0, 2, 6, 9, 13, 15 # longest increasing subsequence (not unique)&lt;br /&gt;&lt;br /&gt;Using Back-Tracking technique:&lt;br /&gt;&lt;br /&gt;--A sequence of integers is either empty or, an integer followed by a sequence of integers.&lt;br /&gt;--The only subsequence of the empty sequence is the empty sequence.&lt;br /&gt;--A subsequence of A[1 .. n] is either a subsequence of A[2 .. n] or A[1] followed by a subsequence of A[2..n]&lt;/div&gt;&lt;div&gt;&lt;br /&gt;The Algorithm:&lt;br /&gt;The LIS of A[1 .. n] is:  either the LIS of A[2 .. n]  or, A[1] followed by the LIS of A[2 .. n] with elements larger than A[1], &amp;nbsp;&lt;u&gt;whichever is longer&lt;/u&gt;.&lt;br /&gt;&lt;br /&gt;If A[1] &amp;lt;= x,&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; the LIS of A[1 .. n] with elements larger than x is the LIS of A[2 .. n] with elements larger than x.  Otherwise,&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; the LIS of A[1 .. n] with elements larger than x is  either the LIS of A[2 .. n] with elements larger than x&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; or,&amp;nbsp;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; A[1] followed by the LIS of A[2 .. n] with elements larger than A[1], &amp;nbsp;&lt;u&gt;whichever is longer&lt;/u&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Simple to Understand Algorithm:&lt;br /&gt;&lt;br /&gt;A simple way of finding the longest increasing subsequence is to use the &lt;a href="http://www.algorithmist.com/index.php/Longest_Common_Subsequence"&gt;Longest Common Subsequence&lt;/a&gt; (&lt;a href="http://www.algorithmist.com/index.php/Dynamic_Programming"&gt;Dynamic Programming&lt;/a&gt;) algorithm.&lt;br /&gt;Make a &lt;a href="http://www.algorithmist.com/index.php/Sorting"&gt;sorted&lt;/a&gt; copy of the sequence A, denoted as B. O(nlog(n)) time. &lt;br /&gt;Use &lt;a href="http://www.algorithmist.com/index.php/Longest_Common_Subsequence"&gt;Longest Common Subsequence&lt;/a&gt; on with A and B. O(n2) time.&lt;br /&gt;&lt;br /&gt;PS: You may look up at my previous post on LCS/DP &lt;a href="http://cella-door.blogspot.com/2011/04/dynamic-programming-longest-common.html"&gt;here&lt;/a&gt;&lt;/div&gt;&lt;div&gt;C++ Code :&lt;br /&gt;&lt;br /&gt;&lt;pre class="default prettyprint" style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 10px; margin-left: 0px; margin-right: 0px; margin-top: 0px; max-height: 600px; overflow-x: auto; overflow-y: auto; padding-bottom: 5px; padding-left: 5px; padding-right: 5px; padding-top: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span class="com" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span class="Apple-style-span" style="color: grey; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif;"&gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;#include &amp;lt;vector&amp;gt;&lt;br /&gt;using namespace std;&lt;br /&gt; &lt;br /&gt;/* Finds longest strictly increasing subsequence. O(n log k) algorithm. */&lt;br /&gt;void find_lis(vector&amp;lt;int&amp;gt; &amp;amp;a, vector&amp;lt;int&amp;gt; &amp;amp;b)&lt;br /&gt;{&lt;br /&gt; vector&amp;lt;int&amp;gt; p(a.size());&lt;br /&gt; int u, v;&lt;br /&gt; &lt;br /&gt; if (a.empty()) return;&lt;br /&gt; &lt;br /&gt; b.push_back(0);&lt;br /&gt; &lt;br /&gt; for (size_t i = 1; i &amp;lt; a.size(); i++) &lt;br /&gt;    {&lt;br /&gt;      // If next element a[i] is greater than last element of                          current longest subsequence a[b.back()], just push it at                      back of "b" and continue&lt;br /&gt;      if (a[b.back()] &amp;lt; a[i]) &lt;br /&gt;                {&lt;br /&gt;      p[i] = b.back();&lt;br /&gt;      b.push_back(i);&lt;br /&gt;      continue;&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;       // Binary search to find the smallest element referenced by b which is        just bigger than a[i]&lt;br /&gt;       // Note : Binary search is performed on b (and not a). Size of b is           always &amp;lt;=k and hence contributes O(log k) to complexity.    &lt;br /&gt;  for (u = 0, v = b.size()-1; u &amp;lt; v;) &lt;br /&gt;  {&lt;br /&gt;     int c = (u + v) / 2;&lt;br /&gt;     if (a[b[c]] &amp;lt; a[i]) u=c+1; else v=c;&lt;br /&gt;  }&lt;br /&gt; &lt;br /&gt;  // Update b if new value is smaller then previously referenced value &lt;br /&gt;  if (a[i] &amp;lt; a[b[u]]) &lt;br /&gt;  {&lt;br /&gt;   if (u &amp;gt; 0) p[i] = b[u-1];&lt;br /&gt;   b[u] = i;&lt;br /&gt;  } &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; for (u = b.size(), v = b.back(); u--; v = p[v]) b[u] = v;&lt;br /&gt;}&lt;br /&gt; &lt;br /&gt;/* Example of usage: */&lt;br /&gt;#include &amp;lt;cstdio&amp;gt;&lt;br /&gt;int main()&lt;br /&gt;{&lt;br /&gt; int a[] = { 1, 9, 3, 8, 11, 4, 5, 6, 4, 19, 7, 1, 7 };&lt;br /&gt; vector&amp;lt;int&amp;gt; seq(a, a+sizeof(a)/sizeof(a[0])); // seq : Input Vector&lt;br /&gt; vector&amp;lt;int&amp;gt; lis;                              // lis : Vector containing                                                    indexes of longest subsequence &lt;br /&gt; find_lis(seq, lis);&lt;br /&gt; &lt;br /&gt; //Printing actual output &lt;br /&gt; for (size_t i = 0; i &amp;lt; lis.size(); i++)&lt;br /&gt;    printf("%d ", seq[lis[i]]);&lt;br /&gt; printf("\n");    &lt;br /&gt; &lt;br /&gt; return 0;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div&gt;&lt;code style="background-attachment: initial; background-clip: initial; background-color: #eeeeee; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span class="com" style="background-attachment: initial; background-clip: initial; background-color: transparent; background-image: initial; background-origin: initial; border-bottom-width: 0px; border-color: initial; border-left-width: 0px; border-right-width: 0px; border-style: initial; border-top-width: 0px; font-size: 14px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px; vertical-align: baseline;"&gt;&lt;span class="Apple-style-span" style="color: grey; font-family: Consolas, Menlo, Monaco, 'Lucida Console', 'Liberation Mono', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Courier New', monospace, serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/273616926724373216-7922614875662828846?l=cella-door.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cella-door.blogspot.com/feeds/7922614875662828846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cella-door.blogspot.com/2011/04/longest-increasing-sequence.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/273616926724373216/posts/default/7922614875662828846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/273616926724373216/posts/default/7922614875662828846'/><link rel='alternate' type='text/html' href='http://cella-door.blogspot.com/2011/04/longest-increasing-sequence.html' title='Longest Increasing Sequence'/><author><name>Cellar Door</name><uri>http://www.blogger.com/profile/08361512500990202557</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-273616926724373216.post-5699980796219197936</id><published>2011-04-13T23:44:00.000-07:00</published><updated>2011-04-13T23:44:08.944-07:00</updated><title type='text'>Edit Distance | Dynamic Programming contd...</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;br /&gt;The algorithm thought process:&lt;br /&gt;&lt;br /&gt;F &amp;nbsp;O O  D &amp;nbsp; &amp;nbsp; (m = 4)&lt;br /&gt;M O N E Y&amp;nbsp;(n = 4)&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;While travelling distance here we'll encounter either of these four for any pair of chars. As usual a Brute-Force will ask us to visit and compare m*n times - taking into consideration of all permutations of the characters.&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;u&gt;Deletion&lt;/u&gt;: Delete Y&lt;/div&gt;&lt;div&gt;&lt;u&gt;Chang&lt;/u&gt;e: Change F to M&lt;/div&gt;&lt;div&gt;&lt;u&gt;Insertion&lt;/u&gt;:&lt;/div&gt;&lt;div&gt;&lt;u&gt;Same Characte&lt;/u&gt;r: Nothing to be done&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You may recall DP as:&lt;br /&gt;&lt;u&gt;Dynamic Programming Hallmark #1&lt;/u&gt;:&lt;br /&gt;OPTIMAL SUBSTRUCTURE - An optimal Solution to a problem (or an instance of problem) contains optimal solution to a subproblem.&lt;br /&gt;&lt;u&gt;Dynamic Programming Hallmark #2&lt;/u&gt;:&lt;br /&gt;OVERLAPPING SUBPROBLEMS - A recursive solution contains a small number of distinct subproblems repeated many times.&lt;br /&gt;&lt;br /&gt;Like my previous post for calculating Longest Common Subsequence, we can define a recursive method on the same line. Later, we can use a table to store and look-up and update the values[ the distance between the words]&lt;br /&gt;&lt;br /&gt;Source Code:&lt;br /&gt;// myProject.cpp : Defines the entry point for the console application.&lt;br /&gt;//&lt;br /&gt;&lt;br /&gt;#include "stdafx.h"&lt;br /&gt;#include &amp;lt;string&amp;gt;&lt;br /&gt;#include &amp;lt;vector&amp;gt;&lt;br /&gt;#include &amp;lt;algorithm&amp;gt;&lt;br /&gt;#include &amp;lt;fstream&amp;gt;&lt;br /&gt;#include &amp;lt;iostream&amp;gt;&lt;br /&gt;#include "BaseClass.h"&lt;br /&gt;using namespace std;&lt;br /&gt;&lt;br /&gt;int EDITDISTANCE(const char A[], const char B[], int m, int n)&lt;br /&gt;{&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;int Edit[20][20] = {0, };&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;for(int j = 0; j &amp;lt; n; j++)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;Edit[0][j] = j;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;for(int j = 0; j &amp;lt; m; j++)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;Edit[j][0] = j;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;for(int i = 1; i &amp;lt;= m; i++)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;for(int j = 1; j &amp;lt;= n; j++)&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;{&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;if (A[i] == B[j])&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;Edit[i][j] = std::min( std::min( Edit[i-1][j] + 1, Edit[i][j-1] + 1), Edit[i-1][j-1] );&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;else&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;Edit[i][j] = std::min( std::min( Edit[i-1][j] + 1, Edit[i][j-1] + 1), Edit[i-1][j-1] + 1);&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;return Edit[m][n];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int _tmain(int argc, _TCHAR* argv[])&lt;br /&gt;{&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;char A[] = "ALGORITHM";&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;char B[] = "ALTRUISTIC";&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;printf("%d\n", EDITDISTANCE(A, B, 9, 10));&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;printf("Hello World!");&lt;br /&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;For ease try visualizing the table.&lt;br /&gt;References:&lt;br /&gt;&lt;iframe align="left" frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=cellardoor0b-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=bpl&amp;amp;asins=0262033844&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="align: left; height: 245px; padding-right: 10px; padding-top: 5px; width: 131px;"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/273616926724373216-5699980796219197936?l=cella-door.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cella-door.blogspot.com/feeds/5699980796219197936/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cella-door.blogspot.com/2011/04/edit-distance-dynamic-programming-contd.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/273616926724373216/posts/default/5699980796219197936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/273616926724373216/posts/default/5699980796219197936'/><link rel='alternate' type='text/html' href='http://cella-door.blogspot.com/2011/04/edit-distance-dynamic-programming-contd.html' title='Edit Distance | Dynamic Programming contd...'/><author><name>Cellar Door</name><uri>http://www.blogger.com/profile/08361512500990202557</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-273616926724373216.post-5591383111381420399</id><published>2011-04-13T23:23:00.000-07:00</published><updated>2011-04-13T23:29:06.595-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dynamic Programming  Longest Common Subsequence Algorithm Recursion'/><title type='text'>Dynamic Programming | Longest Common Subsequence</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;For the shake of chapter notes let me put forward the hallmarks of solving problem using Dynamic Programming.&lt;br /&gt;&lt;div&gt;&lt;div&gt;&lt;u&gt;Dynamic Programming Hallmark #1&lt;/u&gt;:&lt;/div&gt;&lt;div&gt;&lt;u&gt;OPTIMAL SUBSTRUCTURE&lt;/u&gt;&amp;nbsp;- An optimal Solution to a problem (or an instance of problem) contains optimal solution to a subproblem.&lt;/div&gt;&lt;div&gt;&lt;u&gt;Dynamic Programming Hallmark #2&lt;/u&gt;:&lt;/div&gt;&lt;div&gt;&lt;u&gt;OVERLAPPING SUBPROBLEMS&lt;/u&gt;&amp;nbsp;- A recursive solution contains a small number of distinct subproblems&amp;nbsp;repeated&amp;nbsp;many times.&lt;/div&gt;&lt;div&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Enough stated before I explain a bit. Actually, any problem where one can see subproblem to a problem[or a problem instance] and that there is fair chance of solving the same using Brute-Force Algorithm can be solved by applying Dynamic Programming Concepts. One may go for recursive methods to solve such problem - But that's going to be a Brute-Force method. A word of caution here as there is a lot of possibility that one can't solve problems using Brute-Force method, leaving alone the efficient ones. So, after we are done with a recursive solution we can look at the recursion tree of those solvable problems. In most of the cases there is a fair chance that&amp;nbsp;a small number of distinct subproblems will be repeated&amp;nbsp;many times. As I go forward I'll explain how Longest Common Subsequence[LCS] problem's recursion tree has repeated subproblems. So, there comes Dynamic programming techniques for the rescue. Its second Hallmark, stated above, implies that One can avoid those subproblems getting computed again and again by saving those results. Though, it raise memory constraint but it reduces the computing overhead drastically - and more often, It provides an only way to solve for even moderately large n.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;LCS:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;X = A B C B D A B (Length m = 7)&lt;/div&gt;&lt;div&gt;Y = B D C A B A&amp;nbsp;(Length n = 6)&lt;/div&gt;&lt;div&gt;Xi = {x1, x2, ... xi}&lt;/div&gt;&lt;div&gt;Length[i,j] = LCS value&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Recursive Algo for LCS [merely, a brute force method]:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here the thought lies as if the LCS of k-1th long string is known then we compare kth character of the string with each character of other string. If it matches then that means LCS can be increased by 1. If that does not match then assign LCS as maximum of Length[k-1-1, j] and Length[k-1, j-1] where j is the index of current character under consideration of 2nd string.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;LCS(x, y, i, j)&lt;/div&gt;&lt;div&gt;&amp;nbsp;for i = 1 to m&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;for j = 1 to n&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; if x[i] = y[j]&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;then Length[i, j] &amp;lt;- LCS (x, y, i-1, j-1) + 1&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;else Length[i, j] &amp;lt;- max ( LCS ( x, y, i-1, j), LCS(&amp;nbsp;x, y, i, j -1) )&lt;/div&gt;&lt;div&gt;return Length[i, j]&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As evident from Recursion tree, the height is (m+n) and so time reqd = 2 raised to (m+n) with &lt;u&gt;a lot of repeated subproblems&lt;/u&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;LCS(x,y,6,5) will be computed twice for instance.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;DP gives us better solution.&amp;nbsp;&lt;/div&gt;&lt;div&gt;As evident we always need either of these:&amp;nbsp;LCS (x, y, i-1, j-1),&amp;nbsp;&amp;nbsp;LCS ( x, y, i-1, j) and LCS(&amp;nbsp;x, y, i, j -1)&amp;nbsp;&lt;/div&gt;&lt;div&gt;Therefore, we can store previous values at a 2D matrix and whenever needed we use previous value - based upon current characters under consideration - and populate new one.&lt;/div&gt;&lt;div&gt;That makes a small change to our previous Algorithm:&lt;/div&gt;&lt;div&gt;&lt;div&gt;LCS(x, y, i, j)&lt;/div&gt;&lt;div&gt;for i = 1 to m&lt;/div&gt;&lt;div&gt;Length[0, i] &amp;lt;- 0&lt;/div&gt;&lt;div&gt;&lt;div&gt;for i = 1 to n&lt;/div&gt;&lt;div&gt;Length[i, 0] &amp;lt;- 0&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;for i = 1 to m&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp;for j = 1 to n&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; if x[i] = y[j]&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;then Length[i, j] &amp;lt;- LCS (x, y, i-1, j-1) + 1&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;else Length[i, j] &amp;lt;- max ( LCS ( x, y, i-1, j), LCS(&amp;nbsp;x, y, i, j -1) )&lt;/div&gt;&lt;div&gt;return Length[i, j]&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The value at Length[m,n] will have the final value. And the LCS is done.&lt;/div&gt;&lt;div&gt;For better visualization one can draw a table.&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp;A B C B D A B&lt;/div&gt;&lt;div&gt;&amp;nbsp;&amp;nbsp; 0 0 &amp;nbsp;0 &amp;nbsp;0 0 &amp;nbsp;0 0 &amp;nbsp;0&amp;nbsp;&lt;/div&gt;&lt;div&gt;B0 0 &amp;nbsp;1 &amp;nbsp;1 &amp;nbsp;1 &amp;nbsp;1 1 &amp;nbsp;1&lt;/div&gt;&lt;div&gt;D0 0 &amp;nbsp;1 &amp;nbsp;1 &amp;nbsp;1 &amp;nbsp;2 ...&lt;/div&gt;&lt;div&gt;C0 ...&lt;br /&gt;A0&lt;/div&gt;&lt;div&gt;B0&lt;/div&gt;&lt;div&gt;A0&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;iframe align="left" frameborder="0" marginheight="0" marginwidth="0" scrolling="no" src="http://rcm.amazon.com/e/cm?t=cellardoor0b-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=bpl&amp;amp;asins=0262033844&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;m=amazon&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" style="align: left; height: 245px; padding-right: 10px; padding-top: 5px; width: 131px;"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/273616926724373216-5591383111381420399?l=cella-door.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cella-door.blogspot.com/feeds/5591383111381420399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cella-door.blogspot.com/2011/04/dynamic-programming-longest-common.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/273616926724373216/posts/default/5591383111381420399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/273616926724373216/posts/default/5591383111381420399'/><link rel='alternate' type='text/html' href='http://cella-door.blogspot.com/2011/04/dynamic-programming-longest-common.html' title='Dynamic Programming | Longest Common Subsequence'/><author><name>Cellar Door</name><uri>http://www.blogger.com/profile/08361512500990202557</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-273616926724373216.post-2227287955419015745</id><published>2011-04-13T21:22:00.000-07:00</published><updated>2011-04-13T21:22:02.254-07:00</updated><title type='text'>Amit | अमित</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;span class="Apple-style-span" style="line-height: 20px;"&gt;&lt;span class="Apple-style-span" style="color: #444444; font-family: inherit;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="line-height: 1.5em; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 0.4em;"&gt;&lt;span class="Apple-style-span" style="color: #444444; font-family: inherit;"&gt;In&amp;nbsp;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Hindi" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Hindi"&gt;Hindi&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Bengali" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;"&gt;Bengali&lt;/a&gt;, Amit (&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Hindi_language" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Hindi language"&gt;Hindi&lt;/a&gt;:&amp;nbsp;&lt;span lang="hi" xml:lang="hi"&gt;अमित&lt;/span&gt;) means infinite or immeasurable or boundless. It is the wordstem root of the&amp;nbsp;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Amitabha_Buddha" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Amitabha Buddha"&gt;Amitabha Buddha&lt;/a&gt;&amp;nbsp;and one of the 108 names of Hindu God Shri&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Ganesha" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;"&gt;Ganesha&lt;/a&gt;. It also means an eternal&amp;nbsp;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Friend" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Friend"&gt;friend&lt;/a&gt;&amp;nbsp;of everyone in Hindi, Nepali and&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Sanskrit" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;"&gt;Sanskrit&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: 1.5em; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 0.4em;"&gt;&lt;span class="Apple-style-span" style="color: #444444; font-family: inherit;"&gt;In&amp;nbsp;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Hebrew" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Hebrew"&gt;Hebrew&lt;/a&gt;, Amit (&lt;a href="http://en.wikipedia.org/wiki/Hebrew_language" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Hebrew language"&gt;Hebrew&lt;/a&gt;:&amp;nbsp;&lt;span dir="rtl" lang="he" xml:lang="he"&gt;עמית&lt;/span&gt;‎) means&amp;nbsp;&lt;b&gt;colleague&lt;/b&gt;,&amp;nbsp;&lt;b&gt;friend&lt;/b&gt;.&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: 1.5em; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 0.4em;"&gt;&lt;span class="Apple-style-span" style="color: #444444; font-family: inherit;"&gt;In&amp;nbsp;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Arabic" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Arabic"&gt;Arabic&lt;/a&gt;, Amit (&lt;a href="http://en.wikipedia.org/wiki/Arabic_language" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Arabic language"&gt;Arabic&lt;/a&gt;:&amp;nbsp;&lt;span lang="ar" xml:lang="ar"&gt;&lt;b&gt;اميت&lt;/b&gt;&lt;/span&gt;‎) means being highly praised, beloved and victorious.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div style="line-height: 1.5em; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 0.4em;"&gt;&lt;span class="Apple-style-span" style="color: #444444; font-family: inherit;"&gt;More...&lt;/span&gt;&lt;/div&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style="line-height: 1.5em; margin-bottom: 0.5em; margin-left: 0px; margin-right: 0px; margin-top: 0.4em;"&gt;&lt;span class="Apple-style-span" style="color: #444444; font-family: inherit;"&gt;&lt;span class="Apple-style-span" style="line-height: 20px;"&gt;&lt;b&gt;Amitābha&lt;/b&gt;&amp;nbsp;(&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Sanskrit_language" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Sanskrit language"&gt;Sanskrit&lt;/a&gt;: अमिताभ,&amp;nbsp;&lt;i&gt;Amitābha&lt;/i&gt;&amp;nbsp;(wordstem),&amp;nbsp;&lt;small&gt;Hindi pronunciation:&amp;nbsp;&lt;/small&gt;&lt;span class="IPA" title="Pronunciation in IPA"&gt;&lt;a href="http://en.wikipedia.org/wiki/Wikipedia:IPA_for_Hindi_and_Urdu" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Wikipedia:IPA for Hindi and Urdu"&gt;[əmɪˈt̪aːbʱə]&lt;/a&gt;&lt;/span&gt;) is a celestial&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Buddhahood" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Buddhahood"&gt;buddha&lt;/a&gt;&amp;nbsp;described in the scriptures of the&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Mahayana" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Mahayana"&gt;Mahāyāna&lt;/a&gt;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/School_of_Buddhism" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="School of Buddhism"&gt;school of Buddhism&lt;/a&gt;. Amitābha is the principal buddha in the&amp;nbsp;&lt;a class="mw-redirect" href="http://en.wikipedia.org/wiki/Pure_Land_sect" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;" title="Pure Land sect"&gt;Pure Land sect&lt;/a&gt;, a branch of Buddhism practiced mainly in&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/East_Asia" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;"&gt;East Asia&lt;/a&gt;, while in&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Vajrayana" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;"&gt;Vajrayana&lt;/a&gt;Amitābha is known for his longevity attribute and the aggregate of distinguishing (recognition) and the deep awareness of individualities. According to these scriptures, Amitābha possesses infinite merits resulting from good deeds over countless past lives as a&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Bodhisattva" style="background-attachment: initial; background-clip: initial; background-color: initial; background-image: none; background-origin: initial; text-decoration: none;"&gt;bodhisattva&lt;/a&gt;&amp;nbsp;named Dharmakāra. "Amitābha" is translatable as "Infinite Light," hence Amitābha is often called "The Buddha of Infinite Light."&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/273616926724373216-2227287955419015745?l=cella-door.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cella-door.blogspot.com/feeds/2227287955419015745/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://cella-door.blogspot.com/2011/04/amit.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/273616926724373216/posts/default/2227287955419015745'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/273616926724373216/posts/default/2227287955419015745'/><link rel='alternate' type='text/html' href='http://cella-door.blogspot.com/2011/04/amit.html' title='Amit | अमित'/><author><name>Cellar Door</name><uri>http://www.blogger.com/profile/08361512500990202557</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
