कंप्यूटर निर्धारक हैं और यादृच्छिक संख्या उत्पन्न नहीं कर सकते हैं। इसके बजाय, वे गणितीय सूत्रों पर भरोसा करते हैं जो यादृच्छिक दिखने वाली संख्याओं का वितरण वापस करते हैं।इन्हें छद्म-यादृच्छिक संख्या जेनरेटर कहा जाता है। हालांकि, निर्धारणा के कारण, हमें समस्या है कि यदि हम अपने कार्यक्रम के प्रत्येक आमंत्रण के दौरान इन सूत्रों को उसी तरह से चलाते हैं, तो हमें वही यादृच्छिक संख्या जेनरेटर मिलेंगे। जाहिर है, यह कोई अच्छा नहीं है, क्योंकि हम चाहते हैं कि हमारी संख्या यादृच्छिक हो! इस प्रकार, हमें यादृच्छिक जनरेटर को प्रारंभिक बीज मान प्रदान करना होगा जो रन-टू-रन से बदलता है। अधिकांश लोगों के लिए (यानी, वे क्रिप्टोग्राफिकल सामान नहीं कर रहे हैं), यादृच्छिक संख्या जेनरेटर वर्तमान समय से बीजित होता है। हास्केल में, यह छद्म-यादृच्छिक जनरेटर StdGen
प्रकार द्वारा दर्शाया गया है। mkStdGen
फ़ंक्शन का उपयोग बीज के साथ यादृच्छिक संख्या जेनरेटर बनाने के लिए किया जाता है। सी के विपरीत, जहां एक वैश्विक यादृच्छिक संख्या जेनरेटर है, हास्केल में, आप जितना चाहें उतना हो सकते हैं, और आप उन्हें विभिन्न बीजों के साथ बना सकते हैं।
हालांकि, एक चेतावनी है: चूंकि संख्या छद्म-यादृच्छिक हैं, इसलिए कोई गारंटी नहीं है कि अलग-अलग बीजों के साथ यादृच्छिक संख्या जेनरेटर दूसरे नंबर की तुलना में यादृच्छिक दिखते हैं। इसका अर्थ यह है कि जब आप randomBool
पर कॉल करते हैं और इसे लगातार बीज मान देते हैं, तो इस बात की कोई गारंटी नहीं है कि आपके द्वारा बनाए गए StdGen
से प्राप्त संख्या StdGen
की तुलना में यादृच्छिक है। यही कारण है कि आप लगभग 50000 True
प्राप्त करते हैं।
वास्तव में यादृच्छिक दिखने वाले डेटा को प्राप्त करने के लिए, आपको उसी यादृच्छिक संख्या जनरेटर का उपयोग करना जारी रखना होगा। यदि आप देखते हैं, random
हास्केल फ़ंक्शन में StdGen -> (a, StdGen)
एक प्रकार है। चूंकि हास्केल शुद्ध है, random
फ़ंक्शन एक यादृच्छिक संख्या जेनरेटर लेता है, एक छद्म-यादृच्छिक मान (वापसी मूल्य का पहला तत्व) उत्पन्न करता है और फिर एक नया StdGen
देता है जो मूल बीज के साथ बीजित जनरेटर का प्रतिनिधित्व करता है, लेकिन एक देने के लिए तैयार है नया यादृच्छिक संख्या। यादृच्छिक डेटा प्राप्त करने के लिए आपको इसे अन्य StdGen
को चारों ओर रखने और इसे अगले random
फ़ंक्शन पर रखने की आवश्यकता है।
यहां एक उदाहरण है, तीन यादृच्छिक बूल, a
, b
, और c
उत्पन्न करना।
randomBools :: StdGen -> (Bool, Bool, Bool)
randomBools gen = let (a, gen') = random gen
(b, gen'') = random gen''
(c, gen''') = random gen'''
in (a, b, c)
सूचना कैसे gen
चर "पिरोया" है यादृच्छिक करने के लिए कॉल के माध्यम से।
आप एक राज्य मोनड का उपयोग करके गुजरने वाले राज्य को सरल बना सकते हैं। उदाहरण के लिए,
import Control.Monad.State
import System.Random
type MyRandomMonad a = State StdGen a
myRandom :: Random a => MyRandomMonad a
myRandom = do
gen <- get -- Get the StdGen state from the monad
let (nextValue, gen') = random gen -- Generate the number, and keep the new StdGen
put gen' -- Update the StdGen in the monad so subsequent calls generate new random numbers
return nextValue
अब आप randomBools
समारोह लिख सकते हैं:
randomBools' :: StdGen -> (Bool, Bool, Bool)
randomBools' gen = fst $ runState doGenerate gen
where doGenerate = do
a <- myRandom
b <- myRandom
c <- myRandom
return (a, b, c)
आप Bool
रों की (परिमित) सूची उत्पन्न करना चाहते हैं, तो आप
randomBoolList :: StdGen -> Int -> ([Bool], StdGen)
randomBoolList gen length = runState (replicateM length myRandom) gen
कर सकते हैं ध्यान दें कि हम वापस किए गए जोड़ी के दूसरे तत्व के रूप में StdGen
को वापस कैसे करते हैं, ताकि इसे नए कार्यों को दिया जा सके।
अधिक सरलता से, यदि आप StdGen
से उसी प्रकार के यादृच्छिक मानों की अनंत सूची उत्पन्न करना चाहते हैं, तो आप randoms
फ़ंक्शन का उपयोग कर सकते हैं। इसमें हस्ताक्षर (RandomGen g, Random a) => g -> [a]
है। x
के शुरुआती बीज का उपयोग करके Bool
की अनंत सूची उत्पन्न करने के लिए, आप बस randoms (mkStdGen x)
चलाते हैं। आप length $ takeWhile id (randoms (mkStdGen x))
का उपयोग करके अपना उदाहरण कार्यान्वित कर सकते हैं। आपको सत्यापित करना चाहिए कि x
के विभिन्न प्रारंभिक मानों के लिए आपको अलग-अलग मान मिलते हैं, लेकिन यदि आप उसी x
की आपूर्ति करते हैं तो हमेशा वही मान प्राप्त करें।
अंत में, यदि आपको IO
मोनैड से बंधे होने की परवाह नहीं है, तो हास्केल भी एक वैश्विक यादृच्छिक संख्या जेनरेटर प्रदान करता है, जो अनिवार्य भाषाओं की तरह है। IO
मोनैड में फ़ंक्शन randomIO
को कॉल करने से आप जो कुछ भी पसंद करते हैं उसका यादृच्छिक मूल्य आपको प्रदान करेगा (जब तक यह कम से कम Random
टाइपक्लास का उदाहरण है)। IO
मोनैड को छोड़कर, आप इसे समान रूप से myRandom
पर उपयोग कर सकते हैं। इसमें अतिरिक्त सुविधा है कि यह हास्केल रनटाइम द्वारा पूर्व-बीजित है, जिसका अर्थ है कि आपको StdGen
बनाने की चिंता करने की आवश्यकता नहीं है। तो, IO
इकाई में 10 Bool
रों के एक यादृच्छिक सूची बनाने के लिए, तुम सब करने की ज़रूरत है replicateM 10 randomIO :: IO [Bool].
आशा इस :)
इस पर विस्तार से बता दें मदद करता है: यादृच्छिक जनरेटर एक है करने के लिए गारंटी नहीं है बीज मूल्यों पर यादृच्छिक वितरण, लेकिन यह उत्पादित मूल्यों के अनुक्रमों पर एक यादृच्छिक वितरण देने की गारंटी है। – mange