दीर्घवर्तिक सामान्य उपानुक्रम (लांगेस्ट कॉमन सब सीक्वेंस)
सबसे लंबा सामान्य अनुवर्ती (LCS) अनुक्रमों के एक सेट (अक्सर केवल दो अनुक्रम) में सभी अनुक्रमों के लिए सामान्य सबसे लंबा अनुवर्ती होता है। यह सबसे लंबे सामान्य सबस्ट्रिंग से भिन्न है: सबस्ट्रिंग के विपरीत, बाद के अनुक्रमों को मूल अनुक्रमों के भीतर लगातार स्थिति पर कब्जा करने की आवश्यकता नहीं होती है। सबसे लंबे सामान्य अनुवर्ती की गणना करने की समस्या एक क्लासिक कंप्यूटर विज्ञान समस्या है, जो अंतर उपयोगिता जैसे डेटा तुलना कार्यक्रमों का आधार है|diff
उपयोगिता, और कम्प्यूटेशनल भाषा विज्ञान और जैव सूचना विज्ञान में इसके अनुप्रयोग हैं। इसका व्यापक रूप से संशोधन नियंत्रण द्वारा भी उपयोग किया जाता है जैसे कि मर्ज (संशोधन नियंत्रण) के लिए गिट (सॉफ्टवेयर) फ़ाइलों के संशोधन-नियंत्रित संग्रह में कई बदलाव किए जाते हैं।
उदाहरण के लिए, अनुक्रमों (एबीसीडी) और (एसीबीएडी) पर विचार करें। उनकी 5 लंबाई-2 सामान्य अनुवर्ती हैं: (एबी), (एसी), (एडी), (बीडी), और (सीडी); 2 लंबाई-3 सामान्य अनुवर्ती: (एबीडी) और (एसीडी); और अब सामान्य अनुवर्ती नहीं हैं। अतः (ABD) और (ACD) उनके सबसे लंबे सामान्य अनुवर्ती हैं।
जटिलता
इनपुट अनुक्रमों की मनमानी संख्या के सामान्य मामले के लिए, समस्या एनपी कठिन है।[1] जब अनुक्रमों की संख्या स्थिर होती है, तो समस्या को गतिशील प्रोग्रामिंग द्वारा बहुपद समय में हल किया जा सकता है।
दिया गया लंबाई का क्रम , एक अनुभवहीन खोज प्रत्येक का परीक्षण करेगी पहले अनुक्रम के अनुवर्ती यह निर्धारित करने के लिए कि क्या वे शेष अनुक्रमों के भी अनुवर्ती हैं; प्रत्येक अनुवर्ती को शेष अनुक्रमों की लंबाई में रैखिक समय में परीक्षण किया जा सकता है, इसलिए इस एल्गोरिदम के लिए समय होगा
एन और एम तत्वों के दो अनुक्रमों के मामले में, गतिशील प्रोग्रामिंग दृष्टिकोण का चलने का समय बिग ओ अंकन (एन × एम) है।[2] इनपुट अनुक्रमों की एक मनमानी संख्या के लिए, गतिशील प्रोग्रामिंग दृष्टिकोण एक समाधान देता है
कम जटिलता वाली विधियाँ मौजूद हैं,[3] जो अक्सर एलसीएस की लंबाई, वर्णमाला के आकार या दोनों पर निर्भर करता है।
एलसीएस आवश्यक रूप से अद्वितीय नहीं है; सबसे खराब स्थिति में, इनपुट की लंबाई में सामान्य अनुवर्ती की संख्या घातीय होती है, इसलिए एल्गोरिथम जटिलता कम से कम घातीय होनी चाहिए।[4]
दो अनुक्रमों के लिए समाधान
एलसीएस समस्या में एक इष्टतम उप-संरचना होती है: समस्या को छोटे, सरल उप-समस्याओं में विभाजित किया जा सकता है, जो बदले में, सरल उप-समस्याओं में विभाजित किया जा सकता है, और इसी तरह, जब तक कि, अंततः, समाधान तुच्छ न हो जाए। एलसीएस में विशेष रूप से ओवरलैपिंग उपसमस्याएं होती हैं: उच्च-स्तरीय उप-समस्याओं के समाधान अक्सर निचले स्तर की उप-समस्याओं के समाधानों का पुन: उपयोग करते हैं। इन दो गुणों वाली समस्याएं गतिशील प्रोग्रामिंग दृष्टिकोण के लिए उत्तरदायी हैं, जिसमें उप-समस्या समाधान संस्मरण हैं, यानी, उप-समस्याओं के समाधान पुन: उपयोग के लिए सहेजे जाते हैं।
उपसर्ग
उपसर्ग एसn S को S के पहले n वर्णों के रूप में परिभाषित किया गया है।[5] उदाहरण के लिए, S = (AGCA) के उपसर्ग हैं
- एस0 = ()
- एस1 = (ए)
- एस2 = (एजी)
- एस3 = (एजीसी)
- एस4 = (एजीसीए).
मान लीजिए LCS(X, Y) एक ऐसा फ़ंक्शन है जो X और Y के लिए सामान्य सबसे लंबे अनुवर्ती की गणना करता है। ऐसे फ़ंक्शन में दो दिलचस्प गुण होते हैं।
पहली संपत्ति
LCS(X^A,Y^A) = LCS(X,Y)^A, सभी स्ट्रिंग X, Y और सभी प्रतीकों A के लिए, जहां ^ स्ट्रिंग संयोजन को दर्शाता है। यह एक ही प्रतीक में समाप्त होने वाले दो अनुक्रमों के लिए एलसीएस गणना को सरल बनाने की अनुमति देता है। उदाहरण के लिए, LCS( BANANA , ATANA ) = LCS( BANAN , ATAN )^ A , शेष सामान्य प्रतीकों के लिए जारी रखते हुए, LCS( BANANA , ATANA ) = LCS( BANAN , AT )^ ANA ।
दूसरा गुण
यदि A और B अलग-अलग प्रतीक (A≠B) हैं, तो सभी स्ट्रिंग X, Y के लिए LCS(X^A,Y^B) सेट { LCS(X^A,Y), LCS(X,Y^B) } में अधिकतम लंबाई वाली स्ट्रिंग में से एक है।
उदाहरण के लिए, एलसीएस (एबीसीडीईएफजी, बीसीडीजीके) एलसीएस (एबीसीडीईएफजी, बीसीडीजी) और एलसीएस (एबीसीडीईएफ, बीसीडीजीके) के बीच सबसे लंबी स्ट्रिंग है; यदि दोनों की लंबाई समान हो, तो उनमें से एक को मनमाने ढंग से चुना जा सकता है।
संपत्ति का एहसास करने के लिए, दो मामलों में अंतर करें:
- यदि एलसीएस(एबीसीडीईएफजी, बीसीडीजीके) जी के साथ समाप्त होता है, तो अंतिम के एलसीएस में नहीं हो सकता है, इसलिए एलसीएस(एबीसीडीईएफजी, बीसीडीजीके) = एलसीएस(एबीसीडीईएफजी, बीसीडीजी)।
- यदि LCS( ABCDEFG , BCDGK ) का अंत G पर नहीं होता है, तो अंतिम G LCS में नहीं हो सकता है, इसलिए LCS( ABCDEFG , BCDGK ) = LCS( ABCDEF , BCDGK ) है।
एलसीएस फ़ंक्शन परिभाषित
मान लीजिए कि दो अनुक्रमों को इस प्रकार परिभाषित किया गया है: और . के उपसर्ग हैं ; के उपसर्ग हैं . होने देना उपसर्गों के सबसे लंबे सामान्य अनुक्रम के सेट का प्रतिनिधित्व करें और . अनुक्रमों का यह सेट निम्नलिखित द्वारा दिया गया है।
का एलसीएस खोजने के लिए और , तुलना करना और . यदि वे बराबर हैं, तो क्रम उस तत्व द्वारा विस्तारित है, . यदि वे समान नहीं हैं, तो दोनों अनुक्रमों में से सबसे लंबा, , और , रोका गया है। (यदि उनकी लंबाई समान है, लेकिन समान नहीं है, तो दोनों को बरकरार रखा जाता है।) आधार मामला, जब दोनों में से कोई एक हो या खाली है, खाली स्ट्रिंग है, .
कार्य उदाहरण
R = (GAC), और C = (AGCAT) का सबसे लंबा अनुवर्ती सामान्य पाया जाएगा। क्योंकि LCS फ़ंक्शन एक शून्य तत्व का उपयोग करता है, इसलिए इन अनुक्रमों के लिए खाली शून्य उपसर्गों को परिभाषित करना सुविधाजनक है: आर0 = ε; और सी0 = ε. सभी उपसर्गों को पहली पंक्ति में C के साथ एक तालिका में रखा गया है (इसे एक column हेडर बनाते हुए) और R को पहले कॉलम में रखा गया है (इसे एक row हेडर बनाते हुए)।
ε | A | G | C | A | T | |
---|---|---|---|---|---|---|
ε | ε | ε | ε | ε | ε | ε |
G | ε | |||||
A | ε | |||||
C | ε |
इस तालिका का उपयोग गणना के प्रत्येक चरण के लिए एलसीएस अनुक्रम को संग्रहीत करने के लिए किया जाता है। दूसरे कॉलम और दूसरी पंक्ति को ε से भर दिया गया है, क्योंकि जब एक खाली अनुक्रम की तुलना एक गैर-रिक्त अनुक्रम से की जाती है, तो सबसे लंबा सामान्य अनुवर्ती हमेशा एक खाली अनुक्रम होता है।
एलसीएस(आर1, सी1) प्रत्येक अनुक्रम में पहले तत्वों की तुलना करके निर्धारित किया जाता है। जी और ए समान नहीं हैं, इसलिए इस एलसीएस को (दूसरी संपत्ति का उपयोग करके) दो अनुक्रमों में से सबसे लंबा एलसीएस (आर) मिलता है1, सी0) और एलसीएस(आर0, सी1). तालिका के अनुसार, ये दोनों खाली हैं, इसलिए LCS(R1, सी1) भी खाली है, जैसा कि नीचे दी गई तालिका में दिखाया गया है। तीर इंगित करते हैं कि अनुक्रम उपरोक्त दोनों सेल, LCS(R) से आता है0, सी1) और बाईं ओर की सेल, LCS(R1, सी0).
एलसीएस(आर1, सी2) जी और जी की तुलना करके निर्धारित किया जाता है। वे मेल खाते हैं, इसलिए जी को ऊपरी बाएँ अनुक्रम, एलसीएस (आर) में जोड़ा जाता है0, सी1), जो (ε) है, दे रहा है (εG), जो (G) है।
एलसीएस (आर) के लिए1, सी3), G और C मेल नहीं खाते। उपरोक्त क्रम खाली है; बायीं ओर वाले में एक तत्व G है। इनमें से सबसे लंबे तत्व LCS(R) का चयन करें1, सी3) (जी) है. तीर बाईं ओर इंगित करता है, क्योंकि वह दो अनुक्रमों में सबसे लंबा है।
एलसीएस(आर1, सी4), इसी तरह, (जी) है।
एलसीएस(आर1, सी5), इसी तरह, (जी) है।
ε | A | G | C | A | T | |
---|---|---|---|---|---|---|
ε | ε | ε | ε | ε | ε | ε |
G | ε | ε | (G) | (G) | (G) | (G) |
A | ε | |||||
C | ε |
एलसीएस (आर) के लिए2, सी1), ए की तुलना ए से की जाती है। दोनों तत्व मेल खाते हैं, इसलिए ए को ε में जोड़ा जाता है, जिससे (ए) मिलता है।
एलसीएस (आर) के लिए2, सी2), ए और जी मेल नहीं खाते हैं, इसलिए एलसीएस (आर) का सबसे लंबा हिस्सा1, सी2), जो (जी) है, और एलसीएस(आर) है2, सी1), जो (ए) है, का उपयोग किया जाता है। इस मामले में, उनमें से प्रत्येक में एक तत्व होता है, इसलिए इस एलसीएस को दो अनुवर्ती दिए गए हैं: (ए) और (जी)।
एलसीएस (आर) के लिए2, सी3), A, C से मेल नहीं खाता है। LCS(R2, सी2) में अनुक्रम (ए) और (जी) शामिल हैं; एलसीएस(आर1, सी3) (जी) है, जो पहले से ही एलसीएस(आर) में समाहित है2, सी2). परिणाम यह है कि LCS(R2, सी3) में दो अनुवर्ती, (ए) और (जी) भी शामिल हैं।
एलसीएस (आर) के लिए2, सी4), ए, ए से मेल खाता है, जो ऊपरी बाएँ सेल से जुड़ा हुआ है, जो (जीए) देता है।
एलसीएस (आर) के लिए2, सी5), A, T से मेल नहीं खाता है। दो अनुक्रमों, (GA) और (G) की तुलना करने पर, सबसे लंबा (GA) है, इसलिए LCS(R)2, सी5) (GA) है.
ε | A | G | C | A | T | |
---|---|---|---|---|---|---|
ε | ε | ε | ε | ε | ε | ε |
G | ε | ε | (G) | (G) | (G) | (G) |
A | ε | (A) | (A) & (G) | (A) & (G) | (GA) | (GA) |
C | ε |
एलसीएस (आर) के लिए3, सी1), सी और ए मेल नहीं खाते हैं, इसलिए एलसीएस(आर3, सी1) दो अनुक्रमों में से सबसे लंबा प्राप्त करता है, (ए)।
एलसीएस (आर) के लिए3, सी2), C और G मेल नहीं खाते। दोनों एलसीएस(आर3, सी1) और एलसीएस(आर2, सी2) एक तत्व है. परिणाम यह है कि LCS(R3, सी2) में दो अनुवर्ती, (ए) और (जी) शामिल हैं।
एलसीएस (आर) के लिए3, सी3), C और C मेल खाते हैं, इसलिए C को LCS(R) में जोड़ा जाता है2, सी2), जिसमें दो अनुवर्ती (ए) और (जी) शामिल हैं, जो (एसी) और (जीसी) देते हैं।
एलसीएस (आर) के लिए3, सी4), सी और ए मेल नहीं खाते। एलसीएस(आर) का संयोजन3, सी3), जिसमें (एसी) और (जीसी), और एलसीएस (आर) शामिल हैं2, सी4), जिसमें (जीए) शामिल है, कुल तीन अनुक्रम देता है: (एसी), (जीसी), और (जीए)।
अंत में, एलसीएस(आर) के लिए3, सी5), C और T मेल नहीं खाते। परिणाम यह है कि LCS(R3, सी5) में तीन अनुक्रम, (एसी), (जीसी), और (जीए) भी शामिल हैं।
ε | A | G | C | A | T | |
---|---|---|---|---|---|---|
ε | ε | ε | ε | ε | ε | ε |
G | ε | ε | (G) | (G) | (G) | (G) |
A | ε | (A) | (A) & (G) | (A) & (G) | (GA) | (GA) |
C | ε | (A) | (A) & (G) | (AC) & (GC) | (AC) & (GC) & (GA) | (AC) & (GC) & (GA) |
अंतिम परिणाम यह है कि अंतिम सेल में (एजीसीएटी) और (जीएसी) के सभी सबसे लंबे अनुवर्ती सामान्य शामिल हैं; ये हैं (एसी), (जीसी), और (जीए)। तालिका उपसर्गों की प्रत्येक संभावित जोड़ी के लिए सबसे लंबे समय तक सामान्य अनुवर्ती भी दिखाती है। उदाहरण के लिए, (एजीसी) और (जीए) के लिए, सबसे लंबे सामान्य अनुवर्ती (ए) और (जी) हैं।
ट्रेसबैक दृष्टिकोण
एलसीएस तालिका की एक पंक्ति के एलसीएस की गणना के लिए केवल वर्तमान पंक्ति और पिछली पंक्ति के समाधान की आवश्यकता होती है। फिर भी, लंबे अनुक्रमों के लिए, ये क्रम असंख्य और लंबे हो सकते हैं, जिसके लिए बहुत अधिक संग्रहण स्थान की आवश्यकता होती है। भंडारण स्थान को वास्तविक अनुवर्ती को नहीं, बल्कि अनुवर्ती की लंबाई और तीरों की दिशा को सहेजकर बचाया जा सकता है, जैसा कि नीचे दी गई तालिका में है।
ε | A | G | C | A | T | |
---|---|---|---|---|---|---|
ε | 0 | 0 | 0 | 0 | 0 | 0 |
G | 0 | 0 | 1 | 1 | 1 | 1 |
A | 0 | 1 | 1 | 1 | 2 | 2 |
C | 0 | 1 | 1 | 2 | 2 | 2 |
वास्तविक अनुवर्ती ट्रेसबैक प्रक्रिया में निकाले जाते हैं जो तालिका में अंतिम सेल से शुरू होकर पीछे की ओर तीरों का अनुसरण करती है। जब लंबाई घटती है, तो अनुक्रमों में एक सामान्य तत्व होना चाहिए। जब एक सेल में दो तीर दिखाए जाते हैं तो कई पथ संभव होते हैं। नीचे इस तरह के विश्लेषण के लिए तालिका दी गई है, जिसमें उन कोशिकाओं में रंगीन संख्याएं हैं जहां लंबाई घटने वाली है। बोल्ड संख्याएँ अनुक्रम (जीए) का पता लगाती हैं।[6]
ε | A | G | C | A | T | |
---|---|---|---|---|---|---|
ε | 0 | 0 | 0 | 0 | 0 | 0 |
G | 0 | 0 | 1 | 1 | 1 | 1 |
A | 0 | 1 | 1 | 1 | 2 | 2 |
C | 0 | 1 | 1 | 2 | 2 | 2 |
अन्य समस्याओं से संबंध
दो तारों के लिए और , सबसे छोटी सामान्य सुपरसीक्वेंस समस्या की लंबाई एलसीएस की लंबाई से संबंधित है[3]
जब केवल सम्मिलन और विलोपन की अनुमति है (कोई प्रतिस्थापन नहीं), या जब प्रतिस्थापन की लागत सम्मिलन या विलोपन की लागत से दोगुनी है, तो संपादन दूरी है:
गतिशील प्रोग्रामिंग समाधान के लिए कोड
This section does not cite any sources. (March 2013) (Learn how and when to remove this template message) |
एलसीएस की लंबाई की गणना
नीचे दिया गया फ़ंक्शन इनपुट अनुक्रम के रूप में लेता है X[1..m]
और Y[1..n]
, के बीच एलसीएस की गणना करता है X[1..i]
और Y[1..j]
सभी के लिए 1 ≤ i ≤ m
और 1 ≤ j ≤ n
, और इसे संग्रहीत करता है C[i,j]
. C[m,n]
की एलसीएस की लंबाई शामिल होगी X
और Y
.[7]
फ़ंक्शन LCSLength(X[1..m], Y[1..n])
सी = सरणी(0..एम, 0..एन) i के लिए := 0..m सी[i,0] = 0 j के लिए := 0..n सी[0,जे] = 0 मेरे लिए := 1..मी j के लिए := 1..n यदि X[i] = Y[j] सी[आई,जे] := सी[आई-1,जे-1] + 1 अन्य सी[आई,जे] := अधिकतम(सी[आई,जे-1], सी[आई-1,जे]) वापसी सी[एम,एन]
वैकल्पिक रूप से, संस्मरण का उपयोग किया जा सकता है।
====सी#==== में उदाहरण
static int LcsLength(string a, string b)
{
int m = a.Length;
int n = b.Length;
int[,] C = new int[m + 1, n + 1];
for (int i = 0; i <= m; i++)
C[i, 0] = 0;
for (int j = 0; j <= n; j++)
C[0, j] = 0;
for (int i = 1; i <= m; i++)
for (int j = 1; j <= n; j++)
{
if (a[i - 1] == b[j - 1])
C[i, j] = C[i - 1, j - 1] + 1;
else
C[i, j] = Math.Max(C[i, j - 1], C[i - 1, j]);
}
return C[m, n];
}
एलसीएस पढ़ना
निम्नलिखित फ़ंक्शन गणना करते समय लिए गए विकल्पों को बैक ट्रैकिंग करता है C
मेज़। यदि उपसर्गों में अंतिम वर्ण समान हैं, तो उन्हें LCS में होना चाहिए। यदि नहीं, तो जांचें कि किस चीज़ ने रखने का सबसे बड़ा एलसीएस दिया और , और वही चुनाव करें। यदि वे समान रूप से लंबे हों तो बस एक चुनें। फ़ंक्शन को कॉल करें i=m
और j=n
.
फ़ंक्शन बैकट्रैक (C[0..m,0..n], X[1..m], Y[1..n], i, j) यदि मैं = 0 या जे = 0 वापस करना यदि X[i] = Y[j] बैकट्रैक लौटें (सी, एक्स, वाई, आई-1, जे-1) + एक्स[आई] यदि C[i,j-1] > C[i-1,j] बैकट्रैक लौटें (सी, एक्स, वाई, आई, जे-1) बैकट्रैक लौटें (सी, एक्स, वाई, आई-1, जे)
====सी#==== में उदाहरण
string backtrack(int[,] C, char[] aStr, char[] bStr, int x, int y)
{
if (x == 0 | y == 0)
return "";
if (aStr[x - 1] == bStr[y - 1]) // x-1, y-1
return backtrack(C, aStr, bStr, x - 1, y - 1) + aStr[x - 1]; // x-1
if (C[x, y - 1] > C[x - 1, y])
return backtrack(C, aStr, bStr, x, y - 1);
return backtrack(C, aStr, bStr, x - 1, y);
}
सभी एलसीएस को पढ़ना
अगर चुन रहे हैं और समान रूप से लंबा परिणाम देगा, दोनों परिणामी अनुवर्ती पढ़ें। इसे इस फ़ंक्शन द्वारा एक सेट के रूप में लौटाया जाता है। ध्यान दें कि यह फ़ंक्शन बहुपद नहीं है, क्योंकि यदि तार समान हैं तो यह लगभग हर चरण में शाखाबद्ध हो सकता है।
फ़ंक्शन बैकट्रैकऑल(C[0..m,0..n], X[1..m], Y[1..n], i, j) यदि मैं = 0 या जे = 0 वापस करना { } यदि X[i] = Y[j] बैकट्रैकऑल में सभी Z के लिए {Z + X[i] लौटाएं(C, X, Y, i-1, j-1)} आर := {} यदि C[i,j-1] ≥ C[i-1,j] आर := बैकट्रैकऑल(सी, एक्स, वाई, आई, जे-1) यदि C[i-1,j] ≥ C[i,j-1] आर := आर ∪ बैकट्रैकऑल(सी, एक्स, वाई, आई-1, जे) वापसी आर
अंतर प्रिंट करें
यह फ़ंक्शन सी मैट्रिक्स के माध्यम से बैकट्रैक करेगा, और दो अनुक्रमों के बीच अंतर को प्रिंट करेगा। ध्यान दें कि यदि आप आदान-प्रदान करते हैं तो आपको एक अलग उत्तर मिलेगा ≥
और <
, साथ >
और ≤
नीचे।
फ़ंक्शन printDiff(C[0..m,0..n], X[1..m], Y[1..n], i, j) यदि i >= 0 और j >= 0 और X[i] = Y[j] प्रिंटडिफ (सी, एक्स, वाई, आई-1, जे-1) प्रिंट + एक्स[i] अन्यथा यदि j > 0 और (i = 0 या C[i,j-1] ≥ C[i-1,j]) प्रिंटडिफ (सी, एक्स, वाई, आई, जे-1) प्रिंट + + वाई[जे] अन्यथा यदि i > 0 और (j = 0 या C[i,j-1] < C[i-1,j]) प्रिंटडिफ (सी, एक्स, वाई, आई-1, जे) प्रिंट - + एक्स[i] अन्य छपाई
उदाहरण
होने देना होना "XMJYAUZ
" और होना "MZJAWXU
”। के बीच सबसे लंबा सामान्य अनुवर्ती और है "MJAU
”। टेबल C
नीचे दिखाया गया है, जो फ़ंक्शन द्वारा उत्पन्न होता है LCSLength
, के उपसर्गों के बीच सबसे लंबे सामान्य अनुवर्ती की लंबाई दिखाता है और . वें>वें पंक्ति और वां कॉलम बीच में एलसीएस की लंबाई दिखाता है और .
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ||
---|---|---|---|---|---|---|---|---|---|
ε | M | Z | J | A | W | X | U | ||
0 | ε | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | X | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
2 | M | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
3 | J | 0 | 1 | 1 | 2 | 2 | 2 | 2 | 2 |
4 | Y | 0 | 1 | 1 | 2 | 2 | 2 | 2 | 2 |
5 | A | 0 | 1 | 1 | 2 | 3 | 3 | 3 | 3 |
6 | U | 0 | 1 | 1 | 2 | 3 | 3 | 3 | 4 |
7 | Z | 0 | 1 | 2 | 2 | 3 | 3 | 3 | 4 |
हाइलाइट नंबर फ़ंक्शन का पथ दिखाते हैं backtrack
एलसीएस पढ़ते समय, नीचे दाएं से ऊपरी बाएं कोने तक चलेगा। यदि वर्तमान प्रतीकों में और बराबर हैं, वे एलसीएस का हिस्सा हैं, और हम ऊपर और बाएं दोनों तरफ जाते हैं (बोल्ड में दिखाया गया है)। यदि नहीं, तो हम ऊपर या बाएँ जाते हैं, यह इस बात पर निर्भर करता है कि किस सेल की संख्या अधिक है। यह या तो एलसीएस को बीच में लेने से मेल खाता है और , या और .
कोड अनुकूलन
वास्तविक दुनिया के मामलों के लिए इसे तेज़ करने के लिए उपरोक्त एल्गोरिदम में कई अनुकूलन किए जा सकते हैं।
समस्या सेट कम करें
अनुभवहीन एल्गोरिथ्म में सी मैट्रिक्स अनुक्रमों की लंबाई के साथ द्विघात वृद्धि। दो 100-आइटम अनुक्रमों के लिए, 10,000-आइटम मैट्रिक्स की आवश्यकता होगी, और 10,000 तुलनाएँ करने की आवश्यकता होगी। अधिकांश वास्तविक दुनिया के मामलों में, विशेष रूप से स्रोत कोड अंतर और पैच में, फ़ाइलों की शुरुआत और अंत शायद ही कभी बदलते हैं, और लगभग निश्चित रूप से एक ही समय में दोनों नहीं। यदि अनुक्रम के बीच में केवल कुछ आइटम बदले गए हैं, तो शुरुआत और अंत को हटाया जा सकता है। इससे न केवल मैट्रिक्स के लिए मेमोरी आवश्यकताएं कम हो जाती हैं, बल्कि तुलनाओं की संख्या भी कम हो जाती है।
फ़ंक्शन LCS(X[1..m], Y[1..n]) प्रारंभ := 1 m_end := m n_end := n शुरुआत में मेल खाने वाली वस्तुओं को काट दें जबकि प्रारंभ ≤ m_end और प्रारंभ ≤ n_end और X[प्रारंभ] = Y[प्रारंभ] प्रारंभ := प्रारंभ + 1 अंत में मेल खाने वाली वस्तुओं को काट दें जबकि प्रारंभ ≤ m_end और प्रारंभ ≤ n_end और X[m_end] = Y[n_end] m_end := m_end - 1 n_end := n_end - 1 सी = सरणी(प्रारंभ-1..एम_एंड, प्रारंभ-1..एन_एंड) केवल उन आइटमों पर लूप करें जो बदल गए हैं मेरे लिए := प्रारंभ..m_end j के लिए := प्रारंभ..n_end एल्गोरिदम पहले की तरह जारी है...
सर्वोत्तम स्थिति में, बिना किसी बदलाव वाले अनुक्रम में, यह अनुकूलन सी मैट्रिक्स की आवश्यकता को समाप्त कर देगा। सबसे खराब स्थिति में, अनुक्रम में सबसे पहले और आखिरी आइटम में बदलाव के बाद केवल दो अतिरिक्त तुलनाएं की जाती हैं।
तुलना समय कम करें
अनुभवहीन एल्गोरिथ्म द्वारा लिया गया अधिकांश समय अनुक्रमों में वस्तुओं के बीच तुलना करने में व्यतीत होता है। स्रोत कोड जैसे पाठ्य अनुक्रमों के लिए, आप पंक्तियों को एकल वर्णों के बजाय अनुक्रम तत्वों के रूप में देखना चाहते हैं। इसका मतलब एल्गोरिदम में प्रत्येक चरण के लिए अपेक्षाकृत लंबी स्ट्रिंग की तुलना हो सकता है। दो अनुकूलन किए जा सकते हैं जो इन तुलनाओं में लगने वाले समय को कम करने में मदद कर सकते हैं।
स्ट्रिंग्स को हैश में कम करें
अनुक्रमों में स्ट्रिंग के आकार को कम करने के लिए हैश फंकशन या अंततः, का उपयोग किया जा सकता है। अर्थात्, स्रोत कोड के लिए जहां औसत पंक्ति 60 या अधिक वर्ण लंबी है, उस पंक्ति के लिए हैश या चेकसम केवल 8 से 40 वर्ण लंबा हो सकता है। इसके अतिरिक्त, हैश और चेकसम की यादृच्छिक प्रकृति यह गारंटी देगी कि तुलना तेजी से शॉर्ट-सर्किट होगी, क्योंकि शुरुआत में स्रोत कोड की लाइनें शायद ही कभी बदली जाएंगी।
इस अनुकूलन में तीन प्राथमिक कमियाँ हैं। सबसे पहले, दो अनुक्रमों के लिए हैश की पूर्व-गणना करने के लिए पहले से ही काफी समय खर्च करने की आवश्यकता होती है। दूसरा, नए हैशेड अनुक्रमों के लिए अतिरिक्त मेमोरी आवंटित करने की आवश्यकता है। हालाँकि, यहाँ उपयोग किए गए सरल एल्गोरिदम की तुलना में, ये दोनों कमियाँ अपेक्षाकृत न्यूनतम हैं।
तीसरा दोष हैश टकराव का है। चूंकि चेकसम या हैश के अद्वितीय होने की गारंटी नहीं है, इसलिए इस बात की बहुत कम संभावना है कि दो अलग-अलग आइटमों को एक ही हैश में घटाया जा सकता है। स्रोत कोड में इसकी संभावना नहीं है, लेकिन यह संभव है। इसलिए एक क्रिप्टोग्राफ़िक हैश इस अनुकूलन के लिए कहीं अधिक उपयुक्त होगा, क्योंकि इसकी एन्ट्रॉपी एक साधारण चेकसम की तुलना में काफी अधिक होगी। हालाँकि, लाभ छोटी अनुक्रम लंबाई के लिए क्रिप्टोग्राफ़िक हैश की सेटअप और कम्प्यूटेशनल आवश्यकताओं के लायक नहीं हो सकते हैं।
आवश्यक स्थान कम करें
यदि केवल एलसीएस की लंबाई की आवश्यकता है, तो मैट्रिक्स को कम किया जा सकता है मैट्रिक्स, या करने के लिए एक गतिशील प्रोग्रामिंग दृष्टिकोण के रूप में वेक्टर को मैट्रिक्स के केवल वर्तमान और पिछले कॉलम की आवश्यकता होती है। हिर्शबर्ग का एल्गोरिदम समान द्विघात समय और रैखिक स्थान सीमा में ही इष्टतम अनुक्रम के निर्माण की अनुमति देता है।[8]
कैश छूट को कम करें
चौधरी और रामचंद्रन ने एक द्विघात-समय रैखिक-अंतरिक्ष एल्गोरिदम तैयार किया[9][10] एक इष्टतम अनुक्रम के साथ एलसीएस लंबाई खोजने के लिए जो अपने बेहतर कैश प्रदर्शन के कारण व्यवहार में हिर्शबर्ग के एल्गोरिदम से तेज़ चलता है।[9] कैश-ओब्लिवियस#आदर्शीकृत कैश मॉडल के तहत एल्गोरिदम में एक असम्बद्ध रूप से इष्टतम कैश जटिलता है।[11] दिलचस्प बात यह है कि एल्गोरिथ्म स्वयं कैश-अनभिज्ञ है[11]इसका मतलब यह है कि यह मशीन के कैश पैरामीटर (उदाहरण के लिए, कैश आकार और कैश लाइन आकार) के आधार पर कोई विकल्प नहीं बनाता है।
आगे अनुकूलित एल्गोरिदम
कई एल्गोरिदम मौजूद हैं जो प्रस्तुत गतिशील प्रोग्रामिंग दृष्टिकोण से तेज़ चलते हैं। उनमें से एक हंट-स्ज़िमंस्की एल्गोरिदम है, जो आम तौर पर चलता है के लिए समय ), कहाँ दो अनुक्रमों के बीच मिलान की संख्या है।[12] सीमित वर्णमाला आकार की समस्याओं के लिए, चार रूसी की विधि का उपयोग लॉगरिदमिक कारक द्वारा गतिशील प्रोग्रामिंग एल्गोरिदम के चलने के समय को कम करने के लिए किया जा सकता है।[13]
यादृच्छिक तारों पर व्यवहार
इसके साथ शुरुआत Chvátal & Sankoff (1975) ,[14] कई शोधकर्ताओं ने सबसे लंबी सामान्य अनुवर्ती लंबाई के व्यवहार की जांच की है जब दो दिए गए तार एक ही वर्णमाला से यादृच्छिक रूप से खींचे जाते हैं। जब वर्णमाला का आकार स्थिर होता है, तो एलसीएस की अपेक्षित लंबाई दो तारों की लंबाई के समानुपाती होती है, और आनुपातिकता के स्थिरांक (वर्णमाला के आकार के आधार पर) च्वाटल-सैंकॉफ स्थिरांक के रूप में जाने जाते हैं। उनके सटीक मूल्य ज्ञात नहीं हैं, लेकिन उनके मूल्यों की ऊपरी और निचली सीमाएं सिद्ध हो चुकी हैं,[15] और यह ज्ञात है कि वे वर्णमाला के आकार के वर्गमूल के विपरीत आनुपातिक रूप से बढ़ते हैं।[16] सबसे लंबी सामान्य अनुवर्ती समस्या के सरलीकृत गणितीय मॉडल को ट्रेसी-विडोम वितरण द्वारा नियंत्रित दिखाया गया है।[17]
यह भी देखें
- सबसे लंबे समय तक बढ़ने वाला क्रम
- सबसे लंबा वैकल्पिक क्रम
- लेवेनशेटिन दूरी
संदर्भ
- ↑ David Maier (1978). "परवर्ती और अतिपरवर्ती पर कुछ समस्याओं की जटिलता". J. ACM. ACM Press. 25 (2): 322–336. doi:10.1145/322063.322075. S2CID 16120634.
- ↑ Wagner, Robert; Fischer, Michael (January 1974). "स्ट्रिंग-टू-स्ट्रिंग सुधार समस्या". Journal of the ACM. 21 (1): 168–173. CiteSeerX 10.1.1.367.5281. doi:10.1145/321796.321811. S2CID 13381535.
- ↑ 3.0 3.1
L. Bergroth and H. Hakonen and T. Raita (2000). "A survey of longest common subsequence algorithms". Proceedings Seventh International Symposium on String Processing and Information Retrieval. SPIRE 2000. pp. 39–48. doi:10.1109/SPIRE.2000.878178. ISBN 0-7695-0746-8. S2CID 10375334.
{{cite book}}
:|journal=
ignored (help) - ↑ Ronald I. Greenberg (2003-08-06). "सबसे लंबे सामान्य अनुवर्ती की संख्या पर सीमा". arXiv:cs.DM/0301030.
- ↑ Xia, Xuhua (2007). Bioinformatics and the Cell: Modern Computational Approaches in Genomics, Proteomics and Transcriptomics. New York: Springer. p. 24. ISBN 978-0-387-71336-6.
- ↑ Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest and Clifford Stein (2001). "15.4". एल्गोरिदम का परिचय (2nd ed.). MIT Press and McGraw-Hill. pp. 350–355. ISBN 0-262-53196-8.
{{cite book}}
: CS1 maint: multiple names: authors list (link) - ↑ Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford (2009) [1990]. "Dynamic Programming". Introduction to Algorithms (3rd ed.). MIT Press and McGraw-Hill. p. 394. ISBN 0-262-03384-4.
- ↑ Hirschberg, D. S. (1975). "अधिकतम सामान्य अनुवर्ती की गणना के लिए एक रैखिक अंतरिक्ष एल्गोरिदम". Communications of the ACM. 18 (6): 341–343. doi:10.1145/360825.360861. S2CID 207694727.
- ↑ 9.0 9.1 Chowdhury, Rezaul; Ramachandran, Vijaya (January 2006). "कैश-विस्मृत गतिशील प्रोग्रामिंग". Proceedings of the Seventeenth Annual ACM-SIAM Symposium on Discrete Algorithm (SODA): 591–600. doi:10.1145/1109557.1109622. ISBN 0898716055. S2CID 9650418.
- ↑ Chowdhury, Rezaul; Le, Hai-Son; Ramachandran, Vijaya (July 2010). "जैव सूचना विज्ञान के लिए कैश-विस्मृत गतिशील प्रोग्रामिंग". IEEE/ACM Transactions on Computational Biology and Bioinformatics (TCBB). 7 (3): 495–510. doi:10.1109/TCBB.2008.94. PMID 20671320. S2CID 2532039.
- ↑ 11.0 11.1 Frigo, Matteo; Leiserson, Charles E.; Prokop, Harald; Ramachandran, Sridhar (January 2012). "कैश-विस्मृत एल्गोरिदम". ACM Transactions on Algorithms. 8 (1): 1–22. doi:10.1145/2071379.2071383.
- ↑ Apostolico, Alberto; Galil, Zvi (1997-05-29). पैटर्न मिलान एल्गोरिदम. ISBN 9780195354348.
- ↑ Masek, William J.; Paterson, Michael S. (1980), "A faster algorithm computing string edit distances", Journal of Computer and System Sciences, 20 (1): 18–31, doi:10.1016/0022-0000(80)90002-1, MR 0566639.
- ↑ Chvatal, Václáv; Sankoff, David (1975), "Longest common subsequences of two random sequences", Journal of Applied Probability, 12 (2): 306–315, doi:10.2307/3212444, JSTOR 3212444, MR 0405531, S2CID 250345191.
- ↑ Lueker, George S. (2009), "Improved bounds on the average length of longest common subsequences", Journal of the ACM, 56 (3), A17, doi:10.1145/1516512.1516519, MR 2536132, S2CID 7232681.
- ↑ Kiwi, Marcos; Loebl, Martin; Matoušek, Jiří (2005), "Expected length of the longest common subsequence for large alphabets", Advances in Mathematics, 197 (2): 480–498, arXiv:math/0308234, doi:10.1016/j.aim.2004.10.012, MR 2173842.
- ↑ Majumdar, Satya N.; Nechaev, Sergei (2005), "Exact asymptotic results for the Bernoulli matching model of sequence alignment", Physical Review E, 72 (2): 020901, 4, arXiv:q-bio/0410012, Bibcode:2005PhRvE..72b0901M, doi:10.1103/PhysRevE.72.020901, MR 2177365, PMID 16196539, S2CID 11390762.
बाहरी संबंध
- Dictionary of Algorithms and Data Structures: longest common subsequence
- A collection of implementations of the longest common subsequence in many programming languages
- Find Longest Common Subsequence in Python