यह एक शोध परियोजना है, जिससे मैं वर्तमान में गुजर रहा हूं। आवश्यकता लगभग आपकी है, और हमने समस्या को हल करने के लिए अच्छे एल्गोरिदम विकसित किए हैं।
इनपुट
इनपुट अंग्रेजी शब्दों या वाक्यांशों का एक अंतहीन प्रवाह है (हम उन्हें देखें tokens
)।
उत्पादन
- आउटपुट टॉप एन टोकन हमने अब तक देखे हैं (सभी टोकन से हमने देखा है!)
- आउटपुट टॉप एन टोकन एक ऐतिहासिक विंडो में, कहते हैं, आखिरी दिन या आखिरी सप्ताह।
इस शोध का एक अनुप्रयोग ट्विटर या फेसबुक में विषय के गर्म विषय या रुझानों का पता लगाना है। हमारे पास एक क्रॉलर है जो वेबसाइट पर क्रॉल करता है, जो शब्दों की एक धारा उत्पन्न करता है, जो सिस्टम में फीड करेगा। सिस्टम तब समग्र या ऐतिहासिक रूप से शीर्ष आवृत्ति के शब्दों या वाक्यांशों का उत्पादन करेगा। पिछले कुछ हफ़्ते में कल्पना करें कि "विश्व कप" वाक्यांश कई बार ट्विटर पर दिखाई देगा। तो "पॉल ऑक्टोपस" करता है। :)
स्ट्रिंगर्स इन्टर्गर
सिस्टम में प्रत्येक शब्द के लिए एक पूर्णांक आईडी है। यद्यपि इंटरनेट पर लगभग अनंत संभव शब्द हैं, लेकिन शब्दों के एक बड़े सेट को जमा करने के बाद, नए शब्दों को खोजने की संभावना कम और कम हो जाती है। हमने पहले से ही 4 मिलियन अलग-अलग शब्द पाए हैं, और प्रत्येक के लिए एक अद्वितीय आईडी असाइन किया है। डेटा का यह पूरा सेट मेमोरी में हैश टेबल के रूप में लोड किया जा सकता है, लगभग 300 एमबी मेमोरी का उपभोग करता है। (हमने अपनी खुद की हैश टेबल लागू कर दी है। जावा के कार्यान्वयन में बड़ी मेमोरी ओवरहेड लगती है)
प्रत्येक वाक्यांश को तब पूर्णांक की एक सरणी के रूप में पहचाना जा सकता है।
यह महत्वपूर्ण है, क्योंकि पूर्णांक की तुलना में छंटाई और तुलना स्ट्रिंग्स की तुलना में बहुत तेज है।
पुरालेख डेटा
सिस्टम प्रत्येक टोकन के लिए संग्रह डेटा रखता है। मूलतः यह जोड़े हैं (Token, Frequency)
। हालाँकि, डेटा संग्रहीत करने वाली तालिका इतनी विशाल होगी कि हमें तालिका को भौतिक रूप से विभाजित करना होगा। एक बार विभाजन योजना टोकन के कुछ हिस्सों पर आधारित है। यदि टोकन एक शब्द है, तो यह 1 ग्राम है। यदि टोकन दो-शब्द वाक्यांश है, तो यह 2gram है। और यही चलता है। मोटे तौर पर 4 ग्राम पर हमारे पास 1 बिलियन रिकॉर्ड है, जिसमें टेबल का आकार लगभग 60GB है।
आने वाली धाराओं को संसाधित करना
सिस्टम आने वाले वाक्यों को अवशोषित कर लेगा जब तक कि मेमोरी पूरी तरह से उपयोग नहीं हो जाती (हां, हमें मेमोरी मैनजर की आवश्यकता है)। एन वाक्यों को लेने और स्मृति में संग्रहीत करने के बाद, सिस्टम रुक जाता है, और प्रत्येक वाक्य को शब्दों और वाक्यांशों में बदलना शुरू कर देता है। प्रत्येक टोकन (शब्द या वाक्यांश) को गिना जाता है।
अत्यधिक लगातार टोकन के लिए, उन्हें हमेशा स्मृति में रखा जाता है। कम लगातार टोकन के लिए, उन्हें आईडी के आधार पर क्रमबद्ध किया जाता है (याद रखें कि हम स्ट्रिंग को पूर्णांकों की एक सरणी में अनुवाद करते हैं), और एक डिस्क फ़ाइल में क्रमबद्ध।
(हालांकि, आपकी समस्या के लिए, चूंकि आप केवल शब्दों की गिनती कर रहे हैं, तो आप सभी शब्द-आवृत्ति मानचित्र को केवल मेमोरी में रख सकते हैं। सावधानीपूर्वक डिज़ाइन किया गया डेटा 4 मिलियन विभिन्न शब्दों के लिए केवल 300MB मेमोरी का उपभोग करेगा। कुछ संकेत: ASCII char का उपयोग करें। स्ट्रिंग्स का प्रतिनिधित्व करते हैं), और यह बहुत स्वीकार्य है।
इस बीच, एक और प्रक्रिया होगी जो सिस्टम द्वारा उत्पन्न किसी भी डिस्क फ़ाइल को खोजने के बाद सक्रिय हो जाती है, फिर उसे विलय करना शुरू करें। चूंकि डिस्क फ़ाइल को क्रमबद्ध किया गया है, इसलिए विलय विलय की तरह एक समान प्रक्रिया लेगा। कुछ डिज़ाइन को यहाँ पर भी ध्यान रखने की आवश्यकता है, क्योंकि हम बहुत सारे रैंडम डिस्क सीकों से बचना चाहते हैं। विचार एक ही समय में पढ़ने (मर्ज प्रक्रिया) / लिखने (सिस्टम आउटपुट) से बचने के लिए है, और मर्ज प्रक्रिया को एक डिस्क में लिखते हुए एक डिस्क को पढ़ने दें। यह एक लॉकिंग को लागू करने के समान है।
दिन के अंत मे
दिन के अंत में, सिस्टम में मेमोरी में संग्रहीत आवृत्ति के साथ कई बार टोकन होंगे, और कई अन्य कम लगातार टोकन कई डिस्क फ़ाइलों में संग्रहीत होते हैं (और प्रत्येक फ़ाइल को सॉर्ट किया जाता है)।
सिस्टम इन-मेमोरी मैप को डिस्क फ़ाइल में फ्लश करता है (इसे सॉर्ट करें)। अब, समस्या सॉर्ट की गई डिस्क फ़ाइल के एक सेट को मर्ज करना है। इसी तरह की प्रक्रिया का उपयोग करके, हमें अंत में एक सॉर्ट की गई डिस्क फ़ाइल मिलेगी।
फिर, अंतिम कार्य सॉर्ट की गई डिस्क फ़ाइल को आर्काइव डेटाबेस में मर्ज करना है। संग्रह डेटाबेस के आकार पर निर्भर करता है, एल्गोरिथ्म नीचे की तरह काम करता है अगर यह काफी बड़ा है:
for each record in sorted disk file
update archive database by increasing frequency
if rowcount == 0 then put the record into a list
end for
for each record in the list of having rowcount == 0
insert into archive database
end for
अंतर्ज्ञान यह है कि कुछ समय बाद, डालने की संख्या छोटी और छोटी हो जाएगी। अधिक से अधिक ऑपरेशन केवल अपडेट करने पर होगा। और यह अपडेट इंडेक्स द्वारा दंडित नहीं किया जाएगा।
आशा है कि यह पूरी व्याख्या मदद करेगी। :)
what is the most frequent item in the subsequence [2; 2; 3; 3; 3; 4; 4; 4; 4; 5; 5] of your sequence?