क्या द्विआधारी खोज और प्रक्षेप खोज के संयोजन के पीछे कोई अध्ययन या सिद्धांत है?


14

मैंने अभी पढ़ा है कि क्या इस एल्गोरिथ्म को अभी भी एक द्विआधारी खोज एल्गोरिदम माना जा सकता है? और याद आया कि कुछ साल पहले मैंने डेट / टाइम विंडो द्वारा बड़े सादे टेक्स्ट फाइलों में लॉग एंट्री खोजने के लिए लॉग फाइल के लिए एक अनुक्रमणिका / खोज लिखी थी।

यह करते हुए, मैंने प्रक्षेप खोज की कोशिश करने का फैसला किया (मुझे नहीं पता था कि इसे क्या कहा जाता है, मैं अपने आप से इस विचार के पार ठोकर खा गया था)। तब किसी कारण से मैं बाइनरी स्प्लिट स्टेप्स के साथ वैकल्पिक प्रक्षेप चरणों के विचार के लिए जारी रहा: चरण 0 पर मैं परीक्षण बिंदु तय करने के लिए प्रक्षेपित करूंगा, फिर चरण 1 मैं सटीक मिडपॉइंट ले जाऊंगा आदि।

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

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

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

जवाबों:


5

क्या मैं किसी ज्ञात चीज से टकरा गया हूं?

एक साथ, इंटरपोलेशन-सर्च और बाइनरी सर्च के मिश्रण पर आधारित विभिन्न विधियां हैं।हे(एलजी एलजी n)हे(एलजी n)

  • आत्मनिरीक्षण खोज आपकी विधि है (एक प्रक्षेप खोज और एक द्विआधारी खोज के बीच पुनरावृत्ति)। मैंने और विवरण नहीं दिया है।
  • एन। सैंटोरो, जेबी सिडनी (1985) द्वारा इंटरपोलेशन-बाइनरी सर्च (IBS)।

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

    यह आपके दृष्टिकोण के साथ कई सामान्य बिंदु हैं।

  • Biagio Bonasera, Emilio Ferrara, Giacomo Fiumara, Francesco Pagano, Alessandro Provetti द्वारा अनुकूली खोज (AS)

    लेखकों के शब्दों का उपयोग करना:

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

    [कट गया]

    इसलिए, यह दिखाना संभव है कि किसी भी इनपुट के लिए एएस IBS की तुलना में अधिक प्राथमिक कार्रवाई नहीं करेगा।

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


6

दोनों दुनियाओं में सर्वश्रेष्ठ प्राप्त करने के लिए दो एल्गोरिदम को जोड़ना एक ज्ञात तकनीक है, हालांकि यह आमतौर पर उन्हें "समानांतर" में चलाने और जैसे ही समाप्त होता है, एक जवाब वापस करने के लिए कहा जाता है।

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

  • इसमें भयानक (रैखिक) सबसे खराब स्थिति है

  • मिडपॉइंट की गणना करने का ओवरहेड बड़ा है; एक द्विआधारी खोज पुनरावृत्ति एक प्रक्षेप खोज एक की तुलना में सैकड़ों गुना तेज है

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

जैसे-जैसे आपका डेटासेट छोटा होता जाता है, वैसे-वैसे अंतर होता है लॉगn तथा लॉगलॉगn तुच्छ हो जाता है; लॉगn पहले से ही बहुत छोटा है, और लॉगलॉगnसंभवतः बहुत छोटा नहीं हो सकता है। इस बिंदु पर, प्रक्षेप खोज करने का ओवरहेड आपके द्वारा सहेजे जाने वाले पुनरावृत्तियों की तुलना में इसके लायक नहीं है।

मुझे लगता है कि आपके परिणामों को दो घटनाओं द्वारा समझाया जा सकता है:

  • बाइनरी खोज के साथ संयोजन आपको सबसे खराब स्थिति वाले व्यवहार से बचने की अनुमति देता है

  • एक छोटे डेटासेट पर बाइनरी खोज पर स्विच करने का सकारात्मक प्रभाव


