Apprendre à créer des générateurs aléatoires en VBA

Objectif : apprendre à créer des générateurs aléatoires avec la fonction Rnd.

Niveau requis : confirmé

Commentez cet article : 3 commentaires Donner une note  l'article (5)

Article lu   fois.

L'auteur

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Introduction

Définitions utiles :

Le hasard ou aléa est un concept exprimant l'impossibilité de prévoir avec certitude un fait quelconque. Ainsi, pour éclairer le sens du mot, il est souvent dit que hasard est synonyme d'« imprévisibilité », ou « imprédictibilité ».
La probabilité est une valeur permettant de représenter le degré de certitude d'un événement aléatoire. Elle est comprise entre 0 et 1.

Après avoir présenté la fonction de génération de nombres aléatoires Rnd, nous proposerons des exemples d'application :

  1. Générer des mots de passe au hasard ;
  2. Génerer une série d'événements aléatoires ;
  3. Générer des arrangements aléatoires.

Pour conclure, nous décrirons comment créer sa propre fonction de génération de nombres pseudoaléatoires en utilisant une méthode dite de Fibonacci.

[TITRE-PASTOUCHE]

Le code VBA est compatible avec Excel, même si tous les exemples sont réalisés avec Access.

II. Fonction Rnd

Extrait de l'aide sur la fonction Rnd :

Renvoie un nombre aléatoire de type Single inférieur à 1 et supérieur ou égal à 0.

Syntaxe : Rnd[(number)]

L'argument number est un numérique valide.

Si number est 

Rnd génère 

Inférieur à zéro 

Le même nombre à chaque fois, en utilisant nombre comme la valeur de départ. 

Supérieur à zéro 

Nombre aléatoire suivant dans la séquence. 

Égal à zéro 

Le dernier nombre généré. 

Non fourni 

Nombre aléatoire suivant dans la séquence. 

Avant d'appeler Rnd, utilisez l'instruction Randomize sans argument pour initialiser le générateur de nombres aléatoires avec une valeur initiale basée sur l'horloge système.

Parmi les générateurs de nombres aléatoires, celui qui s'est imposé avec l'avènement des ordinateurs est le générateur congruentiel linéairegénérateur congruentiel linéaire. Partant d'un terme initial, il produit une suite de nombres dont chaque terme dépend du précédent, d'où la nécessité d'initialiser le générateur avant de l'utiliser.

II-A. Fonction RndInteger

Elle permet de générer un nombre entier au hasard.

Pour obtenir au hasard un entier compris dans une certaine plage délimitée par les entiers Mini et Maxi, on peut utiliser la formule :

Extrait de l'aide
Sélectionnez
Int((Maxi - Mini + 1) * Rnd + Mini)

On obtient donc aisément la fonction :

RndInteger
Sélectionnez
Function RndInteger(ByVal Mini As Long, ByVal Maxi As Long) As Long
    RndInteger = Int((Maxi - Mini + 1) * Rnd + Mini)  ' Renvoie un nombre entier au hasard compris entre Mini et Maxi
End Function

À chaque appel de la fonction RndInteger, les entiers compris entre Mini et Maxi ont donc la même probabilité de sortir.

III. Génération de chaînes de caractères aléatoires

Pour générer ces chaînes de caractères au hasard, on va se baser sur la table des codes ASCII des 128 caractères, numérotés de 0 à 127 :

Image non disponible
Table des codes ASCII

On se limitera donc volontairement, par la suite, aux caractères ASCII de 0 à 127. On remarquera également que « A » est inférieur à « a » dans la table et que les caractères 0 à 31 sont non imprimables.

III-A. Fonction Chr

L'idée est d'utiliser cette fonction pour renvoyer un caractère numérique (0, 1, 2, …, 9), une lettre, ou un caractère spécial, à partir du code ASCII.

Extrait de l'aide sur la fonction :

Chr(CharCode) retourne le caractère associé au code ASCII spécifié.

L'argument CharCode est un entier représentant le code du caractère. Si CharCode se trouve en dehors de la plage valide, une erreur ArgumentException se produit.

La plage valide pour Chr s'étend de 0 à 255.

