Was ist der Unterschied zwischen srand(1) und srand(0)
Lesezeit: 4 Minuten
Flogo
Ich habe das gerade auf die harte Tour herausgefunden srand(1) setzt den PRNG von C(++) auf den Zustand vor jedem Aufruf zurück srand (wie in der definiert Hinweis). Der Seed 0 scheint jedoch dasselbe zu tun, oder der Zustand vor jedem Aufruf srand scheint den Startwert 0 zu verwenden. Was ist der Unterschied zwischen diesen beiden Aufrufen oder was ist der Grund, warum sie dasselbe tun?
Sehr interessante Frage. Meines Wissens hat srand keinen “magischen” Wert, aber rand() wird einfach mit einem Startwert von 1 initialisiert und beginnt daher mit diesem Startwert, sofern nichts anderes gesagt wird. Was würde implizit bedeutet, dass Sie, wenn Sie srand(1) aufrufen, “auf den ursprünglichen Zustand zurücksetzen”. Die von Ihnen gepostete Ausgabe deutet jedoch darauf hin, dass sie wirklich auf den Seed 0, den Sie zuvor festgelegt hatten, “magisch zurückgesetzt” wird, nicht auf 1 (was übrigens meine Implementierung tut nicht tun).
/* We must make sure the seed is not 0. Take arbitrarily 1 in this case. */
if (seed == 0)
seed = 1;
Aber genau so macht es glibc. Dies hängt von der Implementierung der C-Standardbibliothek ab.
Es handelt sich wahrscheinlich um ein Implementierungsdetail. Der Standard schreibt vor, dass der Zufallsstartwert 1 etwas Besonderes ist, und das interne Register Ihres spezifischen Zufallsgeneratoralgorithmus ist wahrscheinlich mit Null initialisiert, wodurch dieselbe Zufallssequenz für Startwert (0) und Startwert (1) verursacht wird. Ich würde sogar wetten, dass die erste Zeile Ihrer srand()-Implementierung so aussieht:
if ( seed == 1 ) seed = 0;
normkonformes Verhalten zu erzwingen.
Im Allgemeinen müssen die Zufallszahlengeneratoren für rand() und srand() nicht unterschiedliche Sequenzen für unterschiedliche Startwerte liefern, sondern dieselbe Sequenz für denselben Startwert. So, Verlassen Sie sich nicht darauf, dass unterschiedliche Startwerte unterschiedliche Zufallssequenzen erzeugen, und es sollte dir gut gehen. Wenn nicht, willkommen zum implementierungsspezifischen Spaß.
Eigentlich ist der Code eher wie if (seed == 0) seed = 1;da der von der GNU-Implementierung verwendete Algorithmus von rand() funktioniert nicht mit einem Startwert von Null.
– Mike Seymour
8. November 2011 um 11:42 Uhr
Weder der C- noch der C++-Standard sagen viel über die Besonderheiten der Implementierung von aus rand() und srand(). Die Details werden fast ausschließlich dem Implementierer überlassen. Die C-Norm fordert Folgendes:
Wenn dann srand mit demselben Startwert aufgerufen wird, soll die Folge von Pseudo-Zufallszahlen wiederholt werden. Wenn rand aufgerufen wird, bevor Aufrufe an srand getätigt wurden, wird dieselbe Sequenz generiert wie beim ersten Aufruf von srand mit einem Startwert von 1.
aber es enthält keine Anforderung, dass anders Samen müssen produzieren anders Sequenzen. Anscheinend haben auf Ihrem System Samen von Null und Eins denselben Effekt. Ich würde vermuten, dass dies die Abwärtskompatibilität mit einer erwarteten Software bieten soll srand(0) um den PRNG in seinen Anfangszustand zurückzusetzen.
Wenn Seed auf 1 gesetzt ist, wird der Generator auf seinen Anfangswert neu initialisiert und erzeugt die gleichen Werte wie vor jedem Aufruf von rand oder srand. Entnommen aus der Sand Hinweis
Beim Lesen von Handbuchseiten geben sie alle an: “Wenn kein Seed-Wert angegeben wird, wird die rand()-Funktion automatisch mit einem Wert von 1 gesät.” Dies ist wahrscheinlich der Grund, warum die Referenzseite, auf die Sie verlinken, besagt, dass das Seeding mit 1 den Status zurücksetzt.
Dass dasselbe Ergebnis beim Seeding mit 0 und 1 eintritt, ist höchstwahrscheinlich implementierungsabhängig und sollte nicht damit gerechnet werden, dass es auf allen Plattformen auftritt.
Manu
Die Funktion srand() verwendet das Argument als Startwert für eine neue Folge von Pseudozufallszahlen, die von nachfolgenden Aufrufen von rand() zurückgegeben werden. Wenn dann srand() mit demselben Startwert aufgerufen wird, soll die Folge von Pseudo-Zufallszahlen wiederholt werden. Wenn rand() aufgerufen wird, bevor srand() aufgerufen wird, wird dieselbe Sequenz generiert wie beim ersten Aufruf von srand() mit einem Startwert von 1.
Der Grund für die Angabe von 1 liegt darin, dass einige Zufallszahlengeneratoren bei Null hängen bleiben, wenn der Seed auf Null gesetzt wird. Zum Beispiel Schieberegister und multiplikative kongruente Typen, dh r(n+1) = (A * r(n))mod M.
Viele C-Implementierungen verwenden Linear Congruential r(n+1) = (A * r(n) + B) mod MB <> 0, die nicht stecken bleiben.
Was hat das mit der Frage zu tun?
– Melpomen
31. Juli 2016 um 7:24 Uhr
11765400cookie-checkWas ist der Unterschied zwischen srand(1) und srand(0)yes
Sehr interessante Frage. Meines Wissens hat srand keinen “magischen” Wert, aber rand() wird einfach mit einem Startwert von 1 initialisiert und beginnt daher mit diesem Startwert, sofern nichts anderes gesagt wird. Was würde implizit bedeutet, dass Sie, wenn Sie srand(1) aufrufen, “auf den ursprünglichen Zustand zurücksetzen”. Die von Ihnen gepostete Ausgabe deutet jedoch darauf hin, dass sie wirklich auf den Seed 0, den Sie zuvor festgelegt hatten, “magisch zurückgesetzt” wird, nicht auf 1 (was übrigens meine Implementierung tut nicht tun).
– Dämon
8. November 2011 um 11:24 Uhr