Gleiche Zufallszahlen bei jedem Schleifendurchlauf

Lesezeit: 4 Minuten

Gleiche Zufallszahlen bei jedem Schleifendurchlauf
GlassZee

Ich habe ein for Schleife, die 15 Mal läuft, mit dh.setDoors() in jeder Iteration.

Was setDoors ruft an srand(time(0))dann wird immer dann, wenn eine Zufallszahl benötigt wird, verwendet, zum Beispiel carSetter = rand()%3+1. Alternativ kann es verwendet werden decider = rand()%2+1.

Jetzt normal decider und carSetter unterschiedlich verwendet werden, aber ich vermutete ein Problem und ließ es ausdrucken carSetter und decider bei jeder Iteration. Folgendes kam dabei heraus:

Door 1 has car
Decider is 2
Door 1 has car
Decider is 2
Door 1 has car
Decider is 2
Door 1 has car
Decider is 2
Door 1 has car
Decider is 2
etc...

Die Werte ‘1’ und ‘2’ ändern sich, wenn ich es mehrmals ausführe, sind aber während der 15 Male immer noch gleich.

Da die Schleife 15 verschiedene Male ausgeführt wird, sollte dies nicht der Fall sein carSetter und decider bei jeder Iteration eine andere Zufallszahl ausdrucken?

Wenn ich nicht habe srand(time(0))es funktioniert wie erwartet, aber es gibt kein Seed-Set, also ist es jedes Mal dieselbe Folge von “Zufallszahlen”, also ist es wahrscheinlich ein Problem mit dem Seed?

  • Die Aussaat sollte erfolgen Einmal, je. Informieren Sie sich darüber, wie Pseudozufallszahlengeneratoren funktionieren, und es ist wahrscheinlich gut, auch etwas Wahrscheinlichkeitstheorie zu lernen, während Sie dabei sind.

    – Kerrek SB

    12. Februar 2012 um 17:52 Uhr


  • Ich verwende srand nur einmal in setDoors, setDoors wird nur 15 Mal wiederholt. Ist das Problem, dass srand 15 Mal wiederholt wird?

    – GlassZee

    12. Februar 2012 um 17:55 Uhr

  • @GlassZee: Ja. Wie Kerrek bereits sagte, sollten Sie das tun srand einmal in Ihrem Programm.

    – Leichtigkeitsrennen im Orbit

    12. Februar 2012 um 17:56 Uhr


  • @GregHewgill: … das heißt, die tatsächlich Vervollständigen Sie den minimalen Testfall, mit dem das OP debuggt.

    – Leichtigkeitsrennen im Orbit

    12. Februar 2012 um 17:59 Uhr


  • Ein Kommentar zum Stil: Sie verwenden 0 als Zeigerwert in time(0). In modernem C++, insbesondere mit C++11, ist es eine schlechte Idee, es zu verwenden 0 als Zeiger. Verwenden nullptr wenn die Compiler, auf die Sie abzielen, dies unterstützen: srand(time(nullptr)). Wenn der Compiler nicht unterstützt nullptr dann NULL ist zumindest eine kleine Verbesserung gegenüber 0. Auch der <random> Die Bibliothek ist großartig, obwohl sie vielleicht ein bisschen über einen Studenten der ersten Woche hinausgeht.

    – Namen53

    12. Februar 2012 um 22:28 Uhr


Gleiche Zufallszahlen bei jedem Schleifendurchlauf
Greg Hewgill

Wenn du anrufst srand(x)dann der Wert von x bestimmt die Folge von Pseudo-Zufallszahlen, die bei folgenden Aufrufen an zurückgegeben werden rand(), hängt ganz vom Wert ab x.

Wenn Sie in einer Schleife sind und anrufen srand() oben:

while (...) {
    srand(time(0));
    x = rand();
    y = rand();
}

dann ist die gleich Abhängig vom Wert wird eine Zufallszahlenfolge generiert time(0) kehrt zurück. Da Computer schnell sind und Ihre Schleife wahrscheinlich in weniger als einer Sekunde läuft, time(0) gibt die zurück gleich Wert jedes Mal durch die Schleife. Damit x und y wird bei jeder Iteration gleich sein.

Stattdessen müssen Sie in der Regel nur anrufen srand() Einmal zu Beginn Ihres Programms:

srand(time(0));

while (...) {
    x = rand();
    y = rand();
}

Im oben genannten Fall x und y jedes Mal durch die Schleife unterschiedliche Werte haben.

  • Zieh meine blauen Pseudoschuhe an…

    – Kerrek SB

    12. Februar 2012 um 18:19 Uhr

Jedes Mal, wenn Sie aufrufen srand(time(0))du bist Aussaat den Pseudo-Zufallszahlengenerator, der ihn mit einer neuen Pseudo-Zufallszahlenfolge durchdringt. Die Reihenfolge ist unterschiedlich, je nachdem, wozu das Argument dient srand ist, und in diesem Fall verwenden Sie time(0) Wenn Sie also Ihr Programm höchstens einmal pro Sekunde aufrufen, erhalten Sie immer eine neue Sequenz. Wenn du anrufst rand()erhalten Sie nur die nächste Zahl in dieser Sequenz.

Da haben Sie sich jedoch für einen Anruf entschieden srand mehrmals in Ihrem Programm und weil Ihr Programm schnell ist (d. h time(0) ändert sich nicht), alles, was Sie tun, ist, den PRNG wiederholt auf dieselbe Sequenz zurückzusetzen. Aus diesem Grund erhalten Sie immer die gleichen Werte – Sie setzen den PRNG immer wieder neu auf dieselbe Sequenz, und dies bewegt auch den Cursor an den Anfang der Sequenz.

Einmal säen. Einmal.

Wie Kerrek sagte, wird das Seeding nur einmal am Anfang des Programms durchgeführt. Nach einem srand call rand so oft du willst.

1646311808 278 Gleiche Zufallszahlen bei jedem Schleifendurchlauf
Magnus Hof

Du musst laufen srand am Anfang Ihres Programms, zum Beispiel in der main-Funktion.

Wenn du rennst srand(time(0)) oben in der Funktion, die Sie verwenden rand()werden Sie ihm wahrscheinlich jedes Mal denselben Samen geben. time(0) gibt die Zeit in Sekunden an, Sie müssten also vermeiden, anzurufen setDoors zweimal innerhalb derselben Sekunde, um jedes Mal unterschiedliche Zahlen zu erhalten. Wenn du tun Anruf setDoors zweimal innerhalb derselben Sekunde, wird der Zufallsstartwert derselbe sein, und nachfolgende Aufrufe an rand() erzeugt die gleiche Folge von Pseudozufallszahlen.

923550cookie-checkGleiche Zufallszahlen bei jedem Schleifendurchlauf

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

Privacy policy