2011-11-08 20 views
16

मैं सिर्फ पता चला कठिन रास्ता है कि srand(1) फिर सेट करता है सी के PRNG (++) srand के लिए किसी भी कॉल करने से पहले राज्य (के रूप में reference में परिभाषित करने के लिए)। हालांकि, बीज 0 ऐसा ही प्रतीत होता है, या srand पर किसी भी कॉल से पहले राज्य बीज 0 उन दो कॉलों के बीच क्या अंतर है या वे एक ही कारण क्या हैं?क्या srand के बीच का अंतर (1) और srand (0)

उदाहरण के लिए इस कोड (execute on Ideone)

#include <stdio.h> 
#include <stdlib.h> 

int main() { 
    for (int seed = 0; seed < 4; seed++) { 
     printf("Seed %d:", seed); 
     srand(seed); 
     for(int i = 0; i < 5; i++) 
      printf(" %10d", rand()); 
     printf("\n"); 
    } 
    return 0; 
} 

रिटर्न

Seed 0: 1804289383  846930886 1681692777 1714636915 1957747793 
Seed 1: 1804289383  846930886 1681692777 1714636915 1957747793 
Seed 2: 1505335290 1738766719  190686788  260874575  747983061 
Seed 3: 1205554746  483147985  844158168  953350440  612121425 
+1

बहुत ही रोचक सवाल। मेरे ज्ञान के लिए, srand में कोई "जादू" मान नहीं है, लेकिन रैंड() को केवल 1 के बीज में शुरू किया जाता है, और इस प्रकार उस बीज के साथ शुरू होता है जब तक कि कुछ अलग न हो। जो _implicitly_ का अर्थ होगा कि यदि आप srand (1) कहते हैं, तो आप "मूल स्थिति पर रीसेट करें"। हालांकि, आपके द्वारा पोस्ट किए गए आउटपुट से पता चलता है कि यह वास्तव में बीज 0 पर "जादुई रूप से रीसेट" होता है जिसे आपने पहले सेट किया था, न कि 1 (जो, बीटीडब्ल्यू। मेरा कार्यान्वयन _not_ करता है)। – Damon

उत्तर

11

यह शायद एक कार्यान्वयन विस्तार है। मानक जनादेश है कि यादृच्छिक बीज 1 विशेष है, और आपके विशिष्ट यादृच्छिक जनरेटर एल्गोरिदम का आंतरिक रजिस्टर शायद शून्य-प्रारंभिक है, इस प्रकार बीज (0) और बीज (1) के लिए एक ही यादृच्छिक अनुक्रम उत्पन्न होता है। मैं भी दांव लगाना चाहते हैं अपने srand की पहली पंक्ति() कार्यान्वयन की तरह लग रहा है कि:

if (seed == 1) seed = 0; 

मानक अनुरूप व्यवहार के लिए मजबूर करने।

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

+9

असल में, कोड 'if (seed == 0) बीज = 1;' जैसा है, क्योंकि, 'रैंड()' के जीएनयू कार्यान्वयन द्वारा उपयोग किए गए एल्गोरिदम शून्य के बीज के साथ काम नहीं करता है। –

7

न तो सी है और न ही सी ++ मानकों rand() और srand() के कार्यान्वयन की बारीकियों के बारे में ज्यादा कहना है। विवरण लगभग पूरी तरह से कार्यान्वयन करने के लिए छोड़ दिया जाता है। सी मानक की आवश्यकता है कि:

यदि srand को उसी बीज मूल्य के साथ बुलाया जाता है, तो छद्म-यादृच्छिक संख्याओं का अनुक्रम दोहराया जाएगा। यदि रैंड से पहले srand के लिए किसी भी कॉल किया गया है कहा जाता है, उसी क्रम जब srand पहले की 1.

एक बीज मूल्य के साथ कहा जाता है के रूप में उत्पन्न हो जाएगा, लेकिन यह किसी भी आवश्यकता शामिल नहीं है कि अलग बीज विभिन्न अनुक्रमों का उत्पादन करना होगा। जाहिर है, आपके सिस्टम पर, शून्य और एक के बीज समान प्रभाव डालते हैं। मुझे लगता है कि यह पीआरएनजी को प्रारंभिक स्थिति में रीसेट करने के लिए srand(0) की अपेक्षा रखने वाले सॉफ़्टवेयर के कुछ टुकड़े के साथ पिछड़ा संगतता प्रदान करना है।

0

मैन्युअल पृष्ठों को पढ़ते समय, वे सभी कहते हैं कि "यदि कोई बीज मूल्य प्रदान नहीं किया जाता है, तो रैंड() फ़ंक्शन स्वचालित रूप से 1 के मान के साथ बीजित होता है। शायद यही कारण है कि आप संदर्भ पृष्ठ को यह कहते हैं कि 1 से बीजिंग राज्य को रीसेट करता है।

वही परिणाम 0 और 1 दोनों के साथ बीजिंग के लिए होता है, यह संभवतः कार्यान्वयन पर निर्भर करता है, और सभी प्लेटफार्मों पर होने पर गिना नहीं जाना चाहिए।

0

srand() फ़ंक्शन छद्म-यादृच्छिक संख्याओं के एक नए अनुक्रम के लिए बीज के रूप में तर्क का उपयोग करता है जिसे बाद में कॉल द्वारा रैंड() तक वापस किया जाता है। यदि srand() को उसी बीज मान के साथ बुलाया जाता है, तो छद्म-यादृच्छिक संख्याओं का अनुक्रम दोहराया जाएगा। यदि srand() को किसी भी कॉल से पहले रैंड() कहा जाता है, तो वही क्रम उत्पन्न किया जाएगा जब srand() को पहले 1 के बीज मान के साथ बुलाया जाता है।

शायद उपयोगी: http://pubs.opengroup.org/onlinepubs/009695399/functions/rand.html

1

बीज 1 पर सेट है, तो जनरेटर अपनी प्रारंभिक मूल्य के लिए इसे पुनः शुरू और रैंड या srand के लिए किसी भी कॉल करने से पहले मान जैसे ही पैदा करता है।srand संदर्भ

15

कैसे glibc यह करता है से लिया:

around line 181 of glibc/stdlib/random_r.c, समारोह __srandom_r

/* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */ 
    if (seed == 0) 
    seed = 1; 

अंदर लेकिन वह कितना glibc यह करता है। यह सी मानक पुस्तकालय के कार्यान्वयन पर निर्भर करता है।

-3

कारण 1 निर्दिष्ट है क्योंकि कुछ यादृच्छिक संख्या जेनरेटर शून्य पर फंस जाएंगे यदि बीज शून्य पर सेट हो। उदाहरण के लिए शिफ्ट-रजिस्ट्रार और गुणक संगत प्रकार यानी r(n+1) = (A * r(n))mod M

कई सी कार्यान्वयन रैखिक संगठनात्मक r(n+1) = (A * r(n) + B) mod M, बी <> 0 जो अटक नहीं जाते हैं का उपयोग करते हैं।

+0

इस प्रश्न के साथ क्या करना है? – melpomene

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