2012-02-27 14 views
22

हर बार जब मैं rand() के साथ एक प्रोग्राम चलाता हूं तो यह मुझे एक ही परिणाम देता है।रैंड() प्रत्येक रन पर संख्याओं का समान अनुक्रम क्यों उत्पन्न करता है?

उदाहरण:

#include <iostream> 
#include <cstdlib> 

using namespace std; 

int random (int low, int high) { 
    if (low > high) return high; 
    return low + (rand() % (high - low + 1)); 
} 
int main (int argc, char* argv []) { 
    for (int i = 0; i < 5; i++) cout << random (2, 5) << endl; 
} 

आउटपुट:

3 
5 
4 
2 
3 

हर बार जब मैं इस कार्यक्रम में यह एक ही संख्या हर बार आउटपुट चलाते हैं। क्या इसके चारों ओर एक रास्ता है?

उत्तर

33

यादृच्छिक संख्या जेनरेटर के लिए बीज सेट नहीं है।

अधिक यादृच्छिक परिणाम आप srand कॉल करते हैं (समय (शून्य)) तो आप मिल जाएगा:

कारण यह है कि एक यादृच्छिक रैंड() फ़ंक्शन से उत्पन्न संख्या वास्तव में यादृच्छिक नहीं है। यह बस एक परिवर्तन है।विकिपीडिया छद्म यादृच्छिक संख्या जनरेटर के अर्थ का एक बेहतर स्पष्टीकरण देता है: निर्धारक यादृच्छिक बिट जेनरेटर। हर बार जब आप रैंड कहते हैं() यह बीज और/या आखिरी यादृच्छिक संख्या उत्पन्न करता है (सी मानक एल्गोरिदम का उपयोग नहीं करता है, हालांकि सी ++ 11 में कुछ लोकप्रिय एल्गोरिदम निर्दिष्ट करने की सुविधा है), एक चलाता है उन संख्याओं पर गणितीय ऑपरेशन, और परिणाम देता है। तो यदि बीज राज्य हर बार एक जैसा होता है (जैसा कि यदि आप वास्तव में यादृच्छिक संख्या के साथ srand को कॉल नहीं करते हैं), तो आपको हमेशा वही 'यादृच्छिक' संख्याएं मिलेंगी।

आप अधिक जानना चाहते हैं, तो आपको निम्न पढ़ सकते हैं:

http://www.dreamincode.net/forums/topic/24225-random-number-generation-102/

http://www.dreamincode.net/forums/topic/29294-making-pseudo-random-number-generators-more-random/

1

आपको यादृच्छिक संख्या जनरेटर को बीज करने की आवश्यकता है (फ़ंक्शन 'srand' देखें)। मान लीजिए कि आप क्रिप्टोग्राफी नहीं कर रहे हैं, फिर इसे 'समय' के उत्पादन के साथ बीजिंग करना काफी अच्छा है।

11

यदि आप पहले srand() पर कॉल किए बिना rand() पर कॉल करते हैं, तो यह कार्य करेगा जैसे आपने srand(1) को स्पष्ट रूप से बुलाया है। मानक C99 7.20.2.2 The srand function (जिस पर cstdlib आधारित है) की प्रासंगिक बिट राज्यों:

रैंड से पहले srand के लिए किसी भी कॉल किए गए हैं, उसी क्रम जब srand पहले एक बीज के साथ कहा जाता है के रूप में उत्पन्न हो जाएगा कहा जाता है के 1.

मूल्य दूसरे शब्दों में, आप उसी क्रम हर बार मिल जाएगा। यह मानते हुए कि आप इसे एक बार से अधिक एक दूसरे नहीं चला

int main (int argc, char* argv []) { 
    srand (time (0)); // needs ctime header. 
    for (int i = 0; i < 5; i++) 
     cout << random (2, 5) << endl; 
    wait(); 
} 

इसे ठीक करने,: आप अपने main में बदल सकते हैं।

