Elliptic geometry: Difference between revisions

From formulasearchengine
Jump to navigation Jump to search
en>Quondum
Comparison with Euclidean geometry: 90-90-90 → 90°–90°–90°, as small as desired → arbitrarily small
en>RomanSpa
Line 1: Line 1:
{{Distinguish|longest common substring problem}}
Green Coffee Bean Extract is the newest miracle weight loss supplement. Buckle-up plus let's take a close look at what this fresh health supplement provides. Maybe it's the real thing, or it usually be a thing of the past inside a few months. I usually advise my customers to not run out plus purchase everything which is advertised because the upcoming miracle cure, or fat reduction discovery.<br><br>It takes a great deal of effort for we to get rid of weight by diet and exercise. if it's dragging you down, you can try utilizing supplements like pure [http://greencoffeeweightlossplan.com green coffee weight loss]. It assists burn fat at a quicker rate. you furthermore lose fat quicker.<br><br>If you try a diet for a lengthy time period, you must use a lot of willpower, time plus vitality to get rid of fat. It's a pretty hard thing to do plus many people aren't lucrative at it.<br><br>This assists the body to clean and flush out the toxin build up in a body. Since GCBE is 100% natural plus pure, you are able to take this supplement with additional vitamins, nevertheless in the event you are on prescription medication, please consult with your doctor before taking GCBE.<br><br>They assist control appetite, block fat storage, or boost the metabolism a little. In most situations, by themselves they can only assist you lose a few pounds... in the best case. They work right when combined with exercise plus right nutrition... that ought to be the basis for any successful plus permanent fat loss system.<br><br>Some more benefits from the green coffee beans is that it's technique more affordable compared to the roasted ones. Moreover, these are natural beans and never contain any additives. Meaning 1 will truly get the pure impact of chlorogenic acid found inside green coffee beans that initiates fat intake and helps promote fat metabolism in the liver. The same acid is responsible for improving body heat that allows the body to get rid of fats naturally. Additionally, it also assists in preventing the development of fresh fat cells as a result of its anti-oxidant feature.<br><br>In several people, the body naturally takes care of excess amino acids plus alternative unwanted fatty substances. However for almost all of us, our bodies don't have the appropriate balance of chemicals to deal with our very large appetites. And the appetites are for hunger-satisfying fatty foods. The green coffee simply delivers the chemistry the body needs to receive hold of the fatty molecules plus to dispose of them by burning or breaking them down so that the body will dispose of them naturally.<br><br>The information provided on this website is for informational reasons only and is not intended because a substitute for information from the doctor or additional healthcare specialist or any info contained on or in any product label or packaging. You ought not to employ the information on this site for diagnosis or treatment of any wellness issue or for prescription of any drugs or different treatment. You must consult with a medical specialist before beginning any diet, exercise or supplementation system, before taking any medicine, or if you have or suspect you might have a health issue. You should not stop taking any drugs without first consulting your physician.
The '''longest common subsequence''' ('''LCS''') '''problem'''  is to find the longest [[subsequence]] common to all sequences in a set of sequences (often just two). (Note that a subsequence is different from a [[substring]], for the terms of the former need not be consecutive terms of the original sequence.) It is a classic [[computer science]] problem, the basis of [[file comparison]] programs such as [[diff]], and has applications in [[bioinformatics]].
<!-- todo: add definition and example -->
 
== Complexity ==
For the general case of an arbitrary number of input sequences, the problem is [[NP-hard]].<ref>{{cite journal| author = David Maier| title = The Complexity of Some Problems on Subsequences and Supersequences| journal = J. ACM| volume = 25| year = 1978| pages = 322&ndash;336| doi = 10.1145/322063.322075| publisher = ACM Press| | issue = 2}}</ref> When the number of sequences is constant, the problem is solvable in polynomial time by [[dynamic programming]] (see ''Solution'' below). Assume you have <math>N</math> sequences of lengths <math>n_1, ..., n_N</math>. A naive search would test each of the <math>2^{n_1}</math> subsequences of the first sequence to determine whether they are also subsequences of the remaining sequences; each subsequence may be tested in time linear in the lengths of the remaining sequences, so the time for this algorithm would be
:<math>O\left( 2^{n_1} \sum_{i>1} n_i\right).</math>
 
For the case of two sequences of ''n'' and ''m'' elements, the running time of the dynamic programming approach is [[Big O notation|O]](''n'' × ''m''). For an arbitrary number of input sequences, the dynamic programming approach gives a solution in
 
:<math>O\left(N \prod_{i=1}^{N} n_i\right).</math>
 
There exist methods with lower complexity,<ref name="BHR00">
{{cite journal | author = L. Bergroth and H. Hakonen and T. Raita | title = A Survey of Longest Common Subsequence Algorithms | journal = SPIRE | volume = 00 | year = 2000 | isbn = 0-7695-0746-8 | pages = 39&ndash;48 | doi = 10.1109/SPIRE.2000.878178 | publisher = IEEE Computer Society}}</ref>
which often depend on the length of the LCS, the size of the alphabet, or both.
 
