स्कीट के इस उद्धरण से शुरू:
यह फेरबदल का एक तरीका नहीं है जो मुझे पसंद है, ज्यादातर इस आधार पर कि यह ओ (एन लॉग एन) है बिना किसी अच्छे कारण के जब ओ (एन) फेरबदल को लागू करना आसान है। प्रश्न में कोड "काम करता है" मूल रूप से प्रत्येक तत्व को एक यादृच्छिक ( उम्मीद से अनूठा! ) नंबर देता है, फिर उस संख्या के अनुसार तत्वों का आदेश देता है।
मैं उम्मीद है कि अद्वितीय के लिए कारण समझा थोड़ा पर जाऊँगा !
अब, Enumerable.OrderBy से :
यह विधि एक स्थिर प्रकार करती है; अर्थात्, यदि दो तत्वों की कुंजियाँ समान हैं, तो तत्वों का क्रम संरक्षित है
यह बहुत महत्वपूर्ण है! यदि दो तत्व एक ही यादृच्छिक संख्या "प्राप्त" करते हैं तो क्या होगा? ऐसा होता है कि वे उसी क्रम में बने रहते हैं जब वे सरणी में होते हैं। अब, ऐसा होने की क्या संभावना है? यह वास्तव में गणना करना मुश्किल है, लेकिन जन्मदिन की समस्या है कि वास्तव में यह समस्या है।
अब, क्या यह वास्तविक है? क्या यह सच है?
हमेशा की तरह, जब संदेह हो, तो प्रोग्राम की कुछ पंक्तियाँ लिखें: http://pastebin.com/5CDnUxPG
कोड का यह छोटा सा खंड 3 तत्वों की एक सरणी फेरबदल करता है जो कई बार फिशर-येट्स एल्गोरिथ्म का उपयोग करके पिछड़ा हुआ होता है, फिशर-येट्स एल्गोरिथ्म आगे किया जाता है ( विकी पृष्ठ में दो छद्म कोड एल्गोरिदम हैं ... यह समान उत्पादन करते हैं परिणाम, लेकिन एक पहले से अंतिम तत्व तक किया जाता है, जबकि दूसरा अंतिम से पहले तत्व तक किया जाता है), http://blog.codinghorror.com/the-danger-of-naivete/ के भोले गलत एल्गोरिथ्म और का उपयोग कर .OrderBy(x => r.Next())
और .OrderBy(x => r.Next(someValue))
।
अब, Random.Next है
एक 32-बिट हस्ताक्षरित पूर्णांक जो 0 से अधिक या उससे अधिक है और मैक्सवैल्यू से कम है।
इसलिए यह इसके बराबर है
OrderBy(x => r.Next(int.MaxValue))
यह जाँचने के लिए कि क्या यह समस्या मौजूद है, हम ऐरे को बढ़ा सकते हैं (कुछ बहुत धीमी गति से) या बस यादृच्छिक संख्या जनरेटर के अधिकतम मूल्य को कम कर सकते हैं ( int.MaxValue
एक "विशेष" संख्या नहीं है ... यह बस एक बहुत बड़ी संख्या है)। अंत में, यदि एल्गोरिथ्म की गतिहीनता से पक्षपाती नहीं है OrderBy
, तो मूल्यों की किसी भी सीमा को समान परिणाम देना चाहिए।
कार्यक्रम फिर कुछ मूल्यों का परीक्षण करता है, सीमा 1 ... 4096 में। परिणाम को देखते हुए, यह काफी स्पष्ट है कि कम मूल्यों (<128) के लिए, एल्गोरिथ्म बहुत पक्षपाती (4-8%) है। 3 मूल्यों के साथ आपको कम से कम की आवश्यकता है r.Next(1024)
। यदि आप सरणी को बड़ा बनाते हैं (4 या 5), तो भी r.Next(1024)
पर्याप्त नहीं है। मैं फेरबदल और गणित में एक विशेषज्ञ नहीं हूं, लेकिन मुझे लगता है कि सरणी के प्रत्येक अतिरिक्त बिट के लिए, आपको अधिकतम मूल्य के 2 अतिरिक्त बिट्स की आवश्यकता है (क्योंकि जन्मदिन का विरोधाभास sqrt (संख्याओं) से जुड़ा हुआ है), इसलिए यदि अधिकतम मान 2 ^ 31 है, तो मैं कहूंगा कि आप 2 ^ 12/2 ^ 13 बिट्स (4096-8192 तत्व) तक सरणियों को छाँटने में सक्षम होंगे