2010-03-02 6 views
10

Gibt es eine Möglichkeit, den aktuellen Zustand des eingebauten Pseudozufallszahlengenerators in Perl zu speichern, so dass, wenn mein Programm erneut ausgeführt wird, es die Sequenz von dort wieder aufnehmen kann, statt mit einer neuen Sequenz zu beginnen?Wie kann ich den Zustand des Pseudozufallsgenerators in Perl speichern?

Gerade jetzt, ich bin zu speichern, wo ich als auch die anfängliche Samen bin und dann das Anfangssegment Wegwerfen, die ich schon etwas mit ähnlich gesehen haben:

sub consume_upto_n { 
    my ($seed, $n) = @_; 
    $n = 1 unless defined $n and $n >= 1; 
    srand $seed; 
    rand for 1 .. $n - 1; 
    return; 
} 

Zum Beispiel:

srand 0x18; 
my @v = map { rand } 1 .. 5; 

Später:

consume_upto_n(0x18, 3); 
my @z = map { rand } 3 .. 5; 

Dann $z[0] == $v[2], $z[1] == $v[3] usw.

Antwort

1

Ab perl 5.13.4, srand returns the seed:

srand() gibt nun den Samen

Diese Programme erlauben die wiederholbaren Ergebnisse nicht mit ihrem eigenen Samen Erzeugungsmechanismus zu kommen, müssen haben müssen. Stattdessen können sie srand() verwenden und irgendwie die Rückkehr für zukünftigen Gebrauch verstauen. Typisch ist ein Testprogramm, das zu viele Kombinationen hat, um in der ihm zur Verfügung stehenden Zeit jeden Lauf umfassend zu testen. Er kann jedes Mal eine zufällige Teilmenge testen und bei einem Fehler den für diesen Lauf verwendeten Startwert protokollieren, damit er später zur Reproduktion der genauen Ergebnisse verwendet werden kann.

6

Ich glaube nicht, dass die integrierte rand können Sie das tun. Aber Sie können einen Ersatz rand verwenden. Zum Beispiel ermöglicht Ihnen serialize its objects (vermutlich einschließlich $MRMA::PRNG, das ist das Objekt, das durch seinen Ersatz rand verwendet wird).

Ich bin nicht ganz sicher, was der Punkt ist, obwohl. Wenn es eine einigermaßen zufällige Reihenfolge ist, wie können Sie dann feststellen, ob Sie diese Sequenz fortsetzen oder eine neue Sequenz starten?

+4

@cjm Dies ist für Simulationszwecke. Angenommen, ich habe eine Simulation, die 10.000 Züge erfordert. Die Qualität des Zufallszahlengenerators spielt keine große Rolle, aber die Fähigkeit, eine gegebene Sequenz zu reproduzieren (für jede Kombination aus Perl + OS + App-Version), ist wichtig. Ich möchte es in der Mitte unterbrechen und von dort wieder aufnehmen können, wo wir aufgehört haben. Auf diese Weise kann ich später die genaue Abfolge von Ereignissen replizieren, indem ich einfach den Anfangssamen speichere. –

+1

Sinan: Es gibt mehrere Dinge, nach denen du fragst: Die Sequenz an einem beliebigen Punkt fortsetzen zu können und genau denselben Punkt neu starten zu können. Beides kann mit einem der Math :: Random :: * Module geschehen, aber aus einer kursorischen Betrachtung der Perl-Quellen kann dies nicht (einfach) mit dem eingebauten rand() selbst aus XS heraus geschehen! (Perl kann den rand() der c library als Teil seines rand() aufrufen und die Implementierung scheint plattformabhängig zu sein.) – tsee

+0

@cjm und @tsee Es ist besser, sich nicht auf den eingebauten 'rand' zu verlassen. –