फास्ट के बेमेल स्ट्रिंग मिलान एल्गोरिथ्म


10

मैं एक तेज k- बेमेल स्ट्रिंग मिलान एल्गोरिथ्म की तलाश कर रहा हूं। लंबाई मीटर के एक पैटर्न स्ट्रिंग पी, और लंबाई n के एक पाठ स्ट्रिंग टी को देखते हुए, मुझे उन सभी पदों को खोजने के लिए एक तेज (रैखिक समय) एल्गोरिथ्म की आवश्यकता होती है जहां पी सबसे के बेमेल के साथ टी के एक विकल्प से मेल खाता है। यह के-डिफरेंस प्रॉब्लम (एडिट डिस्टेंस) से अलग है। एक बेमेल का अर्थ है सबस्ट्रिंग और पैटर्न का अधिकांश के पदों पर एक अलग अक्षर है। मुझे वास्तव में केवल k = 1 (अधिकतम 1 बेमेल) की आवश्यकता है, इसलिए k = 1 के विशिष्ट मामले के लिए एक तेज़ एल्गोरिथम भी पर्याप्त होगा। वर्णमाला का आकार 26 है (केस-असंवेदनशील अंग्रेजी पाठ), इसलिए अंतरिक्ष की आवश्यकता को वर्णमाला के आकार के साथ बहुत तेजी से नहीं बढ़ना चाहिए (उदाहरण के लिए, FAAST एल्गोरिथ्म, मेरा मानना ​​है, वर्णमाला के आकार में अंतरिक्ष घातीय लेता है, और इसी तरह) केवल प्रोटीन और जीन अनुक्रमों के लिए उपयुक्त है)।

एक गतिशील प्रोग्रामिंग आधारित दृष्टिकोण सबसे खराब स्थिति में ओ (एमएन) होगा, जो बहुत धीमा होगा। मेरा मानना ​​है कि इसके लिए बोयर-मूर एल्गोरिदम के संशोधन हैं, लेकिन मैं ऐसे कागजों पर अपना हाथ नहीं डाल पा रहा हूं। मेरे पास अकादमिक पत्रिकाओं या प्रकाशनों तक पहुंचने के लिए सदस्यता नहीं है, इसलिए किसी भी संदर्भ को सार्वजनिक डोमेन में होना चाहिए।

मैं इस समस्या के लिए किसी भी संकेत या स्वतंत्र रूप से उपलब्ध दस्तावेजों, या एल्गोरिथ्म के संदर्भ में बहुत सराहना करता हूं।


2
यदि पैटर्न तय हो गया है (लेकिन मिलान करने के लिए पाठ भिन्न होता है), तो आप संभवतः एक परिमित ऑटोमेटन बना सकते हैं और उसी के माध्यम से पाठ को चला सकते हैं। प्रत्यय वृक्षों का उपयोग करते हुए एल्गोरिदम भी हैं (आमतौर पर अच्छा है यदि पाठ स्थिर है और पैटर्न भिन्न होता है, लेकिन यह भी लागू होता है यदि दोनों अलग-अलग होते हैं), तो आप वेब पर कुछ संदर्भ ढूंढने में सक्षम हो सकते हैं। (अभी तक कोई जवाब नहीं जोड़ना क्योंकि मुझे प्रत्यय ट्री आधारित एल्गोरिदम का बहुत यकीन नहीं है, अगर कोई जानता है कि कृपया इस टिप्पणी को अनदेखा करने के लिए स्वतंत्र महसूस करें)।
आर्यभट्ट

@ आर्यभट्ट धन्यवाद! पैटर्न और पाठ दोनों बदलते हैं। उस संदर्भ में, एक परिमित ऑटोमेटन का निर्माण बहुत महंगा होगा, खासकर जब 1 बेमेल के लिए गुंजाइश शामिल हो। प्रत्यय वृक्षों / प्रत्यय सरणियों के लिए, मैंने कभी उनका उपयोग नहीं किया है, और उनके बारे में बहुत कम जानते हैं, लेकिन इस धारणा के तहत कि वे निर्माण के लिए धीमा हैं और मुख्य रूप से सटीक मिलान के लिए कुशल हैं। लेकिन मैं इस विकल्प का और विस्तार करूंगा। इस दिशा में कोई संकेत, या किसी अन्य दिशा में सबसे उपयोगी होगा!
परेश

