Gibt es eine alternative zum Einsatz von Zeit, um Samen eine zufällige Zahl generation?
Ich versuche, mehrere Instanzen von einem Stück code (2000-Instanzen oder so) gleichzeitig in einem Rechner-cluster. Die Weise, die es funktioniert, ist, dass ich behaupte, dass die Arbeitsplätze und die cluster werden Sie als Knoten zu öffnen, bis jeder so oft, mehrere jobs pro Knoten. Dies scheint zu produzieren, die gleiche Werte für eine gute Anzahl von Instanzen in random number generation, die eine Zeit-Saatgut.
Gibt es eine einfache alternative, die ich stattdessen verwenden können? Reproduzierbarkeit und Sicherheit sind nicht wichtig, schnelle Generierung von einzigartigen Samen ist. Was wäre der einfachste Ansatz, um dieses, und, wenn möglich, eine cross-Plattform-Ansatz wäre gut.
- Ich bin mir unklar über die situation.Sind Sie re-seeding
- Welcher Algorithmus wird verwendet für die pseudo-random number generation? d.h. lcg, Marsaglia, Mersenne Twister, etc...
- Re-seeding? Es ist ein Aufruf von srand (), wenn der kompilierte code ausgeführt wird. Aber über 100 gleichzeitige Instanzen von der kompilierte code laufen zur gleichen Zeit. Daher werden einige von denen 100 produzieren identische Zufallszahlen, da Ihre srand muss bei der gleichen Zeit.
- sollten Sie eine gettimeofday nennen, und den Samen mit dem tv.tv_usec-Wert.
- Ähm, ignorieren Sie, dass... es timed out oder so... hier meine eigentliche Antwort: Sie könnten versuchen, GUIDs, pürieren Sie diese und verwenden Sie, um Samen. Allerdings, wenn das cluster ist eine Maschine, können Sie eine Menge von gemeinsamen bits. Was könnte ich tun, haben Sie jede Anfrage ein samenkorn aus einem einzigen Samen Bereitstellung von Prozess - ... haben es seed eine Zufallszahl auf der Grundlage der Zeit. Und dann sitzt nur da und wartet für Saatgut-Anforderungen, auf die es reagiert mit die nächste zufällige Zahl in der Sequenz. Das sollte Ihnen eine schöne und gleichmäßige Verteilung der Samen für Ihre 2000 verarbeitet dabei die eigentliche Arbeit.
- Sehen Sie, wenn Sie können die Samen und verwenden Sie Sie als input-Argumente auf Ihrem Programm. Es wird einfacher sein, zu erzeugen, 2000 einzigartige Samen, bevor Sie die 2000 Arbeitsplätze.
- Brian, das wäre extrem kompliziert einzurichten, angesichts der Art und Weise der cluster eingerichtet wird. Einfach regelmäßig in einer Umgebung, die Sie Steuern, aber nicht in diese ein, wo ich kann nicht führen Sie alles auf, ohne sehr bestimmte Ressource anfordert, die kommen in die Warteschlange eingereiht und erst ausgeführt, für die bestimmte angeforderte Zeit, etc. Pre-Erzeugung von Samen ist mehr machbar, erfordert aber ein zusätzliches Skript oder code zu laufen, was irgendwie... unelegant, obwohl ich vielleicht am Ende tut es. Die rdtsc() Antwort unten scheint interessant, werde ich mir wohl geben, dass ein Schuss erste.
- Zeit benutzen, aber fügen Sie in etwas, das in Bezug auf die lokale Plattform, wie zum Beispiel der IP-Adresse oder Ihren aktuellen thread die task-ID oder so.
- Die richtige Antwort ist der eine erwähnt das C++11
std::random_device
unten zu seed eine Zufallszahl-generator. - Das ist nicht die richtige Antwort, da diese Frage ist speziell tagged-C und nicht C++, aber das ist gut für die Menschen zu wissen, ob Sie mit C++11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den
rdtsc
Unterricht ist ein ziemlich zuverlässiges (und zufällige) Streuung.In Windows es ist erreichbar über die
__rdtsc()
immanent.In GNU C, es ist erreichbar über:
Den Unterricht Maßnahmen der total pseudo-Zyklen, da der Prozessor wurde eingeschaltet. Angesichts der hohen Frequenz von heutigen Maschinen, es ist extrem unwahrscheinlich, dass zwei Prozessoren den gleichen Wert zurückgeben, auch wenn Sie gestartet, die gleichzeitig und mit der gleichen Geschwindigkeit.
Ich nehme an, Sie haben einen Prozess starten der anderen Prozesse. Haben Sie es übergeben Sie die Samen zu verwenden. Dann können Sie das master-Prozess übergeben Sie einfach eine zufällige Zahl für jedes Verfahren zu verwenden, als den Samen. Es ist wirklich nur ein beliebiger seed gewählt... Sie können Zeit für, die.
Wenn Sie nicht über ein master-Prozess starten die anderen, dann, wenn jeder Prozess mindestens einen eindeutigen index verfügt, dann, was Sie tun können, ist ein Verfahren generieren eine Reihe von Zufallszahlen in den Speicher (falls shared memory) oder in eine Datei (falls shared-disk) und dann jeden Prozess-ziehen Sie das index ' th-random number zu benutzen, als Ihre Nachkommen.
Nichts wird Ihnen eine gleichmäßige Verteilung der Samen als eine Reihe von Zufallszahlen aus einem einzelnen Samen.
Einer Kombination von PID und die Zeit sollte ausreichend sein, um eine einzigartige Samen. Es ist nicht 100% cross-Plattform, aber
getpid(3)
auf *nix-Plattformen undGetProcessId
auf Windows erhalten Sie zu 99,9% der Weg dorthin. So etwas wie dies funktionieren sollte:Konnte man auch Lesen von Daten aus
/dev/urandom
auf *nix-Systemen, aber es gibt kein äquivalent zu, die auf Windows.#include <unistd.h>
; nur im Fall, dass es nicht möglich war, Folgen Sie dem link, die Sie getpid(3).Ich würde auch empfehlen eine bessere random number generator.
Wenn C++11 verwendet werden können, dann betrachten Sie
std::random_device
. Ich würde vorschlagen, Sie zu beobachten, link eine umfassende Anleitung.Extrahieren der wesentlichen Nachricht von der video-link : Sie sollten nie Verwendung
srand
&rand
sondernstd::random_device
undstd::mt19937
- für die meisten Fällen, wäre das folgende, was Sie wollen:Statt gerade die Zeit, gemessen in Sekunden aus der C-std lib Funktion time (), könnte man stattdessen verwenden Sie die Prozessor-counter? Die meisten Prozessoren haben einen frei Laufenden tick count, zum Beispiel in x86/x64 gibt es die Time Stamp Counter:
(Die Seite hat auch viele Möglichkeiten zum Zugriff auf diesen Zähler auf verschiedenen Plattformen -- gcc/ms-visual-c/etc)
Beachten Sie, dass der timestamp-counter ist nicht ohne Fehler, es kann nicht synchronisiert werden über Prozessoren (Sie werden wahrscheinlich don ' T care für Ihre Anwendung). Und Energiespar-Funktionen kann die Uhr nach oben oder unten der Prozessor (auch du wahrscheinlich don ' T care).
Nur eine Idee... generiert eine GUID (16 bytes) und die Summe einer 4-byte oder 8-byte-Blöcken (abhängig von der erwarteten Breite der Samen), so dass integer-wrap-around. Verwenden Sie das Ergebnis als einen Samen.
GUIDs in der Regel Kapseln Eigenschaften der computer, die Sie generiert haben (z.B. MAC-Adresse), sollte es eher unwahrscheinlich, dass zwei verschiedene Maschinen, wird am Ende der Erzeugung der gleichen zufälliger Reihenfolge.
Dies ist natürlich nicht tragbar, aber die Suche nach entsprechenden APIs/Bibliotheken für das system sollte nicht zu leicht sein (z.B.
UuidCreate
auf Win32uuid_generate
auf Linux).Windows -
Bietet
CryptGenRandom()
undRtlGenRandom()
. Sie geben Ihnen eine Reihe von zufälligen bytes, die Sie verwenden können, als Samen.Finden Sie die Dokumentation über die msdn Seiten.
Linux /UNIX-Versionen
Können Sie Openssl ist
RAND_bytes()
um eine zufällige Anzahl von bytes unter linux. Es wird die Verwendung/dev/random
standardmäßig.Setzen Sie zusammen:
Beachten Sie, dass openssl stellt einen Kryptographisch sicheren PRNG standardmäßig, so können Sie es direkt benutzen. Mehr info hier.
Angenommen, Sie sind auf einem halbwegs POSIX-ish-system, sollten Sie
clock_gettime
. Diese geben die aktuelle Zeit in Nanosekunden, was bedeutet, dass für alle praktischen Zwecke, es ist unmöglich, jemals den gleichen Wert zweimal. (In der Theorie schlecht-Implementierungen könnte noch viel niedrigere Auflösung, z.B. nur die Multiplikation Millisekunden von 1 million, aber auch halb-anständige Systeme wie Linux eine echte Nanosekunden-Ergebnisse.)Wenn Einzigartigkeit ist wichtig, Sie müssen zu arrangieren, die für jeden Knoten, zu wissen, welche IDs haben behauptet worden, durch andere. Man könnte dies mit einem Protokoll Fragen: "wer behauptet, ID x?" oder arrangieren im Voraus für jeden Knoten, um eine Auswahl von IDs, die noch nicht zugeordnet wurden andere.
(GUIDs verwenden Sie die Maschine MAC, so würde in den Herbst "organisieren im Voraus" - Kategorie.)
Ohne irgendeine form von Vereinbarung, wirst du Gefahr, zwei Kletter-Knoten die gleiche ID.