2011-08-13 18 views
5

मैं एफ # का उपयोग करने यादृच्छिक ट्रिपल की एक सूची उत्पन्न करने के लिए कोशिश कर रहा हूँ -> दो यादृच्छिक संख्या और उनके योग:fsharp सूची में यादृच्छिक पीढ़ी

let foo minNum maxNum = 
    let rnd = System.Random() 
    let first = rnd.Next(minNum, maxNum) 
    let second = rnd.Next(minNum, maxNum) 
    let third = first + second 
    first, second, third 

जो इस तरह कहा जा सकता है और अच्छी तरह से काम करता है (हमेशा देता है एक नई यादृच्छिक संख्या) (जब इंटरैक्टिव एफ #) का उपयोग कर

foo 0 50 

जब यह

List.init 100 (fun index -> foo 0 50) 
तरह यादृच्छिक ट्रिपल की एक सूची उत्पन्न करने की कोशिश कर

मैं इस 100 बेतरतीब ट्रिपल की एक सूची होना चाहते हैं, लेकिन इसके बजाय वे सभी एक ही मूल्य के साथ बाहर आते हैं। मैं देख सकता हूं कि यह फ़ंक्शन इंडेक्स पर निर्भर नहीं है और इसलिए इसे पुन: गणना करने की आवश्यकता नहीं है, लेकिन मुझे यकीन नहीं है कि इसके आसपास कैसे काम करना है (मैंने इंडेक्स को एक अप्रयुक्त डमी वैरिएबल के रूप में पेश करने का प्रयास किया, इसने इंडेक्स को एक के रूप में पेश करने का भी प्रयास किया यादृच्छिक बीज, लेकिन न तो मदद की)

उत्तर

14

आप यह सोचते हैं कर रहे हैं कि कारण यह है कि अपने कोड की तरह आप इसे करना चाहते हैं काम नहीं करता है कि संकलक ग़लती से जो foo 0 50 का कारण बनता है केवल एक बार मूल्यांकन किया जाना आम उपसूचक उन्मूलन किसी प्रकार का, लागू होता है । यह मामला नहीं है। कंपाइलर बहुत अच्छी तरह से जानता है कि फ़ंक्शंस अशुद्ध हो सकते हैं और अनुकूलन निष्पादित नहीं करेंगे जो अशुद्ध कोड के साथ टूट जाएंगे (जब तक कि विशिष्ट कोड को अनुकूलित नहीं किया जा सकता है)। इसलिए आपको कंपाइलर को यह सोचने की चिंता करने की ज़रूरत नहीं है कि आप तर्क का उपयोग कर रहे हैं। यह वास्तव में कहा जाता है 100 बार की तरह आप चाहते हैं -

समस्या यह है कि foo 0 50 केवल एक बार कहा जाता है नहीं है। समस्या यह है कि यह 100 गुना प्रत्येक कॉल के समान मूल्य देता है।

लेकिन क्यों यह है कि जब यह विभिन्न मूल्यों रिटर्न आप इसे मैन्युअल का परीक्षण जब करना होगा?

क्योंकि आप एक नया रैंडम वस्तु हर बार बनाने आप foo कहते हैं। चूंकि आप उस यादृच्छिक वस्तु को बीज मूल्य प्रदान नहीं करते हैं, इसलिए इसे वर्तमान सिस्टम समय के साथ बीजित किया जाएगा। इसलिए यदि आप फ़ंक्शन को कई बार गुजरने के साथ कई बार कॉल करते हैं, तो यह हर बार अलग-अलग मान वापस कर देगा। हालांकि अगर आप इसे इतनी कम समय में 100 बार कहते हैं कि सिस्टम समय के बीच में बदलाव नहीं होता है, तो आप 100 गुणा समान मूल्य वापस ले लेंगे।

तो आपकी समस्या का हल एक ही यादृच्छिक वस्तु का पुन: उपयोग करने के बजाय एक नया एक हर बार foo कहा जाता है बनाने की है।

+0

बहुत धन्यवाद, यह काम करता है! –

3

कुछ कोड के साथ sepp2k जवाब पूरक करने के लिए:

let rnd = System.Random() 

let foo minNum maxNum = 
    let first = rnd.Next(minNum, maxNum) 
    let second = rnd.Next(minNum, maxNum) 
    let third = first + second 
    first, second, third 
11

बजाय इस कोशिश करो। यह आप अपने मुख्य दायरे में लगभग एक रखने के लिए बिना एक ही यादृच्छिक वस्तु का पुन: उपयोग होगा:

let foo = 
    let rnd = System.Random() 
    fun minNum maxNum -> 
     let first = rnd.Next(minNum, maxNum) 
     let second = rnd.Next(minNum, maxNum) 
     let third = first + second 
     first, second, third 

भी ध्यान रखें कि अगला इसलिए threadsafe नहीं है, तो आप कई धागे से foo उपयोग करना चाहते हैं आप के लिए कुछ ताला जोड़ने की जरूरत आगामी।

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