XL 2010 Creer tableau avec chiffres aleatoire

chubbaccaa

XLDnaute Nouveau
Bonsoir a tous , je cherche a faire un tableau de 40X40 cases
dans ces 1600 cases , je voudrez y mettre des chiffres compris entre 1 et 1600 , le tout aléatoirement
Jusqu'à maintenant j'arrive a rentré tout ces chiffres aléatoirement mais j'ai des doublons et il ne m'en faut pas
il faut que chaque cases est un chiffre diffèrent

Voila la formule que j'ai écrit dans A1 : =ALEA()*(1-1600)+1600

Je ne trouve as la solution , cela fait plusieurs jours que je cherche mais la , je sèche o_O

Quelqu'un peut il me dire ce qu'il ne va pas
Merci
 

patricktoulon

XLDnaute Barbatruc
re
Bonjour @sylvanu , @Dranreb , @mapomme
chez moi le post #25 est plus long de 3 fois rien mais quand même( avec graine true)
et en plus il fait que sur 10*10 le mien fait sur 40*40
0.02 contre 0.016 avec mon model tb

en 40*40 désolé mais mais c'est 0.03 pour le #post 25
1674281081491.png
 

patricktoulon

XLDnaute Barbatruc
celui encore fait encore moins de temps mais toujours sur 40*40
0.01 sec
dans cet exemple je me sert d'un 2d tableau(array ) comme dictionnaire
VB:
Sub test2()
    Dim tb(), tbd(), x&, Lig&, col&
    ReDim tb(1 To 40, 1 To 40)
    ReDim tbd(1 To (40 * 40))
    Lig = 1: col = 1
    t = Timer
    Do Until x = (40 * 40)
        num = Round(1 + (Rnd * ((40 * 40) - 1)))
        If Val(tbd(num)) = 0 Then
            tbd(num) = num
            x = x + 1
            tb(Lig, col) = num
            col = col + 1
            If col >= 40 Then col = 1: If Lig < 40 Then Lig = Lig + 1
        End If
    Loop
    [A1].Resize(40, 40).Value = tb
    MsgBox Format(Timer - t, "#0.00 sec")
End Sub

1674283864656.png
 

mapomme

XLDnaute Barbatruc
Supporter XLD
Re,

Une petite réflexion :

A mon humble avis, pour "mélanger 1 à N nombres, la méthode de Dranreb sera toujours la plus rapide.
On construit un tableau unidimensionnel à N éléments.
  • On le remplit par une boucle (sans calcul). C'est l'indice de la boucle qu'on stocke directement dans le tableau (durée proportionnelle à N)
  • On le mélange par interversions successives. La durée est aussi proportionnelle à N.
Globalement, le durée est proportionnelle à N. Il est difficile de faire mieux quand on fait intervenir le hasard.

Si on utilise un Dictionary ou un second tableau qui joue le même rôle, le mélange s'apparente à un tirage de boules numérotées avec remise. Plus on aura déjà tiré de numéros différents, plus la probabilité de tirer une boule avec un numéro différent de ceux déjà tirés s'amenuise.

On a N=1000 numéros à mélanger avec 1000 boules numérotées.
  • Quand on tire la 2ème boule, on a 999 chances sur 1000 de tirer une boule avec un numéro différent de celui qui est déjà sorti.
  • Quand on tire la 3ème boule, on a 998 chances sur 1000 de tirer une boule avec un numéro différent des deux déjà sortis.
  • ...
  • Quand on veut le 1 000ème numéro, on n'a plus que 1 chance sur 1000 de tirer une boule avec un numéro qui n'est pas déjà sorti.

On voit que le processus "ralentit" quand le nombre de numéros à mélanger s'accroit.
Nous ne sommes plus dans une durée proportionnelle au nombre N. S'il faut des volontaires pour le tirage je préfère être celui qui tire les 10 premiers numéros que celui qui tire les dix derniers 😜.
Plus le nombre N croit plus les performances de ce type de méthode se dégradent.
 

