न्यूनतम संख्या की तुलना के साथ दो सॉर्ट किए गए सरणियों को मर्ज करने के लिए एल्गोरिदम


24

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

यदि आपके पास एक सस्ता तुलना ऑपरेशन है, तो यह बहुत आसान है। बस सबसे पहले पहले तत्व के साथ सरणी से ले लो जब तक कि एक या दोनों सरणियों को पूरी तरह से ट्रैवर्स नहीं किया जाता है, फिर शेष तत्वों को जोड़ें। कुछ इस तरह से /programming/5958169/how-to-merge-two-sorted-arrays-into-a-sorted-array

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

इस मामले में, आप दो सरणियों को कम से कम तत्व तुलनाओं के साथ मर्ज करना चाहते हैं । यहां कुछ उदाहरण दिए गए हैं, जहां आपको सरल मर्ज एल्गोरिदम की तुलना में बहुत बेहतर करने में सक्षम होना चाहिए:

a = [1,2,3,4, ... 1000]
b = [1001,1002,1003,1004, ... 2000]

या

a = [1,2,3,4, ... 1000]
b = [0,100,200, ... 1000]

कुछ मामले हैं जहां सरल मर्ज एल्गोरिथ्म इष्टतम होगा, जैसे

a = [1,3,5,7,9,....,999]
b = [2,4,6,8,10,....,1000]

इसलिए एल्गोरिथ्म को आदर्श रूप से नीचा दिखाना चाहिए और यदि सरणियों को इंटरलेव किया जाता है, या कम से कम काफी खराब नहीं होना चाहिए, तो अधिकतम n + m-1 तुलना करें।

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

तत्वों के लिए उपलब्ध एकमात्र चीज एक (कुल) आदेश देने वाला कार्य है, इसलिए तुलनात्मक सस्ता बनाने वाली कोई भी योजना संभव नहीं है।

कोई विचार?

मैं स्काला में इस बिट के साथ आया हूं । मेरा मानना ​​है कि यह तुलना की संख्या के बारे में इष्टतम है, लेकिन यह साबित करने की मेरी क्षमता से परे है। कम से कम यह साहित्य में मुझे मिली चीजों की तुलना में बहुत सरल है।

और मूल पोस्टिंग के बाद से, मैंने एक ब्लॉग पोस्ट लिखा कि यह कैसे काम करता है।


2
"सरल मर्ज एल्गोरिथ्म" की तुलना में कम तुलना करने का कोई तरीका नहीं है। आप पहले उल्लेख की तरह किनारे के मामलों को संभालने की कोशिश कर सकते हैं, लेकिन इससे औसत मामला बिगड़ जाएगा।
मेफि

5
@Mephy: हमें बताएं और हमें एक औपचारिक साबित करें, कृपया। या यदि आप नहीं कर सकते, तो अपनी टिप्पणी को हटाने (या कम से कम परिष्कृत) पर विचार करें।
Doc Brown

4
@DocBrown अगर मेरे पास एक औपचारिक सबूत था, तो मैं एक जवाब दूंगा, न कि एक टिप्पणी। वैसे भी, यह एक बहुत स्पष्ट रैखिक समस्या है, क्योंकि एक बेहतर-रैखिक समाधान खोजने की कोशिश करने के लिए कम से कम रैखिक समय की आवश्यकता होगी।
म्पहि

4
@Mephy: मेरा सुझाव है कि आप नीचे दिए गए उत्तर को पढ़ने के लिए समय निकालें, और जो आपने लिखा है उसके बारे में दो बार सोचें।
डॉक ब्राउन

