C++: seeding random number generator außerhalb von main()
War ich ein einfaches Programm, das simuliert einen Münzwurf für meine Klasse. (Eigentlich Klasse ist über diesen Begriff und ich arbeite einfach durch den rest der Projekte, die nicht erforderlich). Es beinhaltet das erstellen und aufrufen einer Funktion generiert eine Zufallszahl zwischen 1 und 2. Ursprünglich habe ich versucht die Samen, die random number generator innerhalb der Funktion, wäre es (coinToss); es kam jedoch nicht eine zufällige Zahl erzeugen. Jedes mal, wenn das Programm ausgeführt wurde, es war die gleiche Nummer, als hätte ich nur verwendet,
rand()
statt
unsigned seed = time(0);
srand(seed);
rand();
Doch, wenn ich bewegt die oben im
int main()
es geklappt hat.
Meine Frage ist, 1)warum hat es nicht funktioniert, wenn das setup innerhalb der Funktion, die es aufgerufen und (2) wie funktioniert rand()
Zugang zu dem, was getan wurde, durch srand()
wenn Sie nicht beide auftreten, in der gleichen Funktion?
Natürlich, ich bin ein Anfänger also bitte verzeiht mir, wenn ich nicht formulieren Sie die Frage richtig. Auch mein Buch hat nur kurz berührt rand()
und srand()
so das ist alles was ich wirklich weiß.
vielen Dank für jede Hilfe!!!
Relevante code:
Ersten Versuch, hat nicht funktioniert:
int main()
{
//...........
coinToss();
//...........
}
int coinToss()
{
unsigned seed = time(0);
srand(seed);
return 1 + rand() % 2;
}
Zweiten Versuch, der nicht funktioniert:
int main()
{
unsigned seed = time(0);
srand(seed);
coinToss();
}
int coinToss()
{
return 1 + rand() % 2;
}
InformationsquelleAutor knobcreekman | 2010-12-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Werden Sie wahrscheinlich wollen nur die Samen, die random number generator einmal.
rand()
liefert die nächste pseudo-Zufallszahl vom internen generator. Jedes mal, wenn Sie rufenrand()
erhalten Sie die nächste Nummer aus dem internen generator.srand()
allerdings setzt die Anfangsbedingungen der random number generator. Sie können denken, es als die Einstellung des Start-und out-point' für den internen Zufallszahlengenerator (in Wirklichkeit ist es viel komplizierter als das, aber es ist eine nützliche kognitive Modell zu Folgen).So ist, sollten Sie den Aufruf
srand(time(0))
genau einmal in der Anwendung - irgendwo in der Nähe der Anfang. Danach können Sie nennenrand()
so oft wie Sie wollen!Jedoch
Zur Beantwortung Ihrer eigentlichen Frage - die erste version funktioniert nicht, weil
time()
gibt die Anzahl der Sekunden seit dem Epoche. Also, Wenn Sie anrufencoinToss()
mehrmals in einer Sekunde (sagen, wenn Sie wollte, um zu simulieren, 100 Münze wirft), dann wären Sie ständig seeding der Zufallszahlen-generator mit der gleichen Nummer, damit ein Reset der interne Zustand (und damit die nächste Zahl, die Sie bekommen) - jedes mal.Sowieso - mit
time()
wie ein samenkornsrand()
ist etwas beschissen aus diesem Grund -time()
nicht chage sehr Häufig, und schlimmer noch, es ist vorhersehbar. Wenn Sie wissen, die aktuelle Zeit können Sie herausfinden, wasrand()
zurück. Das internet hat viele, viele Beispiele für bessersrand()
Samen.srand(time(0))
vielleicht noch OK, wenn Sie getrennt waren, durch genügend Zeit (das könnte schwierig sein, zu garantieren, also vielleicht am besten nur nennen Sie es einmal am Anfang)...danke! so, das war es erzeugen die gleiche Antwort, weil
unsigned seed = time(0)
Schlüsselseed
der Uhr und das Programm dauert weniger als eine Sekunde zu laufen, sounsigned seed = time(0)
ziehen den gleichen Wert jedes mal, wenn es heißt, datime(0)
basiert auf Sekunden?Sicher nicht... Sie könnten in der Lage sein, um zu testen, ob durch Zugabe eines
sleep()
von 2-5 Sekunden zwischen den aufrufen der Funktion.wird die operative Wort. Es ist durchaus möglich, dass die srand monoton steigende Werte jedes mal, wenn Sie rufen, rand würde noch vermasseln die "Zufälligkeit".
Gut, es gibt wirklich keine Notwendigkeit, überhaupt zu call srand() mehrere Male, mit der möglichen Ausnahme von der Anwendung Zugang zu einem besseren Ausgangswert oder einen besseren generator, später in der Ausführung. Aber da reden wir über das, was ist im wesentlichen Hausaufgaben, und nicht die Kryptografie, ich denke wir können es dabei belassen. 🙂
InformationsquelleAutor Thomi
Pseudo-Zufallszahlengeneratoren (wie
rand
) arbeiten, indem Sie eine einzelne startnummer (das samenkorn) und der Durchführung einer numerischen transformation auf jedes mal, wenn Sie eine neue Nummer. Sie möchten Samen der generator nur einmal, oder es wird ständig wieder, das ist nicht, was Sie wollen.Als Sie entdeckt, sollten Sie nur tätigen
srand
nur einmal inmain
. Beachten Sie auch, dass eine Reihe vonrand
Implementierungen haben ziemlich kurze Zyklen auf die niedrigen 4 bits oder so. In der Praxis bedeutet dies, dass Sie eventuell ein leicht vorhersehbarer wiederholenden Zyklus von zahlen, möchten Sie vielleicht, um eine Verschiebung der Rückkehr ausrand
rechts von 4-8 bits, bevor Sie die% 2
.EDIT: würde Der Aufruf so Aussehen:
return 1 + (rand() >> 6) % 2;
Ich bearbeitet meine Antwort, um zu zeigen, wie der code Aussehen würde. Neuere
rand
Implementierungen nicht haben, dass sich Fehler obwohl.ok, vielen Dank. ich lese bis auf, dass
InformationsquelleAutor Mark B
Samen nur einmal pro Programm, nicht jedes mal, wenn Sie anrufen
coinToss()
InformationsquelleAutor John Dibling
Erweitern Mark B ' s Antwort: Es ist nicht so viel, dass der Zufallszahlen-generator wird immer dann zurückgesetzt, setzt es eine neue Variablen in die Berechnung der Zufallszahlen. Aber Ihr Programm nicht tun, dass viel Arbeit zwischen den anrufen zu srand. Deshalb ist jeder Aufruf srand(time(0)) es ist mit den gleichen Samen, Sie sind also das zurücksetzen des internen Zustand des Zufallszahlengenerators . Wenn man ein sleep-in gibt, so dass die Zeit(0) geändert, Sie würden nicht die gleiche Anzahl jedes mal.
Als für wie Daten geht vom srand, rand, es ist ziemlich einfach, eine Globale variable verwendet. Alle Namen beginnen mit einem Unterstrich und einem Großbuchstaben oder zwei Unterstriche sind reserviert für Variablen verwendet, die von Ihrem compiler. Mehr als wahrscheinlich, dass diese variable als static deklariert, so dass es nicht sichtbar außerhalb der übersetzungseinheit(aka die Bibliothek-Datei, die enthält den compiler standard-Bibliothek.) Dies geschieht so, dass #define-SACHEN 5 nicht brechen Sie Ihre standard-Bibliothek.
InformationsquelleAutor stonemetal
für einfache Simulationen, Sie müssen nicht ändern Sie die Samen auf alle während der simulation. Ihre simulation "schlimmer" in diesem Fall.
Um dies zu verstehen, sollten Sie sehen, pseudo-random-Sequenzen als ein großes Glücksrad. Wenn Sie ändern Sie den seed, es ist wie Sie die position ändern, und dann, jeder Aufruf von rand wird Ihnen eine verschiedenen Anzahl. Wenn Sie wieder Rollen, wird es wahrscheinlicher finden, sich wiederholende zahlen ein.
InformationsquelleAutor Javier Loureiro