2011-02-08 20 views
6

सी, रैंड() में यादृच्छिक संख्या उत्पन्न करने की कोशिश करते समय प्रत्येक बार कोड संकलित करते समय अलग-अलग संख्या उत्पन्न नहीं होती है, क्या कोई मुझे बता सकता है कि srand() का उपयोग कैसे करें या उत्पन्न करने के लिए किसी भी अन्य विधि को बताएं।सी (लिनक्स) में यादृच्छिक संख्या यादृच्छिक संख्या कैसे करें?

उत्तर

8

यह आमतौर पर प्रयोग किया जाता है समाधान:

srand (time(NULL)); 

सभी सी कोड का निष्पादन नियतात्मक है, तो आप कुछ में लाने के लिए है कि हर बार जब आप srand फोन अलग है। इस मामले में यह समय है।

या आप /dev/random से डेटा पढ़ सकते हैं (इसे किसी अन्य फ़ाइल की तरह खोलें)।

+3

कार्यक्रम एक सेकंड में कई बार चलाया जाता है, तो एक ही यादृच्छिक संख्या अनुक्रम कई बार उत्पन्न हो जाएगा के रूप में ही बीज इस्तेमाल किया गया था! – Abhi

+0

यदि आप कुछ भी नहीं बदलना चाहते हैं तो आप बस सो सकते हैं (1)। लेकिन यह बेहद sloooow होगा – Tebe

11

pseudorandom संख्याओं का अनुक्रम उत्पन्न करने के लिए, जनरेटर को seeded होना आवश्यक है। बीज पूरी तरह से संख्याओं के अनुक्रम को निर्धारित करता है जो उत्पादित किए जाएंगे। सी में, आप srand के साथ बीज, जैसा कि आप इंगित करते हैं। srand(3) मैन पेज के अनुसार, कोई स्पष्ट बीजिंग का तात्पर्य यह नहीं है कि जेनरेटर बीज के रूप में 1 का उपयोग करेगा। यह बताता है कि आप हमेशा एक ही संख्या क्यों देखते हैं (लेकिन याद रखें कि अनुक्रम स्वयं जेनरेटर के आधार पर गुणवत्ता के साथ बहुत यादृच्छिक है, भले ही अनुक्रम प्रत्येक बार समान होता है)।

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

unsigned int seed; 
FILE* urandom = fopen("/dev/urandom", "r"); 
fread(&seed, sizeof(int), 1, urandom); 
fclose(urandom); 
srand(seed); 

कॉनरोड मेयर की जवाब के प्रकाश में, मैंने सोचा कि मैं थोड़ा और विस्तार से बता चाहते हैं। मैं यादृच्छिक संख्याओं के उपयोग को तीन श्रेणियों में विभाजित करता हूं:

  1. भिन्नता। यदि आप उदाहरण के लिए एक गेम में प्रतीत होता है कि यादृच्छिक या विविध व्यवहार बनाने के लिए यादृच्छिक संख्याओं का उपयोग करते हैं, तो आपको विषय के बारे में बहुत मुश्किल सोचने की ज़रूरत नहीं है, या उचित बीज चुनने की आवश्यकता नहीं है। समय के साथ बीज, और कुछ अन्य समाधान देखो अगर यह पर्याप्त अच्छा नहीं है। यहां तक ​​कि अपेक्षाकृत खराब आरएनजी भी इस परिदृश्य में पर्याप्त यादृच्छिक दिखाई देंगे।
  2. वैज्ञानिक सिमुलेशन। यदि आप मोंटे कार्लो गणनाओं जैसे वैज्ञानिक कार्यों के लिए यादृच्छिक संख्याओं का उपयोग करते हैं, तो आपको अच्छा जनरेटर चुनने का ध्यान रखना होगा। आपका बीज तय किया जाना चाहिए (या उपयोगकर्ता परिवर्तनीय)। आप नहीं चाहते हैं (उपरोक्त अर्थ में); आप निर्धारवादी व्यवहार चाहते हैं लेकिन अच्छी यादृच्छिकता चाहते हैं।
  3. क्रिप्टोग्राफी। आप बेहद सावधान रहना चाहेंगे। यह शायद इस धागे के दायरे से बाहर है।
3

सावधान रहें; लिनक्स पर rand(3) मैनपेज नोट करता है कि कुछ प्लेटफॉर्म पर rand() कार्यान्वयन निम्न-आदेश बिट्स पर अच्छी यादृच्छिकता नहीं देते हैं। इस कारण से, आप असली यादृच्छिक संख्या प्राप्त करने के लिए लाइब्रेरी का उपयोग करना चाह सकते हैं। Glib उपयोगी कार्यों जैसे g_random_int_range() प्रदान करता है जो आपके उद्देश्य को बेहतर ढंग से सुइट कर सकता है।

4

आप एक ओएस है कि प्रदान नहीं करता है/dev/क्या नीचे

timeval t1;
gettimeofday(&t1, NULL);
srand(t1.tv_usec * t1.tv_sec);

दिखाया गया है कोड का यह टुकड़ा की तरह तो का उपयोग यादृच्छिक कुछ अन्य ओएस को आसानी से मोड़ा जा सकता है उपयोग कर रहे हैं।

बीज को बेहतर बनाने के लिए - आप मेजबान मशीन के मैक पते के साथ ऊपर दिखाए गए समय उत्पाद को जोड़ सकते हैं (शायद एमडी 5 या चेकसम एल्गोरिदम का उपयोग कर सकते हैं)।

timeval t1;
gettimeofday(&t1, NULL);
unsigned int seed = t1.tv_usec * t1.tv_sec;

unsigned char mac_addr[6];
getMAC(&mac_addr);
improveSeedWithMAC(&seed, mac_addr) ; // MD5 or checksum ...

srand(seed);

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