एल्गोरिदम को सॉर्ट करें जो बड़ी मात्रा में डेटा पर काम करते हैं


12

मुझे ऐसे एल्गोरिदम की तलाश है जो बड़ी मात्रा में डेटा पर काम कर सकते हैं, यानी कि तब भी काम कर सकते हैं जब पूरे डेटा सेट को एक बार में मुख्य मेमोरी में नहीं रखा जा सकता है।

एकमात्र उम्मीदवार जो मुझे अब तक मिला है, वह मर्ज सॉर्ट है: आप एल्गोरिथ्म को इस तरह से लागू कर सकते हैं कि यह एक बार में सभी डेटा को मुख्य मेमोरी में पकड़े बिना प्रत्येक मर्ज पर सेट किए गए आपके डेटा को स्कैन करता है। मर्ज सॉर्ट की भिन्नता जो मेरे मन में है, वह इस लेख में सेक्शन ड्राइव टेप के साथ प्रयोग में वर्णित है ।

मुझे लगता है कि यह एक अच्छा समाधान है (जटिलता ओ (एनएक्स लॉग (एन)) के साथ) लेकिन मैं यह जानने के लिए उत्सुक हूं कि क्या अन्य (संभवतः तेज) छंटाई वाले एल्गोरिदम हैं जो बड़े डेटा सेट पर काम कर सकते हैं जो मुख्य मेमोरी में फिट नहीं होते हैं।

संपादित करें

यहां कुछ और विवरण दिए गए हैं, जैसे कि उत्तर:

  • डेटा को समय-समय पर सॉर्ट किया जाना चाहिए, जैसे महीने में एक बार। मुझे कुछ रिकॉर्ड सम्मिलित करने की आवश्यकता नहीं है और डेटा को क्रमिक रूप से सॉर्ट किया गया है।
  • मेरा उदाहरण पाठ फ़ाइल 1 GB UTF-8 पाठ के बारे में है, लेकिन मैं सामान्य रूप से समस्या को हल करना चाहता था, भले ही फ़ाइल 20 जीबी की हो।
  • यह एक डेटाबेस में नहीं है और, अन्य बाधाओं के कारण, यह नहीं हो सकता है।
  • डेटा को टेक्स्ट फ़ाइल के रूप में दूसरों द्वारा डंप किया जाता है, इस टेक्स्ट फ़ाइल को पढ़ने के लिए मेरा अपना कोड है।
  • डेटा का प्रारूप एक पाठ फ़ाइल है: नई लाइन वर्ण रिकॉर्ड विभाजक हैं।

एक संभव सुधार जो मुझे ध्यान में था, वह फाइल को फाइलों में विभाजित करने के लिए था जो कि मेमोरी में सॉर्ट करने के लिए काफी छोटा है, और अंत में ऊपर वर्णित एल्गोरिथ्म का उपयोग करके इन सभी फाइलों को मर्ज करें।


1
किस तरह का डेटा? अलग-अलग डेटा सेट का मतलब अलग-अलग एल्गोरिदम हो सकते हैं जो आपके उद्देश्य के लिए सबसे उपयुक्त हों।
whatsisname

यह एक पाठ फ़ाइल है और मुझे लाइनों को क्रमबद्ध करना है। लाइनें निश्चित लंबाई नहीं हैं, लेकिन लंबाई बहुत अधिक नहीं है (प्रति रिकॉर्ड लगभग 50 वर्ण)।
जियोर्जियो

3
मैं आपके पर्यावरण या आपकी बाधाओं को नहीं जानता, लेकिन जब भी संभव हो मैं छांटने के लिए एक डेटाबेस का उपयोग करूंगा। ऐसा इसलिए है क्योंकि यह लगभग 100% त्रुटि-प्रूफ है और मेरे कोड से बहुत अधिक कुशल होगा।
NoChance

मैं लिनक्स / जावा पर काम कर रहा हूं। मैंने मर्ज सॉर्ट लागू किया है और यह काफी सुचारू रूप से काम करता है। कई मिलियन लाइनों को छांटने में काफी समय लगता है लेकिन मुझे केवल एक बार ही ऐसा करने की आवश्यकता है।
जियोर्जियो

