एक अरब संख्याओं के माध्यिका की गणना करें


127

यदि आपके पास एक बिलियन नंबर और एक सौ कंप्यूटर हैं, तो इन नंबरों के मध्य का पता लगाने का सबसे अच्छा तरीका क्या है?

एक समाधान जो मेरे पास है:

  • कंप्यूटर के बीच सेट को समान रूप से विभाजित करें।
  • उन्हें क्रमबद्ध करें।
  • प्रत्येक सेट के लिए माध्यिका खोजें।
  • मंझला पर सेट सॉर्ट करें।
  • सबसे कम माध्यिका से एक बार में दो सेट मिलाएं।

यदि हमारे पास m1 < m2 < m3 ...पहले मर्ज है Set1और Set2परिणामी सेट में हम Set12(मर्ज किए गए) के औसत से कम संख्या को छोड़ सकते हैं । तो किसी भी समय हमारे पास समान आकार के सेट हैं। वैसे यह समानांतर तरीके से नहीं किया जा सकता है। कोई विचार?


3
@ जॉन बोकर: वास्तव में समस्या में दो उपप्रकार शामिल हैं: 1) सूची को क्रमबद्ध करें और 2) सूचकांक 5'000'000'000 के साथ तत्व प्राप्त करें। मैं शायद ही मानता हूं कि संख्याओं को क्रमबद्ध किया जाता है।
रोमन

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

5
@fmsf: मुझे नहीं लगता कि कोई भी अंग्रेजी बोलने वाला देश किसी भी आधिकारिक उद्देश्यों के लिए अंग्रेजी में लंबे अरब का उपयोग करता है। उदाहरण के लिए यूके में, हमने 1974 में इसका इस्तेमाल बंद कर दिया था। मैं "बिलियन" के उपयोग को एक मिलियन मिलियन का मतलब मानूंगा, अंग्रेजी भाषा में एक विकृत चाल सवाल होगा, "वास्तविक बिलियन" बिल्कुल नहीं। बेशक फ्रेंच में यह एक पूरी तरह से अलग मामला होगा, लेकिन सवाल फ्रेंच में नहीं है।
स्टीव जेसोप

5
आपको सॉर्ट करने की आवश्यकता नहीं है! en.wikipedia.org/wiki/…
glebm

2
1 बिलियन नंबर केवल कुछ गीगाबाइट डेटा है, आपको इस कार्य को हल करने के लिए कई पीसी या जटिल एल्गोरिदम की आवश्यकता नहीं है। ओवरकम्प्लीट न करें।
user626528 3

जवाबों:


54

आह, मेरे दिमाग ने सिर्फ गियर में लात मारी है, मेरे पास अब एक समझदार सुझाव है। शायद बहुत देर हो गई अगर यह एक साक्षात्कार था, लेकिन कभी मन नहीं:

मशीन 1 को "नियंत्रण मशीन" कहा जाएगा, और तर्क के लिए या तो यह सभी डेटा के साथ शुरू होता है, और इसे बराबर पार्सल में अन्य 99 मशीनों को भेजता है, या फिर डेटा मशीनों के बीच समान रूप से वितरित होने लगता है, और यह अपने डेटा का 1/99 दूसरों को भेजता है। विभाजन के बराबर होने की जरूरत नहीं है, बस करीब है।

एक-दूसरे मशीन अपने डेटा को सॉर्ट करती है, और ऐसा इस तरह से करती है जो पहले कम मूल्यों को खोजने का पक्षधर है। तो उदाहरण के लिए एक क्विकॉर्ट, हमेशा विभाजन के निचले हिस्से को पहले छाँटता है [*]। यह अपने डेटा को बढ़ते हुए क्रम में नियंत्रण मशीन पर वापस लिखता है जैसे ही वह कर सकता है (अतुल्यकालिक आईओ का उपयोग करना ताकि छंटाई जारी रहे, और शायद नागल ऑन: थोड़ा प्रयोग करें)।

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

यह "झुंड में सबसे धीमी" समस्या से ग्रस्त है। एल्गोरिथ्म तब तक पूरा नहीं हो सकता जब तक कि माध्यिका से कम हर मूल्य एक छँटाई मशीन द्वारा नहीं भेजा गया हो। वहाँ एक उचित मौका है कि इस तरह के एक मूल्य डेटा के पार्सल के भीतर काफी अधिक होगा। इसलिए एक बार डेटा का प्रारंभिक विभाजन पूरा हो जाने के बाद, अनुमानित रनिंग टाइम 1/99 वें डेटा को सॉर्ट करने और नियंत्रण कंप्यूटर पर वापस भेजने का समय का संयोजन है, और नियंत्रण का समय 1/2 डेटा पढ़ने के लिए है। । "संयोजन" उन समयों के अधिकतम और योग के बीच है, जो संभवतः अधिकतम के करीब है।

मेरी वृत्ति यह है कि एक नेटवर्क पर डेटा भेजने के लिए इसे छांटने की तुलना में तेज़ होना चाहिए (केवल मंझले का चयन करने दें) यह एक बहुत ही तेज़ फास्ट नेटवर्क होना चाहिए। हो सकता है कि एक बेहतर संभावना हो, यदि नेटवर्क को तात्कालिक माना जा सकता है, उदाहरण के लिए यदि आपके पास डेटा युक्त रैम तक समान पहुंच के साथ 100 कोर हैं।

चूंकि नेटवर्क I / O के बाउंड होने की संभावना है, ऐसे कुछ ट्रिक्स हो सकते हैं जिन्हें आप कम से कम कंट्रोल मशीन पर वापस आने वाले डेटा के लिए कर सकते हैं। उदाहरण के लिए, "1,2,3, .. 100" भेजने के बजाय, शायद एक छँटाई मशीन एक संदेश भेज सकती है जिसका अर्थ है "101 से कम 100 मान"। नियंत्रण मशीन तब एक संशोधित मर्ज कर सकती है, जिसमें यह उन सभी में से सबसे ऊपर के मानों को कम से कम पाता है, फिर सभी छँटाई मशीनों को बताता है कि यह क्या था, ताकि वे (a) नियंत्रण मशीन को बता सकें कि कैसे उस मान के नीचे "गणना" करने के लिए कई मान हैं, और (बी) उस बिंदु से अपना क्रमबद्ध डेटा भेजना फिर से शुरू करते हैं।

अधिक सामान्यतः, शायद एक चतुर चुनौती-प्रतिक्रिया अनुमान लगाने का खेल है जिसे नियंत्रण मशीन 99 छँटाई मशीनों के साथ खेल सकती है।

इसमें मशीनों के बीच राउंड-ट्रिप शामिल हैं, हालांकि, मेरा सरल संस्करण पहले से बचा जाता है। मुझे वास्तव में नहीं पता है कि उनके सापेक्ष प्रदर्शन को अंधा कैसे करना है, और चूंकि ट्रेड-ऑफ जटिल हैं, इसलिए मुझे लगता है कि वहाँ कुछ भी बेहतर समाधान हैं जो मैं अपने बारे में सोचूंगा, यह कभी भी एक वास्तविक समस्या है।

[*] उपलब्ध स्टैक परमिटिंग - यदि ओ (एन) अतिरिक्त स्थान नहीं है, तो आपकी पसंद का हिस्सा पहले करने के लिए विवश है। लेकिन अगर आपके पास पर्याप्त अतिरिक्त स्थान है, तो आप अपनी पिक ले सकते हैं, और यदि आपके पास पर्याप्त स्थान नहीं है, तो आप कम से कम उपयोग कर सकते हैं जो आपको कुछ कोनों को काटने के लिए है, पहले कुछ विभाजन के लिए छोटा हिस्सा करके।


कृपया मुझे सही करें अगर मैं गलत हूं, तो आप डेटा पर 99-वे मर्ज क्यों कर रहे हैं क्योंकि यह केवल बाद में खारिज करने के लिए आता है। इसके बजाय यह संख्याओं को रखने के लिए पर्याप्त है क्योंकि यह आता है?
श्रीप्रसाद १३'१४ को

4
@SREEPRASADGOVINDANKUTTY: सभी 99 उम्मीदवारों में से सबसे छोटे मान को छोड़ना और गिनती बढ़ाना दोहरा कदम है। यह इस 99-मर्ज कदम के बिना सभी आने वाले मूल्यों की गिनती रखने के लिए बिल्कुल भी उपयोग नहीं है। यदि आप उनकी तुलना नहीं करते हैं क्योंकि वे अंदर आते हैं, तो आप नहीं जानते कि जो मूल्य आप त्याग रहे हैं वह मध्यिका के नीचे है।
स्टीव जेसोप

