Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Créer des objects random indépendants

+2 votes

Pour de la génération procédurale, j'ai besoin d'obtenir des générateurs aléatoires indépendants.

Indépendants :
1/ qui ont leur propre seed
2/ que la génération d'un autre random ( d'un autre object ) n'influe pas sur mon prochain tirage
3/ qui a partir d'un seed et de son initialisation me propose le même tirage

J'ai tenté avec getstate() et setstates(), mais cette approche ne me permet pas de revenir à un tirage antérieur.
Enfin, j'aimerai éviter d'avoir une liste de mes tirages à sauvegarder

demandé 20-Jan-2015 par Kermit (210 points)

3 Réponses

+8 votes
 
Meilleure réponse

Pour moi, random.Random() a l'air de faire exactement ce que tu souhaite.

  • génerateur pseudo aléatoire
  • possibilité de partir d'un seed
  • possibilité d'enregistrer un state et repartir de la-bas.

byseed.py

#! /usr/bin/env python

import random

inita = 42
initb = "Nice seed that will always be the same"

a = random.Random(inita)
b = random.Random(initb)

for i in xrange(10):
    print("a[{0}]: {1:2}".format(i, a.randint(0, 99)))
    print("b[{0}]: {1:2}".format(i, b.randint(0, 99)))

a.seed(inita)
b.seed(initb)
for i in xrange(10):
    print("a[{0}]: {1:2}".format(i, a.randint(0, 99)))
for i in xrange(10):
    print("b[{0}]: {1:2}".format(i, b.randint(0, 99)))

bystate.py

#! /usr/bin/env python

import random

a = random.Random()
b = random.Random()

statea = a.getstate()
stateb = b.getstate()

for i in xrange(10):
    print("a[{0}]: {1:2}".format(i, a.randint(0, 99)))
    print("b[{0}]: {1:2}".format(i, b.randint(0, 99)))

a.setstate(statea)
b.setstate(stateb)
for i in xrange(10):
    print("a[{0}]: {1:2}".format(i, a.randint(0, 99)))
for i in xrange(10):
    print("b[{0}]: {1:2}".format(i, b.randint(0, 99)))

Exemple:

# byseed, toujours le meme resultat, vu que seed dans le code
$ ./byseed.py  | sort -u
a[0]: 63
a[1]:  2
a[2]: 27
[...]
b[0]: 69
b[1]: 45
b[2]: 71
[...]
# state généré, et simplement réutilisé
$ ./bystate.py  | sort -u
a[0]: 96
a[1]: 33
a[2]: 31
[...]
b[0]: 19
b[1]: 34
b[2]: 10
[...]

L'un comme l'autre permet un rejeu, et donc d'avoir a nouveau les mêmes
valeurs.

Est-ce que cela correspond, ou est-ce qu'il y a une subtilité de la question que je n'ai pas compris?

répondu 20-Jan-2015 par ze (308 points)
sélectionné 20-Jan-2015 par Kermit

Ok, là je peux pas me mettre au niveau :) +1

Vous avez bien compris mon problème
Je suis passé totalement à coté de l'objet random.Random() dans la doc

0 votes

Je ne suis pas sur de comprende la question, mais si ce que tu veux est :

Générer une suite de nombre qui parait aléatoire, mais qui en réalité
ne l'est pas du tout car on peu retrouver la même suite à partir de la
même seed.

A ce moment là, je pense que la réponse est plutôt un algo de hash qu'un algo de générateur aléatoire.

def gen_number(seed, range):
   plant = seed
   while True:
       plant = hash(str(plant)) % range
       yield plant

my_gen = gen(20, 10)
my_gen.next()

ainsi on génére un nouveau nombre "aléatoire" (en fait carrément pas aléatoire) a chaque appel a next().
chaque nombre est basé sur le nombre précédemment généré. et un meme seed donne la meme liste de nombre (pas) aléatoire.

répondu 20-Jan-2015 par yohann (312 points)
+1 vote

Je pense que ce que tu cherches est :

from random import Random
generator = Random()
répondu 20-Jan-2015 par Sam (5,000 points)
...