Notice that the LCS is not necessarily unique; for example the LCS of "ABC" and "ACB" is both "AB" and "AC". Indeed the LCS problem is often defined to be finding ''all'' common subsequences of a maximum length. This problem inherently has higher complexity, as the number of such subsequences is exponential in the worst case,<ref name="">{{cite arxiv | author = Ronald I. Greenberg | title = Bounds on the Number of Longest Common Subsequences  | date = 2003-08-06  | eprint = cs.DM/0301030}}</ref> even for only two input strings.
 
== Solution for two sequences ==
The LCS problem has an [[optimal substructure]]:  the problem can be broken down into smaller, simple "subproblems", which can be broken down into yet simpler subproblems, and so on, until, finally, the solution becomes trivial. The LCS problem also has [[overlapping subproblems]]:  the solution to a higher subproblem depends on the solutions to several of the lower subproblems. Problems with these two properties—optimal substructure and overlapping subproblems—can be approached by a problem-solving technique called [[dynamic programming]], in which the solution is built up starting with the simplest subproblems.  The procedure requires [[memoization]]—saving the solutions to one level of subproblem in a table (analogous to writing them to a ''memo'', hence the name) so that the solutions are available to the next level of subproblems.
This method is illustrated here.
 
=== Prefixes ===
The subproblems become simpler as the sequences become shorter.  Shorter sequences are conveniently described using the term ''prefix''.  A prefix of a sequence is the sequence with the end cut off. Let ''S'' be the sequence (AGCA).  Then, the sequence (AG) is one of the prefixes of ''S''. Prefixes are denoted with the name of the sequence, followed by a subscript to indicate how many characters the prefix contains.<ref>{{cite book
| last = Xia | first = Xuhua
| title = Bioinformatics and the Cell:  Modern Computational Approaches in Genomics, Proteomics and Transcriptomics
| year = 2007
| publisher = Springer
| location = New York
| page = 24
| isbn = 0-387-71336-0
}}</ref>  The prefix (AG) is denoted ''S''<sub>2</sub>, since it contains the first 2 elements of ''S''.  The possible prefixes of ''S'' are
:''S''<sub>1</sub> = (A)
:''S''<sub>2</sub> = (AG)
:''S''<sub>3</sub> = (AGC)
:''S''<sub>4</sub> = (AGCA).
 
The solution to the LCS problem for two arbitrary sequences, ''X'' and ''Y'', amounts to construct some function, ''LCS''(''X'', ''Y''), that gives the longest subsequences common to ''X'' and ''Y''.  That function relies on the following two properties.
 
=== First property ===
Suppose that two sequences both end in the same element.  To find their LCS, shorten each sequence by removing the last element, find the LCS of the shortened sequences, and to that LCS append the removed element.
:For example, here are two sequences having the same last element:  (BANANA) and (ATANA).
:Remove the same last element. Repeat the procedure until you find no common last element. The removed sequence will be (ANA).
:The sequences now under consideration:  (BAN) and (AT)
:The LCS of these last two sequences is, by inspection, (A).
:Append the removed element, (ANA), giving (AANA), which, by inspection, is the LCS of the original sequences.
 
In terms of prefixes,
: if ''x<sub>n</sub>''=''y<sub>m</sub>'', ''LCS''(''X<sub>n</sub>'', ''Y<sub>m</sub>'') = (''LCS''( ''X<sub>n''-1</sub>, ''Y<sub>m''-1</sub>), ''x<sub>n</sub>'')
where the comma indicates that the following element, ''x<sub>n</sub>'', is appended to the sequence.  Note that the LCS for ''X<sub>n</sub>'' and ''Y<sub>m</sub>'' involves determining the LCS of the shorter sequences, ''X<sub>n''-1</sub> and ''Y<sub>m''-1</sub>.
 
=== Second property ===
Suppose that the two sequences X and Y do not end in the same symbol.
Then the LCS of X and Y is the longer of the two sequences LCS(X<sub>n</sub>,Y<sub>m-1</sub>) and LCS(X<sub>n-1</sub>,Y<sub>m</sub>).
 
To understand this property, consider the two following sequences :
 
sequence X: ABCDEFG (n elements)<br />
sequence Y: BCDGK (m elements)
 
The LCS of these two sequences either ends with a G (the last element of sequence X) or does not.
 
'''Case 1: the LCS ends with a G'''<br />
Then it cannot end with a K. Thus it does not hurt to remove the K from sequence Y: if K were in the LCS, it would be its last character; as a consequence K is not in the LCS. We can then write: LCS(X<sub>n</sub>,Y<sub>m</sub>) = LCS(X<sub>n</sub>, Y<sub>m-1</sub>).
 
