2010-10-20 21 views
13

मैं एक अतिरिक्त आवश्यकता के साथ प्राथमिकता कतार लागू करने पर विचार कर रहा हूं, एक खोज/खोज फ़ंक्शन जो बताएगा कि कोई आइटम कतार के भीतर कहीं भी है या नहीं। तो कार्य होंगे: डालें, डेल-मिनट और ढूंढें।प्राथमिकता कतार एक खोज समारोह के साथ - सबसे तेज़ कार्यान्वयन

मुझे यकीन है कि मुझे एक हीप या स्व-संतुलन बाइनरी खोज पेड़ का उपयोग करना चाहिए या नहीं। ऐसा प्रतीत होता है कि पीक्यू आमतौर पर एक हीप के साथ लागू होते हैं, लेकिन मुझे आश्चर्य है कि बाइनरी सर्च पेड़ का उपयोग करने में कोई फायदा है या नहीं, क्योंकि मुझे उस फ़ंक्शन को भी ढूंढने की आवश्यकता है।

इसके अलावा, औसत पर मैं हटाए जाने से अधिक आवेषण करूँगा। मैं d-ary heap पर भी विचार कर रहा हूं। असल में, हर दूसरे मायने रखता है।

धन्यवाद!

+0

"औसतन मैं हटाए जाने से अधिक आवेषण करूँगा" - क्या वह _really_ है जो आप कहना चाहते थे? यदि ऐसा है, तो आप अंततः स्मृति समाप्त कर देंगे, नहीं? – paxdiablo

+2

प्राथमिकता कतार पथ-खोज एल्गोरिदम के लिए है। जब मैं अपने लक्ष्य तक पहुंच जाता हूं, तो मैं किसी भी प्रकार के पुन: संतुलन के बिना प्राथमिकता कतार के अवशेषों को हटा सकता हूं। – Harry

+1

@ पक्सडीब्लो - दूसरी तरफ दौर असंभव है ... हर कार्यक्रम लंबे समय से चल रहा है – tobyodavies

उत्तर

0

आईआईआरसी खोज/ढेर पर खोजने O(n) है जबकि एक पेड़ पर यह O(log(n)) है और अन्य मानक पीक्यू संचालन समान हैं।

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

+1

मैंने इस जवाब को कम किया क्योंकि यह गलत है। ढेर और खोज पेड़ों में वास्तव में अलग-अलग संचालन समर्थित हैं और विभिन्न जटिलताएं हैं। एक ढेर में 'खोज-मिनट' 'ओ (1)' है जबकि एक संतुलित खोज पेड़ में यह 'ओ (लॉग एन) 'है। कुछ ढेर में डालें 'ओ (1) 'है, खोज पेड़ों में यह' ओ (लॉग एन)' है। और यह सिर्फ सिद्धांत नहीं है। ये 'ओ (लॉग एन)' बनाम 'ओ (1)' जटिलताओं में एक बड़ा प्रदर्शन हिट हो सकता है। – Celelibi

4

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

4

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

यदि 'खोज' से आपको वास्तव में 'ढूंढें और संशोधित करें' (मुझे लगता है कि मुझे अक्सर सामान्य डालने/डेल-मिनट की प्राथमिकता कतारों से चीजों को हटाने की आवश्यकता होती है), यहां तीन दृष्टिकोण हैं जिनका मैंने उपयोग किया है:

एक छोटे से काम करने वाले सेट (500-1000) पर डालने/डेल-मिनट (100k/s निरंतर) की उच्च दर और खोज-डिलीवरी (1/एस) की एक कम दर को देखते हुए मैंने एक रैखिक खोज की तत्व और फिर इसे मानक तरीके से पेड़ से हटा दिया।

डालने की उच्च दर/डेल-मिनट प्लस काफी बार-बार खोजने वाले डिलीटों को देखते हुए मैंने हटाए गए ऑब्जेक्ट्स को अप्रत्यक्ष रूप से ढूंढने के बाद "अनिच्छुक" के रूप में चिह्नित किया। वास्तविक मुक्त तब तक स्थगित कर दिया गया जब तक ऑब्जेक्ट सामान्य के रूप में नहीं छोड़ा गया।

केवल कुछ तत्वों और काफी कम विलोपनों के बारे में एक छोटी सी std :: primary_queue (जिसमें सम्मिलित/डेल-मिनट के बाहर कोई पहुंच विधियां नहीं हैं) को देखते हुए, मैंने बस पूरी कतार को एक अस्थायी std :: वेक्टर में कॉपी किया और कॉपी किया कतार में संशोधित/वांछित हिस्सा वापस। तब मैंने खुद को सोने के लिए रोया।

+0

"अनिच्छुक" ध्वज मेरे लिए जीवन बचा सकता है। –

-1

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

मैंने पिछले प्रोजेक्ट में हैश टेबल के साथ एक ब्लूम फ़िल्टर का मिलान किया और यह लगभग 10k वस्तुओं के औसत के साथ हैश टेबल पर 400 बार चीजें फैला।

खिलने फिल्टर में कुछ दिलचस्प गुण है: जवाब एक खिलने फिल्टर से नहीं है

  • हैं, तो यह 100% विश्वसनीय है।
  • यदि उत्तर हाँ है, तो यह सुनिश्चित करने के लिए कि आइटम वास्तव में मौजूद है, आपको अन्य डेटा संरचना को देखना होगा।
  • सुनिश्चित करें कि आप एक अच्छा हैश समारोह :)
+0

आप ब्लूम फ़िल्टर से कोई तत्व नहीं हटा सकते हैं, इसलिए एक बार जब आप पॉप() करते हैं, तो ब्लूम फ़िल्टर _always_ तत्व को दिखाएगा। आखिरकार, ब्लूम फ़िल्टर _always_ दिखाएगा _anything_ वहाँ है। –

2

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

यदि यह insert है तो दोनों को तत्व डालें।

यदि यह find है तो आप बाइनरी खोज पेड़ का उपयोग करके तत्व पा सकते हैं और यदि यह पाया गया तो प्राथमिकता कतार में इसे खोजना जारी रखें।

यदि यह min है तो इसे प्राथमिकता कतार से पहले हटा दें और अब आप जानते हैं कि यह कौन सा तत्व है, तो आप इसे बाइनरी खोज पेड़ से निकाल सकते हैं।

यदि यह del है तो पहले इसे बाइनरी खोज पेड़ में ढूंढें और इसे हटा दें, फिर इसे प्राथमिकता कतार में ढूंढें और इसे वहां से हटा दें।

यह माना जाता है कि बाइनरी पेड़ के नोड्स और प्राथमिकता कतार के नोड्स आपके तत्वों के लिए पॉइंटर्स हैं।

0

Radix trees एक मिनी-ढेर संपत्ति के साथ आपको आवश्यक संपत्तियां प्रदान की जाएंगी। यह वास्तव में आपको अपने परिचालनों के लिए निरंतर समय जटिलता देगा। उदाहरण के लिए, यदि हम this Haskell implementation देखते हैं, तो आपके द्वारा उपयोग किए जाने वाले सभी तीन परिचालनों में समय जटिलता ओ (न्यूनतम (एन, डब्ल्यू)) है। जहां n तत्वों की संख्या है, और डब्ल्यू एक int (32 या 64) में बिट्स की संख्या है।

संबंधित मुद्दे