लेकिन इस बात की कोई कम संभावना नहीं है कि इनमें से किसी भी विभाजन में माध्यिका की तुलना में केवल संख्याएँ अधिक होती हैं और इसलिए इसका कोई भी निचला विभाजन माध्यिका की तुलना में अधिक होगा, लेकिन जैसा कि नियंत्रण को यह पता नहीं है कि यह उन्हें त्यागने से कम होगा। मंझला और असफल ...?
गुल्यद्वारफ़

@ गुलीद्वारफ: एक बहु-मार्ग मर्ज केवल 99 मानों में से सबसे छोटे को हाथ में रखता है, जिनमें से प्रत्येक अन्य मशीनों में से सबसे छोटा शेष मूल्य है। यदि विभाजनों में से एक पूरी तरह से मध्यिका से अधिक है, तो यह उन 99 मानों में से कम से कम तब तक नहीं बनेगा जब तक कि मध्यकाल अतीत में नहीं चला जाता है (जिस बिंदु पर हम समाप्त हो चुके हैं)। इसलिए इसे खारिज नहीं किया जाएगा।
स्टीव जेसप

52
sort -g numbers | head -n 500000001 | tail -n 2 | dc -e "1 k ? ? + 2 / p"

2
जबरदस्त हंसी। क्या यह वास्तव में काम करता है या ओओएम हत्यारा इसे पूरा करने से पहले इसे परमाणु करेगा? (किसी भी उचित कंप्यूटर पर)
इसक सावो

5
करना चाहिए। सॉर्ट जानता है कि आउट-ऑफ-कोर सॉर्ट कैसे करना है, इसलिए यह मेमोरी से बाहर नहीं चलेगा।
DrPizza

6
@Zagfai मुझे नहीं लगता कि इसमें बहुत समय लगेगा; एक बिलियन नंबर 32-बिट इनट्स / फ्लोट्स के लिए केवल 4 जीबी है, 64-बिट इनट्स / डबल्स के लिए 8 जीबी है। न ही जबरदस्त कर लगता है।
DrPizza

13
बस एक इंटेल i5-4200M @ 3.1 GHz (4 कोर) पर प्रयास किया गया। timeपूरी पाइपलाइन पर लागू कमांड के अनुसार , इसमें real=36m24s("दीवार घड़ी का समय"), user=113m15s ("समानांतर समय", सभी कोर जोड़े गए)। सबसे लंबी कमान, दूसरों से बहुत आगे sort, भले ही यह 100% पर मेरे चार कोर से पिरोया गया था । रैम की खपत बहुत स्वीकार्य थी।
मॉर्गन टोवरे क्विंग

11
फिर 100 कंप्यूटरों पर चलाएं, ताकि आप 100 गुना अधिक सुनिश्चित हो सकें कि परिणाम सही है :)
डॉस

26

मुझे यहाँ विरोधाभासी होने से नफरत है, लेकिन मेरा मानना ​​है कि छंटाई की आवश्यकता नहीं है, और मुझे लगता है कि किसी भी एल्गोरिथ्म में एक बिलियन / 100 की संख्या को शामिल करना धीमा होने वाला है। आइए एक कंप्यूटर पर एक एल्गोरिथ्म पर विचार करें।

1) अरब से यादृच्छिक पर 1000 मानों का चयन करें, और संख्याओं के वितरण का विचार प्राप्त करने के लिए उनका उपयोग करें, विशेष रूप से एक सीमा।

2) मूल्यों को छाँटने के बजाय, उन्हें आपके द्वारा गणना की गई वितरण के आधार पर बाल्टी में आवंटित करें। बाल्टी की संख्या को चुना जाता है ताकि कंप्यूटर उन्हें कुशलता से संभाल सके, लेकिन अन्यथा सुविधाजनक के रूप में बड़े होने चाहिए। बकेट रेंज इतनी होनी चाहिए कि प्रत्येक बकेट में लगभग समान मान चलते हैं (यह एल्गोरिथम के लिए महत्वपूर्ण नहीं है, लेकिन यह दक्षता में मदद करता है। 100,000 बकेट उपयुक्त हो सकते हैं)। प्रत्येक बाल्टी में मूल्यों की संख्या पर ध्यान दें। यह एक O (n) प्रक्रिया है।

3) पता लगाएँ कि कौन सी बाल्टी में माध्य झूठ है। यह बस प्रत्येक बाल्टी में कुल संख्या की जांच करके किया जा सकता है।

4) उस बाल्टी में मूल्यों की जांच करके वास्तविक मंझले का पता लगाएं। यदि आप चाहें तो आप यहां एक प्रकार का उपयोग कर सकते हैं, क्योंकि आप केवल 10,000 की संख्या में छंटनी कर रहे हैं। यदि उस बाल्टी में मानों की संख्या बड़ी है तो आप इस एल्गोरिथ्म का फिर से उपयोग कर सकते हैं जब तक कि आपके पास छाँटने के लिए पर्याप्त संख्या न हो।

यह दृष्टिकोण कंप्यूटर के बीच के मूल्यों को विभाजित करके तुच्छ रूप से समानांतर करता है। प्रत्येक कंप्यूटर प्रत्येक बाल्टी में एक 'कंट्रोल' कंप्यूटर पर योग की रिपोर्ट करता है जो चरण 3 करता है। चरण 4 के लिए प्रत्येक कंप्यूटर कंट्रोल बाल्टी में प्रासंगिक बाल्टी में (सॉर्ट किए गए) मान भेजता है (आप उन दोनों एल्गोरिदम को समानांतर में भी कर सकते हैं, लेकिन यह शायद इसके लायक नहीं है)।

कुल प्रक्रिया O (n) है, क्योंकि दोनों चरण 3 और 4 तुच्छ हैं, बशर्ते कि बाल्टी की संख्या काफी बड़ी हो।


1
मुझे लगता है कि यह मध्यस्थों और त्वरित एल्गोरिदम के मध्य के बीच का कुछ है। en.wikipedia.org/wiki/Selection_al
एल्गोरिदम

चरण 4 में, बाल्टियों में केवल 10,000 नहीं हो सकते हैं। यह हो सकता है कि वितरण मध्य की ओर तिरछा हो, जिसमें, इसमें 80% डेटा हो सकता है, जो कि अभी भी बहुत बड़ा है।
३३:३३ पर ३३

उस का हिसाब लेने का संपादन किया।
डीजेकेवर्थ

मुझे यह तरीका पसंद है।
अल कीप

4
इस एल्गोरिथम में प्रदर्शन O (n) नहीं है: आप "माध्यिका" बाल्टी में सबसे अधिक संख्या में गिर सकते हैं, और यह हर चीज को छांटने के रूप में बुरी तरह से प्रदर्शन कर सकता है।
स्किलिविज़

12

एक अरब वास्तव में एक आधुनिक कंप्यूटर के लिए काफी उबाऊ कार्य है। हम यहां 4 बाइट पूर्णांक के 4 जीबी मूल्य के बारे में बात कर रहे हैं ... 4 जीबी ... यह कुछ स्मार्टफोन की रैम है।

public class Median {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();

        int[] numbers = new int[1_000_000_000];

        System.out.println("created array after " +  (System.currentTimeMillis() - start) + " ms");

        Random rand = new Random();
        for (int i = 0; i < numbers.length; i++) {
            numbers[i] = rand.nextInt();
        }

        System.out.println("initialized array after " + (System.currentTimeMillis() - start) + " ms");

        Arrays.sort(numbers);

        System.out.println("sorted array after " + (System.currentTimeMillis() - start) + " ms");

        if (numbers.length % 2 == 1) {
            System.out.println("median = " + numbers[numbers.length / 2 - 1]);
        } else {
            int m1 = numbers[numbers.length / 2 - 1];
            int m2 = numbers[numbers.length / 2];
            double m = ((long) m1 + m2) / 2.0;
            System.out.println("median = " + new DecimalFormat("#.#").format(m));
        }
}

मेरी मशीन पर आउटपुट:

created array after 518 ms
initialized array after 10177 ms
sorted array after 102936 ms
median = 19196

इसलिए यह मेरी मशीन पर दो मिनट से भी कम समय में पूरा होता है (1:43, जिसमें से 0:10 एक ही कोर का उपयोग करके यादृच्छिक संख्या उत्पन्न करते हैं) और यह एक पूर्ण प्रकार भी कर रहा है। वास्तव में कुछ भी नहीं फैंसी।

