Il s’agit probablement d’un problème lié à la machine, mais je ne peux pas comprendre ce qui pourrait ne pas être correct.
#include #include #include int main(int argc, char** argv) { srand(time(NULL)); int r1 = rand(); int r2 = rand(); printf("%d %d\n", r1, r2); }
Je comstack le code ci-dessus en utilisant
gcc randd.c
Ensuite, exécutez-le plusieurs fois manuellement et les premiers nombres semblent incroyablement similaires, tandis que les seconds semblent aléatoires:
1025720610 1435057801 1025737417 1717533050 1025754224 2000008299 1025771031 134999901 1025787838 417475150
Ce premier appel à rand()
semble fortement corrélé au temps et augmente ssortingctement au fil du temps. Des idées quant à pourquoi cela se produit ou comment le résoudre?
Cela se produit sur OSX 10.11
rand()
est assez mauvais, évitez-le si possible. Dans tout bon GNA, les premières valeurs seront impossibles à distinguer du hasard, même lorsque la graine est proche (distance de Hamming). En rand
ce n’est pas le cas. rand()
plusieurs fois au lieu de ré-ensemencer-en-appelant. Par exemple de 2, considérons:
#include #include #include int main(int argc, char** argv) { int t=time(NULL); srand(t); for(int i=0; i < 10; i++) { float r = (float)rand()/(float)(RAND_MAX); printf("%f\n", r); } }
Avec le résultat:
0.460600 0.310486 0.339473 0.519799 0.258825 0.072276 0.749423 0.552250 0.665374 0.939103
C'est toujours un mauvais RNG mais au moins, la plage est meilleure lorsque vous lui permettez d'utiliser l'état interne au lieu de lui donner une autre graine similaire.
C’est exactement ce à quoi vous devez vous attendre. Il n’y a pas une telle chose comme “un nombre aléatoire”. Il n’y a que des séquences de nombres avec une dissortingbution aléatoire. La fonction rand()
génère de telles séquences, mais vous ne lui en donnez pas la chance, car vous continuez à la ré-ensemencer. Le premier nombre généré par rand()
peut très bien être une simple fonction de la graine, ou de la graine elle-même. Certaines fonctions de rand()
peuvent hacher le germe pour cacher cela, mais cela ne les améliore pas vraiment, car le contrat de rand()
consiste à produire une séquence aléatoire.
Si vous avez besoin d’une séquence de nombres aléatoires qui survit en exécutant plusieurs programmes, vous devrez faire quelque chose comme: (a) Ecrivez un programme qui appelle srand()
une fois, puis plusieurs fois avec rand()
, puis demandez à vos autres programmes nombres aléatoires de ce programme sur IPC; (b) Utilisez quelque chose comme /dev/urandom
; (c) Utilisez quelque chose comme random.org
.