Comment générer une séquence de nombres aléatoires reproductible?
Je voudrais une fonction qui permet de générer une séquence pseudo-aléatoire de valeurs, mais pour que la séquence soit reproductible à chaque course. Les données que je veux doit être relativement bien distribués aléatoirement sur un intervalle donné, il n'a pas à être parfait.
Je veux écrire un peu de code qui ont les performances les tests s'exécutent sur la, sur la base des données aléatoires. Je voudrais que les données soient les mêmes pour chaque série de tests, sur chaque machine, mais je ne veux pas avoir à expédier les données aléatoires avec les tests pour le stockage des raisons (il pourrait être de plusieurs mégaoctets).
La bibliothèque pour le random
module n'apparaît pas à dire que la même graine donnera toujours la même séquence sur n'importe quelle machine.
EDIT: Si vous êtes en train de suggérer que je semences de données (comme je l'ai dit ci-dessus), veuillez fournir les documents qui dit que l'approche valable, et fonctionne sur une gamme de machines/implémentations.
EDIT: Disponible 2.7.1 et PyPy 1.7 sur Mac OS X et Disponible 2.7.1 et Disponible 2.52=.2 Ubuntu semble donner les mêmes résultats. Encore, pas de docs qui stipulent ce en noir et blanc.
Des idées?
source d'informationauteur Joe
Vous devez vous connecter pour publier un commentaire.
La documentation ne disent pas explicitement que le fait de fournir une graine de toujours garantir les mêmes résultats, mais qui est garanti avec Python de la mise en œuvre de l'aléatoire basé sur l'algorithme qui est utilisé.
Selon la documentation, Python utilise le Mersenne Twister comme le noyau générateur. Une fois cet algorithme est ensemencée il ne reçoit pas de sortie externe qui permettrait de modifier les appels suivants, afin de lui donner la même graine et vous sera obtenir les mêmes résultats.
Bien sûr, vous pouvez également observer par la constitution d'une graine et de générer de grandes listes de nombres aléatoires et de vérifier qu'ils sont le même, mais je ne comprends pas vouloir faire confiance qu'à lui seul.
Je n'ai pas vérifié que d'autres implémentations de Python en plus Disponible, mais je doute fortement qu'ils mettraient en œuvre le module random entièrement à l'aide d'un algorithme différent.
Pour cela, j'ai utilisé une répétition de hachage MD5, depuis l'intention d'une fonction de hachage est une croix-plate-forme de one-to-one de la transformation, de sorte qu'il sera toujours le même sur différentes plates-formes.
De sortie:
Essentiellement, le code va prendre votre graine (pour être valable, toute chaîne de caractères) et à plusieurs reprises de hachage, générant ainsi des nombres entiers de 0 à 255.
Il y a des différences de plate-forme, donc, si vous déplacez votre code entre les différentes plates-formes, je voudrais aller pour la méthode que DrRobotNinja décrit.
Veuillez jeter un oeil à l'exemple suivant. Python sur mon ordinateur de bureau (64 bits Ubuntu avec un Core i7, Python 2.7.3) donne moi les suivantes:
Mais si j'exécute le même code sur mon Raspberry Pi (Raspbian sur ARM11), j'obtiens un résultat différent (pour la même version de Python)
Spécifier une graine pour le générateur de nombre aléatoire. Si vous fournissez la même semence, vos nombres aléatoires doit être la même.
http://docs.python.org/library/random.html#random.seed
Aussi une réponse pourquoi l'exemple de cette réponse ne produit pas de sortie sur plusieurs machines:
C'est parce que quand on sème le générateur aléatoire de la graine doit être un nombre entier. Si vous la graine du générateur avec certains non-entier, il doit être haché premier. Les fonctions de hachage themselfes ne sont pas indépendant de la plateforme (à l'évidence, au moins, pas tous d'entre eux, corrigez-moi si vous en savez plus).
Donc, pour tirer tous ensemble: Python utilise un générateur de nombres pseudo aléatoires. Par conséquent, lorsqu'il est démarré à partir d'un même etat, le produit de la séquence de nombres aléatoires sera toujours le même, indépendamment de la plate-forme. Il a juste un deteministic algorithme sans autre intervention de l'extérieur.
Cela signifie: tant que vous initialiser le générateur aléatoire avec le même état, il va produire la même séquence de nombres. Arriver à un même état peut être fait en utilisant le même entier de graines ou par l'épargne et la réapplication de la vieille état (aléatoire.getstate() et aléatoire.setstate()).
À l'aide de random.de la graine(...) Vous pouvez générer un modèle de séquence. Une démonstration:
Cela fonctionne car aléatoire.de la graine(...) n'est pas vraiment aléatoire: il est pseudo-aléatoire, lequel successives numéros sont produites en permutant de l'état de la machine, étant donné un premier état de départ, la "graine".
Si la qualité de nombres aléatoires n'est pas aussi critique que la répétabilité-sur-plates-formes, vous pouvez utiliser l'un des classiques linéaire des générateurs à congruence:
Puisque c'est codée dans votre programme en utilisant l'arithmétique des nombres entiers, il devrait être de manière déterministe réutilisable dans la mesure du raisonnable plate-forme.
J'ai juste essayé la suivante:
Je suis entré à chaque ligne, à la CLI, à des vitesses différentes sur plusieurs périodes. Produit les mêmes valeurs à chaque fois.