6

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

  1. पूर्ण (32-बिट) एक वस्तु का हैश एक रैखिक congruential यादृच्छिक संख्या जनरेटर बीज के प्रयोग किया जाता है।
  2. जनरेटर 32-बिट संख्या उत्पन्न करता है और मॉड्यूलस को यह निर्धारित करने के लिए लिया जाता है कि हैश तालिका में आगे की जांच करने के लिए कहां है।

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

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

फिर, इस तरह के एक अलोकप्रिय टकराव समाधान रणनीति की यादृच्छिक क्यों है?

उत्तर

3

पायथन का शब्दकोश कार्यान्वयन यह करता है।dictobject.c में एक बहुत ही अच्छा टिप्पणी कहते हैं:

... 
The first half of collision resolution is to visit table indices via this 
recurrence: 

    j = ((5*j) + 1) mod 2**i 

For any initial j in range(2**i), repeating that 2**i times generates each 
int in range(2**i) exactly once (see any text on random-number generation for 
proof). 
... 

ज़रूर मेरे लिए एक रैखिक congruential RNG की तरह लग रहा है!

ध्यान दें कि इस तरह के एक RNG से भरा राज्य केवल मैं बिट्स है - है हो सकता है, प्रविष्टियों की समीक्षा से बचने के लिए - तो आप सार्थक उपयोग नहीं कर सकते "[टी] वह पूर्ण (32-बिट) हैश एक वस्तु का "आरएनजी बीज करने के लिए। पाइथन शुरुआत में जेi हैश से बिट्स के साथ बीज। यदि कोई और टकराव है, तो यह हैश से 5 बिट्स पकड़ता है और मिश्रण में फेंकता है। (उस टिप्पणी के बाकी हिस्सों को पढ़ें, खासकर जहां यह PERTURB_SHIFT के बारे में बात करता है।) यह तब तक जारी रहता है जब प्रत्येक टकराव के साथ अधिक बिट्स जोड़ते हैं, जब तक कि यह पूरे हैश कोड का उपयोग नहीं करता है। इस तरह पाइथन हैश कोड ऑफ़र जो भी यादृच्छिकता का एक सभ्य राशि का उपयोग करता है, और कोड सरल और तेज़ है।

यह कुछ बेहतरीन कोड है जिसे मैंने कभी पढ़ा है। यह Beautiful Code के अध्याय 18 में दिखाया गया है। तो मैं कहूंगा कि आप कुछ पर हैं!

+0

दिलचस्प। मेरा कार्यान्वयन बस गारंटी नहीं देता है कि यह कभी भी एक ही स्लॉट को एक से अधिक बार नहीं देखेगा। मैंने कुछ मोंटे कार्लो सिमुलेशन किया और निष्कर्ष निकाला कि, व्यावहारिक रूप से, यह चिंता करने के लिए बहुत बार होता है। यहां तक ​​कि यदि आप एक ही स्लॉट को एक से अधिक बार देखने की अनुमति देते हैं, तो भी आपको ** अपेक्षित ** ओ (1) लुकअप टाइम मिल जाएगा। – dsimcha

0

क्या आपको कोई समस्या नहीं है कि एक गैर-दुर्लभ आबादी वाली तालिका में सम्मिलन के लिए कोई गारंटी नहीं है कि आप डुप्लिकेट तत्वों पर पुनरावृत्ति शुरू करने से पहले हैश तालिका के सभी तत्वों को हिट करेंगे?

परिणामस्वरूप सम्मिलन समय अच्छी तरह से परिभाषित नहीं किया जाएगा। (ओ

+0

एक अच्छा आरएनजी देखते हुए, इसे सभी बाल्टीओं को समान रूप से देखना चाहिए। प्रविष्टि समय रैखिक और वर्गिक जांच के लिए या तो अच्छी तरह परिभाषित नहीं है। – Thomas

+1

आप उस घटना की संभावना को बाध्य कर सकते हैं :) – Anna

4

करने के कारणों में रेखीय या द्विघात जांच कि

  • ही बुरी से बुरी हालत समय जटिलता (ओ (तालिका का आकार))
  • ही सबसे मामले समय जटिलता है कर रहे हैं (1))
  • लागू करने के लिए
  • एक अच्छा RNG से अधिक तेजी से कर रहे हैं (के बाद से गति hashtables के लिए एक प्रमुख विक्रय बिंदु)

है आसान होता है लेकिन मुझे यकीन नहीं। क्या आपने अपने स्वयं के हैशटेबल को एक और टक्कर रिज़ॉल्यूशन के साथ कार्यान्वित किया है और दोनों को अलग-अलग परिस्थितियों में तुलना करें? वह बहुत प्रबुद्ध होगा।

6

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

चेन हैशिंग शायद इसकी सादगी के कारण उपयोग किया जाता है।

0

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

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