2011-01-31 19 views
10

संभावित डुप्लिकेट:
c# - getting the same random number repeatedly
Random number generator not working the way I had planned (C#)यादृच्छिक संख्या पीढ़ी - एक ही नंबर लौटे

मैं एक विधि है कि ints की एक कतार बनाता है:

public Queue<int> generateTrainingInts(int count = 60) 
    { 
     Queue<int> retval = new Queue<int>(); 

     for (int i = 0; i < count; i++) 
     { 
      retval.Enqueue(JE_Rand.rInt(2001, 100)); 
     } 

     return retval; 
    } 

JE_Rand .rInt() सिर्फ एक समारोह है जो प्रतिनिधि रैंडम वर्ग के एक समारोह के लिए तों:

public static int rInt(int exclUB, int incLB = 0) 
    { 
     Random rand = new Random(DateTime.Now.Millisecond); 
     int t = rand.Next(incLB, exclUB); 
     rand = null;    
     return t; 
    } 

लेकिन जब मैं generateTrainingInts कहते हैं, एक ही नंबर हर बार कतारबद्ध कर रहा है। हालांकि, यदि मैं स्थानीय उदाहरण के बजाय रैंडम क्लास के स्थिर उदाहरण का उपयोग करने के लिए आरआईएनटी बदलता हूं (फ़ंक्शन स्कोप के साथ जैसा ऊपर परिभाषित किया गया है), तो यह सही ढंग से काम करता है (यादृच्छिक पूर्णांक संलग्न करें)। क्या कोई जानता है कि ऐसा क्यों होता है?

संपादित करें: प्रिय उत्तरदाताओं जिन्होंने मेरे प्रश्न को पूरी तरह से नहीं पढ़ा, जैसा कि आप में से कुछ ने बताया, मैं ऐसा क्यों करता हूं कि यह क्यों होता है, इसकी एक अच्छी व्याख्या की तलाश में है। मैं समान संख्या में जेनरेट की गई समस्या का समाधान नहीं ढूंढ रहा हूं, क्योंकि मैंने पहले से ही तय किया है जैसा मैंने उपरोक्त कहा था। यद्यपि आपके उत्साह के लिए धन्यवाद :) मैं वास्तव में इस तरह की चीजों को समझना चाहता हूं, क्योंकि मेरा पहला कार्यान्वयन मेरे लिए अवधारणात्मक रूप से अधिक समझ में आया है।

+0

लगता है नकल ... -http तरह realted सवालों को देखो: //stackoverflow.com/questions/1437825/random-number-generation-in-c –

+0

यह इसलिए होता है क्योंकि 'Random' वस्तु से आरंभ नहीं हो जाता 'पर्यावरण।GetTickCount', जो एक मिलीसेकंद टाइमर है। इसलिए यदि आप एक ही मिलीसेकंड में दो बार 'रैंडम' कन्स्ट्रक्टर को कॉल करते हैं, तो आपको वही प्रारंभिक मान प्राप्त होगा। –

+0

जब रैंड को उसी बीज के साथ तत्काल किया जाता है (उदा। डेटटाइम.अब। मिलिसेकंड आपके मामले में), तो यह मानों के समान अनुक्रमों को वापस कर देगा। आपको इसे एक बार तुरंत चालू करना चाहिए (और इसे एक स्थिर चर में स्टोर करें), या प्रत्येक बार विभिन्न बीज के साथ। – AFract

उत्तर

23

आपको उसी Random ऑब्जेक्ट को रखने की आवश्यकता है। एक स्थिर सदस्य

private static Random rand = new Random(); 

public static int rInt(int exclUB, int incLB = 0) 
{ 
    int t = rand.Next(incLB, exclUB); 
    return t; 
} 

संपादित
कारण घड़ी की परिमित संकल्प Random प्रारंभ करने में प्रयोग किया जाता है के रूप में अपने स्थिर विधि के बाहर डाल दिया। यादृच्छिक क्रम में यादृच्छिक अनुक्रम में प्रारंभिक प्रारंभिक स्थिति समान प्रारंभिक स्थिति प्राप्त होगी। उसी रैंडम का पुन: उपयोग करते समय यादृच्छिक अनुक्रम में अगला मान हमेशा उत्पन्न होता है।

+0

ओपी ने पहले ही कोशिश की है और * क्यों * पूछ रहा था। –

+0

पीढ़ी के बाद नल को रैंड क्यों असाइन करें ?? चूंकि रैंड की बहुत कम समय सीमा में तत्काल हो जाएगा, दोनों उदाहरणों को एक ही बीज मिलेगा और उसी मूल्य को वापस कर देगा, बिल्कुल लेखक के संस्करण में। आपको इसे स्थिर रखना चाहिए और हमेशा एक ही उदाहरण रखना चाहिए। विभिन्न बीजों के साथ कई उदाहरणों का उपयोग करना भी संभव है, उदाहरण के लिए "Guid.NewGuid()। GetHashCode()" बीज के रूप में उपयोग करके, लेकिन आपको भयानक प्रदर्शन मिलेगा। – AFract

+0

मुझे लगता है कि आपने अपना कोड नमूना सही किया है। यह boggus था लेकिन यह अब काम करना चाहिए ... – AFract

5

निम्नलिखित कोड का उपयोग करें और मुझे लगता है कि यही कारण है कि आप देखेंगे:

void PrintNowAHundredTimes() 
{ 
    for (int i = 0; i < 100; ++i) 
    { 
     Console.WriteLine(DateTime.Now); 
    } 
} 

Random वस्तुओं पर एक ही बीज मिल रहा है। ऐसा इसलिए है क्योंकि सिस्टम समय की ग्रैन्युलरिटी DateTime.Now द्वारा लौटा दी गई है, काफी सरल है। उदाहरण के लिए मेरी मशीन पर मूल्य केवल ~ 15 एमएस बदलता है। तो उस समय अवधि के भीतर लगातार कॉल एक ही समय में लौट आती है।

और जैसा कि मुझे संदेह है कि आप पहले से ही जानते हैं, दो Random वही बीज मूल्य के साथ शुरू की गई वस्तुएं समान यादृच्छिक अनुक्रम उत्पन्न करती हैं। (यही कारण है कि यह, कूट-यादृच्छिक कहा जाता है तकनीकी रूप से है।)

तुम भी जानते हैं कि भले ही यह समझ में अपने विधि के भीतर स्थानीय स्तर पर एक नया Random वस्तु का दृष्टांत के लिए बनाया जाना चाहिए, null करने के लिए इसे स्थापित करने के लिए अभी भी (कोई उद्देश्य पूरा होगा एक बार विधि बाहर निकलती है वैसे भी ऑब्जेक्ट के लिए कोई और संदर्भ नहीं होगा, इसलिए यह कचरा इकट्ठा किया जाएगा)।

1
public class JE_Rand 
{ 
    private static Random rand= new Random(DateTime.Now.Millisecond); 

    public static int rInt(int exclUB, int incLB = 0) 
    { 
     int t = rand.Next(incLB, exclUB); 
     return t; 
    } 
} 
+0

क्यों रैंड = शून्य? यह ऑब्जेक्ट डंप करेगा, और अगली कॉल एक अपवाद फेंक देगा – walter

+0

@walter: यह एक पुराना जवाब है, लेकिन मैं बस उसकी कोड कॉपी और पेस्ट कर रहा था और विधि कॉल के बाहर नया रैंडम (....) ले जा रहा था। हालांकि आप 100% सही हैं। मैं अपना जवाब संपादित करूंगा। – BFree

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