En regardant les différents codes ASCII (colonne Dec) et leur caractère (colonne Char) affichés dans la table, on remarque que pour obtenir un caractère numérique (0, 1, …, 9), on passera à la fonction un entier compris entre 48 et 57. Pour obtenir un caractère alphabétique en majuscule (A, B, …, Z), on lui passera un entier compris entre 65 et 90. Enfin, pour obtenir un caractère alphabétique en minuscule, on choisira un entier entre 97 et 122.

III-B. Fonctions aléatoires

III-B-1. Fonction RndNumChr

Elle permet de générer un caractère numérique au hasard.

Comme l'indique la table des codes ASCII, pour obtenir un caractère numérique, on doit passer à la fonction Chr un entier compris entre 48 et 57.

Codes ASCII correspondant aux chiffres

Codes ASCII 

Caractères 

48 à 57 

0,1, 2, …, 9

La fonction RndNumChr, permettant de générer un caractère numérique au hasard, s'écrit donc :

Fonction RndNumChr
Sélectionnez
Function RndNumChr() as string
    Dim i as Integer
    i=RndInteger(48, 57) ' Code du caractère ASCII tiré au hasard entre 48 et 57
    RndNumChr=Chr(i) ' Caractère ASCII correspondant
End Function

III-B-2. Fonction RndLCaseLetter

Elle permet de générer une lettre minuscule au hasard.

Comme l'indique la table des codes ASCII, pour obtenir une lettre en minuscule au hasard, on doit passer à la fonction Chr un entier compris entre 97 et 122.

Codes ASCII correspondant aux lettres en minuscule

Codes ASCII 

Caractères 

97 à 122 

a, b, c, …, …z 

La fonction RndLCaseLetter, permettant de générer une lettre minuscule au hasard, s'écrit donc :

Fonction RndLCaseLetter
Sélectionnez
Function RndLCaseLetter() as string
    Dim i as Integer
    i=Int((122 - 97 + 1) * Rnd + 97) ' Code du caractère ASCII tiré au hasard
    RndLCaseLetter=Chr(i) ' Caractère ASCII correspondant
End Function

III-B-3. Fonction RndUCaseLetter

Elle permet de générer une lettre majuscule au hasard.

Comme l'indique la table des codes ASCII, pour obtenir une lettre en majuscule, on doit passer à la fonction Chr un entier compris entre 65 et 90.

Codes ASCII correspondant aux lettres en majuscule

Codes ASCII 

Caractères 

65 à 90 

A, B,  C…, Z 

La fonction RndUCaseLetter, permettant de générer une lettre majuscule au hasard, s'écrit donc :

Fonction RndUCaseLetter
Sélectionnez
Function RndUCaseLetter() as string
    Dim i as Integer
    i=Int((90 - 65 + 1) * Rnd + 65) ' Code du caractère ASCII tiré au hasard
    RndUCaseLetter=Chr(i) ' Caractère ASCII correspondant
End Function

III-B-4. Fonction RndSpecChr

Elle permet de générer un caractère spécial au hasard.

Pour obtenir un caractère spécial, cette fois-ci on doit passer en argument une chaîne contenant la liste des caractères spéciaux. Ensuite on tire au hasard l'indice de la position dans la chaîne, qui nous permet de retourner le caractère correspondant :

Fonction RndSpecChr
Sélectionnez
'********************************************************************************
'************** Fonction générant un caractère spécial au hasard ****************
'********************************************************************************
Function RndSpecChr(Optional s As String = "~!@#$%^&*()-_=+[]{};:,.<>/?") As String
    ' s : chaîne optionnelle contenant les caractères spéciaux autorisés
    Dim i As Integer ' Indice indiquant la position dans la chaîne contenant les caractères spéciaux
    
    i = RndInteger(1, Len(s)) ' Indice de position tiré au hasard
    
    RndSpecChr = Mid(s, i, 1) ' Caractère spécial correspondant
End Function

III-B-5. Fonction RndChr

Elle permet de générer au hasard un caractère ASCII dont le code est compris entre Mini et Maxi :