'''Case 2: the LCS does not end with a G'''<br />
Then it does not hurt to remove the G from the sequence X (for the same reason as above). And then we can write: LCS(X<sub>n</sub>,Y<sub>m</sub>) = LCS(X<sub>n-1</sub>, Y<sub>m</sub>).
 
In any case, the LCS we are looking for is one of LCS(X<sub>n</sub>, Y<sub>m-1</sub>) or LCS(X<sub>n-1</sub>, Y<sub>m</sub>). Those two last LCS are both common subsequences to X and Y. LCS(X,Y) is the longest. Thus its value is the longest sequence of LCS(X<sub>n</sub>, Y<sub>m-1</sub>) and LCS(X<sub>n-1</sub>, Y<sub>m</sub>).
 
=== ''LCS'' function defined ===
Let two sequences be defined as follows:  ''X'' = (''x''<sub>1</sub>, ''x''<sub>2</sub>...''x''<sub>m</sub>) and ''Y'' = (''y''<sub>1</sub>, ''y''<sub>2</sub>...''y''<sub>n</sub>).  The prefixes of ''X'' are ''X''<sub>1, 2,...m</sub>; the prefixes of ''Y'' are ''Y''<sub>1, 2,...n</sub>.  Let ''LCS''(''X''<sub>''i''</sub>, ''Y''<sub>''j''</sub>) represent the set of longest common subsequence of prefixes ''X<sub>i</sub>'' and ''Y<sub>j</sub>''.  This set of sequences is given by the following.
 
:<math>
LCS\left(X_{i},Y_{j}\right) =
\begin{cases}
  \empty
& \mbox{ if }\ i = 0 \mbox{ or }  j = 0 \\
  \textrm{  } LCS\left(X_{i-1},Y_{j-1}\right) +  1
& \mbox{ if } x_i = y_j \\
  \mbox{longest}\left(LCS\left(X_{i},Y_{j-1}\right),LCS\left(X_{i-1},Y_{j}\right)\right)
& \mbox{ if } x_i \ne y_j \\
\end{cases}
</math>
 
To find the longest subsequences common to ''X<sub>i</sub>'' and ''Y<sub>j</sub>'', compare the elements ''x<sub>i</sub>'' and ''y<sub>j</sub>''.  If they are equal, then the sequence ''LCS''(''X''<sub>''i''-1</sub>, ''Y''<sub>''j''-1</sub>) is extended by that element, ''x<sub>i</sub>''.  If they are not equal, then the longer of the two sequences, ''LCS''(''X''<sub>''i''</sub>, ''Y''<sub>''j''-1</sub>), and ''LCS''(''X''<sub>''i''-1</sub>, ''Y''<sub>''j''</sub>), is retained.  (If they are both the same length, but not identical, then both are retained.)  Notice that the subscripts are reduced by 1 in these formulas.  That can result in a subscript of 0.  Since the sequence elements are defined to start at 1, it was necessary to add the requirement that the LCS is empty when a subscript is zero.
 
=== Worked example ===
The longest subsequence common to ''C'' = (AGCAT), and ''R'' = (GAC) will be found.  Because the ''LCS'' function uses a "zeroth" element, it is convenient to define zero prefixes that are empty for these sequences:  ''C''<sub>0</sub> =  Ø; and ''R''<sub>0</sub> =  Ø.  All the prefixes are placed in a table with ''C'' in the first row (making it a <u>c</u>olumn header) and ''R'' in the first column (making it a <u>r</u>ow header).
 
{| class="wikitable" style="text-align:center"
|+ LCS Strings
|-
!  || 0 || A || G || C || A || T
|-
! 0
| Ø || Ø || Ø || Ø || Ø || Ø
|-
! G
| Ø
|
|
|
|
|
|-
! A
| Ø
|
|
|
|
|
|-
! C
| Ø
|
|
|
|
|
|-
|}
 
This table is used to store the LCS sequence for each step of the calculation.  The second column and second row have been filled in with Ø, because when an empty sequence is compared with a non-empty sequence, the longest common subsequence is always an empty sequence.
 
''LCS''(''R''<sub>1</sub>, ''C''<sub>1</sub>) is determined by comparing the first elements in each sequence.  G and A are not the same, so this LCS gets (using the "second property") the longest of the two sequences, ''LCS''(''R''<sub>1</sub>, ''C''<sub>0</sub>) and  ''LCS''(''R''<sub>0</sub>, ''C''<sub>1</sub>).  According to the table, both of these are empty, so ''LCS''(''R''<sub>1</sub>, ''C''<sub>1</sub>) is also empty, as shown in the table below.  The arrows indicate that the sequence comes from both the cell above, ''LCS''(''R''<sub>0</sub>, ''C''<sub>1</sub>) and the cell on the left, ''LCS''(''R''<sub>1</sub>, ''C''<sub>0</sub>).
 
''LCS''(''R''<sub>1</sub>, ''C''<sub>2</sub>) is determined by comparing G and G.  They match, so G is appended to the upper left sequence, ''LCS''(''R''<sub>0</sub>, ''C''<sub>1</sub>), which is (Ø), giving (ØG), which is (G).
 