sylvanu

XLDnaute Barbatruc
Supporter XLD
Re,
C'est ce que tenté d'expliquer :
Si on compare les deux algos sur l'exemple donné :
- Matrice 1600*1 : 1600 RND à calculer, mais construction de la matrice 40*40 avant transfert.
- Matrice 40*40 : 3200 RND à calculer mais transfert direct de la matrice.
L'algo de tri 1600*1 sera plus rapide qu'un algo de tri 40*40, mais ce gain sera compensé par la construction d'une matrice 40*40, les deux algos, in fine, se valent. L'algo de Dranreb est légèrement plus rapide à 1% près.
Cependant l'algo 40*40 requiert une matrice de 1600 éléments, alors que l'ago 1600*1 en requiert 2.
C'est donc une question de choix pour l'utilisateur.
 

patricktoulon

XLDnaute Barbatruc
re
re
bonjour @sylvanu
oui je suis assez d'accords avec @mapomme sur la logique
cependant (et nous l'avons vu plusieurs fois avec @mapomme sur des boucles sur string ) en vba les faits peuvent être différents selon les outils ou fonctions vba dans le code

chez moi sur mon pc( mon nouveau pc W10 ) c'est mon dernier algo(celui avec l'algo avec le tableau dico) le plus rapide pourtant en effet j'utilise le tirage au hasard du nombre /index qui peut donc être tiré plusieurs fois
 

patricktoulon

XLDnaute Barbatruc
a noter quand même qu'avec le Mélange de Fisher-Yates
on peut retrouver des case qui ne changent pas d'index
VB:
Rem. Mélange de Fisher-Yates :
   For P = UBound(TAl, 1) * UBound(TAl, 2) To 2 Step -1
      L2 = (P - 1) \ UBound(TAl, 2) + 1: C2 = (P - 1) Mod UBound(TAl, 2) + 1
      Q = Int(Rnd * P) + 1'peut etre tiré plusieur fois
      'ce qui implique comme on fait  une boucle sur la moitié du count  que certains ne seront pas déplacés
L1 = (Q - 1) \ UBound(TAl, 2) + 1: C1 = (Q - 1) Mod UBound(TAl, 2) + 1
      X = TAl(L1, C1): TAl(L1, C1) = TAl(L2, C2): TAl(L2, C2) = X
      Next P
 

chaelie2015

XLDnaute Accro
Bonsoir a tous , je cherche a faire un tableau de 40X40 cases
dans ces 1600 cases , je voudrez y mettre des chiffres compris entre 1 et 1600 , le tout aléatoirement
Jusqu'à maintenant j'arrive a rentré tout ces chiffres aléatoirement mais j'ai des doublons et il ne m'en faut pas
il faut que chaque cases est un chiffre diffèrent

Voila la formule que j'ai écrit dans A1 : =ALEA()*(1-1600)+1600

Je ne trouve as la solution , cela fait plusieurs jours que je cherche mais la , je sèche o_O

Quelqu'un peut il me dire ce qu'il ne va pas
Merci
Bonsoir
Il existe plusieurs façons de créer un tableau de 40x40 cases contenant des chiffres aléatoires uniques compris entre 1 et 1600. Voici une méthode possible en utilisant VBA dans un module :

VB:
Sub remplir_tableau() 
Dim tbl(1 To 40, 1 To 40) As Integer 
Dim i As Integer, j As Integer 
Dim valeur As Integer 
Dim valeurs_utilisees() As Boolean 
ReDim valeurs_utilisees(1 To 1600) 
For i = 1 To 40 
For j = 1 To 40 valeur = Int((1600 - 1 + 1) * Rnd() + 1) 
While valeurs_utilisees(valeur) = True 
valeur = Int((1600 - 1 + 1) * Rnd() + 1) 
Wend 
valeurs_utilisees(valeur) = True 
tbl(i, j) = valeur 
Cells(i, j) = valeur 
Next j 
Next i 
End Sub