@ जियोर्जियो, यह अच्छा है कि आपने इस तरह के एल्गोरिदम को लागू किया है। उत्पादन कार्य के लिए, मैं अभी भी सुझाव देता हूं कि आप एक डेटाबेस का उपयोग करें। न केवल गति के लिए बल्कि विश्वसनीयता और रखरखाव में आसानी के लिए भी।
NoChance

जवाबों:


13

छँटाई और खोज पर विहित संदर्भ Knuth, Vol है। ३ । वहाँ शुरू करो।

पुस्तक को मूल रूप से वापस लिखा गया था जब कंप्यूटर अब की तुलना में बहुत छोटे और धीमे थे, जो कि आज की तुलना में स्मृति-छांटने की तकनीकों को अधिक महत्वपूर्ण बना दिया।


2
संदर्भ के लिए धन्यवाद: मुझे लगभग यकीन है कि मुझे नुथ की किताब में दिलचस्प सामग्री मिलेगी। मुझे यकीन नहीं है कि आउट-ऑफ-मेमोरी सॉर्टिंग तकनीक आज भी प्रासंगिक नहीं हैं। शायद आम, हर दिन के कार्यों के लिए नहीं, लेकिन मैं सोच सकता हूं कि अभी भी बहुत सारी स्थितियां हैं जिनमें बहुत बड़े डेटा सेट को संसाधित करने की आवश्यकता है।
जियोर्जियो

नुथ के एल्गोरिदम हमेशा मददगार होते हैं। उदाहरण के लिए ढेर-प्रकार के बफर के साथ एक विलय प्रकार बहुत प्रभावी हो सकता है और लागू करने में बहुत आसान है।
सुल्तान

4
बहुत उपयोगी उत्तर नहीं है क्योंकि संदर्भित सामग्री मुफ़्त नहीं है। ओपी के लिए, मैं एक जवाब के लिए गुग्लिंग का सुझाव देता हूं। इस तरह की जानकारी जब आप वेब के आसपास खुदाई करके पा सकते हैं, तो आपको एक पुस्तक प्राप्त करने के लिए $ 50 रुपये देने की आवश्यकता नहीं है। बेशक, आप शायद इसे ( अहम ) कुछ साइटों से मुफ्त में डाउनलोड कर सकते हैं । एक स्वीकृत उत्तर के योग्य।
थॉमस एडिंग

1
@ThomasEding में, "पुस्तकालयों" नामक ये चीजें हैं, जिनमें बड़ी मात्रा में इन अप्रचलित सूचना भंडारण और पुनर्प्राप्ति उपकरणों को "पुस्तकें" कहा जाता है। "लाइब्रेरी" "किताबें" मुफ़्त लान के लिए उपलब्ध हैं। यदि आपकी विशेष "लाइब्रेरी" में आपके लिए विशेष "पुस्तक" नहीं है, तो वे "इंटरलॉन्ड्री लोन" नामक एक निशुल्क सेवा भी प्रदान करते हैं, जो "लाइब्रेरी" को "पुस्तक" को किसी अन्य "लाइब्रेरी" से उधार लेने की अनुमति देता है, इसलिए वे कर सकते हैं आप इसे उधार दें।
जॉन आर। स्ट्रोम

6

UNIX sortकमांड में बाहरी R-Way का विलय एक अच्छा विकल्प है। आपके फॉर्मूलेशन से, मुझे यकीन नहीं है कि अगर वह एल्गोरिथ्म है जिसका अर्थ "मर्ज सॉर्ट" है, और यदि आप इसे नहीं जानते हैं, तो एक नज़र डालें।


धन्यवाद। एक्सटर्नल आर-वे मर्ज मेरे दिमाग में जो बात थी उससे अलग लगती है। दिलचस्प पढ़ना।
जियोर्जियो

4

अधिक बारीकियों के बिना "मर्ज सॉर्ट" शायद सबसे अच्छा उत्तर होगा जो आपको मिलेगा, हालांकि आप अपनी आवश्यकताओं के आधार पर कुछ अधिक चतुर लागू कर सकते हैं।