For ''LCS''(''R''<sub>1</sub>, ''C''<sub>3</sub>), G and C do not match.  The sequence above is empty; the one to the left contains one element, G.  Selecting the longest of these, ''LCS''(''R''<sub>1</sub>, ''C''<sub>3</sub>) is (G).  The arrow points to the left, since that is the longest of the two sequences.
 
''LCS''(''R''<sub>1</sub>, ''C''<sub>4</sub>), likewise, is (G).
 
''LCS''(''R''<sub>1</sub>, ''C''<sub>5</sub>), likewise, is (G).
 
{| class="wikitable" style="text-align:center"
|+ "G" Row Completed
|-
!  || Ø || A || G || C || A || T
|-
! Ø
| Ø || Ø || Ø || Ø || Ø || Ø
|-
! G
| Ø
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>Ø
| <math>\overset{\nwarrow}{\ }</math>(G)
| <math>\overset{\ }{\leftarrow}</math>(G)
| <math>\overset{\ }{\leftarrow}</math>(G)
| <math>\overset{\ }{\leftarrow}</math>(G)
|-
! A
| Ø
|
|
|
|
|
|-
! C
| Ø
|
|
|
|
|
|-
|}
 
For ''LCS''(''R''<sub>2</sub>, ''C''<sub>1</sub>), A is compared with A.  The two elements match, so A is appended to Ø, giving (A).
 
For ''LCS''(''R''<sub>2</sub>, ''C''<sub>2</sub>), A and G do not match, so the longest of ''LCS''(''R''<sub>1</sub>, ''C''<sub>2</sub>), which is (G), and ''LCS''(''R''<sub>2</sub>, ''C''<sub>1</sub>), which is (A), is used.  In this case, they each contain one element, so this LCS is given two subsequences:  (A) and (G).
 
For ''LCS''(''R''<sub>2</sub>, ''C''<sub>3</sub>), A does not match C.  ''LCS''(''R''<sub>2</sub>, ''C''<sub>2</sub>) contains sequences (A) and (G); LCS(''R''<sub>1</sub>, ''C''<sub>3</sub>) is (G), which is already contained in ''LCS''(''R''<sub>2</sub>, ''C''<sub>2</sub>).  The result is that ''LCS''(''R''<sub>2</sub>, ''C''<sub>3</sub>) also contains the two subsequences, (A) and (G).
 
For ''LCS''(''R''<sub>2</sub>, ''C''<sub>4</sub>), A matches A, which is appended to the upper left cell, giving (GA).
 
For ''LCS''(''R''<sub>2</sub>, ''C''<sub>5</sub>), A does not match T.  Comparing the two sequences, (GA) and (G), the longest is (GA), so ''LCS''(''R''<sub>2</sub>, ''C''<sub>5</sub>) is (GA).
 
{| class="wikitable" style="text-align:center"
|+ "G" & "A" Rows Completed
|-
!  || Ø || A || G || C || A || T
|-
! Ø
| Ø || Ø || Ø || Ø || Ø || Ø
|-
! G
| Ø
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>Ø
| <math>\overset{\nwarrow}{\ }</math>(G)
| <math>\overset{\ }{\leftarrow}</math>(G)
| <math>\overset{\ }{\leftarrow}</math>(G)
| <math>\overset{\ }{\leftarrow}</math>(G)
|-
! A
| Ø
| <math>\overset{\nwarrow}{\ }</math>(A)
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>(A) & (G)
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>(A) & (G)
| <math>\overset{\nwarrow}{\ }</math>(GA)
| <math>\overset{\ }{\leftarrow}</math>(GA)
|-
! C
| Ø
|
|
|
|
|
|-
|}
 
For ''LCS''(''R''<sub>3</sub>, ''C''<sub>1</sub>), C and A do not match, so ''LCS''(''R''<sub>3</sub>, ''C''<sub>1</sub>) gets the longest of the two sequences, (A).
 
For ''LCS''(''R''<sub>3</sub>, ''C''<sub>2</sub>), C and G do not match.  Both ''LCS''(''R''<sub>3</sub>, ''C''<sub>1</sub>) and ''LCS''(''R''<sub>2</sub>, ''C''<sub>2</sub>) have one element.  The result is that ''LCS''(''R''<sub>3</sub>, ''C''<sub>2</sub>) contains the two subsequences, (A) and (G).
 
For ''LCS''(''R''<sub>3</sub>, ''C''<sub>3</sub>), C and C match, so C is appended to ''LCS''(''R''<sub>2</sub>, ''C''<sub>2</sub>), which contains the two subsequences, (A) and (G), giving (AC) and (GC).
 