3
आपने लिखा है: "एक द्विआधारी खोज पुनरावृत्ति एक प्रक्षेप खोज एक की तुलना में सैकड़ों गुना तेज है"। कृपया ध्यान दें कि ओपी के मामले में, उन दो तरीकों में मिडपॉइंट की गणना करने के बीच का अंतर I / O द्वारा मिडपॉइंट के मान को पुनः प्राप्त करने के लिए आवश्यक बौना है।
लियोरी

@ लियोरी: एक ही डेटा पर बार-बार द्विआधारी खोजों की शुरुआती कुछ पुनरावृत्तियों अधिक कैश-फ्रेंडली हो सकती हैं, क्योंकि कुछ ही तत्वों का उपयोग किया जाता है। इसलिए क्वार्टर और शायद इगेट्स से कैश में गर्म रहने की उम्मीद की जा सकती है। बाइनरी के साथ शुरू करने और तीन पुनरावृत्तियों के बाद प्रक्षेपित करने के लिए स्विच करने से समझ में आ सकता है, यदि रेंज काफी बड़ी हैं। (या यदि आप async I / O कर सकते हैं और जो भी परिणाम पहले आता है) का उपयोग करें।
पीटर कॉर्डेस

इसके अलावा, इन-मेमोरी सर्च के लिए भी, कैश मिस (200 से अधिक चक्रों की विलंबता) में एक 64 बिट पूर्णांक विभाजन (32-96 चक्र) की विलंबता है, उदाहरण के लिए इंटेल हैसवेल पर । 32 बिट पूर्णांक विभाजन काफी तेज है (22-29 चक्र)। मुख्य मेमोरी बैंडविड्थ सभी कोर के लिए एक साझा संसाधन है, लेकिन पूर्णांक विभाजन केवल प्रत्येक कोर पर डुप्लिकेट किए गए संसाधनों का उपयोग करता है।
पीटर कॉर्डेस

2
हालाँकि, मेमोरी लेटेंसी मेमोरी बैंडविड्थ की तुलना में बहुत खराब होती है, क्योंकि एक ही बार में एक ही बार उड़ान भरने पर कई बिखरे हुए एक्सेस तेजी से चलते हैं। यह एक (साथ प्रीफ़ेच करने के लिए जीत है prefetcht0निर्देश ) वर्तमान मध्य लोड हो रहा है, आधुनिक x86 हार्डवेयर पर एक में स्मृति bsearch के लिए इससे पहले कि अगले चरण के लिए दोनों संभावनाओं। आप ऐसा नहीं कर सकते हैं यदि आप समय से पहले अगले पतों के पते की भविष्यवाणी नहीं कर सकते हैं। तो व्यावहारिक कार्यान्वयन विवरण सैद्धांतिक कारणों से महत्वपूर्ण हो सकता है, एक तरफ
पीटर कॉर्डेस

@liori: निश्चित रूप से I / O प्रति मिडपॉइंट एक लॉग फ़ाइल को अनुक्रमित करते समय मुख्य कारक था, क्योंकि यह रिकॉर्ड खोजने के लिए मांग पर पढ़ा जा रहा था। फ़ाइल में ऑफसेट गणना और एक ब्लॉक को पढ़ने के बीच परिमाण के दो से अधिक आदेश शायद थे - इसलिए गणना की गई मिडपॉइंट की संख्या निर्णायक कारक होगी। मुझे लगता है कि अगर मैं अब एक लॉग फ़ाइल के बिना अनुक्रमणिका में दोहराता हूं - कुछ मैं कोशिश करूंगा और यहां पोस्ट करूंगा - कि एक औसत दर्जे का गति अंतर नहीं हो सकता है, लेकिन एक औसत दर्जे का हो सकता है "मिडपॉइंट की संख्या की आवश्यकता है" अंतर।
नील स्लेटर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.