Fonction RndChr
Sélectionnez
Function RndChr(ByVal Mini As Variant, ByVal Maxi As Variant) As String
    '---------------------------------------------------------------------------------------
    ' Mini = un code ASCII ou le caractère alpha.
    ' Maxi = un code ASCII ou le caractère alpha.
    '---------------------------------------------------------------------------------------
    ' Retourne un caractère compris entre les bornes mini et maxi.
    ' Auteur : Laurent Ott
    '---------------------------------------------------------------------------------------
    ' Cas particulier des chiffres 0 à 9 qu'il ne faut pas confondre des valeurs :
    If Mini Like "[0-9]" Then Mini = Asc(Mini)
    If Maxi Like "[0-9]" Then Maxi = Asc(Maxi)
    ' Convertir en valeur Asc les arguments passés en String :
    If Val(Mini) = 0 Then Mini = Asc(Mini)
    If Val(Maxi) = 0 Then Maxi = Asc(Maxi)
    RndChr = Chr(RndInteger(Mini, Maxi))
End Function

III-B-6. Fonction RndPwdChr

Elle permet de générer au hasard un caractère ASCII du type lettre minuscule, lettre majuscule, chiffre ou caractère spécial :

Fonction RndPwdChr
Sélectionnez
'********************************************************************************
'*************** Fonction générant un caractère ascii au hasard *****************
'********************************************************************************
Public Function RndPwdChr(ByVal c As String, Optional s As String = "~!@#$%^&*()-_=+[]{};:,.<>/?") As String
    ' s : chaîne optionnelle contenant les caractères spéciaux autorisés
    ' renvoie un caractère ascii au hasard
    ' en fonction du type de caractère ('l': lettre minuscule, 'L': lettre majuscule, 'c': chiffre, "s": caractère spéc.)
      
    If StrComp(c, "l", vbBinaryCompare) = 0 Then ' Comparaison sensible à la casse
        RndPwdChr = RndLCaseLetter  ' On génère au hasard une lettre minuscule
       
    ElseIf StrComp(c, "L", vbBinaryCompare) = 0 Then
        RndPwdChr = RndUCaseLetter ' On génère au hasard une lettre majuscule
       
    ElseIf StrComp(c, "c", vbBinaryCompare) = 0 Then
        RndPwdChr = RndNumChr  ' On génère au hasard un chiffre
    
    ElseIf StrComp(c, "s", vbBinaryCompare) = 0 Then
        RndPwdChr = RndSpecChr(s)  ' On génère au hasard un caractère spécial
       
    End If
End Function

III-B-7. Fonction RndString

Elle renvoie une chaîne de caractères aléatoire de NbCar éléments.

Les arguments acceptés par la fonction RndString sont :

  • Nbcar : le nombre de caractères à générer ;
  • ListeChoix : la liste des types de caractères (bornes mini et maxi), passés en caractères ou en code ASCII.

En résumé, voici le déroulé de la fonction :

  1. Passage en argument de la liste des bornes délimitant les codes ASCII ;
  2. Génération au hasard, à chaque passage de boucle, de l'indice de la liste passée en argument ;
  3. Détermination des bornes Mini et Maxi correspondant à l'indice ;
  4. Renvoi, en bout de chaîne, du résultat de la fonction aléatoire RndChr obtenu avec ces bornes ;
  5. Après NbCar passages de boucles, renvoi de la chaîne complète obtenue.
Code de la fonction RndString
Cacher/Afficher le codeSélectionnez
Exemples d'appels
Sélectionnez
RndString(1, "A,E") ' pour un caractère entre A et E.
RndString(1, "65,69") ' pour un caractère entre A et E.
RndString(1, "A,E", "G,J", "W,Z" ) ' pour un caractère entre A et E, ou entre G et J ou entre W et Z.

III-B-8. Fonction RndPwd

Elle permet de générer une chaîne constituée de caractères tirés au hasard, il nous suffit de générer chacun des caractères au moyen des fonctions décrites précédemment.

Pour cela, la fonction prend en arguments des variables indiquant le nombre de caractères de chaque type à générer :

  • NbCarMin : le nombre de lettres minuscules ;
  • NbCarMaj : le nombre de lettres majuscules ;
  • NbCarNum : le nombre de chiffres ;
  • NbCarSpec : le nombre de caractères spéciaux.

En résumé, voici le déroulé de la fonction :

  1. Passage en arguments du nombre de caractères par type ;
  2. Constitution d'une chaîne contenant les codes correspondant aux types de caractères ;
  3. Parcours des nbCar caractères de la chaîne dans une boucle ;
  4. Génération au hasard, à chaque passage de boucle, de l'indice dans la chaîne ;
  5. Pour chaque type de caractère, renvoi en bout de chaîne du résultat de la fonction aléatoire RndPwdChr ;
  6. Après NbCar passages de boucles, renvoi de la chaîne complète obtenue.