4
@Mephy अधिकांश चीजें जो स्पष्ट हैं ("आप O (n ^ 2) से कम में गुणा नहीं कर सकते हैं", "अगर मैं बदलूं तो मैंने कौन सा दरवाजा उठाया, मैं एक कीमत जीतने के अपने अवसरों में सुधार नहीं करूंगा" , "आप कर सकते हैं" O (n log n) ", ..) से कम में t सॉर्ट गलत हैं। उदाहरण के लिए छोटी सूची पर एक द्विआधारी खोज दृष्टिकोण का उपयोग करने से औसत मामले में सुधार करना चाहिए।
Voo

जवाबों:


31

सामान्य मर्ज सॉर्ट एल्गोरिथ्म - मर्ज चरण सामान्य रूप से लागू n + m -1 तुलना, जहां एक सूची आकार n की है और दूसरी सूची आकार m की है। इस एल्गोरिथ्म का उपयोग दो क्रमबद्ध सूचियों को संयोजित करने के लिए सबसे सरल दृष्टिकोण है।

यदि तुलना बहुत महंगी है, तो आप दो काम कर सकते हैं - या तो आप तुलना की संख्या को कम करते हैं या आप तुलना की लागत को कम करते हैं।

आइए तुलना की लागत को कम करने पर ध्यान दें। आप और केवल आप ही तय कर सकते हैं कि आप जिस डेटा की तुलना कर रहे हैं, उसे मात्राबद्ध किया जा सकता है या नहीं। यदि आप उन्हें परिमाणित कर सकते हैं, जो हैश पद्धति को लागू करने का एक रूप है, जो क्रम को बनाए रख रहा है। उदाहरण के लिए, यदि आपके डेटा की तुलना नाम से की जाती है, तो पहले tname, ... आप "Klaehn, Ruediger" नाम के पहले चार्ट को ले सकते हैं और अपने डेटा तत्व को "Kl.Ru" में घटा सकते हैं, यदि आप इसकी तुलना करते हैं "पैकर, द" आप ऑर्डरिंग को संरक्षित करते हैं "Pa.Th" - अब आप कम मूल्यों की तुलना करते हुए एक सस्ता तुलना एल्गोरिथ्म लागू कर सकते हैं। लेकिन अगर आपको एक और "Kl.Ru" मिल जाता है, तो आपके पास अब एक निकट मूल्य है, और आप अब इन तत्वों की तुलना में अधिक महंगा दृष्टिकोण पर स्विच कर सकते हैं।

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

मैंने आपकी तुलना को कम करने के लिए एक और तरीका भी बताया।

मैंने क्लासिक किताब TAOCP- वॉल्यूम 3-सॉर्टिंग और सर्चिंग, (pp.197-207, अनुभाग 5.3.2) पर एक नज़र डाली, जिसमें इस विषय पर पूरे 10 पृष्ठ हैं। मुझे एल्गोरिदम के दो संदर्भ मिले जो n + m-1 तुलना से तेज हैं।

पहले में ह्वांग-लिन मर्ज अल्गोरिद्म है और दूसरा ग्लेन के मनचेर का सुधार है - दोनों को TAOCP द्वारा और साथ ही क्रिस्टन द्वारा एक एल्गोरिथ्म का हवाला दिया गया है, जो लंबाई n और m पर विशेष परिस्थितियों में, आवश्यक तुलनाओं के निचले हिस्से से संपर्क करता है। सूचियों की।

मैनचेर के एल्गोरिथ्म को एसीएम वॉल्यूम के जर्नल में प्रस्तुत किया गया था। 26 नंबर 3 पेज 434-440 पर: "हवन-लिन" मर्जिंग एल्गोरिदम के लिए महत्वपूर्ण सुधार। एम आइटम के साथ सूची और एन आइटम के साथ सूची अलग-अलग लंबाई की हो सकती है, लेकिन उन्हें उन तत्वों की संख्या से भी विच्छेदित किया जाना चाहिए जिनमें वे m <= n हैं

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

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

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


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

4
आपके उत्तर में सुधार करने के बाद, हर कोई जिसने आपको नीचे उतारा है, आपको फिर से उभारने का मौका मिलेगा ;-)
Doc Brown

+1 यह ध्यान देने के लिए कि यदि आकार बहुत भिन्न हैं तो मानक मर्ज इष्टतम नहीं है।
फ्लोरियन एफ

1

मान लें कि दो सरणियों में एन और एम तत्व हैं, एन and एम, और सभी तत्व अलग हैं।

यदि सॉर्ट किए गए सरणी में N का एक तत्व x होता है, जिसके बाद M या इसके विपरीत y का तत्व y होता है, तो x और y की तुलना की जानी चाहिए, अन्यथा हमें नहीं पता होगा कि वे किस क्रम में हैं। (उदाहरण के लिए, जहाँ हम जानते हैं कि x, a, b, c, अन्य तत्वों की एक श्रृंखला नहीं हो सकती है, उदाहरण के लिए, क्योंकि x और y के बीच कोई तत्व नहीं हैं। इसलिए x और y की तुलना की जानी चाहिए। सीधे।

यदि N> M है, तो एक ऐसा सरणी होना संभव है जहां M का प्रत्येक तत्व पूर्ववर्ती हो और उसके बाद N का एक तत्व हो, जिसका अर्थ है कि कम से कम 2M तुलना की आवश्यकता है - भले ही आप एक गैर-नियतात्मक छँटाई एल्गोरिथ्म का उपयोग कर सकते हैं जो बना सकते हैं एक सही अनुमान जो तुलना करने के लिए संख्या है। (इसका क्या अर्थ है: मान लें कि आपके पास N बड़ा है, M = 1. बाइनरी सर्च में O (log2 N) स्टेप्स हैं, एक गैर-नियतात्मक एल्गोरिथ्म का अनुमान होगा कि किन दो तत्वों के बीच दूसरा एरे का एक तत्व है, और दो तुलना करने के लिए अनुमान की पुष्टि करें)।

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