IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Randomize - Algorithme, mécanisme, comment fonctionne l'aléa sous VBA Excel


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 817
    Billets dans le blog
    10
    Par défaut Randomize - Algorithme, mécanisme, comment fonctionne l'aléa sous VBA Excel
    Bonjour,

    Bonjour Jacques

    Lors de cette discussion (n'allez pas la consulter, elle est sans rapport avec la présente), a été soulevé le problème de la génération de nombres aléatoires sous VBA.

    Dans cette même discussion, Marc-L utilise un code générant aléatoirement 5 lettres qu'il répartit sur 65000 lignes et 5 colonnes.
    Ce code [donné dans cette réponse] génère systématiquement la même série de lettres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Sub Initialisation()
            Const N = 65535
            Dim C&, R&, S$(N, 4)
            Randomize 666.666
            ActiveSheet.UsedRange.Clear
            [I1].Select
        For R = 0 To N
            For C = 0 To 4:  S(R, C) = Chr$((5 * Rnd) + 65):  Next
        Next
            Application.ScreenUpdating = False
            [A1].Resize(N + 1, 5).Value = S
            Application.ScreenUpdating = True
    End Sub
    Rappel de Unparia :
    Citation Envoyé par unparia Voir le message
    Petite mise au point et/ou rappel en ce qui concerne les nombres aléatoires. Rien n'est plus hasardeux que de les traiter par l'informatique, du fait même de la répétition de ce sur quoi on assoit l'aléa.
    C'est là un VRAI problème, dont il faut avoir conscience. Personne, jusqu'à présent, n'est parvenu avec un simple ordinateur, à tirer, sur une très longue série de tirages, un nombre à peu près égal de tirages pour chacun des éléments composant l'ensemble sur lequel on procède au tirage.
    Dans son code, Marc "assoit" son aléa sur la même valeur numérique : 666.666.
    Il obtient systématiquement le même résultat.
    Si l'on change 666.666 par une autre constante, on obtient une autre série qui, restera immuable avec cette autre valeur.
    Si l'on supprime cette valeur (Randomize seul) la série évoluera à chaque appel (il en va de même si on lui donne une valeur changeante telle que Randomize Timer).

    Je voudrais aujourd'hui approfondir le sujet et comprendre :
    1. Comment fonctionne Randomize,
    2. Est ce qu'il est initialisé à chaque appel de Rnd(),
    3. Quel est (ou quel serait) l'algorithme utilisé pour la génération des nombres aléatoires,
    4. Etc...
    5. Lister les cas d'utilisation les plus fréquents,
    6. En fonction de ces différents cas, trouver une solution adaptée.
    7. Etc...


    Merci par avance de toutes contributions.

  2. #2
    Expert confirmé
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 84
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Par défaut
    Bonjour Franck

    De bon matin (il vaut d'ailleurs mieux compte tenu de la complexité de cet aspect) !
    Les aleas des mécanismes (eux-mêmes aléatoires) de génération d'aléas !!!
    Je crois que le tout premier pas devra être la lecture TRES attentive de ceci :
    https://fr.wikipedia.org/wiki/Comple..._de_Kolmogorov

    EDIT : tiens (juste pour rigoler avec un exemple finalement très mal aléatoire) :
    "Je vais choisir au hasard un volontaire parmi vous, messieurs. Et tiens : au "hasard", donc, mon doigt est plutôt attiré vers ceux que j'aime le moins"
    Qui montre (celui-ci de manière très grossière) que le "hasard" n'est pas toujours pur, y compris de manière inconsciente.

    EDIT 2 (et puisque c'est l'époque) : crois-tu vraiment que toto, à qui l'on demande de désigner depuis sous la table, celui auquel est destinée telle ou telle autre part de la galette des rois, ne désignera pas les attributaires dans un ordre presque toujours assez similaire (pas identique, mais similaire) ? Car toto a lui-même ses habitudes inconscientes ... et elles l'influent à son insu.

  3. #3
    Membre Expert
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 817
    Billets dans le blog
    10
    Par défaut
    Bonjour Jacques,

    J'ai lu l'article relatif à la complexité de kolmogorov.
    Je crois l'avoir compris, mais, s'il faut le considérer comme une approche simple, je crois également que je vais être vite largué.
    Concernant tes Edit, il est clair que le hasard est toujours guidé (par l'expérience, les sentiments, certains diraient par Dieu, ...).
    Cela concerne davantage un aspect philosophique qu'informatique, mais il est intéressant de conserver cette notion à l'esprit lorsque l'on étudie les aléas.

    J'ai donc commencé mes recherches (tu t'en doutais) et mes lectures m'ont aiguillé sur cette page wikipédia à propos d'un générateur linéaire congruentiel.
    Il s'agit là du plus simple des algos permettant de trouver une série de nombres pseudo aléatoire.
    Donc, nous sommes très loin de la difficulté soulignée par ton lien :
    Citation Envoyé par kolmogorov
    Une suite peut alors être considérée comme d’autant plus « aléatoire » que sa complexité est grande par rapport à sa taille.
    [...]
    La complexité de Kolmogorov n'est pas calculable. En d'autre termes il n'existe pas de programme informatique qui prenne en entrée s et renvoie K(s).
    Puisque l'on est dans la section VBA et que je cherche à comprendre comment peuvent être générés des nombres de manière aléatoire, je me suis dit qu'écrire du code pouvait être une bonne idée pour une meilleure compréhension.
    Je te livre le code de cette fonction :
    Linear congruential generator :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    Option Explicit
     
    'https://en.wikipedia.org/wiki/Linear_congruential_generator
     
    Sub test()
    Dim mo#, mu#, i#, sv#, lcg#, TbLcg(30000) As Double, Cpt#
    'valeurs de départ choisies aléatoirement par mes soins... (donc pas si aléatoires que cela)
        mo = 65896
        i = 1282
        mu = 8192 'la preuve, ce nombre m'a été soufflé par une précédente discussion à propos de Range.Areas
        lcg = 1
     
        Do
            lcg = Linear_congruential_generator(mo, mu, i, lcg)
            If lcg <> -1 Then
                TbLcg(Cpt) = lcg
                Cpt = Cpt + 1
            Else
                lcg = 1
            End If
        Loop While Cpt < UBound(TbLcg)
        [A1].Resize(UBound(TbLcg)) = Application.Transpose(TbLcg)
    End Sub
     
    Private Function Linear_congruential_generator(modulus#, multiplier#, increment#, start_value#) As Double
    '0<m – the "modulus"
    '0<a<m – the "multiplier"
    'c<m – the "increment"
    'X_{0}<m – the "seed" or "start value"
        If multiplier >= modulus Then Linear_congruential_generator = -1: Exit Function
        If increment >= modulus Then Linear_congruential_generator = -1: Exit Function
        If start_value >= modulus Then Linear_congruential_generator = -1: Exit Function
        Linear_congruential_generator = ((multiplier * start_value) + increment) Mod modulus
    End Function
    Je n'ai pas encore eu le temps d'analyser les résultats (je crois qu'une fonction sur les doublons va m'être nécessaire ) mais ce que l'on peut en dire c'est que pour une valeur de départ identique (lcg = 1), la liste des résultats sera toujours la même.
    Cela rejoint ce que j'annonçais dans le sujet de cette discussion à propos de Randomize Constante.

    EDIT : La fonction ci-dessus retourne 8237 valeurs uniques sur une série de 30000.
    Avec 3 doublons sur 4 nombres, peut-on parler d'aléa?

  4. #4
    Expert confirmé
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 84
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Par défaut
    Je n'ai pas encore eu le temps d'analyser les résultats (je crois qu'une fonction sur les doublons va m'être nécessaire ) mais ce que l'on peut en dire c'est que pour une valeur de départ identique (lcg = 1), la liste des résultats sera toujours la même.
    Tu n'as pas besoin de t'embarrasser d'une fonction sur les doublons pour analyser les résultats. Utilise tout simplement (bien plus pratique et suffisant pour visualiser) l'outil de tri personnalisé de Excel, en triant la colonne A
    Les résultats sont toujours forcément les mêmes dès lors que l'algorithme de leur calcul est toujours le même et que la cadence d'avancement l'est également

    EDIT :
    Avec 3 doublons sur 4 nombres, peut-on parler d'aléa?
    Ben ... Déjà : le nombre de doublons est dépendant du nombre de calculs (les 30000 dans ton exemple). Les aléas étant des aléas, il faudrait un nombre infini de calculs pour pouvoir faire des comparaisons valables sur le nombre des doublons.

  5. #5
    Membre Expert
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 817
    Billets dans le blog
    10
    Par défaut
    Citation Envoyé par unparia Voir le message
    Tu n'as pas besoin de t'embarrasser d'une fonction sur les doublons pour analyser les résultats. Utilise tout simplement (bien plus pratique et suffisant pour visualiser) l'outil de tri personnalisé de Excel, en triant la colonne A
    Oui, bien sur. C'était juste un petit clin d'oeil entre nous.
    Citation Envoyé par unparia Voir le message
    Les résultats sont toujours forcément les mêmes dès lors que l'algorithme de leur calcul est toujours le même et que la cadence d'avancement l'est également
    Je vais donc avancer dans ce sens, en modifiant les valeurs des certaines des constantes.

    Par contre, aurais tu un lien quelque part qui pourrait éventuellement répondre à mes trois premières question?
    Je ne trouve en effet, pas grand chose au sujet de Randomize...

  6. #6
    Expert confirmé
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 84
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Par défaut
    Pour "répondre" (pas vraiment, donc) à tes 3 1ères questions :
    1) Comment fonctionne Randomize,
    2) Est ce qu'il est initialisé à chaque appel de Rnd(),
    3) Quel est (ou quel serait) l'algorithme utilisé pour la génération des nombres aléatoires,
    1) il applique un algo du genre (en plus complexe, probablement) de celui que tu as montré. Il l'applique au nombre que tu définis. Par défaut, c'est la valeur du Timer
    2) Oui. Je le pense, du moins (et l'espère également)
    3) je l'ignore bien évidemment totalement, mais imagine qu'il est accompagné d'un second calcul/algo qui va déterminer quel "article" il va choisir dans la liste des résultats du 1er. Et c'est là, que le bât blessera toujours et c'est là que prend toute sa signification mon expression "aléas d'aléas". Je devine un peu (car j'avais il y a longtemps mis au point une détermination "plus pseudo-aléatoire", mais elle-même demeurant impure) l'utilisation d'un autre modulo (après obtention des résultats du 1er calcul). J'avais quant à moi choisi pour ce second modulo d'utiliser comme diviseur le dernier chiffre de la valeur du Timer. C'était déjà moins mal, mais non parfait, puisque le timer avance de manière parfaitement cadencée et que cette perfection dans la cadence est déjà contraire à l'esprit même du pur hasard.

  7. #7
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut
    Bonjour.

    Citation Envoyé par pijaku Voir le message
    Ce code [donné dans cette réponse] génère systématiquement la même série de lettres
    Oui sur un PC de tests sous la version 2003
    mais pas sur un autre sous Excel 2010 où malgré le Randomize fixe la génération est différente à chaque exécution !

    Là aussi j'aurais bien aimé trouver une explication …

  8. #8
    Expert confirmé
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 84
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Par défaut
    Bonjour Marc

    Je ne crois pas que la version d'Excel soit une explication.
    Je viens en effet d'appliquer et adapter (notamment et surtout pour l'affichage des résultats) ce mécanisme depuis autre chose que VBA --->> toujours les mêmes résultats.

    EDIT : on parle bien sûr de l'application du mécanisme montré par Franck. Randomize n'y a rien à voir et n'y est pas appliqué.

  9. #9
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut

    Bonjour Jacques,

    non j'évoquais mon code Initialisation en lien et publié dans le post initial de Franck …

  10. #10
    Membre Expert
    Avatar de pijaku
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    1 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Août 2010
    Messages : 1 817
    Billets dans le blog
    10
    Par défaut
    Merci Jacques pour tes réponses à mes trois questions.
    C'est un très bon début pour moi.

    Bonjour Marc,
    Ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Sub Initialisation()
            Const N = 65535
            Dim C&, R&, S$(N, 4)
            Randomize 666.666
            ActiveSheet.UsedRange.Clear
            [I1].Select
        For R = 0 To N
            For C = 0 To 4:  S(R, C) = Chr$((5 * Rnd) + 65):  Next
        Next
            Application.ScreenUpdating = False
            [A1].Resize(N + 1, 5).Value = S
            Application.ScreenUpdating = True
    End Sub
    lancé sous mon Excel 2010 me donne systématiquement la même série.
    Rien à voir avec la version donc.
    Par contre, je suis surpris que, chez toi, les séries changent...

    EDIT :
    C'était déjà moins mal, mais non parfait, puisque le timer avance de manière parfaitement cadencée et que cette perfection dans la cadence est déjà contraire à l'esprit même du pur hasard.
    A creuser également...

  11. #11
    Expert éminent
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Par défaut

    Merci du retour Franck !

    Du coup je sais que c'est bien spécifique à cet ordinateur ayant peut-être des anomalies depuis l'upgrade de l'OS …

Discussions similaires

  1. Comment fonctionne l'intégration sous simulink?
    Par Nathaniel_etudiant dans le forum Simulink
    Réponses: 0
    Dernier message: 18/11/2010, 11h35
  2. comment fonctionne mises à jour sous linux
    Par princesse95 dans le forum Debian
    Réponses: 3
    Dernier message: 27/04/2009, 10h44
  3. Comment fonctionne la sécurité sous Vista ?
    Par DranDane dans le forum Windows Vista
    Réponses: 5
    Dernier message: 30/01/2009, 13h02
  4. Comment fonctionne la mémoire sous Xp ou plutôt.
    Par zoltix dans le forum Windows XP
    Réponses: 4
    Dernier message: 27/07/2007, 12h01
  5. [VBA-E] Comment créer un tableau sous vba excel
    Par jeanpierreco dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 27/01/2007, 09h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo