2009-01-20 7 views
5

Tenir compte de l'extrait de code Lua suivant:Pourquoi le premier nombre aléatoire est-il toujours le même sur certaines plateformes de 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 

Sur une machine Linux, le résultat est, comme prévu, des nombres aléatoires. Mais il semble qu'au moins sur Mac OS X, le premier nombre aléatoire après avoir changé la graine soit toujours le même!

Je suppose que cela est lié au fait que Lua s'appuie sur la fonction C rand() pour générer des nombres aléatoires, mais quelqu'un a-t-il une explication?

EDIT: voici un extrait de la sortie du code ci-dessus sur une machine linux (la sortie est comme prévu):

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

Sur une machine OS X, le premier numéro après « ensemençant avec ... "était toujours 66.

+0

Utilisez-vous les mêmes versions lua sur les deux machines? Peut-être un bug dans celui de Mac OS X. –

+0

Oui, j'utilise la dernière version de lua. – Wookai

Répondre

4

Lua's random utilisé pour utiliser les fonctions C rand(3) et srand(3) (see here). MISE À JOUR: versions plus récentes Lua use random(3) where available.

La norme C90 et POSIX suggèrent une implémentation multiplateforme de rand et srand qui n'est pas la meilleure. Il manque surtout de caractère aléatoire dans les bits inférieurs.

Certaines plates-formes comme Linux sont passées de la recommandation standard à une meilleure implémentation (par exemple random(3)).

OS/X reste fidèle à l'implémentation rand classique, et Lua en hérite.

+1

Cela n'explique toujours pas pourquoi il reçoit toujours le 66 en tant que premier numéro, mais c'est une bonne information. –

+1

Que l'algorithme "n'est pas le meilleur" est tout à fait un euphémisme;) Il ne fait pas ce qu'il devrait et est complètement inutile et brisé. Et non, vous ne pouvez pas argumenter que "vous ne devriez pas l'utiliser comme ça", les programmeurs ne devraient pas être tenus d'avoir cette connaissance. – Sire

+2

Aucune des normes C, y compris C90, ne définit d'implémentation pour 'rand' ou' srand'. Ils spécifient simplement ce que les fonctions sont supposées faire (renvoyer des nombres pseudo-aléatoires). Les normes incluent un exemple de mise en œuvre, mais les exemples ne sont pas normatifs dans les normes ISO --- ils n'imposent aucune contrainte. Les implémentations de C sont autorisées à utiliser toutes les versions de 'rand' et' srand' qu'elles veulent, et l'utilisation de définitions autres que l'exemple n'est définitivement pas "non conforme". Je vous suggère de changer votre formulation :) (Par exemple, [C89] (http://port70.net/~nsz/c/c89/c89-draft.html#4.10.2)). –

-2

Si vous utilisez la même graine, vous obtiendrez la même chaîne de nombres de la fonction C rand(), mais vous devriez obtenir une chaîne de nombres différente à chaque fois que vous semblez utiliser l'heure actuelle comme la graine.

Editer: Je suppose que je devrais élaborer sur ma réponse. Si vous n'obtenez pas une chaîne aléatoire de nombres lors du semis avec os.time(), vous risquez de ne pas obtenir ce que vous attendez de cet appel de fonction. Quelles sont les valeurs que vous récupérez depuis os.time()?

Édition 2: De même, quelle est la sortie de ce bloc de code?

+0

Je suis bien conscient du fait que l'utilisation de la même graine donne la même séquence de nombres pseudo-aléatoires. Ma question concerne le fait qu'avec des graines différentes, le premier nombre généré semble être le même sur certaines plateformes. – Wookai

2

Il est généralement une mauvaise idée d'appeler srand plusieurs fois avec des graines qui sont numériquement proches (et surtout mal à le faire avec des valeurs de temps). Dans de nombreux cas, la variance du premier nombre aléatoire est similaire à la variance des graines. Lorsqu'il s'agit d'un langage de script qui doit convertir des représentations de nombres, cela peut être encore plus vrai.

Est-ce que la même chose se produit si vous changez la valeur de votre graine d'une plus grande quantité?

1

Comme d'autres l'ont noté, Lua utilise intentionnellement le générateur aléatoire C90 pour des raisons de portabilité - et C90 RNG n'est pas très bon.

Si vous avez besoin de bons nombres aléatoires, utilisez un module Lua pour l'obtenir. Par exemple, here est Mersenne Twister RNG liaison par l'un des auteurs Lua.

Questions connexes