1
नहीं, प्रत्यय पेड़ों का उपयोग अनुमानित मैचों के लिए भी किया जा सकता है। कम से कम विकी का दावा है: en.wikipedia.org/wiki/Suffix_tree
आर्यभट्ट

जवाबों:


5

इस समस्या के लिए प्रत्यय सरणियों का उपयोग किया जा सकता है। वे लेक्सिकोग्राफ़िक क्रम में छाँटे गए स्ट्रिंग के प्रत्येक प्रत्यय के शुरुआती पदों को समाहित करते हैं। भले ही वे जटिलता में भोलेपन से निर्मित किए जा सकते हैं , फिर भी उन्हें निर्माण करने के तरीके हैं in जटिलता। उदाहरण के लिए देखें यह और यह । हमें इस प्रत्यय सरणी SA कहते हैं।Θ ( n )O(nlogn)Θ(n)

प्रत्यय सरणी का निर्माण हो जाने के बाद, हमें प्रत्यय सरणी के लिए एक सबसे लंबी कॉमन प्रीफ़िक्स (LCP) सरणी बनाने की आवश्यकता है। LCP सरणी प्रत्यय सरणी (lexicographic लगातार प्रत्ययों) में दो लगातार उपसर्गों के बीच सबसे लंबे सामान्य उपसर्ग की लंबाई संग्रहीत करता है। इस प्रकार, LCP [i] में SA [i] और SA [i + 1] के बीच सबसे लंबे आम उपसर्ग की लंबाई है। इस सरणी का निर्माण रैखिक समय में भी किया जा सकता है: कुछ अच्छे संदर्भों के लिए यहां , यहां और यहां देखें ।

अब, प्रत्यय के पेड़ में किसी भी दो प्रत्ययों के लिए सबसे लंबे समय तक उपसर्ग की लंबाई की गणना करने के लिए (लगातार प्रत्ययों के बजाय), हमें कुछ आरएमक्यू डेटा संरचना का उपयोग करने की आवश्यकता है । यह ऊपर दिए गए संदर्भों में दिखाया गया है (और आसानी से देखा जा सकता है यदि सरणी को एक प्रत्यय के पेड़ के रूप में कल्पना की जाती है), कि प्रत्यय सरणी में और ( ) वाले दो प्रत्ययों के बीच सबसे लंबे आम उपसर्ग की लंबाई है , रूप में प्राप्त किया जा सकता है । एक अच्छा RMQ या समय में सरणी को प्री-प्रोसेस कर सकता है और में फॉर्म के प्रश्नों का जवाब देता है।v u < v m i n u < = k < = v - 1 L C P [ k ] L C P O ( n ) O ( n log n ) L C P [ u , v ] O ( 1 )uvu<vminu<=k<=v1LCP[k]LCPO(n)O(nlogn)LCP[u,v]O(1)समय। देखें यहाँ एक लधु RMQ एल्गोरिथ्म के लिए, और यहाँ RMQ के पर एक अच्छा ट्यूटोरियल, और रिश्ते (और कटौती) एलसीए और RMQs के बीच के लिए। यह एक और अच्छा विकल्प है।

