2010-03-07 16 views
5

Ich muss eine MonteCarlo-Simulationen parallel auf verschiedenen Maschinen ausführen. Der Code ist in C++, aber das Programm ist eingerichtet und gestartet mit einem Python-Skript, das eine Menge Dinge, insbesondere die zufällige Saat setzt. Die Funktion setseed thake eine 4 Byte unsigned integerBester Seed für parallelen Prozess

ein einfaches

import time 
setseed(int(time.time())) 

Verwendung ist nicht sehr gut, weil ich die Jobs in eine Warteschlange auf einem Cluster einreichen, bleiben sie für einige Minuten anhängig dann sie beginnt, aber es kann die Startzeit ist impredicible sein, dass zwei Jobs zur gleichen Zeit (Sekunden) beginnen, so dass ich wechseln:

setseet(int(time.time()*100)) 

aber ich bin nicht glücklich. Was ist die beste Lösung? Vielleicht kann ich Informationen kombinieren aus: Zeit, Maschinen-ID, Prozess-ID. Oder vielleicht ist die beste Lösung, von/dev/random (Linux-Maschinen) zu lesen?

Wie liest man 4 Bytes aus/dev/random?

f = open("/dev/random","rb") 
f.read(4) 

geben Sie mir eine Zeichenfolge, ich möchte eine ganze Zahl!

+1

Sie haben nicht wirklich gesagt, was "am besten" ausmacht. Ich nehme an, dass Sie versuchen, sicherzustellen, dass jede Instanz einen anderen Samen verwendet. Aber sollten sie zwischen verschiedenen Jobs in einem einzigen Durchlauf eindeutig sein, oder benötigen Sie etwas, das der globalen Eindeutigkeit (alle ausgeführt und alle Jobs) nahe kommt (oder garantiert ist)? Zweitens, müssen Sie in der Lage sein, einen Lauf mit den gleichen Startwerten zu wiederholen (manchmal hilfreich beim intermittierenden Debugging). Und es könnte andere Komplikationen geben. – dmckee

+0

Ich möchte für jeden Fall einen Zufallssamen haben. Wenn der Seed von 0 bis 2^(8 * 4) -1 ist, ist es sehr wahrscheinlich, dass die Samenkörner für jeden Fall unterschiedlich sind. Ich zwinge die Samen nicht dazu, anders zu sein, selbst wenn es vielleicht besser wäre, wenn sie es wären. Ich denke, es ist kein großes Problem. Ich brauche nicht wiederholen mit dem gleichen Saatgut laufen. –

+0

Nun, das ist der einfache Fall und Sie haben bereits gute Antworten. Prost. – dmckee

Antwort

5

Lesen von /dev/random ist eine gute Idee. Nur wandeln die 4-Byte-String in einen Integer:

f = open("/dev/random","rb") 
rnd_str = f.read(4) 

Entweder mit struct:

import struct 
rand_int = struct.unpack('I', rnd_string)[0] 

aktualisieren Versalien- I benötigt wird.

Oder multiplizieren und fügen:

rand_int = 0 
for c in rnd_str: 
    rand_int <<= 8 
    rand_int += ord(c) 
+0

Beachten Sie, dass Sie, wenn Sie diese Spur abfahren, daran denken, Ihre Samen zu speichern, um sicherzustellen, dass Sie später die genauen Ergebnisse reproduzieren können. – Joey

+0

Ich speichere den Seed im Namen der Ausgabedatei –

+0

Danke, aber ändern 'ich' zu 'I' und rnd_string zu rnd_str –

2

Sie einfach über die vier Bytes in eine ganze Zahl kopieren könnte, sollte das die wenigsten Sorgen sein.

Aber parallele Pseudozufallszahlengenerierung ist ein ziemlich komplexes Thema und sehr oft nicht gut gemacht. Normalerweise erzeugen Sie Samen auf einer Maschine und verteilen sie an die anderen.

Werfen Sie einen Blick auf SPRNG, die genau Ihr Problem behandelt.

0

können Sie eine Zufallszahl als der Samen verwendet werden, die den Vorteil der betriebssystemunabhängig (no/dev/random erforderlich) hat, ohne Konvertierung von String in int:

Warum nicht einfach

verwenden
random.randrange(-2**31, 2**31) 

als der Keim für jeden Prozess? Etwas andere Startzeiten geben wild verschiedene Samen, auf diese Weise ...

Sie könnten auch die random.jumpahead Methode verwenden, wenn Sie ungefähr wissen, wie viele Zufallszahlen jeder Prozess verwenden wird (die Dokumentation von random.WichmannHill.jumpahead ist nützlich).

1

Wenn dies Linux oder ein ähnliches Betriebssystem ist, möchten Sie /dev/urandom - es produziert immer sofort Daten.

/dev/random möglicherweise warten, bis das System Zufälligkeit sammeln. Es produziert kryptografische Zufallszahlen, aber das ist zu viel für Ihr Problem.

+0

Ich weiß, aber ich bevorzuge zufällig. Ich brauche nur 4 Bytes Zufallszahl, es ist nicht zu viel –