Code de la fonction RndPwd
Cacher/Afficher le codeSélectionnez
Exemple d'appel
Sélectionnez
RndPwd(4, 4, 2, 2) ' Pour 4 lettres minuscules, 4 majuscules, 2 chiffres et 2 caractères spéciaux

Vous pouvez facilement définir si le tirage a lieu avec ou sans remise avec le dernier argument de la fonction.

III-C. Génération de mots de passe au hasard

Le principe est de générer une chaîne de caractères aléatoire à l'aide de la fonction RndPwd et de tester s'il est présent dans une table. S'il n'est pas présent, on l'ajoute dans la table, sinon on en génère un autre, jusqu'à ce qu'il ne soit pas présent.

III-C-1. Table T_Utilisateur

On utilise pour cela une table T_Utilisateur qui va contenir les nom et prénom des utilisateurs, accompagnés de leur mot de passe :

T_Utilisateur

Nom du champ 

Type du champ 

Description 

IdUtilisateur 

Entier long 

Identifiant de l'utilisateur 

NomUtilisateur 

Texte 

Nom de l'utilisateur 

PrenomUtilisateur 

Texte 

Prénom de l'utilisateur 

MotDePasse 

Texte 

Mot de passe de l'utilisateur 

Exemple de données :

Affichage des données

IdUtilisateur 

NomUtilisateur 

PrenomUtilisateur 

MotDePasse 

Dupont 

Jean 

pmH5X6XLfk 

Durand 

Ludovic 

7sBEkiN1Aw 

Martin 

Olivier 

qFh4AkBN0l 

.. 

.. 

.. 

.. 

III-C-2. Fonction GenerateRandomPassword

Fonction principale qui va appeler la précédente pour composer la chaîne de caractères constituant le mot de passe.

En résumé, voici le déroulé de la fonction principale :

  1. Ouverture du recordset pour l'ajout du mot de passe dans la table ;
  2. Génération d'un nouveau mot de passe tant que celui-ci est présent dans la base ;
  3. Sortie de la boucle une fois que la chaîne générée n'est pas présente dans la base ;
  4. Ajout de la séquence de caractères constituant le mot de passe dans la table.
Code de la fonction GenerateRandomPassword
Cacher/Afficher le codeSélectionnez

Étant développeur VBA Access, j'utilise le modèle objet DAO plutôt que ADO, car il est plus adapté au logiciel Access.

IV. Génération de séries d'événements aléatoires

On souhaite générer et enregistrer dans une table, une série d'événements ayant chacun une certaine probabilité d'advenir.

Voici les différentes étapes du processus :

  1. Enregistrer dans une table les événements et leur probabilité ;
  2. Évaluer le nombre d'événements du même type à générer en fonction de leur probabilité ;
  3. Générer la liste des événements dans une table temporaire ;
  4. Tirer au hasard les événements dans la table temporaire, pour les ajouter à la table T_SerieAlea.
[TITRE-PASTOUCHE]

On prendra en compte des tirages successifs avec ou sans remise.

IV-A. Enregistrement des événements

On utilise pour cela une table T_Evenement :

T_Evenement

Nom du champ 

Type du champ 

Description 

IdEvenement 

Entier long 

Identifiant de l'événement 

NomEvenement 

Texte 

Nom de l'événement 

ProbaEvenement 

Réel simple 

Estimation de la probabilité de l'événement, comprise entre 0 et 1 

Exemple de données :

Affichage des données

IdEvenement 

NomEvenement 

ProbaEvenement 

0.1 

0.25 

0.25 

0.4 

IV-B. Estimation du nombre d'événements de chaque type

On va obtenir le nombre d'événements de chaque type à partir de leur probabilité d'advenir et du nombre total de tirages successifs à effectuer.

Si le nombre total de tirages est omis, on calcule à la place un nombre minimum permettant d'avoir les bonnes quantités de chaque :

Dans un premier temps, on multiplie la probabilité par une puissance de 10 pour supprimer la virgule et obtenir uniquement des entiers :