यह निश्चित रूप से संख्याओं के बड़े सेट के लिए एक दिलचस्प काम है। मैं यहाँ एक बिंदु बनाना चाहता हूँ: एक बिलियन मूंगफली है। इसलिए आश्चर्यजनक रूप से सरल कार्यों में जटिल समाधान फेंकने से पहले दो बार सोचें;)


यह मैंने अपने उत्तर में यहाँ कहा है :-) stackoverflow.com/a/31819222/363437
vidstige

1
@vidstige मैंने ईमानदारी से इसे नहीं पढ़ा, लेकिन आप सही हैं। मेरा जवाब निश्चित रूप से अधिक हाथों पर है, हालांकि, लोगों को थोड़ा और अधिक सराहना करने के लिए लगता है;)
sfussenegger

हालांकि यह मंझला नहीं है, मंझला है (numbers[numbers.length / 2]+numbers[numbers.length / 2+1])/2तो numbers.lengthसम और numbers[numbers.length / 2]केवल अगर numbers.lengthविषम है।
Sklivvz

@Sklivvz सही है, लेकिन यह ध्यान देने योग्य गणना करने में लगने वाले समय को प्रभावित नहीं करना चाहिए।
vidstige

1
@Sivivvz तुम बिल्कुल सही हो। मैंने केवल माध्य गणना को अद्यतन किया है। हालांकि यह बाकी के जवाब को नहीं बदलता है।
sfussenegger

10

मंझला और 99 वें प्रतिशतक जैसे आदेश आँकड़ों का अनुमान टी-डाइजेस्ट या क्यू-डाइजेस्ट जैसे एल्गोरिदम के साथ कुशलतापूर्वक वितरित किया जा सकता है

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

यह दृष्टिकोण द्वारा किया जाता है elasticsearch और, शायद, BigQuery (QUANTILES समारोह के विवरण को देखते हुए)।


5

संख्याओं के इस सेट के लिए माध्यिका

2, 3, 5, 7, 11, 13, 67, 71, 73, 79, 83, 89, 97

67 है।

संख्याओं के इस सेट के लिए माध्यिका

2, 3, 5, 7, 11, 13, 67, 71, 73, 79, 83, 89

40 है।

मान लें कि प्रश्न लगभग 1,000,000,000 पूर्णांकों (x) का था जहां 0> = x <= 2,147,483,647 और वह ओपी खोज रहा था (तत्व (499,999,999) + तत्व (500,000,000)) 2 (यदि संख्याओं को क्रमबद्ध किया गया था)। यह भी मानते हुए कि सभी 100 कंप्यूटर सभी समान थे।

मेरे लैपटॉप और गिग का उपयोग कर ...

मैंने पाया कि मेरा लैपटॉप 1.3 सेकंड में 10,000,000 Int32 को सॉर्ट कर सकता है। तो एक मोटा अनुमान यह होगा कि एक बिलियन नंबर सॉर्ट में 100 x 1.3 सेकंड (2 मिनट 10 सेकंड);) लगेगा।

गीगाबिट ईथरनेट पर एक 40MB फ़ाइल के एक-तरफ़ा फ़ाइल हस्तांतरण का एक अनुमान है .32 सेकंड। इसका मतलब है कि सभी कंप्यूटरों से छांटे गए परिणाम लगभग 32 सेकंड में वापस आ जाएंगे (कंप्यूटर 99 को शुरू होने के 30 सेकंड बाद तक अपनी फ़ाइल नहीं मिली)। वहां से सबसे कम 499,999,998 नंबरों को छोड़ने के लिए अगले 2 को जोड़ने और 2 से विभाजित करने में लंबा समय नहीं लेना चाहिए।


3
नीचे मतदाता टिप्पणी? यह मुझे यह समझने में मदद करेगा कि मैं कैसे बेहतर कर सकता हूं।
dbasnett

5
मैं नीचे मतदाता नहीं हूं, लेकिन एक अरब संख्याओं को छांटने में 10 मिलियन छंटाई करने में 100 गुना समय नहीं लगेगा, क्योंकि किसी सूची को छांटने की सबसे खराब स्थिति हे (एन लॉग एन) है। जब आप मेमोरी से बाहर निकलते हैं और डिस्क पर छँटाई शुरू करनी होती है, तो छँटाई भी परिमाण धीमी करने के आदेश हैं।
रिचर्ड पोले

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

यह मानते हुए कि उनके पास एक ही कारक है (जो वे शायद स्मृति मुद्दों के कारण नहीं हैं) a*(1e7)log(1e7) = 1.3sec= a = 1.6e-9sec = => a*(1e9)log(1e9) ~ 167sec, इसलिए आपका अनुमान बंद नहीं था।
बोर्सो

आपके अनुमान वैसे ही बहुत कठिन हैं। सबसे पहले, कुछ सॉर्टिंग एल्गोरिदम सबसे खराब स्थिति में ओ (एन ^ 2) के रूप में जाते हैं (उदाहरण के लिए आमतौर पर इस्तेमाल किया जाने वाला क्विकॉर्ट)। दूसरे, आपने एक परीक्षण डेटासेट चुना है जो आपके L2 कैश के आकार के बारे में है। इससे परिणामों में गिरावट आई है। तीसरे आप (कई अन्य उत्तरदाताओं के रूप में) "संख्या" का अर्थ है "पूर्णांक"। इसका मतलब फ्लोट, डबल या दशमलव हो सकता है, जिसमें बहुत अलग प्रदर्शन विशेषताएं हैं।
स्केलीवेज़

5

यह लोगों को आश्चर्यचकित कर सकता है, लेकिन यदि संख्या पूर्णांक से 32-बिट (या छोटे) के अंदर फिट होने के लिए पर्याप्त है - बस एक बाल्टी सॉर्ट करें! केवल 32-बिट के किसी भी संख्या के लिए 16GB RAM की आवश्यकता है और O (n) में रन करता है, जो कि उचित n, जैसे कि एक बिलियन के लिए किसी भी वितरित सिस्टम को बेहतर बनाना चाहिए।

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

एक सरल कार्यान्वयन नीचे दिखाया गया है। केवल 16-बिट पूर्णांक के लिए काम करता है, लेकिन 32-बिट तक विस्तार आसान होना चाहिए।

#include <stdio.h>
#include <string.h>

int main()
{
    unsigned short buckets[65536];
    int input, n=0, count=0, i;

    // calculate buckets
    memset(buckets, 0, sizeof(buckets));
    while (scanf("%d", &input) != EOF)
    {
        buckets[input & 0xffff]++;
        n++;
    }

    // find median 
    while (count <= n/2)
    {
        count += buckets[i++];
    }

    printf("median: %d\n", i-1);

    return 0;
}

एक अरब के साथ (10 एक पाठ फ़ाइल का उपयोग करते हुए 9 ) संख्या और के साथ चल रहा timeहै ताकि तरह

time ./median < billion

मेरी मशीन 1m49.293 पर चलने का समय देता है। अधिकांश समय चल रहा है, शायद डिस्क IO aswell है।


यह वास्तव में सवाल का जवाब नहीं देता है और यह मान्यताओं पर निर्भर करता है। उदाहरण के लिए, आप यह भी नहीं जानते कि वे पूर्णांक हैं।
स्किलिविज

किस तरह से यह सवाल का जवाब नहीं देता है? और हाँ, मेरा उत्तर मानता है कि संख्या पूर्णांक हैं। मैंने अपनी मान्यताओं को स्पष्ट रूप से बताने की कोशिश की है।
vidstige

आपको यह प्रतीत नहीं होता है कि पूर्णांक होना एक धारणा है, और न ही आप ओपी के बारे में पूछे जाने वाले 100 कंप्यूटरों का उपयोग कैसे करते हैं। आप एक नोड पर माध्यिका की गणना कर सकते हैं लेकिन यह "सर्वश्रेष्ठ" समाधान नहीं है जब तक कि आप क्यों नहीं दिखाते हैं। इसके अलावा, मूलांक तरह ओ (एन) नहीं है अगर अंकों की संख्या बदलती रहती है, जो इस मामले में निश्चित रूप से करता है, के अनुसार en.wikipedia.org/wiki/Radix_sort#Efficiency , यह ओ (एन एन लॉग इन करें)
Sklivvz

