F #

2011-09-18 14 views
5

में किसी फ़ंक्शन के एकाधिक मूल्यांकन को बल दें I F # में एक यादृच्छिक संख्या "जनरेटर" विकसित करने का प्रयास कर रहा हूं।F #

मैं सफलतापूर्वक निम्नलिखित समारोह बनाया:

let draw() = 
    let rand = new Random() 
    rand.Next(0,36) 

यह ठीक काम करता है और यह 0 और 36.

हालांकि बीच की एक संख्या उत्पन्न करता है, मैं एक समारोह इस समारोह में कई बार चलाता है कि बनाने के लिए कोशिश कर रहा हूँ ।

मैं निम्नलिखित

let multipleDraws (n:int) = 
    [for i in 1..n -> draw()] 

की कोशिश की लेकिन, मैं केवल एक ही परिणाम मिलता है, के रूप में draw समझ के लिए केवल एक बार मूल्यांकन किया जाता है।

मैं draw फ़ंक्शन के एकाधिक निष्पादन को कैसे लागू कर सकता हूं?

उत्तर

8

समस्या यादृच्छिक प्रकार के साथ है। यह बीज उत्पन्न करने के लिए कंप्यूटर के समय का उपयोग करता है और फिर यादृच्छिक संख्या उत्पन्न करता है। चूंकि व्यावहारिक रूप से कॉल का समय समान है, वही बीज उत्पन्न होता है और इसी प्रकार भी वही संख्या लौटा दी जाती है। रेमन के जवाब समझने में सहायता मिलेगी इस जोड़ना

let multipleDraws (n:int) = 
    [for i in 1..n -> draw()] 
+0

ठीक है धन्यवाद, लेकिन मुझे समझ में नहीं आता है, समाधान का उपयोग करके, मुझे अभी भी बीज के साथ एक ही समस्या क्यों नहीं है? – SRKX

+0

रैंडम के निर्माता को कॉल करते समय, आप वर्तमान कंप्यूटर के समय के आधार पर एक बीज उत्पन्न करते हैं। फिर, अगली विधि के लिए प्रत्येक कॉल पिछले बीज * के आधार पर एक नया बीज * उत्पन्न करता है, और उस समय के आधार पर नहीं।चूंकि आप अब समय पर निर्भर नहीं हैं, इससे कोई फ़र्क नहीं पड़ता कि आपकी कॉल उसी मशीन समय पर की जाती है। –

+2

@ एसआरकेके: आप 'printfn "ड्रा को जोड़ना चाहते हैं, जिसे' ड्रॉ 'बॉडी की पहली पंक्ति के रूप में जाना जाता है, यह देखने के लिए कि क्या हो रहा है: आपको केवल एक आउटपुट दिखाई देगा। आपका 'ड्रा' फ़ंक्शन पूर्णांक लौटाता है, जबकि उत्तर में से एक हस्ताक्षर '(इकाई -> int)' के साथ अनाम कार्य देता है जिसे वास्तव में सूची समझ में बुलाया जाता है। यह अज्ञात फ़ंक्शन 'रैंड' मान को बंद करने में कैप्चर करता है, 'रैंड' केवल एक बार बीजित हो जाता है। –

6

:

यह आपकी समस्या का समाधान होगा:

let draw = 
    let rand = new Random() 
    fun() -> 
    rand.Next(0,36) 

और फिर।

यह कोड लैम्बडा फ़ंक्शन का उपयोग करता है।

let draw = 
    let rand = new Random() 
    fun() -> 
    rand.Next(0,36) 

यदि आप लैम्ब्डा फ़ंक्शन को नाम देते हैं तो यह समझना आसान हो सकता है कि क्या हो रहा है।

let draw = 
    let rand = new Random() 
    let next() = 
     rand.Next(0,36) 
    next 

परिवर्तनीय ड्रा को अगले कार्य को सौंपा जा रहा है। असाइनमेंट को सीधे देखने के लिए आप ड्रैंड के दायरे से आगे और आगे बढ़ सकते हैं।

let rand = new Random() 
let next() = 
    rand.Next(0,36) 
let draw = next 

आप उपरोक्त कोड, जबकि यह SRKX के उदाहरण में कई बार कहा जाता है कि रेमन के जवाब में नए रैंडम केवल एक बार कहा जाता है से देख सकते हैं।

जैसा कि रेमन रैंडम द्वारा वर्णित एक यादृच्छिक बीज के आधार पर संख्याओं का अनुक्रम उत्पन्न करता है। यदि आप एक ही बीज का उपयोग करते हैं तो यह हमेशा संख्याओं का एक ही अनुक्रम उत्पन्न करेगा। आप इस new Random(2) जैसे यादृच्छिक बीज को पारित कर सकते हैं। यदि आप इसे एक मूल्य नहीं पारित करते हैं तो यह वर्तमान समय का उपयोग करता है। तो यदि आप बीज के बिना लगातार पंक्ति में नए रैंडम को कई बार कॉल करते हैं तो इसकी संभावना उतनी ही बीज होगी (क्योंकि समय बदल नहीं गया है)। यदि बीज नहीं बदलता है तो अनुक्रम की पहली यादृच्छिक संख्या हमेशा वही होगी। यदि आप एसआरकेएक्स के मूल कोड को आज़माते हैं और बड़ी संख्या में एकाधिक ड्रॉ को कॉल करते हैं, तो लूप के दौरान समय बदल जाएगा और आप संख्याओं का एक अनुक्रम वापस प्राप्त करेंगे जो हर बार बदलते हैं।

+0

अतिरिक्त स्पष्टीकरण के लिए धन्यवाद! यह इसे और भी स्पष्ट बनाता है। – SRKX

संबंधित मुद्दे