Multiplication par 100

IdEvenement 

NomEvenement 

Nombre représentatif 

0.1*100=10 

0.25*100=25 

0.25*100=25 

0.4*100=40 

Puis, on détermine le PGCD entre 10, 25, 25 et 40, afin de simplifier ces résultats. Ici, on constate qu'ils se divisent par 5 :

Division par 5

IdEvenement 

NomEvenement 

Nombre représentatif 

10/5=2 

25/5=5 

25/5=5 

40/5=8 

Les valeurs obtenues (2, 5, 5 et 8) constituent, en les additionnant, le nombre minimum de tirages nécessaires :

 
Sélectionnez
2 + 5 + 5 + 8 = 20

En conclusion, dans ce cas, pour obtenir les bonnes quantités de chaque, on aura donc besoin d'effectuer un nombre de tirages n qui soit un multiple de 20.

IV-B-1. Fonction NbTiragesMini

Elle va permettre d'obtenir le nombre minimum de tirages nécessaires.

Déroulé de la fonction :

  1. Déterminer le nombre maximum de chiffres après la virgule parmi les valeurs de probabilité ;
  2. Évaluer la puissance de 10 permettant d'éliminer la virgule pour toutes les valeurs de probabilité ;
  3. Déterminer, parmi les valeurs entières obtenues, le plus grand commun diviseur ;
  4. Diviser la puissance de 10 par le PGCD pour obtenir le nombre minimum de tirages nécessaires.
Code de la fonction NbTiragesMini
Cacher/Afficher le codeSélectionnez

IV-C. Génération de la série d'événements

On va constituer la série des événements aléatoires à partir de leur probabilité pour un tirage avec ou sans remise.

Déroulé de la fonction :

  1. Vidage de la table temporaire T_EvenementTmp ;
  2. Ajout des événements dans la table temporaire T_EvenementTmp, en fonction de leur probabilité contenue dans la table T_Evenement ;
  3. Tirage au hasard des événements dans la table temporaire, pour les ajouter à la table T_SerieAlea.
Code de la fonction GenerateRandomEventsSeries
Cacher/Afficher le codeSélectionnez

On peut également optimiser la fonction en utilisant une collection à la place de la table temporaire :

Code de la fonction GenerateRandomEventsSeriesV2
Cacher/Afficher le codeSélectionnez

V. Génération d'arrangements aléatoires

On souhaite tirer au hasard l'ensemble des dispositions possibles de n ouvriers sur p machines, afin d'évaluer celle qui offre le meilleur rendement. Les données des ouvriers sont enregistrées dans une table T_Personne (NumPersonne, NomPersonne), et celles des machines sont sauvegardées dans une table T_Machine (NumMachine, NomMachine).

Voici les différentes étapes du processus de génération des arrangements :

  1. Enregistrer, dans les tables correspondantes, des données concernant les personnes et les machines ;
  2. Déterminer les paramètres n et p du nombre m d'arrangements ;
  3. Parcourir, dans une boucle, les m arrangements ;
  4. À chaque passage de boucle, tirer au hasard une série de p numéros de personnes distincts ;
  5. Si cette série n'a pas déjà été tirée, la retenir, sinon effectuer un nouveau tirage ;
  6. Pour chaque arrangement obtenu, l'enregistrer dans une table.
[TITRE-PASTOUCHE]

Dans ce cas, il s'agit de tirages successifs sans remise. Le nombre de résultats possibles est donné par une formule mathématique appelée arrangements.

V-A. Table T_Arrangement

Table permettant d'enregistrer les différentes dispositions de n personnes sur p machines.

T_Arrangement

Nom du champ 

Type du champ 

Description 

NumArrangement 

Entier long 

Numéro de l'arrangement 

NumMachine 

Entier long 

Numéro de la machine 

NumPersonne 

Entier long 

Numéro de la personne 

V-B. Fonction GenerateArrangement

Pour simplifier, on va commencer par tirer au hasard p personnes parmi n, pour les placer sur p machines. Cela revient à générer un seul arrangement.

Déroulé de la fonction :

  1. Déterminer les paramètres n et p correspondant aux nombres d'enregistrements contenus dans les tables T_Personne et T_Machine ;
  2. Copier les numéros des n personnes dans une collection ;
  3. Tirer au hasard dans cette colllection une série de p numéros de personnes distincts pour les enregistrer suivant l'ordre des machines.
