Création
d'entreprise

Générer des nombres aléatoires efficacement avec rand()


Générer des nombres aléatoires efficacement avec rand()


Vous avez peut-être remarqué qu'en C, en utilisant la fonction rand() de la bibliothèque standard, vous obtenez des résultats décevants, trop souvent les mêmes.

Prenons un exemple, vous voulez générer 5 nombres aléatoires d'affilée:

#include <stdlib.h>
#include <stdio.h>

int main()
{
    int i;
    for(i=0; i<5; i++)
    {
        printf("%d\n", rand());
    }
    return 0;
}


Exécutons ce programme et regardons ce qu'il nous écrit:
41
18467
6334
26500
19169


C'est bien, ce sont des résultats sensiblement différents. Mais si vous relancez votre programme, vous aurez la même série de nombres.

Pour modifier le comportement du générateur de nombres aléatoires, on peut modifier une variable sur laquelle il se base pour ses calculs. On appelle ça une graine (ou seed).
Cette graine se modifie avec la fonction srand():
srand(valeur de la graine)

Il faut un nombre que l'on ne peut pas prévoir facilement et qui varie toujours d'un instant à l'autre.
Par exemple, vous pouvez prendre le nombre de cycles utilisés par votre processeur depuis le démarrage.
Il peut être obtenu, sur les processeurs x86 (intel, Amd etc...), avec la commande assembleur rdtsc.
L'écriture d'une fonction rdtsc() appelant cette commande en assembleur pourra vous faciliter la vie, la syntaxe suivante fonctionne avec gcc sous Linux, que vous pouvez retrouver d'ailleurs avec dev C++ sous Windows.

#include <stdlib.h>
#include <stdio.h>

int rdtsc()
{
    __asm__ __volatile__("rdtsc");
}

int main()
{
    int i;
    for(i=0; i<5; i++)
    {
        srand(rdtsc());
        printf("%d\n", rand());
    }
    return 0;
}


Avec ce code, vous aurez déjà des nombres aléatoires plus efficaces.

Attention, cette solution ne fonctionne que sur les processeurs x86. Si votre programme doit être portable sur d'autres architectures de processeurs, il faudra envisager autre chose.

Evitez également d'activer des optimisations dans le compilateur (option -O1, -O2, -O3 etc...) ; si vous utilisez cette fonction rdtsc, vous risquez d'avoir un comportement étrange....
Publié par kilian - Dernière mise à jour le 17 juillet 2008 à 21:34 par sebsauvage
Ce document intitulé « Générer des nombres aléatoires efficacement avec rand() » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Suggestions
  •  Générer des nombres aléatoires efficacement avec rand()
  •  [Langage C] Générer nombre aléatoire (Résolu) » Meilleure réponse: #include <stdio.h> #include <stdlib.h> #include <time.h> #include <conio.h> int Random (int _iMin, int _iMax) { return (_iMin + (rand () % (_iMax-_iMin+1))); } int main (void) { int iRandom; srand (time (NULL)); iRandom = Random (50
  •  Nombres aléatoires de 0 à 100 (MATLAB) (Résolu) » Meilleure réponse: par définition rand (nombre aléatoir) donne des nombre de l'intervalle [0;1[ par suite logique, pour avoir un nombre de l'interval [0;10[ on fera 10*rand pour un nombre de 0 à 355 on fera 356*rand... ensuite les jeux de simulations sont
  •  Tirage au sort aléatoire selon une liste (Résolu) » Meilleure réponse: Choisir un jour de la semaine =CHOISIR(ENT(ALEA()*7)+1;"lundi";"mardi";"mercredi";"jeudi";"vendredi";"samedi";"dimanche") application à votre question : Choisir une personne parmis une liste aléatoirement de 10 personnes :...
  •  Je cherche une fonction random en C/C++ (Résolu) » Meilleure réponse: En C, tu peut faire ainsi Au début du programme, tu initialises le générateur de nombre aléatoire. srand(time(null)); // Une fois suffit ensuite, pour générer un nombre aléatoire, tu n'as plus qu'à taper : int nb_aleatoire = Rand(); Si
  •  Problème génération de nombre aléatoire. [C] (Résolu) » Bonjour, Alors voilà, cela fait quelques temps que je fait de la programmation en langage C et j'ai voulu créer un programme. Le but est de lancer 2 dé. Si les deux dé on un résultat identique alors le joueur gagne 10euros, sinon il perd la la...
Dossier à la une
Passage au tout numérique : quel coût pour les particuliers ?
Langage C - C/C++ Erreur de segmentation
Manipuler des entiers en 64 bits