Was ist der Unterschied zwischen srand(1) und srand(0)

Lesezeit: 4 Minuten

Benutzer-Avatar
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?

Zum Beispiel dieser Code (auf Ideone ausführen)

#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;
}

kehrt zurück

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

  • 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


Wie glibc es macht:

etwa Zeile 181 von glibc/stdlib/random_r.cInnenfunktion __srandom_r

  /* 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.

Benutzer-Avatar
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.

Könnte nützlich sein: http://pubs.opengroup.org/onlinepubs/009695399/functions/rand.html

Benutzer-Avatar
AlessioX

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

1176540cookie-checkWas ist der Unterschied zwischen srand(1) und srand(0)

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy