J'ai un petit problème qui me laisse perplexe ! Je veux générer un grand
nombre de nombre aléatoire ( Par exemple n fois) puis je le stock dans
un fichier. Et de réitérer l’expérience plusieurs fois.
> Voici le programme qui généré les nombres aléatoire :
#include <stdio.h>
#include <stdlib.h>
#include <time.h> //Ne pas oublier d'inclure le fichier time.h
int main(void){
int i = 0;
int nombre_aleatoire = 0;
srand(time(NULL)); // initialisation de rand
for(i=0; i<500; i++){
nombre_aleatoire = rand();
printf("%d\n",nombre_aleatoire);
}
return 0;
}
> Et voici le programme qui appel au générateur de nombre aléatoire
plusieurs fois (100fois) et socket les résultats dans un fichier
différant pour chaque expérience.
#!/bin/bash
for i in {1..100}
do
./random > experience-$i.csv
done
> Pour regarder si chaque expérience est différant, je fait un md5 de
chaque fichier qui contient les nombres aléatoire :
$ md5sum *
7f6ed5ee2ef611cbe913dad427b766d6 experience-100.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-10.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-11.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-12.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-13.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-14.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-15.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-16.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-17.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-18.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-19.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-1.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-20.csv
7f6ed5ee2ef611cbe913dad427b766d6 experience-21.csv
....
> Je ne comprend pas pourquoi j'ai la même chose dans chaque fichier
alors que je remplis chaque fichier avec n nombre aléatoire !
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
Olivier Miakinen
Bonjour,
Le 13/10/2012 00:07, ZarkXe a écrit :
J'ai un petit problème qui me laisse perplexe ! Je veux générer un grand nombre de nombre aléatoire ( Par exemple n fois) puis je le stock dans un fichier. Et de réitérer l’expérience plusieurs fois.
[...] srand(time(NULL)); // initialisation de rand [...]
#!/bin/bash
for i in {1..100} do ./random > experience-$i.csv done
[...]
Je ne comprend pas pourquoi j'ai la même chose dans chaque fichier
alors que je remplis chaque fichier avec n nombre aléatoire !
Je parie que ça prend moins d'une seconde à créer les 100 fichiers. Du coup tu initialises 100 fois srand() avec la même valeur, et il est parfaitement normal que les 100 fichiers aient le même contenu.
Je ne connais pas ton besoin, mais une idée pourrait être que ton programme stocke dans un fichier fixe sous /tmp la dernière valeur de rand(), et que ce soit celle-ci qui soit utilisée comme graine à l'appel suivant.
Cordialement, -- Olivier Miakinen
Bonjour,
Le 13/10/2012 00:07, ZarkXe a écrit :
J'ai un petit problème qui me laisse perplexe ! Je veux générer un grand
nombre de nombre aléatoire ( Par exemple n fois) puis je le stock dans
un fichier. Et de réitérer l’expérience plusieurs fois.
[...]
srand(time(NULL)); // initialisation de rand
[...]
#!/bin/bash
for i in {1..100}
do
./random > experience-$i.csv
done
[...]
Je ne comprend pas pourquoi j'ai la même chose dans chaque fichier
alors que je remplis chaque fichier avec n nombre aléatoire !
Je parie que ça prend moins d'une seconde à créer les 100 fichiers.
Du coup tu initialises 100 fois srand() avec la même valeur, et il
est parfaitement normal que les 100 fichiers aient le même contenu.
Je ne connais pas ton besoin, mais une idée pourrait être que ton
programme stocke dans un fichier fixe sous /tmp la dernière valeur
de rand(), et que ce soit celle-ci qui soit utilisée comme graine
à l'appel suivant.
J'ai un petit problème qui me laisse perplexe ! Je veux générer un grand nombre de nombre aléatoire ( Par exemple n fois) puis je le stock dans un fichier. Et de réitérer l’expérience plusieurs fois.
[...] srand(time(NULL)); // initialisation de rand [...]
#!/bin/bash
for i in {1..100} do ./random > experience-$i.csv done
[...]
Je ne comprend pas pourquoi j'ai la même chose dans chaque fichier
alors que je remplis chaque fichier avec n nombre aléatoire !
Je parie que ça prend moins d'une seconde à créer les 100 fichiers. Du coup tu initialises 100 fois srand() avec la même valeur, et il est parfaitement normal que les 100 fichiers aient le même contenu.
Je ne connais pas ton besoin, mais une idée pourrait être que ton programme stocke dans un fichier fixe sous /tmp la dernière valeur de rand(), et que ce soit celle-ci qui soit utilisée comme graine à l'appel suivant.
Cordialement, -- Olivier Miakinen
Samuel DEVULDER
Le 13/10/2012 00:07, ZarkXe a écrit :
... srand(time(NULL)); // initialisation de rand ...
Je ne comprend pas pourquoi j'ai la même chose dans chaque fichier
alors que je remplis chaque fichier avec n nombre aléatoire !
Hypothèse: la génération des 100 fichiers se fait en moins d'1 sec. Du coup time(NULL) retourne la même graine pour chacune des 100 exécutions.
Contournement: initialiser avec des micro-secondes (voit gettimeofday je crois), ou un autre aléa (pid?). Attention avec les micro-secondes (tv_usec), c'est une valeur modulo 1000000, donc toutes les secondes les valeurs sont identiques. Il vaudrait mieux mélanger tous les champs de la struct timeval pour augmenter l'entropie.
Il faut aussi savoir que le générateur de rand() n'est pas terrible. Il vaudrait mieux passer par un générateur plus robuste tel random(3). A mon sens l'idéal sous un POSIX est d'utiliser le fichier /dev/random car il utilise une entropie globale au système. Si la lecture de ce fichier est trop lente pour ton appli (/dev/random est blocant quand l'entropie du système est trop faible), tu peux probablement te contenter de l'utiliser comme graine au début de ton programme et basculer ensuite sur le random(3) du C.
sam.
Le 13/10/2012 00:07, ZarkXe a écrit :
...
srand(time(NULL)); // initialisation de rand
...
Je ne comprend pas pourquoi j'ai la même chose dans chaque fichier
alors que je remplis chaque fichier avec n nombre aléatoire !
Hypothèse: la génération des 100 fichiers se fait en moins d'1 sec. Du
coup time(NULL) retourne la même graine pour chacune des 100 exécutions.
Contournement: initialiser avec des micro-secondes (voit gettimeofday je
crois), ou un autre aléa (pid?). Attention avec les micro-secondes
(tv_usec), c'est une valeur modulo 1000000, donc toutes les secondes les
valeurs sont identiques. Il vaudrait mieux mélanger tous les champs de
la struct timeval pour augmenter l'entropie.
Il faut aussi savoir que le générateur de rand() n'est pas terrible. Il
vaudrait mieux passer par un générateur plus robuste tel random(3). A
mon sens l'idéal sous un POSIX est d'utiliser le fichier /dev/random
car il utilise une entropie globale au système. Si la lecture de ce
fichier est trop lente pour ton appli (/dev/random est blocant quand
l'entropie du système est trop faible), tu peux probablement te
contenter de l'utiliser comme graine au début de ton programme et
basculer ensuite sur le random(3) du C.
... srand(time(NULL)); // initialisation de rand ...
Je ne comprend pas pourquoi j'ai la même chose dans chaque fichier
alors que je remplis chaque fichier avec n nombre aléatoire !
Hypothèse: la génération des 100 fichiers se fait en moins d'1 sec. Du coup time(NULL) retourne la même graine pour chacune des 100 exécutions.
Contournement: initialiser avec des micro-secondes (voit gettimeofday je crois), ou un autre aléa (pid?). Attention avec les micro-secondes (tv_usec), c'est une valeur modulo 1000000, donc toutes les secondes les valeurs sont identiques. Il vaudrait mieux mélanger tous les champs de la struct timeval pour augmenter l'entropie.
Il faut aussi savoir que le générateur de rand() n'est pas terrible. Il vaudrait mieux passer par un générateur plus robuste tel random(3). A mon sens l'idéal sous un POSIX est d'utiliser le fichier /dev/random car il utilise une entropie globale au système. Si la lecture de ce fichier est trop lente pour ton appli (/dev/random est blocant quand l'entropie du système est trop faible), tu peux probablement te contenter de l'utiliser comme graine au début de ton programme et basculer ensuite sur le random(3) du C.
sam.
ZarkXe
Merci à tous. Je comprend mieux le problème, cela vient principalement de ma graine.
Le 10/13/2012 12:36 AM, Samuel DEVULDER a écrit :
Le 13/10/2012 00:07, ZarkXe a écrit :
... srand(time(NULL)); // initialisation de rand ...
Je ne comprend pas pourquoi j'ai la même chose dans chaque fichier
alors que je remplis chaque fichier avec n nombre aléatoire !
Hypothèse: la génération des 100 fichiers se fait en moins d'1 sec. Du coup time(NULL) retourne la même graine pour chacune des 100 exécutions.
Contournement: initialiser avec des micro-secondes (voit gettimeofday je crois), ou un autre aléa (pid?). Attention avec les micro-secondes (tv_usec), c'est une valeur modulo 1000000, donc toutes les secondes les valeurs sont identiques. Il vaudrait mieux mélanger tous les champs de la struct timeval pour augmenter l'entropie.
Il faut aussi savoir que le générateur de rand() n'est pas terrible. Il vaudrait mieux passer par un générateur plus robuste tel random(3). A mon sens l'idéal sous un POSIX est d'utiliser le fichier /dev/random car il utilise une entropie globale au système. Si la lecture de ce fichier est trop lente pour ton appli (/dev/random est blocant quand l'entropie du système est trop faible), tu peux probablement te contenter de l'utiliser comme graine au début de ton programme et basculer ensuite sur le random(3) du C.
sam.
Merci à tous. Je comprend mieux le problème, cela vient principalement
de ma graine.
Le 10/13/2012 12:36 AM, Samuel DEVULDER a écrit :
Le 13/10/2012 00:07, ZarkXe a écrit :
...
srand(time(NULL)); // initialisation de rand
...
Je ne comprend pas pourquoi j'ai la même chose dans chaque fichier
alors que je remplis chaque fichier avec n nombre aléatoire !
Hypothèse: la génération des 100 fichiers se fait en moins d'1 sec. Du
coup time(NULL) retourne la même graine pour chacune des 100 exécutions.
Contournement: initialiser avec des micro-secondes (voit gettimeofday je
crois), ou un autre aléa (pid?). Attention avec les micro-secondes
(tv_usec), c'est une valeur modulo 1000000, donc toutes les secondes les
valeurs sont identiques. Il vaudrait mieux mélanger tous les champs de
la struct timeval pour augmenter l'entropie.
Il faut aussi savoir que le générateur de rand() n'est pas terrible. Il
vaudrait mieux passer par un générateur plus robuste tel random(3). A
mon sens l'idéal sous un POSIX est d'utiliser le fichier /dev/random car
il utilise une entropie globale au système. Si la lecture de ce fichier
est trop lente pour ton appli (/dev/random est blocant quand l'entropie
du système est trop faible), tu peux probablement te contenter de
l'utiliser comme graine au début de ton programme et basculer ensuite
sur le random(3) du C.
Merci à tous. Je comprend mieux le problème, cela vient principalement de ma graine.
Le 10/13/2012 12:36 AM, Samuel DEVULDER a écrit :
Le 13/10/2012 00:07, ZarkXe a écrit :
... srand(time(NULL)); // initialisation de rand ...
Je ne comprend pas pourquoi j'ai la même chose dans chaque fichier
alors que je remplis chaque fichier avec n nombre aléatoire !
Hypothèse: la génération des 100 fichiers se fait en moins d'1 sec. Du coup time(NULL) retourne la même graine pour chacune des 100 exécutions.
Contournement: initialiser avec des micro-secondes (voit gettimeofday je crois), ou un autre aléa (pid?). Attention avec les micro-secondes (tv_usec), c'est une valeur modulo 1000000, donc toutes les secondes les valeurs sont identiques. Il vaudrait mieux mélanger tous les champs de la struct timeval pour augmenter l'entropie.
Il faut aussi savoir que le générateur de rand() n'est pas terrible. Il vaudrait mieux passer par un générateur plus robuste tel random(3). A mon sens l'idéal sous un POSIX est d'utiliser le fichier /dev/random car il utilise une entropie globale au système. Si la lecture de ce fichier est trop lente pour ton appli (/dev/random est blocant quand l'entropie du système est trop faible), tu peux probablement te contenter de l'utiliser comme graine au début de ton programme et basculer ensuite sur le random(3) du C.