For ''LCS''(''R''<sub>3</sub>, ''C''<sub>4</sub>), C and A do not match.  Combining ''LCS''(''R''<sub>3</sub>, ''C''<sub>3</sub>), which contains (AC) and (GC), and ''LCS''(''R''<sub>2</sub>, ''C''<sub>4</sub>), which contains (GA), gives a total of three sequences:  (AC), (GC), and (GA).
 
Finally, for ''LCS''(''R''<sub>3</sub>, ''C''<sub>5</sub>), C and T do not match.  The result is that ''LCS''(''R''<sub>3</sub>, ''C''<sub>5</sub>) also contains the three sequences, (AC), (GC), and (GA).
 
{| class="wikitable" style="text-align:center"
|+ Completed LCS Table
|-
!  || Ø || A || G || C || A || T
|-
! Ø
| Ø || Ø || Ø || Ø || Ø || Ø
|-
! G
| Ø
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>Ø
| <math>\overset{\nwarrow}{\ }</math>(G)
| <math>\overset{\ }{\leftarrow}</math>(G)
| <math>\overset{\ }{\leftarrow}</math>(G)
| <math>\overset{\ }{\leftarrow}</math>(G)
|-
! A
| Ø
| <math>\overset{\nwarrow}{\ }</math>(A)
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>(A) & (G)
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>(A) & (G)
| <math>\overset{\nwarrow}{\ }</math>(GA)
| <math>\overset{\ }{\leftarrow}</math>(GA)
|-
! C
| Ø
| <math>\overset{\ \uparrow}{\ }</math>(A)
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>(A) & (G)
| <math>\overset{\nwarrow}{\ }</math>(AC) & (GC)
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>(AC) & (GC) & (GA)
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>(AC) & (GC) & (GA)
|-
|}
 
The final result is that the last cell contains all the longest subsequences common to (AGCAT) and (GAC); these are (AC), (GC), and (GA).  The table also shows the longest common subsequences for every possible pair of prefixes.  For example, for (AGC) and (GA), the longest common subsequence are (A) and (G).
 
=== Traceback approach ===
Calculating the LCS of a row of the LCS table requires only the solutions to the current row and the previous row.  Still, for long sequences, these sequences can get numerous and long, requiring a lot of storage space.  Storage space can be saved by saving not the actual subsequences, but the length of the subsequence and the direction of the arrows, as in the table below.
 
{| class="wikitable" style="text-align:center"
|+ Storing length, rather than sequences
|-
!  || Ø || A || G || C || A || T
|-
! Ø
| 0 || 0 || 0 || 0 || 0 || 0
|-
! G
| 0
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>0
| <math>\overset{\nwarrow}{\ }</math>1
| <math>\overset{\ }{\leftarrow}</math>1
| <math>\overset{\ }{\leftarrow}</math>1
| <math>\overset{\ }{\leftarrow}</math>1
|-
! A
| 0
| <math>\overset{\nwarrow}{\ }</math>1
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>1
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>1
| <math>\overset{\nwarrow}{\ }</math>2
| <math>\overset{\ }{\leftarrow}</math>2
|-
! C
| 0
| <math>\overset{\ \uparrow}{\ }</math>1
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>1
| <math>\overset{\nwarrow}{\ }</math>2
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>2
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>2
|-
|}
 
The actual subsequences are deduced in a "traceback" procedure that follows the arrows backwards, starting from the last cell in the table.  When the length decreases, the sequences must have had a common element.  Several paths are possible when two arrows are shown in a cell.  Below is the table for such an analysis, with numbers colored in cells where the length is about to decrease.  The bold numbers trace out the sequence, (GA).<ref>{{cite book | author = [[Thomas H. Cormen]], [[Charles E. Leiserson]], [[Ronald L. Rivest]] and [[Clifford Stein]] | title = [[Introduction to Algorithms]] | publisher = MIT Press and McGraw-Hill | year = 2001 | isbn = 0-262-53196-8 | edition = 2nd | chapter = 15.4 | pages = 350–355 }}</ref>
 
{| class="wikitable" style="text-align:center"
|+ Traceback example
|-
!  || Ø || A || G || C || A || T
|-
! Ø
| 0 || style="background:silver" | '''0''' || 0 || 0 || 0 || 0
|-
! G
| style="background:silver" | 0
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>0
| style="background:silver;color:#FF6600" | <math>\overset{\nwarrow}{\ }</math>'''1'''
| style="background:silver" | <math>\overset{\ }{\leftarrow}</math>'''1'''
| <math>\overset{\ }{\leftarrow}</math>1
| <math>\overset{\ }{\leftarrow}</math>1
|-
! A
| 0
| style="background:silver;color:#FF6600" | <math>\overset{\nwarrow}{\ }</math>1
| style="background:silver" | <math>\overset{\ \ \uparrow}{\leftarrow}</math>1
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>1
| style="background:silver;color:#FF6600" | <math>\overset{\nwarrow}{\ }</math>'''2'''
| style="background:silver" | <math>\overset{\ }{\leftarrow}</math>'''2'''
|-
! C
| 0
| <math>\overset{\ \uparrow}{\ }</math>1
| <math>\overset{\ \ \uparrow}{\leftarrow}</math>1
| style="background:silver;color:#FF6600" | <math>\overset{\nwarrow}{\ }</math>2
| style="background:silver" | <math>\overset{\ \ \uparrow}{\leftarrow}</math>2
| style="background:silver" | <math>\overset{\ \ \uparrow}{\leftarrow}</math>'''2'''
|-
|}
 
