2010-03-02 6 views
10

Existe-t-il un moyen de stocker l'état actuel du générateur de nombres pseudo-aléatoires intégré dans Perl de sorte que lorsque mon programme est exécuté à nouveau, il peut reprendre la séquence là où elle l'avait laissée?Comment puis-je stocker l'état du générateur pseudo-aléatoire dans Perl?

En ce moment, je stocke où je suis, ainsi que la graine initiale puis jeter le segment initial que je l'ai déjà vu en utilisant quelque chose de similaire à:

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

Par exemple:

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

plus tard:

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

Ensuite, $z[0] == $v[2], $z[1] == $v[3] etc.

Répondre

1

Au perl 5.13.4, srand returns the seed:

srand() retourne maintenant la graine

Cela permet aux programmes qui ont besoin d'avoir des résultats reproductibles pour ne pas avoir à venir avec leur propre mécanisme de production de semences. Au lieu de cela, ils peuvent utiliser srand() et en quelque sorte stocker le retour pour une utilisation future. Typique est un programme de test qui a trop de combinaisons pour tester complètement le temps disponible pour chaque course. Il peut tester un sous-ensemble aléatoire à chaque fois, et en cas d'échec, consigner la graine utilisée pour cette analyse afin de pouvoir ensuite l'utiliser pour reproduire les résultats exacts.

6

Je ne pense pas que le rand intégré vous permet de faire cela. Mais vous pouvez utiliser un substitut rand. Par exemple, vous permet de serialize its objects (en incluant vraisemblablement $MRMA::PRNG, qui est l'objet qui est utilisé par son remplacement rand).

Je ne suis pas très sûr de ce que le point est, cependant. Si c'est une séquence raisonnablement aléatoire, comment pouvez-vous dire si vous continuez cette séquence ou en commencez une nouvelle?

+4

@cjm Ceci est à des fins de simulation. Dites que j'ai une simulation qui nécessite 10 000 tirages. La qualité du générateur de nombres aléatoires n'a pas beaucoup d'importance mais la possibilité de répliquer (pour n'importe quelle combinaison de versions d'application 'perl' + OS +) une séquence donnée est importante. Je veux pouvoir l'interrompre au milieu et reprendre d'où nous nous sommes arrêtés. De cette façon, je peux répliquer la séquence exacte des événements plus tard en stockant simplement la graine initiale. –

+1

Sinan: Il y a plusieurs choses que vous demandez: Pouvoir continuer la séquence à un point arbitraire et être capable de redémarrer exactement le même point. Les deux peuvent être faites en utilisant l'un des modules Math :: Random :: * mais à partir d'une inspection rapide des sources perl, cela ne peut pas être (facilement) fait avec le rand intégré() même à partir de XS! (Perl peut appeler rand() dans la bibliothèque c (et l'implémentation semble dépendant de la plate-forme.) – tsee

+0

@cjm et @tsee Il est préférable de ne pas avoir à se fier au 'rand' intégré de toute façon. –