उदाहरण के लिए, क्या आप फ़ाइल के इन-मेमोरी इंडेक्स को बना सकते हैं और फिर विभिन्न प्रमुख मूल्यों के स्थान को कैशिंग करके सभी मानों को एक ही बार में कॉपी कर सकते हैं? क्या 1/2 एक बार में मेमोरी में फिट होता है, या 1/1000000 में? यदि यह दूसरा है तो आप मेमोरी में एक इंडेक्स को फिट करने में सक्षम नहीं हो सकते हैं, यदि पहली बार आप दोनों हिस्सों को अधिक कुशलता से सॉर्ट कर सकते हैं तो उन्हें एक ही अंतिम चरण में एक साथ मर्ज कर सकते हैं।

नरक, चूंकि आपने यह निर्दिष्ट नहीं किया है कि यह संभव है कि आपका डेटा एक डेटाबेस में है, यदि ऐसा है तो आप केवल एक इंडेक्स टेबल बना सकते हैं और इसे अच्छा कह सकते हैं (मुझे लगता है कि यह मामला नहीं है, लेकिन सिर्फ यह इंगित करता है कि आपकी स्थिति इस तरह एक जटिल समस्या को हल करने के लिए महत्वपूर्ण है)।

यदि आप इसे केवल एक बार करना चाहते हैं और बहुत जल्दी हैक की तलाश में हैं तो ऐसा लगता है कि यदि आप यूनिक्स चला रहे हैं तो बाहरी मर्ज सॉर्ट एक अच्छी शुरुआत होगी।

यदि आपको इसे क्रम में रखना है और हमेशा एक ही रिकॉर्ड जोड़ रहे हैं तो एक प्रविष्टि प्रकार आवश्यक होगा (सॉर्ट किए गए डेटा में एक रिकॉर्ड जोड़ना हमेशा प्रविष्टि प्रकार होता है)।

क्या आप उस कोड को नियंत्रित कर सकते हैं जो डेटा को "पढ़ता है"? यदि ऐसा है तो अनुक्रमणिका के कई रूप (डिस्क पर डेटा को इधर-उधर छांटने के बजाय) ए लॉट (वास्तव में एक परम आवश्यकता होगी) में मदद करेंगे।

इसलिए:

  • जगह या कई फ़ाइल में?
  • एक समय, समय-समय पर या इसे हर समय हल किया जाता है?
  • मेमोरी से कितना बड़ा (पूरे डेटा सेट के माध्यम से प्राप्त करने के लिए कितने मेमोरी-लोड)?
  • क्या यह किसी डेटाबेस में है? यह हो सकता है?
  • क्या आप उस कोड को नियंत्रित करते हैं जो डेटा को पढ़ता है, या दूसरों को सीधे एक फ़ाइल डंपिंग होगी?
  • फाइल प्रारूप? (पाठ? निश्चित रिकॉर्ड)
  • किसी भी अन्य विशेष परिस्थितियों के बारे में मैंने नहीं पूछा?

जवाब के लिए धन्यवाद। "इन प्लेस या मल्टीपल रिकॉर्ड" से आपका क्या अभिप्राय है?
जियोर्जियो

क्षमा करें, मेरे उत्तर को प्रूफ़-रीड करना चाहिए - मेरा मतलब था कि कई फ़ाइल। इन-प्लेस बहुत निश्चित रूप से रिकॉर्ड आकार और अनुक्रमण करता है, जिस बिंदु पर आप संभवतः एक डेटाबेस चाहते हैं।
बिल के

नहीं, यह जगह में नहीं है: रिकॉर्ड निश्चित आकार नहीं हैं। मैं अपने वर्तमान कार्यान्वयन के लिए चार अस्थायी फ़ाइलों का उपयोग करता हूं।
जियोर्जियो

क्या आप कोड के साथ आउटपुट की व्याख्या कर सकते हैं या क्या इसे एक विशिष्ट प्रारूप (फ्लैट टेक्स्ट फ़ाइल?) में होना है? इसे कितनी बार क्रमबद्ध करने की आवश्यकता है - हर बार कुछ जोड़ा जाता है या कभी-कभी? जब कुछ जोड़ा जाता है तो क्या इसे अंत में जोड़ा जाता है या आप इसे जोड़ने वाले कोड को लिख सकते हैं?
बिल के

