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

Arduino Discussion :

Utilisation de la Fonction random()


Sujet :

Arduino

  1. #21
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    936
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 936
    Par défaut
    test :générateur congruentiel linéaire comme ceux de Derrick Lehmer

    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
     
    // Paramètres du GCL (modifiables selon les besoins)
    const unsigned long a = 16807;       // multiplicateur (ex: Lehmer)
    const unsigned long m = 2147483647;  // module (2^31 - 1, un nombre premier)
    unsigned long seed = 123456789;      // graine initiale (doit être entre 1 et m-1)
     
    void setup() {
      Serial.begin(9600);
      while (!Serial); // Attendre que la connexion série soit prête (utile pour certains Arduino)
     
      Serial.println("Generateur congruentiel lineaire:");
      for (int i = 0; i < 10; i++) {
        seed = (a * seed) % m;  // GCL: Xn+1 = (a * Xn) mod m
        Serial.println(seed);
      }
    }
     
    void loop() {
      // Rien ici, car tout se fait dans setup()
    }
    çà génère çà :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Generateur congruentiel lineaire:
    469048755
    2037437125
    1578992516
    1671778077
    2045573356
    885673461
    1304694740
    48965453
    476131388
    816165668
    mais comment puis-je intégrer çà dans mon programme svp ? ( là je suis un peu paumé )


    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
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
     
    #include <Adafruit_NeoPixel.h>
    #include "TM1637Display.h"
     
    #define BUTTON_PIN     2
    #define RESET_PIN      6
    #define LEDA_PIN       3
    #define RED_PIN        4
    #define BLUE_PIN       5
    #define NUM_LEDS       10
    #define BRILLANCE      25
     
    #define CLK            7
    #define DIO            8
     
    TM1637Display display(CLK, DIO);
    Adafruit_NeoPixel ledA(8, LEDA_PIN, NEO_GRB + NEO_KHZ800);
    Adafruit_NeoPixel redLED(NUM_LEDS, RED_PIN, NEO_GRB + NEO_KHZ800);
    Adafruit_NeoPixel blueLED(NUM_LEDS, BLUE_PIN, NEO_GRB + NEO_KHZ800);
     
    bool joueurBleuActif = false;
    bool gameStarted = false;
    int redScore = 0;
    int blueScore = 0;
    int totalTurns = 0;
    long randNumber;
    bool lastButtonState = HIGH;
    bool lastResetState = HIGH;
     
     
    void setup() {
      Serial.begin(9600);
      randomSeed(analogRead(0));
      pinMode(BUTTON_PIN, INPUT_PULLUP);
      pinMode(RESET_PIN, INPUT_PULLUP);
      ledA.begin();
      redLED.begin();
      blueLED.begin();
      ledA.show(); redLED.show(); blueLED.show();
      ledA.setBrightness(BRILLANCE);
      redLED.setBrightness(BRILLANCE);
      blueLED.setBrightness(BRILLANCE);
     
      display.setBrightness(2);
      resetGame();
    }
     
    void loop() {
      bool startState = digitalRead(BUTTON_PIN);
      bool resetState = digitalRead(RESET_PIN);
     
      if (lastResetState == HIGH && resetState == LOW) {
        resetGame();
      }
     
      if (lastButtonState == HIGH && startState == LOW && !isGameOver()) {
        if (!gameStarted) {
          joueurBleuActif = tirageInitial();
          gameStarted = true;
        } else {
          tourDeJeu();
        }
      }
     
      lastButtonState = startState;
      lastResetState = resetState;
    }
     
    void resetGame() {
      joueurBleuActif = false;
      redScore = 0;
      blueScore = 0;
      totalTurns = 0;
      gameStarted = false;
      ledA.clear(); ledA.show();
      redLED.clear(); redLED.show();
      blueLED.clear(); blueLED.show();
      display.clear();
      updateDisplay();
      Serial.println("🔄 Jeu réinitialisé !");
    }
     
    bool tirageInitial() {
      bool couleur=DeterminePlayer();
      animationBlanche();
      Serial.println(couleur);
      clignoter(couleur);
      updateDisplay();
      Serial.print("🔰 Le joueur qui commence est : ");
      Serial.println(couleur ? "BLEU" : "ROUGE");
      return couleur;
    }
     
    void tourDeJeu() {
      bool couleur=DeterminePlayer();
      animationBlanche();
      Serial.println(couleur);
      clignoter(couleur);
      Serial.print("🎲 Couleur tirée : ");
      Serial.println(couleur ? "BLEU" : "ROUGE");
     
      if (couleur == joueurBleuActif) {
        if (joueurBleuActif && blueScore < NUM_LEDS) {
          blueScore++;
        } else if (!joueurBleuActif && redScore < NUM_LEDS) {
          redScore++;
        }
        Serial.println("✅ Bon joueur → rejoue");
      } else {
        if (joueurBleuActif) {
          if (blueScore > 0) blueScore--;
          if (redScore < NUM_LEDS) redScore++;
          joueurBleuActif = false;
        } else {
          if (redScore > 0) redScore--;
          if (blueScore < NUM_LEDS) blueScore++;
          joueurBleuActif = true;
        }
        Serial.println("❌ Mauvais joueur → adversaire rejoue");
      }
     
      totalTurns++;
      updateScores();
      updateDisplay();
     
      if (redScore == NUM_LEDS) {
        Serial.println("🏆 Joueur ROUGE GAGNE !");
        flashWin(redLED, redLED.Color(255, 0, 0));
        blueLED.clear(); blueLED.show();
      } else if (blueScore == NUM_LEDS) {
        Serial.println("🏆 Joueur BLEU GAGNE !");
        flashWin(blueLED, blueLED.Color(0, 0, 255));
        redLED.clear(); redLED.show();
      }
     
      Serial.print("🔴 ROUGE: "); Serial.println(redScore);
      Serial.print("🔵 BLEU : "); Serial.println(blueScore);
      Serial.print("⏳ Nb Tours : "); Serial.println(totalTurns);
    }
     
    bool isGameOver() {
      return (redScore == NUM_LEDS || blueScore == NUM_LEDS );
    }
     
    void animationBlanche() {
      for (int i = 0; i < 15; i++) {
        ledA.clear();
        ledA.setPixelColor(i, ledA.Color(255, 255, 255));
        ledA.show();
        delay(60);
      }
    }
     
    void clignoter(bool isBlue) {
      for (int i = 0; i < 6; i++) {
        ledA.fill(isBlue ? ledA.Color(0, 0, 255) : ledA.Color(255, 0, 0));
        ledA.show();
        delay(200);
        ledA.clear();
        ledA.show();
        delay(200);
      }
    }
     
    void updateScores() {
      redLED.clear();
      blueLED.clear();
     
      for (int i = 0; i < redScore; i++) {
        redLED.setPixelColor(i, redLED.Color(255, 0, 0));
      }
      for (int i = 0; i < blueScore; i++) {
        blueLED.setPixelColor(i, blueLED.Color(0, 0, 255));
      }
     
      redLED.show();
      blueLED.show();
    }
     
    void updateDisplay() {
      // Affichage des tours restants + joueur actif (r = 0x50, b = 0x7C)
      uint8_t digits[4];
     
      digits[0] = display.encodeDigit(totalTurns / 10);
      digits[1] = display.encodeDigit(totalTurns % 10);
      digits[2] = 0;
      //digits[3] = joueurBleuActif ? 0x3E : 0x50; // 'b' or 'r'
      if (totalTurns ==0 ){
        digits[3] = 0x40; // '-'
      }else{
        digits[3] = joueurBleuActif ? 0x7C : 0x50; // 'b' or 'r'
      }
     
     
      display.setSegments(digits);
    }
     
    void flashWin(Adafruit_NeoPixel &strip, uint32_t color) {
      for (int i = 0; i < 6; i++) {
        strip.fill(color); strip.show();
        delay(250);
        strip.clear(); strip.show();
        delay(250);
      }
    }
     
    bool DeterminePlayer(void) {
      return(random(0, 1000) > 500);
    }

  2. #22
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 598
    Par défaut
    Bonjour,

    il suffit d'écrire un truc comme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    bool DeterminePlayer(void) {
       static unsigned long n = 123456789UL;
       n = (16807UL * n) % 2147483647UL;
       return odd(n);
    }
    Cependant, comme déjà évoqué, sur les 2147483647 valeurs, 1076741824 seront true et 1076741825 seront false. Et il n'existe aucune manière de répartir un nombre impair de valeurs en deux groupes égaux.

    La seule solution qui me vienne serait de travailler sur 2 séquences. Par exemple, if((n == 0) { sequence_up = !sequence_up; if (sequence_up) return 1;} à mettre entre les lignes 3 et 4 (et créer le booléen sequence_up correspondant).

    C'est beaucoup de travail pour corriger un impact marginal. La solution déjà proposée d'écrire simplement bool couleur = random(2); // > 0 pour l'esthétique est plus simple (pas de fonction DeterminePlayer) et aussi efficace.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  3. #23
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 817
    Par défaut
    @ Jay M : peu importe que cela soit lent ou pas, l'important est que ce générateur produise un résultat homogène (équiprobable), à savoir que durant ce cycle M, tu n'auras jamais deux fois Xn qui apparaitra et en plus, il apparait dans un désordre non prédictible.

    @ Guesset : mais pourquoi prendre un a qui produit un résultat non conforme aux attentes d'un bon générateur ?
    Je ne sais pas où tu vois un biais, mais je l'utilise depuis longtemps sans jamais avoir pu le mettre en défaut.

    @ cobra38 : pour le calcul, il suffit de faire le rapport R = Xn / m qui donne un nombre flottant dans l'intervalle [0,0 ; 1,0[. Si tu veux un résultat donnant 0 ou 1 entier, il suffit de faire : val = partie entier de [ R*2 ].

    Ou bien, tu fais val = Xn Modulo 2.

    Faire le tour du cycle, disons un lancer par seconde, prendrait 68 ans 18 jours 3 heures 14 minutes et 7 secondes.

  4. #24
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 598
    Par défaut
    Bonjour Artemus,

    Citation Envoyé par Artemus24 Voir le message
    mais pourquoi prendre un a qui produit un résultat non conforme aux attentes d'un bon générateur ?
    Si on ne veut pas introduire de biais lors de la mise à l'échelle (ie smin...smax-1), il faut que les smax - smin = d valeurs se partagent chacune le même nombre de valeurs du générateur source.
    En effet, la probabilité de sortie d'une valeur m est : (nm = nb de valeurs source qui donnent m) / (n = nb total de valeurs de la source). L'équipartition suppose donc que nm est constant. Par ailleurs, la somme des nm doit être égale à n (relation de fermeture)
    Il s'ensuit que d*nm = n donc que d et nm divisent n ce qui n'est pas possible si n est premier comme dans le cas que tu proposes.

    Je ne sais pas où tu vois un biais, mais je l'utilise depuis longtemps sans jamais avoir pu le mettre en défaut.
    Si les conditions précédentes ne sont pas satisfaites il y a un biais certes très faible mais inéluctable. En général les plages de valeurs sont petites devant n ce qui rend le phénomène difficilement perceptible. Si tu prends une gamme relativement importante, par exemple 0 à 390451572 pour n = 2147483647, les biais se manifesteront plus visiblement.

    Dans la réponse donnée à Cobra38 : val = Xn Modulo 2. Sachant que Xn va de 0 à m-1 (m que j'appelle n dans les points précédents), Comme m est impair, il y a une valeur paire de plus que de valeurs impaires :
    0 2 4 6 ... m-3 m-1
    1 3 5 7 ... m-2
    J'ai mis les valeurs dans l'ordre pour simplifier le lecture, mais peu importe l'ordre d'apparition car en m itérations le générateur source balaye toutes les valeurs de 0 à m-1.

    Salut
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  5. #25
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 817
    Par défaut
    Quand j'ai testé ce générateur de nombres aléatoires de Lehmer , je voulais vérifier des martingales sur le jeu de la roulette. Il n'y a pas de bais car le zéro (case verte) est autre chose qu'un pair, un impair, un passe, un manque, un rouge ou encore un noir. Le biais que tu indiques n'a pas lieu d'être au jeu de la roulette. Autre point de vue, comparativement à m, ce biais est minimaliste, vu que j'indique qu'il faut 68 ans pour faire le tour du cycle. Tu n'exploiteras qu'un fraction de ce cycle et cela n'a pas trop d'importance si il existe un léger déséquilibre.

    Ce générateur de Lehmer dit standard est recommandé comme très fiable.

    Pour la graine, Cobra38, tu peux prendre la date système (exemple 2025/05/23), soit huit chiffres. Tu peux introduire aussi l'heure 20:53:15) si ce n'est pas suffisant.

  6. #26
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 817
    Par défaut
    Pour ce teste, j'utilise mon NodeMCU ESP32 (Joy-It) à l'aide de l'IDE Aeduino dans la version 3.2.0. de la carte ESP32 Espressif.

    Voici le sketch de la fonction GNA standard :
    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
    const unsigned long long int a=16807;
    const unsigned long long int m=2147483647;
          unsigned long long int val, gna;
     
    void setup(void)
    {
    	Serial.begin(115200);
    	delay(1000);
     
    	val=(unsigned long long int)esp_random();
    }
     
    void loop(void)
    {
    	val = (a*val)%m;
    	gna  = val%2;
     
    	Serial.printf("VAL = %10llu   GNA = %1llu\r\n", val, gna);
     
    	delay(1000);
    }
    Et un résultat de sa simulation :
    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
            +------------+
            | GNA Lehmer |
            +------------+
     
    VAL =  1251547675   GNA = 1
    VAL =   159451360   GNA = 0
    VAL =  1986899711   GNA = 1
    VAL =   452731927   GNA = 1
    VAL =   530935768   GNA = 0
    VAL =   642899491   GNA = 1
    VAL =  1221517180   GNA = 0
    VAL =    95578940   GNA = 0
    VAL =    77476624   GNA = 0
    VAL =   774529486   GNA = 0
    VAL =  1618686735   GNA = 1
    VAL =   945114949   GNA = 1
    VAL =  1757894631   GNA = 1
    VAL =  2002531438   GNA = 0
    VAL =  1182162682   GNA = 0
    VAL =    89494330   GNA = 0
    VAL =   892651410   GNA = 0
    VAL =   471489928   GNA = 0
    Mon ESP32 permet de gérer des nombres entiers en 64 bits sachant que celui-ci fonctionne en 32 bits. Oui, ça aide.

    Si comme l'indique Guesset sur le biais au jeu de pile ou face, il suffit alors de na pas tenir compte de la valeur produite par le GNA quand il a la valeur zéro. L'équilibre sera respectée et plus de biais.

    Sauf que le problème va se reposer sur chaque modulo que l'on va produire car m est un nombre premier, donc il n'y a jamais un équilibre parfait.

    @+

  7. #27
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 598
    Par défaut
    Bonjour Artemus,
    Citation Envoyé par Artemus24 Voir le message
    ...ce biais est minimaliste, vu que j'indique qu'il faut 68 ans pour faire le tour du cycle. Tu n'exploiteras qu'un fraction de ce cycle et cela n'a pas trop d'importance si il existe un léger déséquilibre...
    Le biais est effectivement faible sauf si la gamme est grande. Les 68 ans correspondent à un essai par seconde, ils tombent à moins de 25 j pour un essai par ms et 35 mn pour un essai par µs (et imaginons des tests faits en // sur 16 cœurs qui tournent à 4 GHz) . Par ailleurs le biais existe sans qu'il soit nécessaire de faire un cycle complet (ce dernier n'est utilisé que pour simplifier la démonstration). Ce biais effectif peut certainement être négligé dans beaucoup de cas. Je voulais juste signaler que l'assertion sans biais n'était pas exacte.

    Salut
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  8. #28
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 817
    Par défaut
    Citation Envoyé par Guesset
    Le biais est effectivement faible sauf si la gamme est grande.
    Si le cycle (m) est trop petit, rien ne t'empêche de prendre celui-ci sur 64 bits au lieu du 32 bits avec le standard :
    --> m = 263 - 25 = 9 223 372 036 854 775 783
    --> a = 6 364 136 223 846 793 005

    Citation Envoyé par Guesset
    Ce biais effectif peut certainement être négligé dans beaucoup de cas.
    C'est ta notion de biais qui n'est pas le même que dans l'usage que je fais.

    Mon biais est celui de ne pas trouver des corrélations entre les valeurs produites par le GNA. Si tu inscris dans un carré, le couple (XN ; XN-1), tu peux constater des alignement. Dans la plupart des cas, ce GNA est bien meilleurs que celui de Windows (Rand()) utilisé en 'C/C++' qui est simple, basique et pas très aléatoire.

    Si maintenant, ce n'est toujours pas suffisant, il existe d'autres approchent pour produire des nombres aléatoires, qui est hors sujet de l'usage simple dans un Arduino ou dans un ESP32.

    Citation Envoyé par Guesset
    Je voulais juste signaler que l'assertion sans biais n'était pas exacte.
    Si les valeurs a et m sont correctement prises, tu auras une équiprobabilité pour chaque tirage, c'est-à-dire que tu vas passer par toutes les valeurs, une et une seul fois, dans le cycle de m. C'est ce que je recherchais comme GNA.

    Comme je l'ai dit précédemment, je l'ai utilisé pour démontrer que ces fameuses martingales ne produisent pas le résultat attendu car le hasard produit par ce GNA est imprévisible et homogènes, sans corrélations.

    Un exemple de ce qu'il ne faut pas faire est de prendre les décimale de Pi comme GNA. On constate, tout au contraire, que le résultat n'est pas du tout homogène et provoque donc un biais qui permet de constater que ces martingales produisent le résultat attendu. A éviter.

    @ Cobra38 : peux tu faire tes calculs en 64 bits comme dans mon exemple, sachant que mon ESP32 fonctionne en 32 bits ? Cela permettrait de simplifier ton sketch.

  9. #29
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 598
    Par défaut
    Bonjour,

    La grande taille de la gamme (et sa relation notamment demi entière avec la longueur de cycle) qui rend le biais plus visible est une taille relative à la longueur de cycle. En fait l'exigence de qualité relative que l'on souhaite lors de la mise à l'échelle implique une longueur minimale de cycle et/ou un cycle multiple de la gamme de valeurs cibles.

    Une distribution de points au hasard a des alignements et des amas, mais notre esprit tend à considérer que le moindre alignement témoigne d'un ordre indigne de "vrai" aléatoire. C'est ce que Jean-Paul Delahaye montre dans son livre "Les inattendus mathématiques" chez Belin au chapitre 11 "Notre vision du hasard est bien hasardeuse" et qu'il appelle l'effet râteau.
    En fait une distribution sans alignement et amas subit une contrainte qui en réduit l'éventail des choix et donc limite la qualité aléatoire. Aussi juger de la qualité d'un générateur sur l'absence d'alignement est assez dangereux. Même si une profusion d'alignements peut s'avérer suspecte.

    Trouver un bon générateur est nécessaire mais pas suffisant si la projection sur l'échelle cible altère la qualité de la source.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  10. #30
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    765
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 765
    Par défaut
    Bonsoir @Artemus24 et @Guesset,

    Un petit peu HS.

    Désolé de m'immiscer dans cette discution qui ne me concerne pas, mais vous semblez tous deux être pro en génération de nombres aléatoires. Existe-t-il un algorithme qui permettrait de générer réellement des nombres aléatoires ? Déjà, le terme "algorithme" signifie que non, mais bon.... Je précise qsue je suis nul en mathématiques théoriques (j'ai eu beaucoup de mal à suivre vos raisonnements)
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent ;)

  11. #31
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 250
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 250
    Par défaut
    Bonjour,
    Les algorithmes pseudo aléatoires imitent l'aléatoire. Pour avoir du vrai aléatoire il faut aller le chercher dans le monde physique.

    Un ADC en l'air, un ADC sur une antenne, un mesure sur une résistance chaude, sur une diode zener etc...
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  12. #32
    Responsable Arduino et Systèmes Embarqués


    Avatar de f-leb
    Homme Profil pro
    Enseignant
    Inscrit en
    Janvier 2009
    Messages
    13 151
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Janvier 2009
    Messages : 13 151
    Billets dans le blog
    47
    Par défaut
    Bonjour à tous,

    Citation Envoyé par edgarjacobs Voir le message
    Existe-t-il un algorithme qui permettrait de générer réellement des nombres aléatoires ? Déjà, le terme "algorithme" signifie que non, mais bon.... Je précise qsue je suis nul en mathématiques théoriques (j'ai eu beaucoup de mal à suivre vos raisonnements)
    Concernant le pseudo-aléatoire, voir par exemple le tutoriel Les générateurs de nombres aléatoires pour comprendre l'essentiel...

  13. #33
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 598
    Par défaut
    Bonjour,

    Les générateurs ne peuvent que faire du faux aléatoire quels qu'ils soient. Ils ont tous un cycle de longueur finie (heureusement qui peut être très grande). Il engendre tous (à ma connaissance) l'élément suivant à partir de l'élément en cours. Il s'ensuit, qu'après son cycle, le générateur le rejoue identiquement.

    Même générer physiquement des valeurs aléatoires n'est pas si simple car il faut se prémunir de perturbateurs, notamment hertziens, omniprésents, dans nos environnements.

    J'aime bien les générateurs utilisant rotations et masques de xor. Il sont simples, rapides et de bonne qualité. Cependant, dans la plupart des cas, les projets n'impliquent pas nécessairement une exigence de qualité très élevée et je me contente des bibliothèques standards. Il me semble en effet qu'il est important de savoir les avantages et inconvénients de tel ou tel, non pas pour utiliser le meilleur par principe, mais pour éclairer un choix pragmatique. Cela vaut aussi pour la projection des sorties du générateur sur des espaces de valeurs réduits.

    Salutations
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  14. #34
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 817
    Par défaut
    Citation Envoyé par Edgarjacobs
    Désolé de m'immiscer dans cette discussion qui ne me concerne pas, mais vous semblez tous deux être pro en génération de nombres aléatoires.
    Je me suis intéressé aux nombres aléatoires quand j'ai étudié les martingales. Certaines joueurs professionnels affirmaient s'enrichir. J'ai quand même eu un gros doute à ce sujet, et j'ai voulu vérifier et il se trouve que le comportement des martingales dépendent du GNA qui est utilisé. Si tu as un GNA déséquilibré, alors oui, ces martingales fonctionnent. J'ai recherché un bon GNA, bien équilibré, facile à programmer, et j'ai trouvé le Générateur Congruentiel linéaire et en particulier ceux de Lehmer (c=0) et plus précisément le standard que j'ai adopté. A partir de ce moment, j'ai pu constater qu'aucune martingale n'est gagnante sur le long terme.

    Citation Envoyé par Edgarjacobs
    Existe-t-il un algorithme qui permettrait de générer réellement des nombres aléatoires ?
    Je dirais des nombres pseudo aléatoires. Je vois dans les messages précédents que vous avez utilisé le même terme pour les désigner.

    Citation Envoyé par Vincent PETIT
    Les algorithmes pseudo aléatoires imitent l'aléatoire. Pour avoir du vrai aléatoire il faut aller le chercher dans le monde physique.
    Si tu veux de vrais nombres aléatoires, c'est-à-dire sans aucune prévisibilité, il y a les détecteurs de particules comme les compteurs Geiger qui mesurent le temps entre deux désintégrations. Cela donne des intervalles aléatoires, convertibles en bits.

    Il y a les composants électroniques produisant du bruit à cause de l'agitation thermique des électrons. En amplifiant ce bruit, on peut extraire des bits aléatoires.

    Il y a le cas de la cryptographie dont le besoin est d'avoir un véritable hasard pour produire des clefs impossibles à deviner. Tout ce qui est jeux d'argent ou encore des simulations scientifiques, si on veut éviter les biais. Ce ne sont pas les applications qui manquent où ce besoin est cruciale.

  15. #35
    Membre Expert Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    765
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 65
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 765
    Par défaut
    Grand merci à tous pour vos réponses très claires

    Edit: merci @f-leb: cet article est très instructif
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent ;)

  16. #36
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 889
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 889
    Par défaut
    Citation Envoyé par cobra38 Voir le message
    Salut Jay M


    Pour que je comprenne bien , lorsque je fais
    la valeur 1000 n'est jamais prise en compte

    le nombre aléatoire sera donc toujours compris ente 1 et 999
    oui c'est ça - vous avez bien compris.

  17. #37
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 889
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 889
    Par défaut
    Citation Envoyé par Guesset Voir le message
    Si on ne veut pas introduire de biais lors de la mise à l'échelle (ie smin...smax-1), il faut que les smax - smin = d valeurs se partagent chacune le même nombre de valeurs du générateur source.
    En effet, la probabilité de sortie d'une valeur m est : (nm = nb de valeurs source qui donnent m) / (n = nb total de valeurs de la source). L'équipartition suppose donc que nm est constant. Par ailleurs, la somme des nm doit être égale à n (relation de fermeture)
    Il s'ensuit que d*nm = n donc que d et nm divisent n ce qui n'est pas possible si n est premier comme dans le cas que tu proposes.
    L'équipartition dont vous parlez n'est "atteinte" que tous les n tirages, tout le reste du temps vous êtes forcément avec une répartition imparfaite (eg vous avez 10 choix, au 15ème tirage vous ne pouvez pas avoir l'égalité pour chacun des choix) donc ça n'a pas vraiment d'importance - l'équipartition exacte n'est pas un objectif sauf à l'infini et aucun d'entre nous n'a ce temps devant lui...

  18. #38
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 598
    Par défaut
    Bonjour Jay M,

    Citation Envoyé par Jay M Voir le message
    L'équipartition dont vous parlez n'est "atteinte" que tous les n tirages, tout le reste du temps vous êtes forcément avec une répartition imparfaite (eg vous avez 10 choix, au 15ème tirage vous ne pouvez pas avoir l'égalité pour chacun des choix) donc ça n'a pas vraiment d'importance - l'équipartition exacte n'est pas un objectif sauf à l'infini et aucun d'entre nous n'a ce temps devant lui...
    L'équipartition garantit que les cas sont équiprobables ce qui est un des éléments clé - mais pas le seul - des générateurs. C'est une caractéristique du générateur non des tirages.

    Salut
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

  19. #39
    Membre prolifique Avatar de Artemus24
    Homme Profil pro
    Agent secret au service du président Ulysses S. Grant !
    Inscrit en
    Février 2011
    Messages
    6 817
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Agent secret au service du président Ulysses S. Grant !
    Secteur : Finance

    Informations forums :
    Inscription : Février 2011
    Messages : 6 817
    Par défaut
    Citation Envoyé par Jay M
    L'équipartition dont vous parlez n'est "atteinte" que tous les n tirages
    Ce n'est pas la définition d'une équirépartition. Si une suite est équirépartie, cela signifie que les termes de la suite se distribuent de manière uniforme. Il n’y a pas de zones plus favorisées qu'une autre sur le long terme, en dehors des écarts pouvant apparaitre. Cela signifie qu'elle occupe l’espace de manière équilibrée. Tu peux prendre l'exemple du dé dont la probabilité uniforme est de 1/6.

    Le retour à l'équilibre, (traduction: toutes les fréquences ont la même valeur) peut se faire, mais rien ne le garantie sur le long terme, voire même, la probabilité de le constater tend vers zéro.

    Citation Envoyé par Jay M
    l'équipartition exacte n'est pas un objectif sauf à l'infini et aucun d'entre nous n'a ce temps devant lui...
    Je pense que tu as une méconnaissance des lois mathématiques régissant les statistiques et les probabilités.

    L'équirépartition est une façon dite homogène de distribuer les tirages d'une façon uniforme. C'est une probabilité quand tu dis qu'elle est de 1/6 au jeu de dé, celui avec six faces. Car tu considères que chaque face à la même probabilité d'apparaitre après un lancé. On ne parle pas d'infini, mais plutôt "sur le long terme", car on observe cette équirépartition souvent sur un nombre fini, mais pas infini.

    Citation Envoyé par Guesset
    C'est une caractéristique du générateur non des tirages.
    Les deux mon général, car la répartition uniforme se fait aussi sur les tirages, sinon la probabilité n'est plus confirmée. En ce qui concerne l'écart, il est possible de ne pas retrouver l'égalité parfaite sur les tirages, mais sur des échantillonnages de grand nombre, on ne doit pas voir le même schéma se reproduire, ce qui pourrait signifier que nous avons un biais. Le calcul de l'écart-type est la façon dont le déséquilibre peut être admissible, sans remettre la loi d'uniforme en cause.

  20. #40
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 598
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 598
    Par défaut
    Bonjour Artemus,

    Citation Envoyé par Artemus24 Voir le message
    ...la répartition uniforme se fait aussi sur les tirages, sinon la probabilité n'est plus confirmée. En ce qui concerne l'écart, il est possible de ne pas retrouver l'égalité parfaite sur les tirages, mais sur des échantillonnages de grand nombre, on ne doit pas voir le même schéma se reproduire, ce qui pourrait signifier que nous avons un biais. Le calcul de l'écart-type est la façon dont le déséquilibre peut être admissible, sans remettre la loi d'uniforme en cause.
    L'équipartition garantit que chaque tirage possible est équiprobable et non que n tirages soient équilibrés ce qui est d'une probabilité très (très) faible et tend vers 0. La répartition uniforme n'existe pas sur les tirages. Aujourd'hui on dirait peut être que c'est juste un attracteur.

    Salut
    Ever tried. Ever failed. No matter. Try Again. Fail again. Fail better. (Samuel Beckett)

Discussions similaires

  1. Utilisation de la fonction Random
    Par Djemàa dans le forum Langage
    Réponses: 4
    Dernier message: 03/04/2012, 19h50
  2. Utilisation de la fonction randomize
    Par acacia dans le forum C
    Réponses: 7
    Dernier message: 21/01/2008, 00h37
  3. [LG]Utilisation de la fonction Random
    Par chloe95 dans le forum Langage
    Réponses: 1
    Dernier message: 01/03/2005, 14h20
  4. Fonction Random en Assembleur
    Par chidi dans le forum Assembleur
    Réponses: 5
    Dernier message: 21/05/2004, 10h16
  5. [LG]librairies : utiliser seulement quelques fonctions
    Par wwwroom dans le forum Langage
    Réponses: 13
    Dernier message: 14/05/2004, 22h50

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