मैं यह कहना शुरू करता हूं "यदि पूर्णांक 32-बिट पूर्णांक के अंदर फिट होने के लिए पर्याप्त छोटा है " ... आपके द्वारा पोस्ट किए गए लिंक में बड़ी स्पष्टता के रूप में एक निरंतर शब्द आकार w के लिए मूलांक सॉर्ट O (n) है । यहाँ मैं 32 का एक निरंतर शब्द आकार ग्रहण करता हूँ।
vidstige

1
आप 99 अन्य कंप्यूटरों के साथ क्या करते हैं, इस उत्तर में प्रासंगिक नहीं है। आप उन्हें पिरामिड बनाने या जलाने के लिए एक दूसरे के ऊपर ढेर कर सकते हैं। या बस उन्हें अनदेखा करें।
vidstige

3

अजीब तरह से पर्याप्त है, मुझे लगता है कि अगर आपके पास पर्याप्त कंप्यूटर हैं, तो आप O(n)औसत दर्जे के एल्गोरिदम का उपयोग करने से बेहतर हैं । (जब तक कि आपकी कोर बहुत, बहुत धीमी नहीं है, हालांकि, मैं सिर्फ एक का उपयोग करूँगा और O(n)केवलee9 नंबर के लिए एक मध्य-खोज एल्गोरिथ्म का उपयोग करूंगा; यदि आपके पास 1e12 था, हालांकि, यह कम व्यावहारिक हो सकता है।)

वैसे भी, मान लें कि इस समस्या से निपटने के लिए हमारे पास लॉग एन कोर से अधिक है, और हम बिजली की खपत के बारे में परवाह नहीं करते हैं, बस जवाब तेजी से प्राप्त कर रहे हैं। चलो आगे यह मान लेते हैं कि यह एक एसएमपी मशीन है जिसमें पहले से ही मेमोरी में लोड किए गए सभी डेटा हैं। (उदाहरण के लिए, सन की 32-कोर मशीनें इस प्रकार की हैं।)

एक धागा सूची को नेत्रहीन रूप से समान आकार के टुकड़ों में काटता है और दूसरे एम थ्रेड्स को उन्हें सॉर्ट करने के लिए कहता है। वे सूत्र (n/M) log (n/M)समय में, परिश्रम से करते हैं । वे तब न केवल अपने मध्यस्थों को वापस करते हैं, बल्कि कहते हैं, उनके 25 वें और 75 वें प्रतिशत के रूप में अच्छी तरह से (विकृत सबसे खराब मामले बेहतर हैं यदि आप थोड़ा अलग संख्या चुनते हैं)। अब आपके पास 4M रेंज का डेटा है। आप तब इन श्रेणियों को क्रमबद्ध करते हैं और सूची के माध्यम से ऊपर की ओर तब तक काम करते हैं जब तक आपको एक संख्या नहीं मिल जाती है, यदि आप हर उस सीमा को फेंक देते हैं जो संख्या से छोटी है या उसमें संख्या है, तो आपने अपना आधा डेटा बाहर फेंक दिया होगा। मंझले के लिए यह आपकी निचली सीमा है। ऊपरी बाउंड के लिए भी ऐसा ही करें। यह M log Mसमय जैसा कुछ लेता है , और सभी कोर को इसके लिए इंतजार करना पड़ता है, इसलिए यह वास्तव में बर्बाद हो रहा हैM^2 log Mसंभावित समय। अब आपके पास अपना एकल धागा है, दूसरों को बताएं कि सीमा के बाहर सभी डेटा को टॉस करें (आपको प्रत्येक पास पर लगभग आधा बाहर फेंकना चाहिए) और दोहराएं - यह एक तुच्छ तेज़ ऑपरेशन है क्योंकि डेटा पहले से ही सॉर्ट किया गया है। log(n/M)इससे पहले कि बचे हुए डेटा को हथियाने और O(n)उस पर एक मानक मंझला खोजक का उपयोग करने के लिए तेज़ होने से पहले आपको इसे अधिक बार दोहराना नहीं चाहिए ।

तो, कुल जटिलता कुछ इस तरह है O((n/M) log (n/M) + M^2 log M log (n/M))। इस प्रकार, यह O(n)एक कोर पर औसत दर्जे की तुलना में तेज़ है यदि M >> log(n/M)और M^3 log M < n, आपके द्वारा वर्णित परिदृश्य के लिए सही है।

मुझे लगता है कि यह एक बहुत बुरा विचार है कि यह कितना अक्षम है, लेकिन यह तेज है।


o (n / M log (n / M)) वस्तुतः o (n लॉग एन) है, क्योंकि o (n / M log (n / M)) = 1 / M o (n (log n - log M)) ) = ओ (एन लॉग एन)। आप वास्तव में इसे ओ (n) के साथ तुलना नहीं कर सकते हैं, जैसा कि "ओ" मूल रूप से "कुछ अनिर्दिष्ट स्थिरांक के साथ बड़े एन के लिए आनुपातिक" है। जब तक आप जानते हैं कि इन स्थिरांक की आप तुलना नहीं कर सकते हैं, हालांकि बड़े पर्याप्त एन स्थिरांक प्रमुख नहीं हैं। कम संख्या के लिए सभी दांव बंद हैं, ओ (1) आसानी से ओ (एन) की तुलना में धीमा हो सकता है।
स्किलिविज

@Sklivvz - nऔर Mवे चर हैं जो मनमाने ढंग से स्केल कर सकते हैं, इसलिए दोनों में एक शामिल है। विशेष रूप से, मैंने उस M> को पोस्ट किया है log n, जिसका अर्थ है कि यदि आप परवाह करते हैं कि यह n log nसिर्फ के बजाय है n, तो आपको इसके बारे में Mभी ध्यान रखना होगा ।
रेक्स केर

3

यह एल्गोरिथ्म वोट किए गए एन (एन लॉग एन) की तुलना में तेजी से किया जा सकता है

- ऑर्डर आंकड़े वितरित एल्गोरिथ्म को वितरित करते हैं - ओ (एन)
एक अनसुलझी सरणी में केटी नंबर खोजने की मूल समस्या के लिए समस्या को सरल करते हैं।
- प्रकार हिस्टोग्राम ओ (एन) की गिनती
करते हुए आपको संख्याओं की सीमा के बारे में कुछ गुणों को समझना होगा - क्या सीमा मेमोरी में फिट हो सकती है? - बाहरी मर्ज सॉर्ट - O (n लॉग एन) - ऊपर वर्णित
आप मूल रूप से पहले पास पर संख्याओं को सॉर्ट करते हैं, फिर दूसरे पर माध्यिका खोजें।
- यदि कुछ भी संख्या के वितरण के बारे में जाना जाता है तो अन्य एल्गोरिदम का उत्पादन किया जा सकता है।

अधिक विवरण और कार्यान्वयन के लिए देखें:
http://www.fusu.us/2013/07/median-in-large-set-across-1000-servers.html


2

एक कंप्यूटर समस्या को हल करने के लिए पर्याप्त से अधिक है।

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

फिर क्रमबद्ध सूची के बीच से नंबर लें (यानी इंडेक्स 5 000 000 000 के साथ)।


3
वैसे भी अब मेरा प्रतिनिधि बहुत गोल है :)
रोमन

विलय सबसे अच्छा O (n) पर है, और आप O (n) में माध्यिका को एक ही कोर पर पा सकते हैं, इसलिए यह बिना किसी लाभ के बहुत सारे अतिरिक्त काम पैदा करता है।
रेक्स केर

2

यह आपके डेटा पर निर्भर करता है। सबसे खराब स्थिति यह है कि यह समान रूप से वितरित संख्या है।

इस मामले में आप इस उदाहरण में O (N) समय में माध्यिका पा सकते हैं:

मान लीजिए कि आपकी संख्या 2,7,5,10,1,6,4,4,6,10,4,7,1,8,4,9,9,3,4,3 (रेंज 1-10 है) ।

हम 3 बाल्टी बनाते हैं: 1-3, 4-7, 8-10। ध्यान दें कि ऊपर और नीचे का आकार समान है।

हम संख्याओं के साथ बाल्टी भरते हैं, गिनते हैं कि प्रत्येक में अधिकतम और न्यूनतम कितने गिरते हैं

  • कम (5): 2,1,1,3,3, न्यूनतम 1, अधिकतम 3
  • मध्य (10): 7,5,6,4,4,6,4,7,7,4,4, 4 मिनट, अधिकतम 7
  • उच्च (5): 10, 10, 8, 9, 9, न्यूनतम 8, अधिकतम 10

मध्य बाल्टी में मतलब गिर जाता है, हम बाकी हिस्सों की उपेक्षा करते हैं

