float - random.choice python
cómo consultar la semilla utilizada por random.random()? (7)
Como nadie mencionó que generalmente la mejor muestra aleatoria que se puede obtener en cualquier lenguaje de programación se genera a través del sistema operativo, tengo que proporcionar el siguiente código:
random_data = os.urandom(8)
seed = int.from_bytes(random_data, byteorder="big")
esto es criptográficamente seguro.
Fuente: https://www.quora.com/What-is-the-best-way-to-generate-random-seeds-in-python
con un valor de 8 parece producir alrededor del mismo número de dígitos que sys.maxsize
para mí.
>>> int.from_bytes(os.urandom(8), byteorder="big")
17520563261454622261
>>> sys.maxsize
9223372036854775807
>>>
¿Hay alguna manera de descubrir qué semilla usó Python para generar su generador de números aleatorios?
Sé que puedo especificar mi propia semilla, pero estoy bastante contento con que Python lo administre. Pero, sí quiero saber qué semilla usó, de modo que si me gustan los resultados que obtengo en una ejecución en particular, podría reproducir esa ejecución más tarde. Si tuviera la semilla que fue utilizada, entonces podría.
Si la respuesta es "no puedo", ¿cuál es la mejor forma de generar una semilla yo mismo? Quiero que siempre sean diferentes de ejecutar a correr --- Solo quiero saber qué se usó.
ACTUALIZACIÓN: sí, me refiero a random.random ()! error ... [título actualizado]
El estado del generador de números aleatorios no siempre es simplemente una semilla. Por ejemplo, un PRNG seguro generalmente tiene un búfer de entropía, que es un bloque de datos más grande.
Sin embargo, puede guardar y restaurar todo el estado del generador de números Randon, para que pueda reproducir sus resultados más adelante:
import random
old_state = random.getstate()
print random.random()
random.setstate(old_state)
print random.random()
# You can also restore the state into your own instance of the PRNG, to avoid
# thread-safety issues from using the default, global instance.
prng = random.Random()
prng.setstate(old_state)
print prng.random()
Los resultados de getstate
pueden, por supuesto, ser escabechado si desea guardarlo persistentemente.
La semilla es una variable interna en el paquete aleatorio que se utiliza para crear el siguiente número aleatorio. Cuando se solicita un nuevo número, la semilla también se actualiza.
Simplemente usaría 0 como semilla si quiere asegurarse de tener los mismos números aleatorios todo el tiempo, o haga que sea configurable.
CorelDraw tuvo una vez un generador de patrones aleatorios, que se inicializó con una semilla. Los patrones variaron drásticamente para diferentes semillas, por lo que la semilla fue información importante de configuración del patrón. Debería ser parte de las opciones de configuración para tus carreras.
EDITAR: Como se señala por ephemis, el estado interno de un generador de números aleatorios puede ser más complejo que la semilla, dependiendo de su implementación.
No es posible sacar la semilla automática del generador. Normalmente genero semillas como esta:
seed = random.randrange(sys.maxsize)
rng = random.Random(seed)
print("Seed was:", seed)
De esta forma se basa en el tiempo, por lo que cada vez que ejecute el script (manualmente) será diferente, pero si está utilizando múltiples generadores, no tendrán la misma semilla simplemente porque se crearon casi simultáneamente.
Puede subclasificar el random.Random, reescribir el método seed () de la misma forma que lo hace python (v3.5 en este ejemplo) pero almacenar el valor inicial en una variable antes de llamar a super ():
import random
class Random(random.Random):
def seed(self, a=None, version=2):
from os import urandom as _urandom
from hashlib import sha512 as _sha512
if a is None:
try:
# Seed with enough bytes to span the 19937 bit
# state space for the Mersenne Twister
a = int.from_bytes(_urandom(2500), ''big'')
except NotImplementedError:
import time
a = int(time.time() * 256) # use fractional seconds
if version == 2:
if isinstance(a, (str, bytes, bytearray)):
if isinstance(a, str):
a = a.encode()
a += _sha512(a).digest()
a = int.from_bytes(a, ''big'')
self._current_seed = a
super().seed(a)
def get_seed(self):
return self._current_seed
Si lo prueba, un primer valor aleatorio generado con una nueva semilla y un segundo valor generado usando la misma semilla (con el método get_seed () que creamos) será el mismo:
>>> rnd1 = Random()
>>> seed = rnd1.get_seed()
>>> v1 = rnd1.randint(1, 0x260)
>>> rnd2 = Random(seed)
>>> v2 = rnd2.randint(1, 0x260)
>>> v1 == v2
True
Si almacena / copia el valor de la semilla enorme e intenta usarlo en otra sesión, el valor generado será exactamente el mismo.
Si "establece" la semilla usando random.seed(None)
, el aleatorizador se siembra automáticamente como una función de la hora del sistema. Sin embargo, no puede acceder a este valor, como observó. Lo que hago cuando quiero aleatorizar pero aún sé la semilla es esto:
tim = datetime.datetime.now()
randseed = tim.hour*10000+tim.minute*100+tim.second
random.seed(randseed)
Nota: la razón por la que prefiero usar el time.time()
propuesto por @Abdallah es porque de esta manera el randseed es legible por el ser humano e inmediatamente comprensible, lo que a menudo tiene grandes beneficios. También se pueden agregar componentes de fecha e incluso microsegmentos según sea necesario.
Yo quería hacer lo mismo, pero no pude obtener la semilla. Entonces, pensé, ya que la semilla se genera a partir del tiempo. Creé mi semilla usando la hora del sistema y la usé como una semilla, así que ahora sé qué semilla se usó.
SEED = int(time.time())
random.seed(SEED)