Et en gruge, je m'y connais...
jvernet a écrit :@CRet: balaise, j'ai rien compris!
C'est vrai que je n'est donné aucune explication.
L'idée de base de la méthode se base sur trois constats.
Le premier est que si l'on demande au Pocket de donner 9 nombres entre 1 et 9, il devra répondre 1;2;3;4;5;6;8;7;8;9.
Il n'a pas le choix.
Le code effectuant cela sera quelque chose du style :
Code : Tout sélectionner
X%=0 : FOR I=9 TO 1 STEP -1 : X%=X%+1 : PRINT X%; : NEXT I : PRINT
Maintenant, si je veux paramétrer cela, j'introduis mes paramètres : A% et B% les bornes de l'intervalle et N% le nombre de tirage.
Mon code devient alors :
Code : Tout sélectionner
10 PRINT "TIRAGE DE 9 NOMBRES ENTRE 1 ET 9 : " ; : A%=1 : B%=9 : N%=9:GOSUB 1000 : END
1000 X%=A%-1 : IF B%<A%+N% THEN STOP
1010 FOR I=N% TO 1 STEP -1 : X%=X%+1 : PRINT X%; : NEXT I : PRINT : RETURN
Si l'intervalle [A%,B%] est suffisamment grand, au lieu de tirer les entiers successifs, on peut prendre un sur deux, ou un sur trois, ou un sur quatre, etc. On aura donc une suite d'entiers croissant successifs mais uniformément répartis entre A% et B%.
L'idée est donc d'utiliser le générateur de nombre pseudo aléatoire RND pour choisir à chaque tirage, combien de positions entières on "saute". Cela revient donc à chaque tirage de considérer non plus l'intervalle [A%,B%], mais l'intervalle ]X%,B%].
Pour être clair, un petit schéma peut être plus éloquent que ma prose:
Supposons que l'on veille tirer 4 nombres entre 1 et 10.
On a donc A%=1:B%=10 et N%=4
Code : Tout sélectionner
A%=1:B%=10:N%=1
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////| | | | | | | | | | |///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
Amplitude: o o o o o o o o o o = 10
Pour I=1 X% = 1 + X% + INT(10 * RND(1))
Pour le premier tirage tous les nombres de 1 à 10 ne sont possibles.
Dans le cas d'un seul tirage, il y a 10 positions possibles car il 'y aura pas d'autres tirage et il n'est pas besoin de réserver une position.
Par contre, si l'on veut tirer plusieurs nombres, il ne faut leur réserver au moins une place, sinon on ne pourra plus continuer.
Dans l'exemple ci-dessous, on demande 4 nombre, il faut donc lors du premier tirage réserver au moins les trois dernières positions pour les tirages suivant. Qui ne seront qu'éventuellement à ces positons. Leur position finale dépendra du hasard. Mais si on oublie de les réserver, on ne pourra pas mener l'opération à terme.
Code : Tout sélectionner
A%=1:B%=10:N%=4
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////| | | | | | | |//T2///|//T3///|///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
Amplitude: o o o o o o o = 7
Pour I=1 X% = 1 + X% + INT( 6 * RND(1))
Iniitalement X%=0, il faut donc tirer un nombre aléatoire strictement inférieur à 7 que l'on ajoutera à X% pour obtenir la valeur du premier tirage.
En fait, à chaque itération, au lieu de tirer les nombres, on tire au hasard l'avancement (ou l'incrément) de façon à tomber dans l'interval possible. Il faut faire attention à laisser des valeurs pour les tirages suivants, mais aussi à 'faire avancer l'interval' de façon à ce qu'éventuellement la dernière valeur de X% tirée soit (éventuellement - par hasard) la dernière (B%) .
De plus on souhaite que les nombres soient distincts, il faut donc avancer à chaque fois au minimum de 1.
Donc pour le premier tirage, le nombre aléatoire qui sera tiré sera compris entre 0 et 5 (tous deux inclus) et on ajoutera automatiquement 1 à X% comme dans précédemment.
8 est en fait l'amplitude de l'intervalle restant (au-delà de X% et réservant encore (I-1) positions pour les tirages suivants.
Supposons que le premier nombre tiré soit 3. Pour le second tirage, nous sommes donc dans la situation suivante:
Code : Tout sélectionner
A%=1:B%=10:N%=4
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////| | | T1 | | | | |//T2///|//T3///|///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######| | | | | |//T3///|///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
Amplitude: o o o o o = 5
Pour T=1 I=4 X% = 3
T=2 I=3 X% = 1 + 3 + INT( 5 * RND(1)) -----> X(2)% = 6
On constate que la valeur de l'amplitude à chaque itération dépend à la fois du numéro de tirage (une position est libérée à droite) et du X% précèdent; en fonction de la positon qui a été tirée au tour précèdent, l'amplitude de l'intervalle possible est directement affectée.
Supposons que le second nombre tiré soit 6, on se trouve donc à la situation suivante pour le choix du troisième tirage:
Code : Tout sélectionner
A%=1:B%=10:N%=4
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////| | | T1 | | | | |//T2///|//T3///|///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######| | | T2 | | |//T3///|///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######|///////|///////|#######| | | |///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
Amplitude: o o o = 3
Pour T=1 I=4 X% = 3
T=2 I=3 X% = 6
T=3 I=2 X% = 1 + 6 + INT( 3 * RND(1)) -----> X(3)% = 8
Attention INT (7*RND(1)) retourne 0 1 2 3 4 5 ou 6 (et donc jamais 7).
Supposons que le troisième tirage tombe sur 8, nous obtenons la dernière étape du tirage :
Code : Tout sélectionner
A%=1:B%=10:N%=4
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////| | | T1 | | | | |//T2///|//T3///|///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######| | | T2 | | |//T3///|///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######|///////|///////|#######| | T3 | |///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######|///////|///////|#######|///////|#######| | |///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
Amplitude: o o = 2
Pour T=1 I=4 X% = 3
T=2 I=3 X% = 6
T=3 I=2 X% = 1 + 6 + INT( 3 * RND(1)) -----> X(3)% = 8
T=4 I=1 X% = 1 + 8 + INT( 2 * RND(1)) -----> X(4)% = 10
Code : Tout sélectionner
A%=1:B%=10:N%=4
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////| | | T1 | | | | |//T2///|//T3///|///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######| | | T2 | | |//T3///|///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######|///////|///////|#######| | T3 | |///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######|///////|///////|#######|///////|#######| | T4 |///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######|///////|///////|#######|///////|#######|///////|#######|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
On obtient donc le code suivant :
Code : Tout sélectionner
10 PRINT "TIRAGE DE 9 NOMBRES ENTRE 1 ET 9 : " ; : A%=1 : B%=9 : N%=9:GOSUB 1000 : END
1000 X%=A%-1 : IF B%<A%+N% THEN STOP
1010 FOR I=N% TO 1 STEP -1
1020 : X%=X%+1+(1+B%-I-X%)*RND(1)
1030 : PRINT X%;
1040 NEXT I
1050 PRINT : RETURN
Supposons que la fonction RND() est très proche d'un tirage parfaitement aléatoire et uniforme. Il devrait donc y avoir équi-répartition des tirages, et si l'on réalise un nombre suffisamment grand, nous admettrons, pour simplifier ma démonstration que la 'probabilité' de tomber sur l'un des dix nombre entier est bien 1/10. Et s'il n'y a que n position, nous obtenons 1/n pour chaque (la somme faisant donc bine n/n soit 1 - je peux donc parler de probabilité).
S'il y a qu'un seul tirage, pas de soucis, les tirages sont bien équiprobables:
Code : Tout sélectionner
A%=1:B%=10:N%=1
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////| 1/10 | 1/10 | 1/10 | 1/10 | 1/10 | 1/10 | 1/10 | 1/10 | 1/10 | 1/10 |///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
Si nous reprenons le cas ci-dessus, nous pouvons dresser le tableau donnant les équi-répartitions (ou l’équiprobabilité) à chaque tirage:
Code : Tout sélectionner
A%=1:B%=10:N%=4
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////| 1/7 | 1/7 | 1/7 | 1/7 | 1/7 | 1/7 | 1/7 |///////|///////|///////|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######| 1/5 | 1/5 | 1/5 | 1/5 | 1/5 |///////|///////|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######|///////|///////|#######| 1/3 | 1/3 | 1/3 |///////|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######|///////|///////|#######|///////|#######| 1/2 | 1/2 |///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|Total:/| 1/7 | 1/7 | 1/7 | 12/35 | 12/35 | 12/35 | 71/105| 8/15 | 5/6 | 1/2 |///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
.1428 .1428 .1428 .3429 .3429 .3429 .6762 .5333 .8333 .5000
La méthode est donc, comme vous l’aviez signalé dès mon premier post, fortement biaisé. A un tel point que si on utilise le code tel qu’il est donné ci-dessus, on obtiendra pratiquement que des tirages qui finisse par …7, 8, 9 ou … 8, 9, 10.
Il faut donc pondérer l’amplitude des tirages dès le premier de façon à tendre vers une meilleure équi-répartition. L’idée est de limiter l’amplitude des premiers tirages afin de laisser plus de place aux derniers tirages et tendre ainsi vers quelque chose de plus régulier.
En quelque sorte c’est comme si l’on cherchait à diviser l’intervalle restant à chaque tirage en autant de sous-intervalles qui contiendront chacun un des tirages. Mais si l’on fait cela, tous les premiers tirage d’un groupe de 4 nombres se trouveront obligatoirement dans le premier quart. C’est un peu comme si l’on cherchait à rendre en plus les tirages aussi répartis que possible.
D’où le terme diviseur en I^(N/(N+1)) qui vient fractionner à chaque tirage l’intervalle restant (l’amplitude) en autant de sous –intervalles réguliers (mais non equivalents).
D’où le code final :
Code : Tout sélectionner
10 PRINT "TIRAGE DE 9 NOMBRES ENTRE 1 ET 9 : " ; : A%=1 : B%=9 : N%=9:GOSUB 1000 : END
1000 X%=A%-1 : IF B%<A%+N% THEN STOP
1010 FOR I=N% TO 1 STEP -1
1020 : X%=X%+1+(1+B%-I-X%)*RND(1)/I^(N/(N+1))
1030 : PRINT X%;
1040 NEXT I
1050 PRINT : RETURN
Code : Tout sélectionner
A%=1:B%=10:N%=4
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////| | | T1 |///////|///////|///////|///////|//T2///|//T3///|///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######| | | T2 |///////|///////|//T3///|///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######|///////|///////|#######| | T3 |///////|///T4//|///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|///////|///////|///////|#######|///////|///////|#######|///////|#######| | T4 |///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
|Total: | 1/3 | 1/3 | 1/3 | 1/3 | 1/3 | 1/3 | 1/2 | 1/2 | 1/2 | 1/2 |///////|
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+
Donc, l’équiprobabilité ne sera jamais parfaite, mais bien meilleure que sans pondération.