हम 3 बाल्टी बनाते हैं: 4, 5-6, 7. लो 5 की गिनती के साथ शुरू होगा और अधिकतम 3 के साथ और 8 के मिनट के साथ उच्च और 5 की गिनती के साथ।

प्रत्येक संख्या के लिए हम गिनते हैं कि कम और उच्च बाल्टी, अधिकतम और न्यूनतम में कितने गिरे हैं, और मध्य बाल्टी रखें।

  • पुराना कम (5)
  • कम (5): 4, 4, 4, 4, 4, अधिकतम 4
  • मध्य (3): 5,6,6
  • उच्च (2): 7, 7, मिनट 7
  • पुराना उच्च (5)

अब हम सीधे माध्यिका की गणना कर सकते हैं: हमारे पास इस तरह की स्थिति है

old low    low          middle  high  old high
x x x x x  4 4 4 4 4 4   5 6 6  7 7   x x x x x

इसलिए मंझला 4.5 है।

मान लें कि आप वितरण के बारे में थोड़ा जानते हैं, तो आप धुन को ठीक कर सकते हैं कि गति को अनुकूलित करने के लिए श्रेणियों को कैसे परिभाषित किया जाए। किसी भी स्थिति में, प्रदर्शन ओ (एन) के साथ जाना चाहिए, क्योंकि 1 + 1/3 + 1/9 ... = 1.5

किनारे के मामलों के कारण आपको न्यूनतम और अधिकतम की आवश्यकता होती है (उदाहरण के लिए यदि माध्य पुराने कम और अधिकतम तत्व के बीच औसत है)।

इन सभी ऑपरेशनों को समानांतर किया जा सकता है, आप प्रत्येक कंप्यूटर को 1/100 डेटा दे सकते हैं और प्रत्येक नोड में 3 बाल्टी की गणना कर सकते हैं, फिर आपके द्वारा रखी गई बाल्टी को वितरित कर सकते हैं। यह फिर से आपको नेटवर्क का कुशलता से उपयोग करने की सुविधा देता है क्योंकि प्रत्येक संख्या औसतन 1.5 बार (इसलिए O (N)) पास की जाती है। आप यह भी हरा सकते हैं कि यदि आप केवल नोड्स के बीच न्यूनतम संख्या पास करते हैं (जैसे यदि नोड 1 में 100 नंबर हैं और नोड 2 में 150 नंबर हैं, तो नोड 2 नोड 1 को 25 नंबर दे सकता है)।

जब तक आप वितरण के बारे में अधिक नहीं जानते, मुझे संदेह है कि आप यहां ओ (एन) से बेहतर कर सकते हैं, क्योंकि आपको वास्तव में कम से कम एक बार तत्वों को गिनना होगा।


1
क्या वास्तविक बदतर स्थिति (आपके एल्गोरिथ्म के लिए) नहीं है जब सभी संख्याएँ समान हों? अगर मैं सही हूं, तो आपके सभी तत्वों में से कोई भी बाल्टी बीच से अलग नहीं होगी। इस प्रकार, आपको हर बार सभी तत्वों को पार करना होगा, अंतराल के मध्य तक तेजी से प्रगति करना। मेरा मानना ​​है कि यह O(n log n)उस मामले में एक होगा । क्या इस का कोई मतलब निकलता है ? वैसे मुझे आपका विचार पसंद है
Dici

1
@ वास्तव में नहीं: सबसे पहले आप आसानी से "सभी समान" परिदृश्य को शार्टकट कर सकते हैं क्योंकि आप मिनट और अधिकतम जानते हैं। जैसा कि मैंने उत्तर में कहा है, वितरण को जानने से आपके बकेटिंग विकल्पों को चलाया जा सकता है; दूसरे, यह अभी भी ले जाएगा o(n)+o(n/3)+o(n/9)+...जो अभी भी है o(n)और नहीं है o(n log n)
स्किलिविज़

दूसरी ओर, संभवतः एक अलग सबसे खराब स्थिति है, एक यू आकार का वितरण। मुझे इसके बारे में थोड़ा सोचने, सबसे बुरे मामले को औपचारिक रूप देने की आवश्यकता है, लेकिन यह संभवतः o(n)भोली विभाजन के साथ उस मामले में भी बदतर कर सकता है ।
स्किलिविज

मम्म हाँ, न्यूनतम और अधिकतम "सभी समान" मामले को आसानी से संभालने में मदद करेगा
Dici

2

एक आसान तरीका है वेटेड नंबरों का होना।

  • कंप्यूटर के बीच बड़े सेट को विभाजित करें
  • प्रत्येक सेट को क्रमबद्ध करें
  • छोटे-सेट के माध्यम से पुनरावृति, और दोहराया तत्वों के लिए वजन की गणना करें
  • प्रत्येक 2 सेट को 1 में मर्ज करें (प्रत्येक पहले से ही सॉर्ट किया गया है) वजन को अपडेट करता है
  • केवल एक सेट प्राप्त होने तक मर्जिंग सेट रखें
  • जब तक आप OneBillion / 2 तक नहीं पहुंच जाते तब तक इस सेट के भार के माध्यम से पुनरावृति

1

प्रत्येक कंप्यूटर पर 10 ^ 9 नंबर, 10 ^ 7 को विभाजित करें ~ प्रत्येक पर 80 एमबी। प्रत्येक कंप्यूटर अपनी संख्याओं को क्रमबद्ध करता है। फिर कंप्यूटर 1, कंप्यूटर 2, कंप्यूटर 3 और 4, आदि से उन लोगों के साथ अपने स्वयं के नंबरों को मर्ज करता है ... फिर कंप्यूटर 1 संख्याओं का आधा वापस 2, 3 से 4, आदि तक लिखता है। फिर 1 मर्ज कंप्यूटर से संख्याओं को सॉर्ट करता है 1,2,3,4, उन्हें वापस लिखता है। और इसी तरह। कंप्यूटर पर रैम के आकार के आधार पर, आप प्रत्येक चरण पर व्यक्तिगत कंप्यूटर पर सभी संख्याओं को वापस नहीं लिखने के साथ दूर हो सकते हैं, आप कई चरणों के लिए कंप्यूटर 1 पर संख्याओं को जमा करने में सक्षम हो सकते हैं, लेकिन आप गणित करते हैं।

ओह, अंत में 500000000 वां और 500000001 वां मान प्राप्त करें (लेकिन जांच करें कि वहां पर्याप्त 00s हैं, मैंने नहीं किया है)।

संपादित करें: @ रोमन - यदि आप विश्वास नहीं कर सकते हैं कि यह सच भी है, तो मेरी सच्चाई या प्रस्ताव के झूठ का खुलासा करने का कोई मतलब नहीं है। मेरे कहने का मतलब यह था कि पाशविक बल कभी-कभी दौड़ में होशियार हो जाता है। एक एल्गोरिथ्म को तैयार करने में मुझे लगभग 15 सेकंड का समय लगा, जिस पर मुझे भरोसा है कि मैं इसे लागू कर सकता हूं, जो काम करेगा, और जो कंप्यूटरों के इनपुट्स और नंबरों के आकार की एक विस्तृत श्रृंखला के अनुकूल होगा, और कंप्यूटर की विशेषताओं के लिए ट्यूनेबल होगा और नेटवर्किंग की व्यवस्था। यदि यह आपको, या किसी और को ले जाता है, तो 15 मिनट का कहना है कि एक अधिक परिष्कृत एल्गोरिथ्म को तैयार करने के लिए मुझे अपने समाधान को कोड करने और इसे चालू करने के लिए 14m45s लाभ है।

लेकिन मैं स्वतंत्र रूप से मानता हूं कि यह सब जोर है, मैंने कुछ भी नहीं मापा है।


यहाँ हम सभी संख्याओं को मिला रहे हैं। क्या हम इसका उपयोग बेहतर तरीके से कर सकते हैं: - "हम लोगन समय में दो क्रमबद्ध सूचियों के मध्य का पता लगा सकते हैं। n प्रत्येक सूची की लंबाई है।"
एनोव

1
@anony - जब आप अपने स्वयं के प्रश्न का उत्तर देते हैं, तो मेरे पास मेरे समाधान को कोडित किया जाएगा, परीक्षण किया जाएगा और किया जाएगा। मुझे उम्मीद है कि बेहतर तरीके हैं, लेकिन कभी-कभी एक सरल तरीके से समानांतर करना मुझे वास्तव में कठिन समस्याओं पर अपना सिर खरोंच करने के लिए स्वतंत्र छोड़ देता है।
उच्च प्रदर्शन मार्क