जैसा कि बताया गया है, आपको इसके लिए ctime शीर्षलेख की आवश्यकता होगी। आपको cstdlib में भी खींचना चाहिए क्योंकि rand और srand लाइव है। उदाहरण के लिए math.h के बजाय XXX.h वाले (cmath) के बजाय cXXX हेडर का उपयोग करना आमतौर पर एक अच्छा विचार है।

तो, सभी उन परिवर्तनों (और स्पष्ट नामस्थान, जो मैं पसंद का उपयोग कर, हालांकि दूसरों को नहीं कर सकते हैं) बना रहा है, मैं के साथ समाप्त होता है:

#include <iostream> 
#include <cstdlib> 
#include <ctime> 
#include <cmath> 

void wait() { 
    int e; 
    std::cin >> e; 
} 

int random (int low, int high) { 
    if (low > high) return high; 
    return low + (std::rand() % (high - low + 1)); 
} 

int main (int argc, char* argv []) { 
    std::srand (std::time (0)); 
    for (int i = 0; i < 5; i++) 
     std::cout << random (2, 5) << '\n'; 
    wait(); 
} 

जो एक अलग अनुक्रम हर बार देता है मैं वैसे भी, कुछ बार के लिए इसे चलाने के लिए। जाहिर है, डेटा दोहराए जाने पर एक कठोर सीमा है (केवल 4 संभावनाएं हैं) और आउटपुट की "यादृच्छिक" प्रकृति का अर्थ है कि यह पहले भी दोहरा सकता है :-)

0

आप वास्तव में प्राप्त कर रहे हैं psuedo यादृच्छिक संख्या। उन्हें "अधिक यादृच्छिक" बनाने के लिए आप यादृच्छिक संख्या जनरेटर को "परिवर्तन" (आमतौर पर वर्तमान समय) का उपयोग करके बीज कर सकते हैं।

+1

नाइट: गणितीय रूप से, उन्हें "अधिक यादृच्छिक" नहीं बनाएगा। –

+0

सच है, लेकिन ओपी के प्रश्न के संदर्भ में ... (प्लस यह उद्धरणों में है ;-) – John3136

2

rand() समारोह की एक विशेषता है कि।

आपके पास जो यादृच्छिक संख्या जनरेटर नहीं है, लेकिन अधिक सख्ती से "Pseudo Random Number Generator" है। एक ही बीज के लिए एक ही यादृच्छिक अनुक्रमों को पुन: उत्पन्न करने में सक्षम होने के नाते (srand(x) फ़ंक्शन का उपयोग करके आप बीज) बग को पुन: पेश करने या प्रोग्राम रनों में राज्य को संरक्षित करने के लिए महत्वपूर्ण हो सकते हैं।

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

नोट, हालांकि, न तो सी और न ही सी ++ rand() से संख्या अनुक्रम को परिभाषित करता है। इसलिए यदि आपको प्लेटफार्मों में गारंटीकृत अनुक्रमों की आवश्यकता है, तो C++ 11 के नए यादृच्छिक संख्या जेनरेटर (उदाहरण के लिए mersenne twister) का उपयोग करें, अपना खुद का रोल करें (कुछ जेनरेटर समझने के लिए लगभग तुच्छ हैं, हालांकि, उनमें से अधिकतर विशिष्ट अतिप्रवाह व्यवहार पर भरोसा करते हैं कार्यान्वयन छोटा नहीं हो सकता है), या किसी तृतीय पक्ष घटक का उपयोग करें (जैसे बूस्ट :: यादृच्छिक)।

1

यादृच्छिक() का उपयोग करें। यह स्वचालित रूप से मूल्य बीज। या यदि आप रैंड() का उपयोग करना चाहते हैं तो आप srand (seedvalue) का उपयोग करके इसे बीज कर सकते हैं; बीज मूल्य सिस्टम समय की तरह कुछ भी हो सकता है .. यह आपको हर बार

+1

'यादृच्छिक' मानक सी ++ फ़ंक्शन नहीं है। आप किस मंच के बारे में बात कर रहे हैं? –

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