इस जानकारी के साथ, हम बीच में एक सीमांकक (जैसे कि टी # पी, जहां '#' या तो स्ट्रिंग में नहीं होता है) के साथ दो तारों के संघात के लिए प्रत्यय सरणी और संबंधित सरणियों (जैसा कि ऊपर वर्णित है) का निर्माण करते हैं। फिर, हम "कंगारू" पद्धति का उपयोग करके k बेमेल स्ट्रिंग मिलान कर सकते हैं। यह और यह प्रत्यय पेड़ों के संदर्भ में कंगारू विधि की व्याख्या करता है, लेकिन सीधे प्रत्यय सरणियों पर भी लागू किया जा सकता है। टेक्स्ट के हर इंडेक्स के लिए , से शुरू होने वाले के प्रत्यय का और का प्रत्यय 0. पर शुरू होता है। यह स्थान देता है जिसके बाद मिलान करते समय पहला बेमेल होता है।iएल सी पी टी मैं पी पी टी [ मैं ] एल 0 टी पी एल सी पी टी [ मैं + एल 0 + 1 ]TLCPTiPPसाथ । इस लंबाई को होने । और दोनों में बेमेल चरित्र को छोड़ दें और शेष तारों का मिलान करने का प्रयास करें। यही है, फिर से और का खोजें । इसे तब तक दोहराएं जब तक आप बेमेल प्राप्त नहीं करते, या तो स्ट्रिंग फ़िनिश करते हैं। प्रत्येक है । कर रहे हैं 'प्रत्येक सूचकांक के लिए है की , इस की कुल जटिलता दे रही ।T[i]l0TPLCPT[i+l0+1]P[l0+1]kLCPO(1)O(k) LCPiTO(nk)

O ( n k + n लॉग एन ) m = O ( n )O(nk+(n+m)log(n+m))O(nk+nlogn)m=O(n)O(nk)


महान! मैं अपनी TODO सूची पर अब कुछ पढ़ने लगा हूं :-)
आर्यभट्ट

दूसरे पैराग्राफ में siam.org लिंक टूटा हुआ है, लेकिन लिंक किया गया पेपर यहां पाया जा सकता है epubs.siam.org/doi/pdf/10.1137/1.9781611972917.3
leecbaker

4

O(n+m)kO(nk+m)

विचार सटीक स्थानापन्न मैचों के लिए राबिन-कार्प रोलिंग हैश एल्गोरिथम के समान है ।

m2km/2k2k2k

k

k

मैं उम्मीद करता हूं (कैविएट: खुद इसे आजमाया नहीं गया है) यह शायद व्यवहार में तेजी से होगा, और शायद प्रत्यय ट्री आधारित दृष्टिकोण का उपयोग करने की तुलना में कोड को बनाए रखने / बनाए रखने में आसान होगा।


बस एक स्पष्टीकरण की जरूरत है। द्वारा ".. लंबाई के प्रत्येक तार को m / 2k आकार के 2k खंडों में m में विभाजित करें ...", आपका मतलब है कि लंबाई के प्रत्येक प्रतिस्थापन को T (लंबाई n) के 2k खंडों में अलग करें। और इस हैश की गणना रोलिंग हैश विधि द्वारा O (n) में की जा सकती है। फिर, पैटर्न स्ट्रिंग को 2k ब्लॉकों में भी विभाजित किया जाएगा, और इसी हैश की तुलना की जाएगी, जिससे अधिकतम k ब्लॉकों को बेमेल करने के लिए भत्ता दिया जा सके। यदि ऐसा है, तो हम उन सभी मामलों को संभावित रूप से त्यागने में सक्षम होंगे जहां बेमेल की संख्या k से अधिक है। क्या मैंने सही समझा?
परेश

kΩ(nk)O(n)

मुझे यह तरीका पसंद है! फिर भी, यह दृष्टिकोण सामान्य रूप से तेज़ है, लेकिन मेल की संख्या अधिक होने पर O (mnk) में गिरावट आती है (O (n) मैच)। इसे ध्यान में रखते हुए, मैंने दो रोलिंग हैश बनाए रखा, इस धारणा के तहत कि दोनों एक ही इनपुट के लिए टकराव नहीं कर सकते हैं (मैं यह गणितीय रूप से नहीं करता था क्योंकि मैं गति देखना चाहता था)। इस तरह, अगर हम दो हैश सहमत होते हैं तो हमें एक मैच चार-चार-चार सत्यापित करने की आवश्यकता नहीं है। यह सामान्य रूप से बहुत तेज है, लेकिन यह बहुत धीमा है अगर मैचों की संख्या बड़ी है। इसके साथ और जिस तरह से आपने सुझाव दिया, वह बड़े मैचों के लिए धीमा था।
परेश 10

mm/2kmO(nkm)

mm/2k2kk+1k+cΩ(nm)mm/2k
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.