क्या आपने वास्तव में इसे 7 मिनट में किया है ? मुझे विश्वास नहीं हो रहा है कि भले ही यह सच हो। मैंने इसी तरह का कार्य किया (यह एक विश्वविद्यालय असाइनमेंट था) और सभी रीमोटिंग सामान को लागू करने और परीक्षण करने में लगभग 2 घंटे का समय लगा (मैंने जावा आरएमआई का उपयोग किया)।
रोमन

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

'अस्पष्ट रूप से प्रशंसनीय' - यह मेरे लिए काफी अच्छा है @ सच! विशेष रूप से एक अस्पष्ट प्रचलित प्रश्न के जवाब में।
उच्च प्रदर्शन मार्क

1

यह उन डेटा का उपयोग करके नोड्स पर किया जा सकता है जो निम्न तरीके से नोड्स के पार नहीं होते हैं (लॉग फ़ाइलों से कहते हैं)।

1 पैरेंट नोड और 99 चाइल्ड नोड्स हैं। बच्चे के नोड में दो एपी कॉल हैं:

  • आँकड़े (): रिटर्न मिनट, अधिकतम और गिनती
  • तुलना (माध्य_गुस्सा): रिटर्न की गिनती मिलान मूल्य, मान से कम और गिनती मान से अधिक होती है

मूल नोड सभी बच्चे नोड्स पर आँकड़े () कहता है, न्यूनतम और अधिकतम सभी नोड्स को देखते हुए।

एक बाइनरी खोज अब निम्नलिखित तरीके से आयोजित की जा सकती है:

  1. न्यूनतम और अधिकतम गोलाई नीचे बिताएं - यह मध्यमान 'अनुमान' है
  2. यदि गिनती से अधिक संख्या गिनती से कम है, तो अनुमान के लिए न्यूनतम सेट करें
  3. यदि गिनती से बड़ी संख्या गिनती से कम है, तो अनुमान के लिए अधिकतम सेट करें
  4. यदि गणना विषम फिनिश है जब न्यूनतम और अधिकतम समान हैं
  5. यदि गणना तब भी समाप्त हो जाती है जब अधिकतम <= न्यूनतम + अनुमान। प्रति_काउंट करें। यह निम्न तरीके से बिना डेटा (लॉग फ़ाइलों से कहे) का उपयोग करके नोड्स पर किया जा सकता है।

1 पैरेंट नोड और 99 चाइल्ड नोड्स हैं। बच्चे के नोड में दो एपी कॉल हैं:

  • आँकड़े (): रिटर्न मिनट, अधिकतम और गिनती
  • तुलना (माध्य_गुस्सा): रिटर्न की गिनती मिलान मूल्य, मान से कम और गिनती मान से अधिक होती है

मूल नोड सभी बच्चे नोड्स पर आँकड़े () कहता है, न्यूनतम और अधिकतम सभी नोड्स को देखते हुए।

एक बाइनरी खोज अब निम्नलिखित तरीके से आयोजित की जा सकती है:

  1. न्यूनतम और अधिकतम गोलाई नीचे बिताएं - यह मध्यमान 'अनुमान' है
  2. यदि गिनती से अधिक संख्या गिनती से कम है, तो अनुमान के लिए न्यूनतम सेट करें
  3. यदि गिनती से बड़ी संख्या गिनती से कम है, तो अनुमान के लिए अधिकतम सेट करें
  4. यदि गणना विषम फिनिश है जब न्यूनतम और अधिकतम समान हैं
  5. यदि गणना तब भी पूरी हो जाती है जब अधिकतम <= न्यूनतम + अनुमान

यदि आंकड़े () और तुलना () O (N / Mlogn / M) सॉर्ट के साथ पूर्व-गणना की जा सकती है, तो O (N / M) प्री-कैलकुलेशन के लिए O (N) के प्री-कैलकुलेशन के साथ प्री- गणना। तब आप निरंतर समय में तुलना () कर सकते थे, इसलिए पूरी चीज (पूर्व-गणना सहित) O (N / MlogN / M) + O (logN) में चलेगी

अगर मुझसे कोई गलती हुई हो तो मुझे बताएं!


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

0

इसके बारे में कैसे: - प्रत्येक नोड 1 बिलियन / 100 नंबर ले सकता है। प्रत्येक नोड पर तत्वों को क्रमबद्ध किया जा सकता है और मध्यमा पाया जा सकता है। पदकों के मध्य का पता लगाएं। हम कर सकते हैं, सभी नोड्स पर माध्यिका-मध्य-माध्यिका से कम संख्याओं की संख्याओं को जोड़कर, x%: y% विभाजन का पता लगाते हैं, जो कि मध्य-मध्य-मध्य बनाता है। अब सभी नोड्स को माध्यकों के मध्य से कम तत्वों को हटाने के लिए कहें (उदाहरण के लिए 30%: 70% विभाजन) ।30% संख्याएं हटा दी जाती हैं। १ बिलियन का ०% illion०० बिलियन है। अब सभी नोड्स जो 3 मिलियन से कम नोड्स को हटाते हैं, उन अतिरिक्त नोड्स को मुख्य कंप्यूटर पर वापस भेज सकते हैं। मुख्य कंप्यूटर इस तरह से पुनर्वितरित होता है कि अब सभी नोड्स में लगभग समान संख्या में नोड्स (7 मिलियन) होंगे। अब यह समस्या 700 मिलियन बिलियन की संख्या तक कम हो गई है .... तब तक चलती रहती है जब तक हमारे पास एक छोटा सा सेट नहीं है जिसे एक कंप्यूटर पर गणना की जा सकती है।


संक्षेप में, हम हमेशा कम से कम 30% द्वारा निर्धारित समस्या को कम कर रहे हैं और हम इसके माध्यम से बहुत अधिक समानांतर कंप्यूटिंग प्राप्त कर रहे हैं। प्रत्येक नोड 10million से शुरू होता है और प्रत्येक पुनरावृत्ति में इसके डेटा को 30% तक कम करता है।
एनोनी

पहले पुनरावृत्ति में हम 500Millionth नंबर की तलाश करते हैं। दूसरे पुनरावृत्ति में - यदि हटाए गए अंकों की संख्या
300 मिलियन है

2
ऐसा लगता है कि यह सही रास्ते पर है, लेकिन आप बहुत स्पष्ट रूप से यह नहीं समझाते हैं कि अपने 30% / 70% विभाजन के साथ दुर्घटना से माध्यिका को फेंकने से कैसे बचें। निम्नलिखित प्रतिधारण करें: मान लें कि आपका पहला 29% सभी शून्य है, और अन्य सभी ब्लॉक 1000 तक गिने जाते हैं, और ब्लॉक का प्रत्येक सेट पिछले से एक अधिक है। 30 वाँ प्रतिशत माध्य डेटा के सभी 29% को फेंक देगा, और केवल 61% डेटा के नीचे, जो कि 29 + 30% = 59% डेटा है। उफ़, हमने अभी-अभी असली मंझला फेंका है! तो जाहिर है आप इसका मतलब यह नहीं है, या कम से कम आप इसका मतलब है कि मैं व्याख्या की तुलना में अधिक चतुराई से।
रेक्स केर

0

आइए सबसे पहले एक मशीन पर n संख्याओं के माध्यिका को खोजने का तरीका जानें: मैं मूल रूप से विभाजन रणनीति का उपयोग कर रहा हूं।

समस्या: चयन (n, n / 2): कम से कम संख्या से n / 2 वें नंबर का पता लगाएं।

आप मध्य तत्व k और विभाजन डेटा को 2 उप सरणियों में कहते हैं। 1 में सभी तत्व शामिल हैं <k और 2 में सभी तत्व हैं> = k।

यदि आकार (प्रथम उप-सरणी)> = n / 2, तो आप जानते हैं कि इस उप-सरणी में माध्यिका है। फिर आप दूसरी उप-सरणी फेंक सकते हैं। इस समस्या के चयन को हल करें (आकार 1 उप-सरणी, n / 2)

किसी अन्य मामले में, इस 1 सबर्रे को फेंक दें और चयन को हल करें (2nd सबर्रे, n / 2 - sizeof (प्रथम उप-श्रेणी))

पुनरावृत्ति करो।

समय जटिलता O (n) अपेक्षित समय है।

