2009-01-20 15 views
5

Considere el siguiente código lua fragmento:¿Por qué el primer número aleatorio siempre es el mismo en algunas plataformas en lua?

local time = os.time() 
for _= 1, 10 do 
    time = time + 1 
    print('Seeding with ' .. time) 
    math.randomseed(time) 
    for i = 1, 5 do 
     print('\t' .. math.random(100)) 
    end 
end 

en una máquina Linux, el resultado es, como se esperaba, números aleatorios. Pero parece que, al menos en Mac OS X, el primer número aleatorio después de cambiar la semilla siempre es el mismo.

Supongo que esto está relacionado con el hecho de que Lua confía en la función C rand() para generar números aleatorios, pero ¿alguien tiene una explicación?

EDIT: aquí es un extracto de la salida del código de seguridad en una máquina Linux (es decir, la salida es como se esperaba):

$ lua test.lua 
Seeding with 1232472273 
    69 
    30 
    83 
    59 
    84 
Seeding with 1232472274 
    5 
    21 
    63 
    91 
    27 
[...] 

En una máquina OS X, el primer número después de "siembra con ... "siempre fue 66.

+0

¿Utiliza las mismas versiones lua en ambas máquinas? Tal vez un error en el Mac OS X uno. –

+0

Sí, uso la última versión de lua. – Wookai

Respuesta

4

Lua se usa al azar para usar las funciones de C rand(3) y srand(3) (see here). ACTUALIZACIÓN: versiones más nuevas de Lua use random(3) where available.

Tanto el estándar C90 como POSIX sugieren una implementación multiplataforma de rand y srand que no es la mejor. Especialmente carece de aleatoriedad en los bits inferiores.

Algunas plataformas como Linux pasaron de la recomendación estándar a una mejor implementación (por ejemplo, random(3)).

OS/X sigue siendo fiel a la implementación clásica rand, y Lua lo hereda.

+1

Eso todavía no explica por qué siempre obtiene 66 como el primer número, pero es una buena información. –

+1

Que el algoritmo "no es el mejor" es un eufemismo;) No hace lo que debería y es completamente inútil y roto. Y no, no puedes argumentar que "tu no debería usarlo así", no se debería exigir que los programadores tengan este conocimiento. – Sire

+2

Ninguno de los estándares C, incluido C90, define ningún tipo de implementación para 'rand' o' srand'. Simplemente especifican qué se supone que deben hacer las funciones (devolver números pseudoaleatorios). Los estándares sí incluyen una implementación de ejemplo, pero los ejemplos no son normativos en las normas ISO; no imponen restricciones. Las implementaciones de C pueden usar cualquier versión de 'rand' y' srand' que quieran, y el uso de definiciones distintas del ejemplo definitivamente no es "no conforme". Le sugiero que cambie su redacción :) (Por ejemplo, [C89] (http://port70.net/~nsz/c/c89/c89-draft.html#4.10.2)). –

-2

Si usa la misma semilla, obtendrá la misma cadena de números de la función C rand(), pero debe obtener una cadena de números diferente cada vez, ya que aparece estar usando la hora actual como la semilla.

Edit: Supongo que debería dar más detalles sobre mi respuesta. Si no obtiene una cadena aleatoria de números cuando se siembra con os.time(), es posible que no obtenga lo que espera de esa llamada de función. ¿Cuáles son los valores que está obteniendo de os.time()?

Edit # 2: Además, ¿cuál es el resultado de ese bloque de código?

+0

Soy muy consciente del hecho de que usar la misma semilla da la misma secuencia de números pseudoaleatorios. Mi pregunta es sobre el hecho de que con diferentes semillas, el primer número generado parece ser el mismo en algunas plataformas. – Wookai

2

Es generalmente una mala idea llamar a srand múltiples veces con semillas que son numéricamente estrecha (y especialmente malo para hacerlo con los valores de tiempo). En muchos casos, la varianza del primer número aleatorio es similar a la varianza de las semillas. Cuando se trata de un lenguaje de scripting que tiene que convertir representaciones numéricas, puede ser incluso más.

¿Ocurre lo mismo si cambia el valor de inicialización por una cantidad mayor?

1

Como otros señalaron, Lua usa intencionadamente el generador aleatorio C90 para el bien de la portabilidad, y C90 RNG no es muy bueno.

Si necesita buenos números aleatorios, use algún módulo Lua para obtenerlo. Por ejemplo, here es un enlace Mersenne Twister RNG por uno de los autores de Lua.

Cuestiones relacionadas