2010-08-27 14 views
5

La clase Random en Ruby 1.9.2 garantiza la generación de números aleatorios en el mismo orden, dada una semilla y un rango específicos. Por ejemplo:Generación de números aleatorios secuenciales distribuidos en Ruby 1.9.2

r = Random.new(23) 
r.rand(100)   # 83 
r.rand(100)   # 40 

Pero supongamos que quiero generar el siguiente número en la secuencia en otro equipo (sin volver a generar los números anteriores en la secuencia). Esto debería ser posible, dado el resultado anterior. ¿Hay alguna manera de hacer esto con la clase Random? ¿O tengo que escribir mi propia implementación del Mersenne twister?

[Editar: Como se señaló en los comentarios a continuación, no es de hecho posible determinar el estado de una instancia Random sólo de la salida, porque sólo parte del estado (en concreto, los bajos 32 bits) se utilizan para la salida.]

+0

¿Por qué debería ser posible hacer esto? – adamse

+0

@adamse El siguiente número se genera determinísticamente dado algún estado interno en 'r'. Entonces, si crea una nueva 'r' con el mismo estado que la anterior, generará el siguiente número en la secuencia. ¿Tiene sentido? Según mi comprensión de los algoritmos que subyacen a "Aleatorio", creo que este estado se puede representar mediante la semilla y el último número generado. –

+0

leyendo la implementación de [backported] (http://github.com/marcandre/backports/blob/master/lib/backports/1.9.2/random/MT19937.rb) parece que de hecho puede encontrar el siguiente estado usando el último y la semilla. Sin embargo, por lo que yo entiendo, es posible que no puedas encontrar el estado dado el número generado. – adamse

Respuesta

2

No se puede probar, pero el generador se puede ordenar, según Marc-André Lafortune here. Entonces esto podría funcionar:

r = Random.new(23) 
r.rand(100)   # 83 
r.rand(100)   # 40 

File.open("/path/to/file","w") do |f| 
    Marshal.dump(r,f) 
end 

# later, may be on another computer 

File.open("/path/to/file","r") do |f| 
    @v = Marshal.load(f) 
end 

puts @v.rand(100) 
+0

Eso podría funcionar, pero parece terriblemente ineficiente. En principio, solo debe transmitir el valor generado más recientemente de una computadora a la otra; no debería tener que serializar todo el objeto. –

+1

Está asumiendo que no hay otro estado interno. Ciertamente podrías escribir un generador de números aleatorios para lo cual es cierto (la manera más fácil: seguir recreando Random con el número anterior como el valor inicial, y solo usar la primera llamada) pero no es realmente justo decir que la clase aleatoria actual " debería, en principio, "mantener la apatridia por un caso de uso poco común". – SFEley

Cuestiones relacionadas