अब अगर हमारे पास कई मशीनें हैं, तो प्रत्येक पुनरावृत्ति में, हमें विभाजित करने के लिए एक सरणी को संसाधित करना होगा, हम सरणी को अलग मशीनों में वितरित करते हैं। प्रत्येक मशीन उनके ऐरे के टुकड़े को प्रोसेस करती है और हब कंट्रोलिंग मशीन को 1 यानि 1 सबर्रे का साइज और 2 सबर्रे का साइज वापस भेजती है। हब मशीनें सारांश जोड़ती हैं और यह तय करती हैं कि कौन सी सबर्रे (1 या 2) आगे और 2 के चयन के पैरामीटर को संसाधित करने के लिए और इसे प्रत्येक मशीन पर वापस भेजती है। और इसी तरह।

नक्शे को कम करने का उपयोग करके इस एल्गोरिथ्म को बहुत करीने से लागू किया जा सकता है?

यह कैसा दिखता है?


0

मुझे लगता है कि स्टीव जेसप का जवाब सबसे तेज होगा।

यदि नेटवर्क डेटा ट्रांसफ़र का आकार अड़चन है, तो यहां एक और दृष्टिकोण है।

Divide the numbers into 100 computers (10 MB each). 
Loop until we have one element in each list     
    Find the meadian in each of them with quickselect which is O(N) and we are processing in parallel. The lists will be partitioned at the end wrt median.
    Send the medians to a central computer and find the median of medians. Then send the median back to each computer. 
    For each computer, if the overall median that we just computed is smaller than its median, continue in the lower part of the list (it is already partitioned), and if larger in the upper part.
When we have one number in each list, send them to the central computer and find and return the median.

32 एमबी प्रत्येक, तुम्हारा मतलब है?
धीकी

सूची के निचले हिस्से में जारी रहने का क्या मतलब है?
रूतविक वेला

0

मैं इसे इस तरह से करूंगा:

शुरुआत में उच्चतम और निम्नतम संख्या को खोजने के लिए सभी 100 काम करते हैं; कंप्यूटर के प्रत्येक भाग में डेटाबेस / फ़ाइल का भाग होता है, जिस पर यह प्रश्न करता है;

जब सबसे अधिक और सबसे कम संख्याएं पाई जाती हैं, तो एक कंप्यूटर डेटा पढ़ता है, और प्रत्येक संख्या को समान रूप से वितरित करता है, शेष 99 तक; संख्या को समान अंतराल द्वारा वितरित किया जाता है; (एक -100 मिलियन से 0 तक हो सकता है, दूसरा - 0 से 100 मिलियन तक, आदि);

संख्या प्राप्त करते समय, कंप्यूटर के 99 में से प्रत्येक पहले से ही उन्हें सॉर्ट करता है;

फिर, मध्यिका को ढूंढना आसान है ... देखें कि प्रत्येक कंप्यूटर में कितने नंबर हैं, उन सभी को जोड़ें (कितने नंबर के योग हैं, खुद नंबर नहीं हैं), 2 से विभाजित करें; गणना करें कि कौन सा कंप्यूटर नंबर है, और किस सूचकांक पर;

:) वॉयला

PS लगता है यहाँ बहुत भ्रम है; मध्ययुगीन - NUMBERS के एक लंबे सूची के मध्य में संख्या है!


0

मंझला खोजने के लिए आप टूर्नामेंट ट्री विधि का उपयोग कर सकते हैं। हम 1000 लीव नोड्स के साथ एक पेड़ बना सकते हैं जैसे कि प्रत्येक पत्ती नोड एक सरणी है। हम फिर विभिन्न सरणियों के बीच n / 2 टूर्नामेंट आयोजित करते हैं। n / 2 टूर्नामेंट के बाद रूट पर मूल्य परिणाम है।

http://www.geeksforgeeks.org/tournament-tree-and-binary-heap/


0

यदि संख्याएँ भिन्न नहीं हैं, और केवल एक निश्चित सीमा से संबंधित हैं, अर्थात वे दोहराए जाते हैं, तो मेरे दिमाग में आने वाला एक सरल उपाय यह है कि संख्या को 99 मशीनों के बीच समान रूप से वितरित करें, और एक मशीन को मास्टर के रूप में रखें। अब प्रत्येक मशीन अपने दिए गए नंबरों पर पुनरावृति करती है, और प्रत्येक संख्या की गिनती को हैश सेट में संग्रहीत करती है। हर बार संख्या उस विशेष कंप्यूटर को आवंटित संख्याओं के सेट में दोहराई जाती है, यह हैश सेट में अपनी गिनती को अपडेट करता है।

फिर सभी मशीनें मास्टर मशीन में अपना हैश सेट लौटा देती हैं। मास्टर मशीन हैश सेट को जोड़ती है, हैश सेट में मिली उसी कुंजी की गिनती को समेटें। उदाहरण के लिए मशीन # 1 के हैश सेट में ("1", 7) की प्रविष्टि थी, और मशीन # 2 के हैश सेट में ("1", 9) की प्रविष्टि थी, इसलिए हैश सेटों का मुकाबला करते समय मास्टर मशीन एक प्रविष्टि करता है। ("1", 16), और इसी तरह।

एक बार हैश सेट को मर्ज कर दिया गया है, तो बस कुंजियों को क्रमबद्ध करें, और अब आप आसानी से (n / 2) वें आइटम और (n + 2/2) वें आइटम को हल किए गए हैश सेट से पा सकते हैं।

यदि बिलियन नंबर अलग हैं, तो यह विधि फायदेमंद नहीं होगी।


0

खैर, मान लीजिए कि आप जानते हैं कि अलग-अलग पूर्णांकों की संख्या (मान लीजिए) 4 बिलियन है, तो आप उन्हें 64k बाल्टियों में बाल्टी कर सकते हैं और क्लस्टर (100 कंप्यूटर) में प्रत्येक मशीन से प्रत्येक बाल्टी के लिए एक वितरित गणना प्राप्त कर सकते हैं। इन सभी गणनाओं को मिलाएं। अब, उस बाल्टी को ढूंढें जिसमें माध्यिका है, और इस बार केवल 64k तत्वों के लिए बाल्टी के लिए कहें जो आपकी बाल्टी में झूठ होगा। इसके लिए आपके "क्लस्टर" पर O (1) (विशेष रूप से 2) क्वेरी की आवश्यकता होती है। : डी


0

मेरे लायक पैसा, आखिरकार जो पहले ही दूसरों द्वारा लाया जा चुका है:

एकल मशीन पर माध्यिका खोजना O (N): https://en.wikipedia.org/wiki/Selection__ एल्गोरिथम है

100 मशीनों पर N नंबर भेजना भी O (N) है। इसलिए, 100 मशीनों का उपयोग करने को दिलचस्प बनाने के लिए, या तो संचार अपेक्षाकृत तेज़ होना चाहिए, या एन इतना बड़ा है कि एक भी मशीन इसे संभाल नहीं सकती है जबकि एन / 100 के लिए उपयुक्त है, या हम सिर्फ गणितीय समस्या पर ध्यान दिए बिना विचार करना चाहते हैं। डेटा संचार।

छोटी चीजों को काटने के लिए, इसलिए मैं यह मानूंगा कि, उचित सीमा के भीतर, हम दक्षता विश्लेषण को प्रभावित किए बिना संख्या भेज / वितरित कर सकते हैं।