Le tableau sera rempli avec des chiffres aléatoires uniques compris entre 1 et 1600.
A+
 

mapomme

XLDnaute Barbatruc
Supporter XLD
a noter quand même qu'avec le Mélange de Fisher-Yates
on peut retrouver des case qui ne changent pas d'index
Ça s'appelle un mélange aléatoire ! Y en a qui peuvent bouger, d'autres pas !

Ce que je dis simplement c'est qu'avec un tirage avec remise (type dico ou index), la durée n'est pas proportionnelle aux nombres n à tirer. Il serait intéressant de trouver la complexité de ce type tirage en fonction de n mais les probabilités m'ont toujours un peu déroutée :(.
Utiliser une matrice à dimension 1 ou 2, ce n'est que du bricolage (en annexe de l'algorithme de tirage des nombres qui a mon avis est la partie la plus intéressante).
 

patricktoulon

XLDnaute Barbatruc
re
@mapomme je ne sais pas j'ai pas fait les test plus poussé
mai il me semble qu'a partir du moment ou tu utilise randomize et (rnd) dans tout les cas les 1600 tours sont fait mais plusieurs fois un même élément peut changer de place
cela dit je suis à 0.016/0.02 avec tout les versions avec un tableau de 40*40
le modèle de @chaelie2015 je l'ai accéléré en remplissant la feuille à la fin
et de 0.031 je suis passer aussi à 0.016 / 0.02

alors que faut il en conclure
@Dranreb 2 boucle lignes collonnes imbriquées pour remplir et une autre pour mélanger
-> 0.016 / 0.02 sec

la mienne
1 seul boucle de 1 à 1600 +rnd+ jumping si existant dans tableau mask
-> 0.016 / 0.02

@chaelie2015 2 boucles imbriqées lignes colones +surboucle while sur le rnd
en remplissant la feuille à la fin
-> 0.016 / 0.02
 

patricktoulon

XLDnaute Barbatruc
re
mais je réitère mon invitation à @chaelie2015 de revenir nous expliquer lignes par ligne
son procédé
car son jeu avec le tableau valeurs_utilisées(valeur)=true me pique les yeux

edit : ca y est j'ai pigé
au final c'est a peu près mon raisonnement sauf que lui c'est booleen moi c'est val(valeur)>0
je serait curieux de savoir combien coute en temps le calcul du nombre aléatoire à chaque fois
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
re
j'ajouterais qu'avec toute les versions proposées et le blocage du rafraichissement d’écran
on est tous à 0.000 sec

j'ai poussé à une matrice de 100*100
@Dranreb --> 0.02 / 0.045sec

@chaelie2015--> ça tourne sans fin (c'est mort )obligé de tuer process excel

la mienne -->0.025/ 0.055

ma conclusion dans les faits
sur une matrice de 10*10 je suis plus rapide que @Dranreb
sur une plus grande matrice @Dranreb prend le devant

il y a donc bien incidence de la manière de coder l'algo(fonction vba et variables,etc...) en fonction de la charge de travail

intéressant tout ça ;)
 

patricktoulon

XLDnaute Barbatruc
re
oui mais dans une matrice 2 dim c'est plus difficile à comprendre
après les temps sont largement raisonnables par rapport a ce que l'on attend de nos pc d'aujourd'hui
me faudra encore du temps pour bien piger ta boucle mélange
qui a un avantage incontestable qui est que le rnd sur 1600 ne nécessite pas un retirage
même si il est trouvé x fois
c'est sans doute là que tu gagne en temps


ce qui m'amène a la conclusion que la partie la plus lourde est bien le rnd retirer plusieurs fois dans ma version par exemple
 

Discussions similaires

Réponses
3
Affichages
292

Statistiques des forums

Discussions
314 497
Messages
2 110 239
Membres
110 708
dernier inscrit
novy16