जॉन ने पहले ही सिद्धांत को कवर कर लिया है , यहाँ एक कार्यान्वयन है:
function shuffle(array) {
var tmp, current, top = array.length;
if(top) while(--top) {
current = Math.floor(Math.random() * (top + 1));
tmp = array[current];
array[current] = array[top];
array[top] = tmp;
}
return array;
}
एल्गोरिथ्म है O(n)
, जबकि छँटाई होनी चाहिए O(n log n)
। देशी sort()
फ़ंक्शन की तुलना में जेएस कोड को निष्पादित करने के ओवरहेड के आधार पर , इससे प्रदर्शन में एक उल्लेखनीय अंतर हो सकता है जो सरणी आकार में वृद्धि होनी चाहिए।
बोबोबो के जवाब के लिए टिप्पणियों में , मैंने कहा कि प्रश्न में एल्गोरिथ्म समान रूप से वितरित संभावनाएं (कार्यान्वयन के आधार पर sort()
) का उत्पादन नहीं कर सकता है ।
मेरा तर्क इन पंक्तियों के साथ जाता है: एक छँटाई एल्गोरिथ्म के लिए निश्चित संख्या c
में तुलना की आवश्यकता होती है , उदाहरण के c = n(n-1)/2
लिए बुलबुले। हमारा यादृच्छिक तुलनात्मक फ़ंक्शन प्रत्येक तुलना के परिणाम को समान रूप से संभव बनाता है, अर्थात 2^c
समान रूप से संभावित परिणाम होते हैं। अब, प्रत्येक परिणाम को n!
सरणी की प्रविष्टियों के क्रमपरिवर्तन में से एक के अनुरूप होना है , जो सामान्य मामले में एक समान वितरण को असंभव बनाता है। (यह एक सरलीकरण है, क्योंकि तुलना की गई वास्तविक संख्या इनपुट सरणी पर निर्भर करती है, लेकिन मुखरता होनी चाहिए।)
जैसा कि जॉन ने बताया, यह अकेले फिशर-येट्स को पसंद करने का कोई कारण नहीं है sort()
, क्योंकि यादृच्छिक संख्या जनरेटर भी n!
क्रमपरिवर्तन के लिए छद्म यादृच्छिक मूल्यों की एक सीमित संख्या को मैप करेगा । लेकिन फिशर-येट्स के परिणाम अभी भी बेहतर होने चाहिए:
Math.random()
रेंज में एक छद्म यादृच्छिक संख्या पैदा करता है [0;1[
। जेएस डबल-सटीक फ़्लोटिंग पॉइंट मूल्यों का उपयोग करता है, यह 2^x
संभव मूल्यों से मेल खाता है जहां 52 ≤ x ≤ 63
(मैं वास्तविक संख्या खोजने के लिए बहुत आलसी हूं)। Math.random()
अगर परमाणु घटनाओं की संख्या परिमाण के समान क्रम की है, तो उपयोग करने से उत्पन्न संभावना वितरण अच्छी तरह से व्यवहार करना बंद कर देगा।
फिशर-येट्स का उपयोग करते समय, प्रासंगिक पैरामीटर सरणी का आकार है, जिसे 2^52
व्यावहारिक सीमाओं के कारण कभी भी दृष्टिकोण नहीं करना चाहिए ।
जब एक यादृच्छिक तुलना फ़ंक्शन के साथ छँटाई होती है, तो फ़ंक्शन मूल रूप से केवल परवाह करता है यदि रिटर्न वैल्यू सकारात्मक या नकारात्मक है, तो यह कभी भी समस्या नहीं होगी। लेकिन एक समान है: क्योंकि तुलनात्मक कार्य अच्छी तरह से व्यवहार किया जाता है, 2^c
संभावित परिणाम समान रूप से संभावित हैं। यदि c ~ n log n
तब 2^c ~ n^(a·n)
कहाँ a = const
, जो इसे कम से कम संभव बनाता 2^c
है जो समान परिमाण का है (या उससे भी कम) n!
और इस प्रकार असमान वितरण के लिए अग्रणी है, भले ही छँटाई एल्गोरिथ्म जहां समान रूप से क्रमपरिवर्तन पर मैप करना है। यदि इसका कोई व्यावहारिक प्रभाव मेरे से परे है।
वास्तविक समस्या यह है कि छंटाई एल्गोरिदम समान रूप से क्रमपरिवर्तन पर मैप करने की गारंटी नहीं है। यह देखना आसान है कि मेरजसोर्ट सममित रूप में करता है, लेकिन बुलबुले के बारे में कुछ तर्क करना या, अधिक महत्वपूर्ण बात, क्विकॉर्ट या हीप्सॉर्ट, ऐसा नहीं है।
लब्बोलुआब यह है कि जब तक sort()
आप मर्जेसॉर्ट का उपयोग करते हैं, तब तक आपको कोने के मामलों को छोड़कर काफी सुरक्षित होना चाहिए (कम से कम मुझे उम्मीद है कि 2^c ≤ n!
एक कोने का मामला है), यदि नहीं, तो सभी दांव बंद हैं।