== Relation to other problems ==
For two strings <math>X_{1 \dots m}</math> and <math>Y_{1 \dots n}</math>, the length of the [[shortest common supersequence problem|shortest common supersequence]] is related to the length of the LCS by<ref name="BHR00" />
 
:<math>\left|SCS(X,Y)\right| = n + m - \left|LCS(X,Y)\right|.</math>
 
The [[Levenshtein distance|edit distance]] when only insertion and deletion is allowed (no substitution), or when the cost of the substitution is the double of the cost of an insertion or  deletion, is:
 
:<math>d'(X,Y) = n + m - 2 \cdot \left|LCS(X,Y)\right|.</math>
 
== Code for the dynamic programming solution ==
{{unreferenced section|date=March 2013}}
=== Computing the length of the LCS ===
The function below takes as input sequences <code>X[1..m]</code> and <code>Y[1..n]</code> computes the LCS between <code>X[1..i]</code> and <code>Y[1..j]</code> for all <code>1 ≤ i ≤ m</code> and <code>1 ≤ j ≤ n</code>, and stores it in <code>C[i,j]</code>. <code>C[m,n]</code> will contain the length of the LCS of <code>X</code> and <code>Y</code>.
 
'''function''' LCSLength(X[1..m], Y[1..n])
    C = array(0..m, 0..n)
    '''for''' i := 0..m
        C[i,0] = 0
    '''for''' j := 0..n
        C[0,j] = 0
    '''for''' i := 1..m
        '''for''' j := 1..n
            '''if''' X[i] = Y[j]
                C[i,j] := C[i-1,j-1] + 1
            '''else'''
                C[i,j] := max(C[i,j-1], C[i-1,j])
    '''return''' C[m,n]
 
Alternatively, [[memoization]] could be used.
 
=== Reading out an LCS ===
The following function [[backtracking|backtracks]] the choices taken when computing the <code>C</code> table. If the last characters in the prefixes are equal, they must be in an LCS. If not, check what gave the largest LCS of keeping <math>x_i</math> and <math>y_j</math>, and make the same choice. Just choose one if they were equally long. Call the function with <code>i=m</code> and <code>j=n</code>.
 
'''function''' backtrack(C[0..m,0..n], X[1..m], Y[1..n], i, j)
    '''if''' i = 0 '''or''' j = 0
        '''return''' ""
    '''else if ''' X[i] = Y[j]
        '''return''' backtrack(C, X, Y, i-1, j-1) + X[i]
    '''else'''
        '''if''' C[i,j-1] > C[i-1,j]
            '''return''' backtrack(C, X, Y, i, j-1)
        '''else'''
            '''return''' backtrack(C, X, Y, i-1, j)
 
=== Reading out all LCSs ===
If choosing <math>x_i</math> and <math>y_j</math> would give an equally long result, read out both resulting subsequences. This is returned as a set by this function. Notice that this function is not polynomial, as it might branch in almost every step if the strings are similar.
 
'''function''' backtrackAll(C[0..m,0..n], X[1..m], Y[1..n], i, j)
    '''if''' i = 0 '''or''' j = 0
        '''return''' {""}
    '''else if''' X[i] = Y[j]
        '''return''' {Z + X[i] '''for all''' Z '''in''' backtrackAll(C, X, Y, i-1, j-1)}
    '''else'''
        R := {}
        '''if''' C[i,j-1] ≥ C[i-1,j]
            R := backtrackAll(C, X, Y, i, j-1)
        '''if''' C[i-1,j] ≥ C[i,j-1]
            R := R ∪ backtrackAll(C, X, Y, i-1, j)
        '''return''' R
 
=== Print the diff ===
This function will backtrack through the C matrix, and print the [[diff]] between the two sequences. Notice that you will get a different answer if you exchange <code>≥</code> and <code>&lt;</code>, with <code>&gt;</code> and <code>≤</code> below.
 
'''function''' printDiff(C[0..m,0..n], X[1..m], Y[1..n], i, j)
    '''if''' i > 0 '''and''' j > 0 '''and''' X[i] = Y[j]
        printDiff(C, X, Y, i-1, j-1)
        print "  " + X[i]
    '''else if''' j > 0 '''and''' (i = 0 '''or''' C[i,j-1] ≥ C[i-1,j])
        printDiff(C, X, Y, i, j-1)
        print "+ " + Y[j]
    '''else if''' i > 0 '''and''' (j = 0 '''or''' C[i,j-1] < C[i-1,j])
        printDiff(C, X, Y, i-1, j)
        print "- " + X[i]
    '''else'''
        print ""
 