Code de la fonction GenerateArrangement
Cacher/Afficher le codeSélectionnez

V-C. Fonction GenerateArrangements

On souhaite maintenant tirer au hasard l'ensemble des dispositions possibles de n personnes sur p machines.

Déroulé de la fonction :

  1. Déterminer les paramètres n et p des arrangements correspondant aux nombres d'enregistrements contenus dans les tables T_Personne et T_Machine ;
  2. Parcourir, dans une boucle, les m arrangements, m étant obtenu avec la fonction Arrangements(n,p) ;
  3. À chaque passage de boucle, copier les numéros de personnes dans une collection ;
  4. À chaque passage de boucle, tirer au hasard une série de p numéros de personnes distincts ;
  5. Si cette série n'a pas déjà été tirée, la retenir en la copiant dans la table T_ArrangementTmp, sinon effectuer un nouveau tirage ;
  6. Pour chaque arrangement obtenu, l'enregistrer dans la table T_Arrangement.
Code de la fonction GenerateArrangements
Cacher/Afficher le codeSélectionnez

V-D. Affichage de résultats

Extrait des résultats de la requête R_Arrangements, avec quatre personnes et trois machines :

R_Arrangements

NumArrangement

NumMachine

NomMachine

NumPersonne

NomPersonne

1

1

M1

3

Martin

1

2

M2

2

Durand

1

3

M3

1

Dupont

2

1

M1

1

Dupont

2

2

M2

3

Martin

2

3

M3

2

Durand

..

..

..

..

..

23

1

M1

1

Dupont

23

2

M2

3

Martin

23

3

M3

4

Ruffin

24

1

M1

4

Ruffin

24

2

M2

3

Martin

24

3

M3

2

Durand

La requête R_Arrangements relie les tables T_Arrangement, T_Machine et T_Personne.

VI. Créer son propre générateur de nombres aléatoires

Si on reprend la définition du début, on peut dire que le hasard est synonyme d'« imprévisibilité », ou « imprédictibilité ». Or, aucune fonction écrite par l'homme ne peut-être absolument imprédictible. Il suffit de connaître l'algorithme pour prévoir son résultat, et la fonction Rnd n'échappe pas à la règle.

On se propose donc d'écrire notre propre fonction de génération de nombres pseudoaléatoires.

VI-A. Méthode de Fibonacci

Cette méthode est basée sur la suite de Fibonacci modulo la valeur maximale désirée, elle a l'avantage d'être très simple à implémenter et ne consomme que peu de ressources :

Formule de Fibonacci
Sélectionnez
x(n) = (x(n-2) + x(n-1)) mod M

Où x(n) désigne la variable d'indice n, x(0) et x(1) correspondent aux valeurs initiales entrées au début du processus aléatoire, et M est la valeur maximale pouvant être générée.

Pour plus de détails, vous pouvez consulter cette pageMéthode de Fibonacci.

VI-A-1. Implémentation

Description du principe :

  1. Initialisation des variables x1 et x2 au moyen de la procédure InitRandom ;
  2. Mise à jour de x1 et x2 avec la formule dite de Fibonacci à chaque appel de la fonction Random.

VI-A-1-a. Variables publiques x1 et x2

Ces variables sont déclarées en haut du module contenant les fonctions. Cela permettra de les mettre à jour et de les transmettre dans les routines InitRandom et Random.

 
Sélectionnez
Option Compare Database
Option Explicit
' Variables représentant les 2 termes de la formule de Fibonacci et utilisées dans les fonctions IniRandom et Random.
Dim x1 As Long, x2 As Long
...

VI-A-1-b. Procédure InitRandom

Cette procédure permet d'initialiser le générateur de nombres aléatoires en mettant à jour les deux variables x1 et x2 avec la fonction Timer.

Fonction InitRandom
Sélectionnez
'********************************************************************************
'******************* Procédure d'initialisation du générateur *******************
'********************************************************************************
Public Sub InitRandom()
    Dim x As Single

    x = Timer * 100 ' On prend comme valeur aléatoire, la valeur donnée par la fonction Timer

    ' Initialisation des 2 variables publiques, leur valeur sera transmise à la fonction génératrice
    x1 = 0
    x2 = x