प्रत्येक पंक्ति को एक रिकॉर्ड (फ़ाइल CSV फ़ाइल है) में पार्स किया जा सकता है, लेकिन अधिकांश फ़ील्ड टेक्स्ट हैं। इसे एक बार (जैसे हर महीने) एक बार हल करने की आवश्यकता होती है और मेरे वर्तमान कार्यान्वयन के साथ इसे हल करने में लगभग 1 घंटे लगते हैं। एक पंक्ति सम्मिलित करने के लिए, मैं उस कोड को लिख सकता हूं जो सही जगह पर लाइन सम्मिलित करता है: मेरे पास अब तक के कोड के साथ मुझे ऐसा उपकरण लिखने में 20 मिनट का समय लगेगा।
जियोर्जियो

3

यदि आप वास्तव में एक स्केलेबल समाधान चाहते हैं, तो आपको TeraSort पर एक नज़र डालनी चाहिए, मानचित्र-कम करने के साथ मानक सॉर्ट कार्यान्वयन; StackOverflow पर अधिक जानकारी


1
+1: दिलचस्प लिंक। क्या मानचित्र / उदाहरण को कम करने के लिए मर्ज नहीं किया जाता है, जहां मानचित्र उप-सूचियों को क्रमबद्ध करने से मेल खाता है, और मर्ज करने के लिए मेल खाता है?
जियोर्जियो

यह देखा जा सकता है, लेकिन आप इसे लिखने के बजाय अपने लिए ऐसा करने के लिए Hadoop का उपयोग कर सकते हैं।
m3th0dman 8

1

आप एक बाल्टी प्रकार में रुचि हो सकती है । औसत मामले का प्रदर्शन रैखिक समय है।

= O (n + d) n: तत्वों की संख्या और d = सबसे बड़ी संख्या की लंबाई यदि आपके डेटा के बारे में अंतर्ज्ञान है। यदि आप जानते हैं कि कितने 'अंक' आपकी सबसे बड़ी संख्या है। इसलिए यदि आपके पास 2 मिलियन 6 अंकों की संख्या है => 0 (n) इस प्रकार रैखिक है।


0

बाहरी मर्ज तरह एल्गोरिथ्म का उपयोग करें (यदि आपके डेटा निरंतर कर रहे हैं), या एक बाल्टी प्रकार के साथ प्रकार की गिनती बाल्टी के लिए छँटाई (अपने डेटा असतत और समान रूप से वितरित कर रहे हैं) के एक कार्यान्वयन के रूप में।

यदि वेतन वृद्धि छोटी है, तो संभवतः अपनी खुद की अनुक्रमणिका / मानचित्रण फ़ाइल का निर्माण करना सबसे अच्छा तरीका है।

  1. किसी तरह अपने "डेटाबेस" का आदेश दें
  2. हर प्रविष्टि (1, 2, 3, 4, ..., n) के लिए पूर्णांक असाइन करें (बेहतर: कुछ विरल अनुक्रमित का उपयोग करें)
  3. वेतन वृद्धि को जोड़ते समय बस एक अंतर खोजें जहां बाईं संख्या कम या बराबर है और सही संख्या अधिक या बराबर है (यह द्विआधारी खोज के कुछ संशोधित संस्करण के साथ मुश्किल नहीं होना चाहिए)
  4. सम्मिलित करें, जबकि अंतराल पर्याप्त रूप से बड़े हैं, यदि नहीं: बस reindex (फिर से सॉर्ट न करें) :-)

0

मैंने कुछ अमूर्त संरचनाओं का निर्माण किया है जिन्हें बड़ी कतार और बड़ी सरणी कहा जाता है ताकि सीमित मेमोरी के साथ एक मशीन पर बड़े डेटा सॉर्टिंग और खोज कार्य को सरल बनाया जा सके। मूल रूप से, उपयोग किया गया एल्गोरिथम आपके द्वारा ऊपर उल्लिखित के समान है - बाहरी मर्ज सॉर्ट।

मैं एक मशीन पर 9 घंटों में 128GB डेटा (प्रत्येक आइटम 100 बाइट्स) सॉर्ट कर सकता हूं और फिर बाइनरी डेटा को लगभग हर समय खोजता हूं।

मेरे खुले स्रोत बड़ी कतार और बड़ी सरणी संरचनाओं का उपयोग करके बड़े डेटा को कैसे खोजा जाए, इसके बारे में एक पोस्ट यहां दी गई है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.