=== Example ===
Let <math>X</math> be “<code>XMJYAUZ</code>” and <math>Y</math> be “<code>MZJAWXU</code>”. The longest common subsequence between <math>X</math> and <math>Y</math> is “<code>MJAU</code>”. The table <code>C</code> shown below, which is generated by the function <code>LCSLength</code>, shows the lengths of the longest common subsequences between prefixes of <math>X</math> and <math>Y</math>. The <math>i</math>th row and <math>j</math>th column shows the length of the LCS between <math>X_{1..i}</math> and <math>Y_{1..j}</math>.
 
{| class="wikitable" style="text-align: center;"
|-
! colspan="2" rowspan="2" |
! 0 !! 1 !! 2 !! 3 !! 4 !! 5 !! 6 !! 7
|-
! Ø !! M !! Z !! J !! A !! W !! X !! U
|-
! 0 !! Ø
| <u>0</u> || 0 || 0 || 0 || 0 || 0 || 0 || 0
|-
! 1 !! X
| <u>0</u> || 0 || 0 || 0 || 0 || 0 || 1 || 1
|-
! 2 !! M
| 0 || <u>1</u> || <u>1</u> || 1 || 1 || 1 || 1 || 1
|-
! 3 !! J
| 0 || 1 || 1 || <u>2</u> || 2 || 2 || 2 || 2
|-
! 4 !! Y
| 0 || 1 || 1 || <u>2</u> || 2 || 2 || 2 || 2
|-
! 5 !! A
| 0 || 1 || 1 || 2 || <u>3</u> || <u>3</u> || <u>3</u> || 3
|-
! 6 !! U
| 0 || 1 || 1 || 2 || 3 || 3 || 3 || <u>4</u>
|-
! 7 !! Z
| 0 || 1 || 2 || 2 || 3 || 3 || 3 || <u>4</u>
|}
 
The underlined numbers show the path the function <code>backtrack</code> would follow from the bottom right to the top left corner, when reading out an LCS. If the current symbols in <math>X</math> and <math>Y</math> are equal, they are part of the LCS, and we go both up and left. If not, we go up or left, depending on which cell has a higher number. This corresponds to either taking the LCS between <math>X_{1..i-1}</math> and <math>Y_{1..j}</math>, or <math>X_{1..i}</math> and <math>Y_{1..j-1}</math>.
 
== Code optimization ==
Several optimizations can be made to the algorithm above to speed it up for real-world cases.
 
=== Reduce the problem set ===
The C matrix in the naive algorithm [[quadratic growth|grows quadratically]] with the lengths of the sequences.  For two 100-item sequences, a 10,000-item matrix would be needed, and 10,000 comparisons would need to be done.  In most real-world cases, especially source code diffs and patches, the beginnings and ends of files rarely change, and almost certainly not both at the same time.  If only a few items have changed in the middle of the sequence, the beginning and end can be eliminated.  This reduces not only the memory requirements for the matrix, but also the number of comparisons that must be done.
 
'''function''' LCS(X[1..m], Y[1..n])
    start := 1
    m_end := m
    n_end := n
    ''trim off the matching items at the beginning''
    '''while''' start ≤ m_end '''and''' start ≤ n_end '''and''' X[start] = Y[start]
        start := start + 1
    ''trim off the matching items at the end''
    '''while''' start ≤ m_end '''and''' start ≤ n_end '''and''' X[m_end] = Y[n_end]
        m_end := m_end - 1
        n_end := n_end - 1
    C = array(start-1..m_end, start-1..n_end)
    ''only loop over the items that have changed''
    '''for''' i := start..m_end
        '''for''' j := start..n_end
            ''the algorithm continues as before ...''
 
In the best case scenario, a sequence with no changes, this optimization would completely eliminate the need for the C matrix.  In the worst case scenario, a change to the very first and last items in the sequence, only two additional comparisons are performed.
 
=== Reduce the comparison time ===
Most of the time taken by the naive algorithm is spent performing comparisons between items in the sequences.  For textual sequences such as source code, you want to view lines as the sequence elements instead of single characters.  This can mean comparisons of relatively long strings for each step in the algorithm.  Two optimizations can be made that can help to reduce the time these comparisons consume.
 
=== Reduce strings to hashes ===
A [[hash function]] or [[checksum]] can be used to reduce the size of the strings in the sequences.  That is, for source code where the average line is 60 or more characters long, the hash or checksum for that line might be only 8 to 40 characters long.  Additionally, the randomized nature of hashes and checksums would guarantee that comparisons would short-circuit faster, as lines of source code will rarely be changed at the beginning.
 
There are three primary drawbacks to this optimization.  First, an amount of time needs to be spent beforehand to precompute the hashes for the two sequences.  Second, additional memory needs to be allocated for the new hashed sequences.  However, in comparison to the naive algorithm used here, both of these drawbacks are relatively minimal.
 