End Sub

VI-A-1-c. Fonction Random

À l'instar de la fonction Rnd, elle permet de générer un nombre aléatoire compris entre 0 et 1.

Fonction Random
Sélectionnez
'********************************************************************************
'************************ Fonction random personnalisée *************************
'********************************************************************************
Function Random() As Single
    Dim x As Long ' Variable contenant le nombre pseudoaléatoire

    x = (x1 + x2) Mod 10000000 ' Formule type fibonacci modulo la valeur maximale
   
    x1 = x2 ' x1 prend la valeur de x1
    x2 = x  ' x2 prend la nouvelle valeur obtenue avec la formule
   
    Random = CLng(x) / 10000000 ' On divise par 10000000 pour avoir un nombre compris entre 0 et 1.
End Function

VI-B. Test de la fonction par la méthode de Monte-Carlo

La méthode de Monte-Carlo consiste à calculer une valeur numérique approchée en utilisant un procédé aléatoire. Elle est particulièrement utilisée pour le calcul de surfaces ou de volumes.

Pour plus de détails, vous pouvez consulter cette pageMéthode de Fibonacci.

VI-B-1. Détermination de la valeur de Pi

Considérons un cercle de centre 0 et de rayon 1/2, inscrit dans un carré de côté 1.

Le procédé aléatoire va consister à jeter un grand nombre de fois un petit objet dans le carré et à compter à chaque fois que l'objet tombe dans le cercle.

En faisant le rapport du nombre de fois où l'objet est tombé dans le cercle sur le nombre total de lancers, on doit obtenir une approximation du rapport entre la surface du cercle et celle du carré, c'est-à-dire Pi/4.

[TITRE-PASTOUCHE]

VI-B-1-a. Fonction Test

Soit un point M de coordonnées (x,y), où -1/2 < x < 1/2 et -1/2 < y < 1/2. On tire aléatoirement les valeurs de x et y avec la fonction Random. Le point M appartient au disque de centre (0,0) de rayon 1/2 si et seulement si x^2 + y^2 <= 1/4. La probabilité que le point M appartienne au disque est donc pi/4.

fonction TestRandom
Sélectionnez
'********************************************************************************
'*************************** Fonction test de Random ****************************
'********************************************************************************
Public Function TestRandom(n As Long)
    ' n : nombre de tirages
    Dim c As Long ' compteur des tirages dans le cercle
    Dim x As Single, y As Single ' coordonnées sur le carré
    Dim i As Long ' indice du tirage

    ' Initialisation du générateur de nombres aléatoires
    InitRandom

    ' Initialisation du compteur
    c = 0:

    For i = 1 To n

        x = (Random - 0.5) ' Génération aléatoire de la valeur pour la coordonnée x
        y = (Random - 0.5) ' Génération aléatoire de la valeur pour la coordonnée y
   
       If Sqr(x ^ 2 + y ^ 2) <= 0.5 Then ' Test si le point de coordonnées (x,y) est dans le cercle
           c = c + 1 ' Si oui on incrémente le compteur
       End If
   
    Next i

    TestRandom = (c / n) * 4 ' Renvoie la valeur approximation de Pi (c/n -> Pi/4 d'où : (c / n) * 4 -> Pi)
End Function

À l'exécution, on remarque que la fonction tend vers Pi à mesure que le nombre de tirages augmente. Elle peut donc être considérée comme un générateur de nombres pseudoaléatoires.

VI-C. Note

Étant donné que l'instruction Randomize et la fonction Rnd commencent par une valeur initiale et génèrent des nombres compris dans une plage finie, les résultats peuvent être prévus par toute personne connaissant l'algorithme utilisé pour les créer. L'instruction Randomize et la fonction Rnd ne doivent donc pas être utilisées pour créer des nombres aléatoires qui seront utilisés en chiffrement.

VII. Les bases de données à télécharger

VIII. Remerciements

Je tiens à remercier Laurent Ott, arkham46 et f-leb pour m'avoir conseillé pour la réalisation de cet article, ainsi que Anthony Jorion pour sa relecture.

Vous avez aimé ce tutoriel ? Alors partagez-le en cliquant sur les boutons suivants : Viadeo Twitter Facebook Share on Google+   

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2017 Denis Hulo Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.