बहुत से प्रोग्राम को वास्तविक दुनिया की घटनाओं का अनुकरण करने के लिए (दिखने में) रैंडम वैल्यू की ज़रूरत होती है।
आम और परिचित उदाहरणों में शामिल हैं:
('H', 'T') में से एक रैंडम वैल्यू।कंप्यूटर से सचमुच रैंडम वैल्यू बनाना आश्चर्यजनक रूप से कठिन तकनीकी चुनौती है, इसलिए आप देख सकते हैं कि इन परिणामों को "स्यूडोरैंडम" कहा जाता है।
ज़रूरी: यह कॉन्सेप्ट क्रिप्टोग्राफिक रूप से सुरक्षित रैंडम संख्याओं को नहीं समझाता, जो कहीं अधिक कठिन चुनौती हैं।
हालाँकि, Julia की स्टैंडर्ड लाइब्रेरी में मौजूद Random मॉड्यूल जैसी अच्छी तरह बनाई गई लाइब्रेरी तेज़ और लचीली होती हैं, और मॉडलिंग, अनुकरण तथा गेम्स के ज़्यादातर उपयोगों के लिए काफी अच्छे परिणाम देती हैं।
Julia रैंडम सुविधाओं को कई जगहों पर बाँटती है:
Base में कुछ बुनियादी लेकिन बहुत काम के फंक्शन, जो हमेशा उपलब्ध रहते हैं।Random मॉड्यूल में विकल्पों की अधिक विस्तृत श्रृंखला।Random स्टैंडर्ड लाइब्रेरी का हिस्सा है और संभवतः पहले से इंस्टॉल होगा, लेकिन इसकी सामग्री को नेमस्पेस में लाने के लिए आपको अपने प्रोग्राम के शुरू में using Random जोड़ना होगा।
rand() फंक्शनयह फंक्शन क्या करता है, यह आपके दिए गए आर्गुमेंट पर निर्भर करता है। विकल्प बहुत सारे हैं।
बिना किसी आर्गुमेंट के, यह 0 (सम्मिलित) से 1 के बीच एक दशमलव संख्या बनाता है।
यह एक uniform वितरण है, जिसमें सभी वैल्यू के होने की संभावना समान होती है, जैसा कि नीचे "वितरणों के साथ काम करना" वाले भाग में बताया गया है।
एक पूर्णांक आर्गुमेंट उस लंबाई का वेक्टर बनाता है।
julia> rand()
0.10261774967264703
julia> rand(5)
5-element Vector{Float64}:
0.24134501977563894
0.5664193284851202
0.9804412082089355
0.6229551330613335
0.47589221741904664
किसी और रेंज के लिए, बस परिणाम को उचित तरीके से शिफ्ट और स्केल कर लीजिए।
नीचे का उदाहरण घटाने के लिए broadcasting का उपयोग करता है, जिसे Vector Operations कॉन्सेप्ट में समझाया गया है।
.- इस गणित को हर वेक्टर एलिमेंट पर लागू कर देता है।
# numbers between -1.0 and +1.0
julia> (rand(5) .- 0.5) * 2
5-element Vector{Float64}:
-0.5303906759076336
0.9635682226775855
-0.048823697086981754
0.465842804648374
0.9880834344780736
केवल एक टाइप को आर्गुमेंट के रूप में देने पर, rand सीमाओं के लिए typemin और typemax का उपयोग करेगा।
शायद आप यही नहीं चाहते!
रैंडम पूर्णांकों के लिए, हम एक रेंज दे सकते हैं, और साथ में वैकल्पिक रूप से यह भी कि कितनी वैल्यू बनानी हैं।
julia> rand(Int64)
-9159538335234594326 # not very useful
julia> rand(1:10, 5)
5-element Vector{Int64}:
1
1
1
4
7
ऊपर दिए rand(1:10, 5) उदाहरण में ध्यान दीजिए कि (संयोग से) कुछ वैल्यू दोहराई गई हैं, क्योंकि हर बार चुनाव स्वतंत्र होता है।
इसे "रिप्लेसमेंट के साथ सैंपलिंग" कहते हैं, जिस पर नीचे और विस्तार से चर्चा की गई है।
किसी रेंज में दशमलव वैल्यू के लिए, आपको आमतौर पर स्टेप साइज़ बताना पड़ेगा। वरना डिफॉल्ट स्टेप 1.0 रहेगा, जो शायद ही कभी काम आता है।
julia> rand(2.4:0.01:3.2, 4)
4-element Vector{Float64}:
3.19
2.53
3.14
3.13
वैकल्पिक रूप से, कोई ऐरे या टपल दीजिए, और rand एक रैंडम एलिमेंट लौटाएगा:
julia> rand([4, 9, 16, 25])
16
# coin flip
julia> rand(['H', 'T'])
'H': ASCII/Unicode U+0048 (category Lu: Letter, uppercase)
# mixed types in tuple
julia> rand( (1, 3.2, "name"), 2 )
2-element Vector{Any}:
1
"name"
कल्पना कीजिए कि हमारे पास एक थैला है जिसमें 3 लाल गेंदें और 4 हरी गेंदें हैं, और हम थैले से बेतरतीब ढंग से एक गेंद निकालते हैं। दूसरी गेंद निकालने के लिए दो तरीके हैं:
पहली स्थिति रिप्लेसमेंट के साथ है, दूसरी उसके बिना, और दोनों अलग-अलग परिणाम देती हैं।
Julia में रिप्लेसमेंट के बिना सैंपलिंग का अनुकरण करने के लिए कुछ विकल्प हैं।
सबसे आसान तरीका (और Exercism में तो यही एकमात्र विकल्प है), Random.shuffle() से एलिमेंट्स को रैंडम क्रम में लगाइए, फिर पहले n एलिमेंट्स इस्तेमाल कीजिए।
छोटी समस्याओं के लिए यह ठीक है, लेकिन बड़े संग्रहों के लिए यह ठीक से काम नहीं कर सकता: shuffle को पूरा ऐरे बनाना पड़ता है, भले ही आपको उसका छोटा-सा हिस्सा ही चाहिए हो।
रिप्लेसमेंट के साथ सैंपलिंग "ठीक से" करने के लिए, StatsBase.jl पैकेज इंस्टॉल कीजिए।
यह पूरी तरह से विकल्पों से भरा sample() फंक्शन देता है।
हम उम्मीद कर सकते हैं कि भविष्य में किसी रिलीज़ में ऐसी ही सुविधा Random में जोड़ दी जाएगी, ताकि यह स्टैंडर्ड लाइब्रेरी का हिस्सा बन जाए (इस दस्तावेज़ के कोड नमूने Julia 1.11 के साथ जाँचे गए हैं)।
अब तक हमने उन मामलों पर ध्यान दिया है जिनमें सभी परिणामों की संभावना समान होती है।
जैसे, rand(1:100) से 1 से 100 तक कोई भी पूर्णांक समान संभावना से मिल सकता है।
वास्तविक दुनिया की बहुत सी स्थितियाँ इससे कहीं अधिक जटिल होती हैं।
इसलिए सांख्यिकीविदों ने "वास्तविक दुनिया" के परिणामों को गणितीय रूप से बताने के लिए तरह-तरह के distributions बनाए हैं।
ऊपर बताया गया rand() फंक्शन तब उपयोग होता है जब सभी प्रायिकताएँ समान हों।
इसे [uniform][uniform-distribution] वितरण कहते हैं।
इसे "सामान्य" वितरण या "घंटी के आकार" का वक्र भी कहते हैं, और यह मापी गई वैल्यू में अनिश्चितता बताने का एक बहुत आम तरीका है।
उदाहरण के लिए, मान लीजिए आपकी फैक्ट्री ने अभी 10,000 बोल्ट खरीदे हैं जो एक जैसे होने चाहिए।
आप उन्हें संभालने के लिए फैक्ट्री का रोबोट सेट करना चाहते हैं, इसलिए आप 100 बोल्ट का नमूना तौलते हैं और पाते हैं कि उनका औसत (या mean) वज़न 4.731g है।
इसका यह अर्थ निकलना बेहद असंभव है कि सबका वज़न ठीक 4.731g ही है।
हो सकता है आप पाएँ कि वैल्यू 4.627 से 4.794g तक हैं, लेकिन 4.731g के आसपास इकट्ठा हैं।
यह Gaussian distribution है, जिसमें प्रायिकता माध्य पर सबसे ऊँची होती है और दोनों तरफ सममित रूप से घटती जाती है (इसीलिए "घंटी के आकार" का)।
सॉफ़्टवेयर में इसका अनुकरण करने के लिए हमें वक्र की चौड़ाई बताने का कोई तरीका चाहिए (आमतौर पर, महँगे बोल्ट सस्ते बोल्टों की तुलना में माध्य के आसपास अधिक कसकर इकट्ठा होते हैं!)。
परंपरा के अनुसार, यह standard deviation से किया जाता है: छोटी वैल्यू तेज़ और संकरे वक्र के लिए, बड़ी वैल्यू नीचे और चौड़े वक्र के लिए।
गणितज्ञों को यूनानी अक्षर बहुत पसंद हैं, इसलिए हम माध्य दिखाने के लिए μ ('mu') और स्टैंडर्ड डेविएशन दिखाने के लिए σ ('sigma') का उपयोग करते हैं।
इसलिए, अगर आप पढ़ें कि "95% वैल्यू μ के 2σ के भीतर हैं" या "हिग्स बोसॉन 5-sigma विश्वास के साथ पाया गया है", तो ऐसी बातें स्टैंडर्ड डेविएशन से जुड़ी होती हैं।
इस बारे में और बातें Statistics कॉन्सेप्ट में होंगी।
randn() फंक्शन"रैंडम नॉर्मल" का छोटा रूप, यह rand() के दशमलव वाले रूप जैसा ही है, बस इसमें वैल्यू माध्य 0 और स्टैंडर्ड डेविएशन 1 वाले गाऊसी वितरण के अनुसार बँटी होती हैं।
फिर से, आप randn के मूल आउटपुट को स्टैंडर्ड डेविएशन के लिए स्केल करना और माध्य के लिए खिसकाना चाह सकते हैं।
नीचे का उदाहरण इसे माध्य 30 और स्टैंडर्ड डेविएशन 5 में बदलता है।
julia> raw = randn(5)
5-element Vector{Float64}:
3.0762588867281475
1.5101100620253902
-0.5914858221637778
0.684175554069735
-0.8416433926114673
julia> raw * 5 .+ 30
5-element Vector{Float64}:
45.38129443364074
37.55055031012695
27.04257088918111
33.420877770348675
25.791783036942665
आउटपुट को देखकर यह बताना मुश्किल है कि मूल आउटपुट यूनिफॉर्म वितरण की तुलना में शून्य के अधिक करीब इकट्ठा होता है। अगर संदेह हो, तो 1000 या उससे अधिक वैल्यू बनाइए और उन्हें प्लॉट कीजिए ताकि यह साफ़ दिखे।
Random मॉड्यूलयह मॉड्यूल अगले स्तर की सुविधाएँ रखता है, जिन्हें Julia के डिफॉल्ट कॉन्फिगरेशन का आकार कम रखने के लिए Base से बाहर रखा गया है।
Random Base के rand और randn के साथ बदलाव करने वाले रूप भी जोड़ता है, rand! और randn!।
एक उपयोगी जोड़ randstring है, जो दी गई लंबाई की एक स्ट्रिंग बनाता है।
डिफॉल्ट रूप से यह बड़े और छोटे अक्षरों के साथ 0 से 9 तक के अंकों का उपयोग करता है, लेकिन और विकल्प भी बताए जा सकते हैं।
julia> using Random
julia> randstring(20)
"BoJnIxrS33pJiWggXZQV"
इसके अलावा, एक bitrand फंक्शन है जो बताई गई लंबाई का रैंडम BitArray बनाता है।
julia> bitrand(5)
julia> bitrand(5)
5-element BitVector:
1
1
0
0
1
किसी Vector के एलिमेंट्स को बेतरतीब ढंग से शफल करने के लिए हमारे पास shuffle है; साथ ही shuffle! भी है जो इनपुट वेक्टर को उसी जगह बदल देता है।
julia> v = ['A', '1', '2', 'J', 'Q', 'K'];
julia> shuffle(v)
6-element Vector{Char}:
'K': ASCII/Unicode U+004B (category Lu: Letter, uppercase)
'1': ASCII/Unicode U+0031 (category Nd: Number, decimal digit)
'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
'J': ASCII/Unicode U+004A (category Lu: Letter, uppercase)
'2': ASCII/Unicode U+0032 (category Nd: Number, decimal digit)
'Q': ASCII/Unicode U+0051 (category Lu: Letter, uppercase)
# shuffles are random:
julia> shuffle(v)
6-element Vector{Char}:
'2': ASCII/Unicode U+0032 (category Nd: Number, decimal digit)
'K': ASCII/Unicode U+004B (category Lu: Letter, uppercase)
'A': ASCII/Unicode U+0041 (category Lu: Letter, uppercase)
'Q': ASCII/Unicode U+0051 (category Lu: Letter, uppercase)
'J': ASCII/Unicode U+004A (category Lu: Letter, uppercase)
'1': ASCII/Unicode U+0031 (category Nd: Number, decimal digit)
कभी-कभी शफल किए गए इंडेक्स रखना काम आता है।
इसके लिए randperm(n) इस्तेमाल कीजिए, जहाँ n अनुक्रम की लंबाई है।
julia> randperm(6)
6-element Vector{Int64}:
6
2
4
1
3
5
वास्तव में, ऊपर का उदाहरण shuffle(1:6) जैसे ही परिणाम देता है।
इससे जुड़े फंक्शनों में randsubseq है, जो तय प्रायिकता के साथ एलिमेंट्स निकालता है, और randcycle है, जो चक्रीय परमुटेशन बनाता है।
इनके लिए कुछ खास जानकारी चाहिए, इसलिए अगर आपकी दिलचस्पी हो तो डॉक्युमेंटेशन देख लीजिए।
कई रैंडम नंबर जनरेटर (RNG) एल्गोरिदम मानक रूप से Random में मौजूद हैं, और उचित गणितीय कौशल रखने वाला कोई भी और जोड़ सकता है।
ऐसी चीज़ें इस दस्तावेज़ के दायरे से कहीं बाहर हैं!
RNG के साथ काम करने का एक और आम कारण seed बताना है, जिससे "रैंडम" आउटपुट का क्रम एक रन से अगले रन तक दोहराने योग्य बन जाता है।
ऐसा दोहराव प्रोडक्शन कोड में उचित नहीं है, लेकिन यह टेस्टिंग और डीबगिंग में मदद कर सकता है।
Exercism के बाहर, रैंडमनेस, प्रायिकता और सांख्यिकी से जुड़े कई इंस्टॉल करने योग्य पैकेज हैं।
थोड़ी और जानकारी के लिए Statistics कॉन्सेप्ट देखिए।
StatsBase.jl पैकेजStatsBase के ज़्यादातर फंक्शन काफी तकनीकी हैं और इस दस्तावेज़ से जुड़े नहीं हैं।
अपवाद StatsBase.sample है, जो रिप्लेसमेंट के साथ या बिना सैंपलिंग का पूरा कार्यान्वयन देता है (ऊपर का भाग देखिए)।
भारित (गैर-यूनिफॉर्म) सैंपलिंग के लिए भी फंक्शन हैं।
Distributions.jl पैकेजuniform और normal (या गाऊसी) वितरण ऊपर बताए गए हैं।
Random मॉड्यूल में randexp भी है, जो Exponential Distribution से सैंपल करता है, जो (बहुत आम) Poisson Distribution से जुड़ा है।
बहुत अधिक विकल्पों के लिए Distributions.jl पैकेज है, उन लोगों के लिए जिनकी सांख्यिकी में उचित पृष्ठभूमि है।