रैंडम नंबर आमतौर पर उसी का अनुसरण करते हैं जिसे हम 'यूनिफ़ॉर्म डिस्ट्रीब्यूशन' कहते हैं, जिसका अर्थ है कि एक ही मौका है कि किसी भी नंबर को चुना जाए।
लेकिन अगर आप चाहते हैं कि कुछ नंबर दूसरों की तुलना में अधिक बार चुने जाएं तो आपको एक अलग रणनीति की आवश्यकता होगी:एक भारित यादृच्छिक संख्या जनरेटर ।
कुछ व्यावहारिक अनुप्रयोगों में शामिल हैं:
- वीडियो गेम में लूट की मेज, जहां दुश्मन अलग-अलग वस्तुओं को अलग-अलग ड्रॉप दरों के साथ गिरा सकते हैं।
- एक रैफल, जहां अधिक टिकट वाले लोगों के जीतने की संभावना अधिक होती है।
साधारण रणनीति
यदि आप रैफल उदाहरण के बारे में सोचते हैं तो आप एक स्पष्ट समाधान के साथ आ सकते हैं:एक सरणी उत्पन्न करें जिसमें प्रत्येक 'टिकट' के लिए आइटम की एक प्रति हो।
उदाहरण के लिए, यदि जॉन 4 रैफ़ल टिकट खरीदता है और डेविड केवल 1 खरीदता है, तो जॉन के पास डेविड की तुलना में 4 गुना अधिक जीतने की संभावना होगी।
यहां एक कार्यशील कार्यान्वयन है :
users = { john: 4, david: 1 }
raffle = []
users.map do |name, tickets|
tickets.times { raffle << name }
end
p raffle
# [:john, :john, :john, :john, :david]
p raffle.sample
# :john
मैं उनके द्वारा खरीदे गए प्रत्येक टिकट के लिए एक बार व्यक्ति का नाम जोड़ रहा हूं, और फिर मैं उस सूची से एक यादृच्छिक नाम चुनता हूं। सूची में अधिक बार होने के कारण, उस नाम के चुने जाने की संभावना बढ़ जाएगी।
मुझे यह तरीका पसंद है क्योंकि यह बहुत आसान है और एक बार आपकी सूची बन जाने के बाद विजेता चुनना बहुत तेज़ होता है।
वजन का योग
ऐसा करने का एक और तरीका है जो अधिक मेमोरी-कुशल है, ट्रेड-ऑफ यह है कि यादृच्छिक मान चुनना धीमा है।
विचार यह है कि 1 और सभी भारों के योग के बीच एक यादृच्छिक संख्या चुनें, और तब तक लूप करें जब तक कि आपको ऐसा वज़न न मिल जाए जो इस संख्या से कम या बराबर हो।
यहां कोड है :
def random_weighted(weighted)
max = sum_of_weights(weighted)
target = rand(1..max)
weighted.each do |item, weight|
return item if target <= weight
target -= weight
end
end
def sum_of_weights(weighted)
weighted.inject(0) { |sum, (item, weight)| sum + weight }
end
यह कोड एक हैश में लेता है जहां चाबियाँ आइटम हैं और मान वजन हैं। आप इस विधि को इस प्रकार कह सकते हैं:
random_weighted(cats: 5, dogs: 1) # :cats
आप इसे कई बार चलाने के बाद परिणामों के वितरण को देखकर परीक्षण कर सकते हैं कि क्या यह अपेक्षित रूप से काम करता है।
यहां एक उदाहरण दिया गया है :
counts = Hash.new(0)
def pick_number
random_weighted(cats: 2, dogs: 1)
end
1000.times { counts[pick_number] += 1 }
p counts
इसे कुछ बार चलाएं और आउटपुट को देखें कि क्या अनुपात वही होना चाहिए जो इसे होना चाहिए।
निष्कर्ष
जबकि अधिक परिष्कृत एल्गोरिदम हैं, इन दोनों को आपकी अच्छी सेवा करनी चाहिए। मुझे आशा है कि आपको यह लेख उपयोगी लगा होगा, कृपया इसे अपने दोस्तों के साथ साझा करें ताकि मैं और अधिक लिख सकूं!