Monsieur Excel
Pour tout savoir faire sur Excel !

02 septembre 2012

Permutation aléatoire améliorée

Dans le dernier article, nous avons vu comment engendrer une série aléatoire de n nombres consécutifs à partir d’un nombre donné. Nous y étions parvenus en utilisant des formules dans deux colonnes.

Nous allons voir aujourd’hui comment atteindre le même objectif en une seule colonne, avec une solution découverte par Roberto Mensa, puis améliorée par Krisztina Szabo et enfin par moi.

 

La formule miracle, en A2 puis recopiée vers le bas, est la suivante :
=si(ligne()<$D$2+2;petite.valeur(si(1-nb.si(A$1:A1;ligne(indirect("1:"&D$2+1))+$D$1-1); ligne(indirect("1:"&D$2+1))+$D$1-1);ent(alea()*(D$2+1-nbval(A$1:A1)))+1);"")

C’est une formule matricielle, donc validée avec [Ctrl]-[Maj]-[Entrée].

Le test =si(ligne()<$D$2+2;…;"") assure tout simplement qu’on ne dépasse pas le nombre de valeurs demandées.

La partie (D$2+1-nbval(A$1:A1)), à la fin, calcule le nombre de valeurs qu’il reste à afficher. Donc ent(alea()*(D$2+1-nbval(A$1:A1)))+1 est un nombre au hasard égal au maximum à ce nombre, qui sera l’indice n quand on prendra la énième petite valeur.

Pour la cellule A6, l’expression 1-nb.si(A$1:A5;ligne(indirect("1:"&D$2))+$D$1-1) est évaluée en {1;0;0;1;0;1;0} : il y a donc un « 1 » pour chaque numéro non encore pris dans la séquence de 1 à 7 des sept nombres possibles (allant de 5 à 11).

Pour sa part, l’expression ligne(indirect("1:"&D$2))+$D$1-1 est évaluée en {5;6;7;8;9;10;11} : c’est le vecteur des valeurs initiales possibles.

Donc, pour la cellule A6, on obtient par conséquent l’évaluation partielle =si(ligne()<$D$2+2;petite.valeur(si({1;0;0;1;0;1;0};{5;6;7;8;9;10;11});ent(alea() *3)+1);""), ce qui donne – puisque le test du si() est évalué en VRAI – la première, la seconde ou la troisième des valeurs de {5,8;10} prise au hasard.

Impressionnant, n’est-ce pas !