2010-07-01 20 views
8

जीसीसी 4.4.4 c89यादृच्छिक संख्या उत्पन्न करने के लिए रैंड का उपयोग

मैं नीचे दिए गए कोड का उपयोग कर रहा हूं। हालांकि, मुझे वही नंबर मिल रहा है:

size_t i = 0; 

    for(i = 0; i < 3; i++) { 
     /* Initialize random number */ 
     srand((unsigned int)time(NULL)); 
     /* Added random number (simulate seconds) */ 
     add((rand() % 30) + 1); 
    } 

मैं 0 से 30 लौटा देना चाहता हूं। हालांकि, पिछली बार जब मैंने इसे चलाया तो मुझे 17 बार तीन बार मिला।

बहुत धन्यवाद,

+2

[रैंडम संख्या समारोह misfiring है] (http के संभावित डुप्लिकेट: // stackoverflow।कॉम/प्रश्न/1068350/यादृच्छिक-संख्या-कार्य-है-मिस्फायरिंग) –

उत्तर

22

आप (क्योंकि जल्दी कैसे पाश निष्पादित किया जाएगा का एक ही मूल्य के साथ) पाश, जो एक ही हर बार होने के लिए उत्पन्न यादृच्छिक संख्या का कारण बनता है अंदर बोने रहे हैं।

/* Initialize random number */ 
srand((unsigned int)time(NULL)); 

for(i = 0; i < 3; i++) { 
    /* Added random number (simulate seconds) */ 
    add((rand() % 30) + 1); 
} 
9

आप कॉल करने के लिए srand सिर्फ एक बार, अपने कार्यक्रम की शुरुआत में की जरूरत है:

आप बाहर पाश अपने बीज समारोह बढ़ने की जरूरत है।

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

आपके मामले में समय पुनरावृत्ति से पुनरावृत्ति में नहीं बदलता है, क्योंकि इसका संकल्प केवल 1 सेकंड है, इसलिए आपको हमेशा छद्म-यादृच्छिक अनुक्रम की पहली संख्या मिल रही है, जो हमेशा समान होती है।

+1

क्या यह वाकई सच है कि आपके कार्यक्रम की शुरुआत में, केवल एक बार srand को कॉल करने की आवश्यकता है। ' मेरा मतलब है कि मुझे लगता है कि अगर किसी को जरूरत है तो उन्हें यादृच्छिक संख्या जनरेटर के बीज को बदलने और यादृच्छिक संख्याओं का एक अलग अनुक्रम प्राप्त करने के लिए 'srand' को कॉल करना चाहिए? –

+0

यह कोड के इस विशेष टुकड़े के लिए सच है;)। बेशक, जब भी आप किसी कारण से बीज बदलना चाहते हैं तो आप इसे कॉल कर सकते हैं; यह मना नहीं है। –

+0

@skwllsp और आमतौर पर केवल एक बार _per request_ है! – alexanderpas

4

आपको लूप से केवल एक बार पहले srand((unsigned int)time(NULL)) करना होगा।

2

यह पूरी तरह से संभव है कि 3 बार 17 अभी भी पूरी तरह से यादृच्छिक हैं।

1-30 और तीन चुनौतियों की एक श्रृंखला का उपयोग करते समय दो संख्याओं को प्राप्त करने के 10 में से लगभग एक मौका है। (यह birthday problem के कारण है)

अब, एक ही परिणाम प्राप्त करने के लिए अभी भी एक ही परिणाम प्राप्त करने के लिए 900 में 1 में से एक की संभावना है।

आप छद्म यादृच्छिक संख्या जनरेटर के लिए analysis page of random.org

+0

इस मामले में (भले ही यह कोडिंग गलती न हो) दो 17s एक पंक्ति के जन्मदिन की समस्या से कोई लेना देना नहीं है। यह मानते हुए कि प्रत्येक यादृच्छिक संख्या स्वतंत्र है, पंक्ति में दो 17s प्राप्त करने की संभावना की गणना करने के लिए 1/30 * 1/30 या 1/900 होगा। तीन के लिए यह 1/30 * 1/30 * 1/30, या 1/27000 होगा। – MarkD

+0

लेकिन आप भूल जाते हैं कि तीन समान संख्याएं प्राप्त करने की 30 अलग-अलग संभावनाएं हैं। 1/27000 * 30 = 1/900 – alexanderpas

+0

अब, दोनों के लिए ... वास्तव में तीन संयोजन XYX, XXY और YXY प्रत्येक 30 सकारात्मकताओं के साथ हैं। 1/900 * 30 = 1/30 * 3 = 3/30 = 1/10 – alexanderpas

1

बीज पर अधिक पृष्ठभूमि को पढ़ने के लिए चाहते हो सकता है केवल एक बार पाश के बाहर बुलाया जाना चाहिए। बीज के रूप में समय का उपयोग करना अच्छी बात है। हालांकि अभी भी वही यादृच्छिक संख्या प्राप्त करने की संभावना है।

1

मैं एसआरएंड() को खिलाने के लिए उपयोग किए जाने वाले बीज को पुनः प्राप्त करने के लिए gettimeofday() सिस्टम कॉल का उपयोग करने का भी सुझाव देता हूं।

कुछ की तरह

 

struct timeval tv; 
... 
gettimeofday(&tv, NULL); 
srand(tv.tv_usec); 
... 
 

यह दृष्टिकोण अपने छद्म संख्या पीढ़ी कोड में अधिक एन्ट्रापी जोड़ सकते हैं। निश्चित रूप से IMHO

Ciao Ciao

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