The third drawback is that of [[hash collision|collisions]].  Since the checksum or hash is not guaranteed to be unique, there is a small chance that two different items could be reduced to the same hash.  This is unlikely in source code, but it is possible.  A cryptographic hash would therefore be far better suited for this optimization, as its entropy is going to be significantly greater than that of a simple checksum.  However, the benefits may not be worth the setup and computational requirements of a cryptographic hash for small sequence lengths.
 
=== Reduce the required space ===
If only the length of the LCS is required, the matrix can be reduced to a <math>2\times \min(n,m)</math> matrix with ease, or to a <math>\min(m,n)+1</math> vector (smarter) as the dynamic programming approach only needs the current and previous columns of the matrix. [[Hirschberg's algorithm]] allows the construction of the optimal sequence itself in the same quadratic time and linear space bounds.<ref>{{cite journal|authorlink = Dan Hirschberg|author=Hirschberg, D. S.|title=A linear space algorithm for computing maximal common subsequences|journal=Communications of the ACM|volume=18|issue=6|year=1975|pages=341–343|doi=10.1145/360825.360861}}</ref>
 
== See also ==
* [[Longest increasing subsequence]]
* [[Longest alternating subsequence]]
 
== References ==
{{reflist}}
<!-- Dead note "GJ78": {{cite book|author = [[Michael R. Garey]] and [[David S. Johnson]] | year = 1979 | title = Computers and Intractability: A Guide to the Theory of NP-Completeness| publisher = W.H. Freeman | isbn = 0-7167-1045-5| pages = 228}} A421: SR10. -->
 
== External links ==
{{Wikibooks|Algorithm implementation|Strings/Longest common subsequence|Longest common subsequence}}
* [http://nist.gov/dads/HTML/longestCommonSubsequence.html Dictionary of Algorithms and Data Structures: longest common subsequence]
* [http://rosettacode.org/wiki/Longest_common_subsequence A collection of implementations of the longest common subsequence in many programming languages]
 
<!-- case of fixed number of input strings -->
<!-- case of arbitrary number of input strings -->
 
{{DEFAULTSORT:Longest Common Subsequence Problem}}
[[Category:Problems on strings]]
[[Category:Combinatorics]]
[[Category:Dynamic programming]]
[[Category:Polynomial-time problems]]
[[Category:NP-complete problems]]

Revision as of 16:56, 14 February 2014

Green Coffee Bean Extract is the newest miracle weight loss supplement. Buckle-up plus let's take a close look at what this fresh health supplement provides. Maybe it's the real thing, or it usually be a thing of the past inside a few months. I usually advise my customers to not run out plus purchase everything which is advertised because the upcoming miracle cure, or fat reduction discovery.

It takes a great deal of effort for we to get rid of weight by diet and exercise. if it's dragging you down, you can try utilizing supplements like pure green coffee weight loss. It assists burn fat at a quicker rate. you furthermore lose fat quicker.

If you try a diet for a lengthy time period, you must use a lot of willpower, time plus vitality to get rid of fat. It's a pretty hard thing to do plus many people aren't lucrative at it.

This assists the body to clean and flush out the toxin build up in a body. Since GCBE is 100% natural plus pure, you are able to take this supplement with additional vitamins, nevertheless in the event you are on prescription medication, please consult with your doctor before taking GCBE.

They assist control appetite, block fat storage, or boost the metabolism a little. In most situations, by themselves they can only assist you lose a few pounds... in the best case. They work right when combined with exercise plus right nutrition... that ought to be the basis for any successful plus permanent fat loss system.

Some more benefits from the green coffee beans is that it's technique more affordable compared to the roasted ones. Moreover, these are natural beans and never contain any additives. Meaning 1 will truly get the pure impact of chlorogenic acid found inside green coffee beans that initiates fat intake and helps promote fat metabolism in the liver. The same acid is responsible for improving body heat that allows the body to get rid of fats naturally. Additionally, it also assists in preventing the development of fresh fat cells as a result of its anti-oxidant feature.

In several people, the body naturally takes care of excess amino acids plus alternative unwanted fatty substances. However for almost all of us, our bodies don't have the appropriate balance of chemicals to deal with our very large appetites. And the appetites are for hunger-satisfying fatty foods. The green coffee simply delivers the chemistry the body needs to receive hold of the fatty molecules plus to dispose of them by burning or breaking them down so that the body will dispose of them naturally.

The information provided on this website is for informational reasons only and is not intended because a substitute for information from the doctor or additional healthcare specialist or any info contained on or in any product label or packaging. You ought not to employ the information on this site for diagnosis or treatment of any wellness issue or for prescription of any drugs or different treatment. You must consult with a medical specialist before beginning any diet, exercise or supplementation system, before taking any medicine, or if you have or suspect you might have a health issue. You should not stop taking any drugs without first consulting your physician.