Générer nombre aléatoirement [Résolu/Fermé]

Signaler
Messages postés
105
Date d'inscription
vendredi 26 juillet 2013
Statut
Membre
Dernière intervention
6 février 2015
-
Messages postés
5411
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 septembre 2020
-
Bonjour, un amis m'a prété son code pour que je réalise un système de loterie.
Pour l'instant, il permet juste de générer des nombres aléatoirement.
Voici son code:
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#define MAX 90
int main(void)
{int tab[MAX]={0},i,numerotire, tirage;
int num[MAX]={0};

for(i=0;i<MAX;i++)
{srand(time(NULL));
tab[i]=rand() % MAX;
numerotire=tab[i];
while(num[numerotire]==1) //Si jamais on avait déjà entrée cette valeur, on recommence
{tab[i]=rand() % MAX;
numerotire=tab[i];}
printf("Le numero tire est : %d\n",numerotire);
num[numerotire]=1; /*on entre 1 dans le 2eme tableau si c'est un nombre qu'on utilise pour la 1ere fois, si non il y a un zéro*/}


}

La première chose que je ne comprend pas, est la boucle while: pourquoi faire appel à un deuxième tableau et pourquoi le tableau prend la valeur 1?
Cette ligne est également visible à la fin du code mais je ne la comprend pas mieux; merci de me venir en aide.

1 réponse

Messages postés
5411
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 septembre 2020
898
Salut stark173,

Le 2ème tableau, comme indiqué par le commentaire, permet de savoir (rapidement) si le numéro a déjà été tiré.

Lors de la déclaration
int num[MAX]={0};
, le tableau est mis à zéro.

Lorsqu'un numéro est tiré, le numéro tiré est utilisé comme index du tableau. Si la valeur est zéro, cela signifie qu'on n'a jamais tiré ce numéro, et on note qu'on l'a déjà tiré en mettant la valeur à 1 (c'est ce que fait le code implicitement après le
while
).

Lors d'un prochain tirage, en accédant directement avec l'index à la position du tableau correspondant au numéro tiré, on sait immédiatement que le numéro a déjà été tiré si on constate que le contenu vaut 1 (et on refait un tirage, c'est ce que fait le
while
).

Cela évite d'avoir à parcourir
int tab[MAX]
pour vérifier, à chaque tirage, si le même numéro ne sort pas. Cette instantanéité de la vérification est au prix d'un espace mémoire double de celui normalement nécessaire.

C'est, en fait, une sorte de table de hachage.

Note aussi que, dans ton code
srand(time(NULL));
devrait être à l'extérieur de la boucle
for
. Une seule initialisation du générateur de nombres aléatoires devrait être faite.

Enfin, tu devrais mettre
#include <stdio.h>
pour ton
printf
.


Dal
Messages postés
5411
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 septembre 2020
898
voilà un générateur un peu plus crédible, pour ceux que cela intéresse, et qui évite de jouer à l'apprenti sorcier en essayant de créer le sien : http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/TINYMT/index.html

Dal
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 697
et il est exact de dire que cela rend les choses théoriquement plus difficiles,
J'ai rebondis initialement sur "c'est pas "plus aléatoire" si tu réinitialises le générateur à chaque tirage ? " où tu réponds par "En théorie oui".
Ma réponse est : ce n'est pas plus aléatoire, c'est simplement plus dur à trouver.
Je tiens juste à rappeler qu'il y a bien 2 problématiques différentes. Ici on parle de génération de nombres aléatoires et non de complexité à prévoir ces chiffres.
Messages postés
11910
Date d'inscription
mardi 24 mai 2011
Statut
Contributeur
Dernière intervention
12 juin 2018
2 280
Alors pour rebondir là-dessus, aucun des nombres générés pas les méthodes ci-dessus n'est vraiment aléatoire finalement: il suffit de connaitre l'algorithme et la graine pour avoir la suite. Et au final, régénérer la graine à chaque tirage rend l'aléa plus fort, puisqu'il faut se farcir le boulot de la deviner à chaque fois. Moi j'aime bien les méthodes qui se basent sur la t° CPU pour générer la graine. Ou sur les variations de tension dans la Ram ^^
Messages postés
11066
Date d'inscription
samedi 5 mai 2007
Statut
Contributeur
Dernière intervention
18 octobre 2016
1 697
aucun des nombres générés pas les méthodes ci-dessus n'est vraiment aléatoire finalement:
Si tu vas par là, aucun algorithme ne peut générer un nombre aléatoire par définition de l'aléa ;-). Sauf peut-être du côté de la théorie quantique.
On parle bien sûr ici de nombres pseudo-aléatoires qu'on qualifie de nombres aléatoires par flemme.
Partant de ce postulat, l'algorithme prévue avec srand()/rand() fait que les suites respectent bons nombres de critères de l'aléas (équiprobabilité, etc.). Mais bien sûr ce sont des suites prédéfinies. Mais bon tous les algorithmes sont déterministes ^^. En tout cas, il n'y a qu'à voir du côté des usenet ou/et à se paluer le fonctionnement de srand()/rand() pour comprendre que ce n'est pas plus aléatoire de réutiliser la graine... Cela rend simplement plus dur la prévision du nombre.
Messages postés
5411
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
29 septembre 2020
898
Bien sûr, chaque suite de nombre pseudo aléatoire produite avec le même algorithme n'est pas "plus aléatoire" que la précédente (et je n'ai jamais dit l'inverse), en revanche :

- l'ensemble produit par l'usage de différentes graines produisant des suites différentes étant plus difficilement prédictible, cet ensemble est certainement "plus aléatoire" que chaque suite isolée

- et la suite "plus complexe" si je comprend bien ce que Kolmogorov veut dire par là pour mesurer ce caractère, puisque, pour prendre l'exemple du C qui nous occupe, il faudrait des lignes de programme additionnelles pour afficher la succession de suites ne serait-ce que pour faire varier la graine à un certain intervalle.

Mais comme les maths et moi cela fait deux, détrompe moi, ou dis moi ce que tu entends par "plus aléatoire" :-)


Dal