फिर निम्नलिखित दृष्टिकोण पर विचार करें, जहां एक मशीन को कुछ सामान्य प्रसंस्करण के लिए "मास्टर" सौंपा गया है। यह तुलनात्मक रूप से तेज़ होगा, इसलिए "मास्टर" उन सामान्य कार्यों में भी भाग लेता है जो प्रत्येक मशीन करता है।

  1. प्रत्येक मशीन को संख्याओं के एन / 100 प्राप्त होते हैं, अपने स्वयं के माध्य की गणना करते हैं और उस जानकारी को मास्टर को भेजते हैं।
  2. मास्टर सभी अलग-अलग मध्यस्थों की एक क्रमबद्ध सूची संकलित करता है और प्रत्येक मशीन पर एक बाल्टी (प्रत्येक मशीन पर समान) के क्रम को परिभाषित करते हुए प्रत्येक मशीन पर भेजता है, प्रत्येक मंझला मूल्य (एक एकल-मूल्य बाल्टी) और प्रत्येक अंतराल के बीच एक के लिए आसन्न मध्यस्थ। बेशक सबसे निचले मीडियन के नीचे और हाइटेस्ट के ऊपर के मूल्यों के लिए निचले-छोर और उच्च-अंत वाली बाल्टी भी हैं।
  3. प्रत्येक मशीन यह गणना करती है कि प्रत्येक बकेट में कितने नंबर आते हैं और उस जानकारी को मास्टर को वापस भेज देता है।
  4. मास्टर यह निर्धारित करता है कि किस बाल्टी में माध्यिका है, कितने कम मूल्य (कुल में) उस बाल्टी से नीचे हैं, और कितने ऊपर हैं।
  5. यदि चयनित बाल्टी एकल-मूल्य वाली बाल्टी है (मध्यिका में से एक) तो चयनित बाल्टी में केवल 1 (N विषम) या 2 (N सम) मान शामिल हैं। अन्यथा हम निम्नलिखित (स्पष्ट) संशोधनों के साथ उपरोक्त चरणों को दोहराते हैं:
  6. चयनित बाल्टी से केवल संख्याएं (पुन:) मास्टर से 100 मशीनों में वितरित की जाती हैं, और इसके अलावा
  7. हम माध्यिका (प्रत्येक मशीन पर) की गणना नहीं करने जा रहे हैं, लेकिन के-वें मूल्य, जहां हम ध्यान में रखते हैं कि कुल से कितने उच्च संख्या को छोड़ दिया गया है, और कितने कम संख्या। वैचारिक रूप से प्रत्येक मशीन में त्याग किए गए कम / उच्च संख्या के अपने हिस्से भी होते हैं और सेट में नए माध्यिका की गणना करते समय यह ध्यान में रखते हैं कि (अवधारणात्मक रूप से) इसमें शामिल संख्याओं को छोड़ दिया गया है।

समय-जटिलता:

  1. थोड़ी सी सोच आपको आश्वस्त करेगी कि प्रत्येक चरण पर विश्लेषण करने के लिए मूल्यों की कुल संख्या कम से कम दो से कम हो जाती है (2 एक बल्कि बीमार मामला होगा; आप काफी बेहतर कमी की उम्मीद कर सकते हैं)। इससे हमें यह मिलता है:
  2. यह मानते हुए कि माध्यिका (या k-th मान), जो O (N) है, को c * N समय लगता है, जहां prefactor c, N के साथ बहुत बेतहाशा भिन्न नहीं होता है ताकि हम इसे क्षण के लिए स्थिर मान सकें, हम 'हम अपना अंतिम परिणाम अधिकतम 2 * c * N / 100 समय पर प्राप्त करेंगे। 100 मशीनों का उपयोग करना हमें देता है, इसलिए, 100/2 का एक गति कारक (कम से कम)।
  3. जैसा कि शुरू में टिप्पणी की गई थी: मशीनों के बीच संख्याओं को संप्रेषित करने में लगे समय को केवल एक मशीन पर सब कुछ करने के लिए और अधिक आकर्षक बनाया जा सकता है। हालाँकि, यदि हम वितरित दृष्टिकोण के लिए जाते हैं, तो सभी चरणों में एक साथ संचारित होने वाली संख्याओं की कुल संख्या 2 * N (N पहली बार, <= N / 2 दूसरी बार <= आधा) से अधिक नहीं होगी। तीसरा, और इसी तरह)।

-1
  1. 1 बिलियन नंबरों को 100 मशीनों में विभाजित करें। प्रत्येक मशीन में 10 ^ 7 नंबर होंगे।

  2. किसी मशीन पर आने वाली प्रत्येक संख्या के लिए, आवृत्ति मानचित्र में संख्या को स्टोर करें, संख्या -> गिनती। प्रत्येक मशीन में न्यूनतम संख्या भी स्टोर करें।

  3. प्रत्येक मशीन में माध्यिका का पता लगाएं: प्रत्येक मशीन में न्यूनतम संख्या से शुरू होता है, जब तक मंझला सूचकांक तक नहीं पहुंच जाता तब तक मायने रखता है। प्रत्येक मशीन में माध्यिका लगभग होगी। कम और अधिक से अधिक 5 * 10 ^ 6 संख्या।

  4. सभी मध्यस्थों के मध्य का पता लगाएं, जो लगभग कम और अनुमानित से अधिक होगा। 50 * 10 ^ 7 नंबर, जो कि 1 बिलियन नंबरों की माध्यिका है।

अब 2 स्टेप के कुछ अनुकूलन: एक आवृत्ति मानचित्र में संग्रहीत करने के बजाय, काउंट को एक चर बिट सरणी में स्टोर करें। उदाहरण के लिए: मान लें कि मशीन में न्यूनतम संख्या से शुरू होता है, ये आवृत्ति गणना हैं:

[min number] - 8 count
[min+1 number] - 7 count
[min+2 number] - 5 count

उपरोक्त बिट सरणी में संग्रहीत किया जा सकता है:

[min number] - 10000000
[min+1 number] - 1000000
[min+2 number] - 10000

ध्यान दें कि पूरी तरह से प्रत्येक मशीन के लिए लगभग 10 ^ 7 बिट्स का खर्च आएगा, क्योंकि प्रत्येक मशीन केवल 10 ^ 7 नंबर संभालती है। 10 ^ 7बिट्स = 1.25 * 10 ^ 6 बाइट्स, जो 1.25MB है

इसलिए उपरोक्त दृष्टिकोण के साथ प्रत्येक मशीन को स्थानीय माध्य की गणना के लिए 1.25MB स्थान की आवश्यकता होगी। और मंझले हुए लोगों की संख्या की गणना उन 100 स्थानीय मध्यस्थों से की जा सकती है, जिसके परिणामस्वरूप 1 बिलियन की संख्या का माध्यिका बनता है।


क्या होगा अगर नंबर फ्लोट हैं?
स्केलीवेज़

-1

मैं लगभग मेडियन की गणना करने के लिए एक विधि का सुझाव देता हूं। :) अगर ये एक बिलियन संख्याएँ अनियमित क्रम में हैं, तो मुझे लगता है कि मैं एक बिलियन नंबर की 1/100 या 1/10 को बेतरतीब ढंग से उठा सकता हूँ, उन्हें 100 मशीन से छाँट सकता हूँ, फिर उनमें से माध्यिका चुनें। या चलो 100 भागों में अरब संख्याओं को विभाजित करते हैं, प्रत्येक मशीन को प्रत्येक भाग के 1/10 को यादृच्छिक रूप से लेने देते हैं, उनमें से औसतन की गणना करते हैं। उसके बाद हमारे पास 100 नंबर हैं और हम 100 नंबर के माध्य की गणना आसान कर सकते हैं। बस एक सुझाव, मुझे यकीन नहीं है कि यह गणितीय रूप से सही है। लेकिन मुझे लगता है कि आप एक अच्छे-से-कम-गणित प्रबंधक को परिणाम दिखा सकते हैं।


यह स्पष्ट रूप से सही नहीं है, और मैं दृढ़ता से आपको सलाह देता हूं कि आप कभी भी अपना साक्षात्कारकर्ता नहीं मान सकते हैं कि आप एक बेवकूफ सुअर है जिसे आप छल कर सकते हैं
Dici

हा ओके, हालांकि यह इस तथ्य को नहीं बदलता है कि आपका उत्तर गलत है। इसे साबित करना बहुत आसान है
डिसी

ठीक है, सांख्यिकीय के बारे में कुछ व्याख्यान पढ़ने के बाद, मुझे लगता है कि 1/100 या यहां तक ​​कि 1/1000 को एक बिलियन संख्या के बेतरतीब ढंग से लेने का विचार है और उनके औसत की गणना करना इतना बुरा नहीं है। यह सिर्फ एक अनुमानित गणना है।
lazyboy

-3

स्टीव जेसोप का जवाब गलत है:

निम्नलिखित चार समूहों पर विचार करें:

{२, ४, ६, 6, १०}

{२१, २१, २४, २६, २ 24}

{12, 14, 30, 32, 34}

{१६, १ 36, ३६, ३ 36, ४०}

मध्यमा 21 है, जो दूसरे समूह में निहित है।

चार समूहों के माध्यक ६, २४, ३०, ३६ हैं, कुल माध्यिका २ four है।

तो पहले लूप के बाद, चार समूह बन जाएंगे:

{6, 8, 10}

{२४, २६, २,}

{१२, १४, ३०}

{१६, १ 36, ३६}

21 पहले ही गलत तरीके से खारिज कर दिया गया है।

यह एल्गोरिथ्म केवल मामले का समर्थन करता है जब दो समूह होते हैं।

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