Grille de chiffres en ...

  • Initiateur de la discussion Initiateur de la discussion Guido
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Re : Grille de chiffres en ...

Re

@Bernard

Curieux !!
Impossible de telecharger ton fichier que Windows prend pour l'adresse d'un site

@bhbh

C'est ce que je te disais dans mon post de 14h54

Citation:
@bhbh
Il me semble que le tableau doive etre tout d'abord revu dans la feuille origine
 
Re : Grille de chiffres en ...

Bonjour à tous
Une autre proposition, sans test ni boucle conditionnels.
Utilisable pour des tableaux plus grands : 1,25 s pour un tableau de 1000 lignes et 200 colonnes.
Code:
[COLOR="DarkSlateGray"]Sub mélange()
Dim odat(), n As Long, k As Long, m As Long, c As Long
Dim l0 As Long, c0 As Long, l1 As Long, c1 As Long, tmp
   recharge [COLOR="SeaGreen"]'facultatif[/COLOR]
   With Range("C3:K22") [COLOR="SeaGreen"]'(A adapter aux données)[/COLOR]
      odat = .Value
      c = UBound(odat, 2)
      n = UBound(odat, 1) * c
      Randomize
      For k = 1 To n - 1
         m = 1 + k + Int((n - k) * Rnd)
         l0 = 1 + (k - 1) \ c: c0 = k - ((k - 1) \ c) * c
         l1 = 1 + (m - 1) \ c: c1 = m - ((m - 1) \ c) * c
         tmp = odat(l0, c0): odat(l0, c0) = odat(l1, c1): odat(l1, c1) = tmp
      Next k
      .Value = odat
   End With
End Sub

Sub recharge()
   [COLOR="SeaGreen"]'(A adapter aux données)[/COLOR]
   Sheets("Feuil1").Range("C3:K22").Value = _
      Sheets("Feuil2").Range("C3:K22").Value
End Sub[/COLOR]
Remarque : Aucun élément du tableau ne peut garder sa place. Ce n'est donc pas une distribution réellement aléatoire.​
ROGER2327
 

Pièces jointes

Re : Grille de chiffres en ...

Suite...
J'ai oublié la fin du message précédent :
Pour que le tirage devienne aléatoire (i.e. avec la possibilité qu'un élément garde sa place dans le tableau), il faut remplacer la ligne
Code:
[COLOR="DarkSlateGray"]         m = [COLOR="Red"][B]1 +[/B][/COLOR] k + Int((n - k) * Rnd)[/COLOR]
par
Code:
[COLOR="DarkSlateGray"]         m = k + Int(([COLOR="Red"][B]1 +[/B][/COLOR] n - k) * Rnd)[/COLOR]
ROGER2327
 
Re : Grille de chiffres en ...

bonjour ROGER

Toujours admiratif de vos codes , je peine parfois a les saisir
Auriez-vous l'amabilité de commenter la sub melange
Vous remerciant par avance, je vous prie d'agreer l'expression de tout mon respect
(Quel dommage que nos parents n'aient point songé à nous presenter ! )
 
Re : Grille de chiffres en ...

(...)
Auriez-vous l'amabilité de commenter la sub melange
(...)
(Quel dommage que nos parents n'aient point songé à nous presenter !)
_
Bonjour pierrejean
  1. L'apparente complexité des calculs de la boucle tient à ce que les données de notre ami sont présentées dans un tableau multidimensionnel. Si on se contente d'un tableau unidimensionnel(*), unicolonne par exemple, la procédure se résume ainsi :
    Code:
    [COLOR="DarkSlateGray"]Sub mélange_colonne()
    Dim oDat(), n As Long, k As Long, m As Long
    Dim tmp
       With Range("A3:A12") [COLOR="SeaGreen"]'Matrice unicolonne (A adapter aux données)    4[/COLOR]
          oDat = .Value                                                  [COLOR="SeaGreen"]' 5[/COLOR]
          n = UBound(oDat, 1)                                            [COLOR="SeaGreen"]' 6[/COLOR]
          Randomize                                                      [COLOR="SeaGreen"]' 7[/COLOR]
          For k = 1 To n - 1                                             [COLOR="SeaGreen"]' 8[/COLOR]
             m = k + Int((1 + n - k) * Rnd) [COLOR="SeaGreen"]'k <= m <= n                 ' 9[/COLOR]
    [COLOR="SeaGreen"]'         m = 1 + k + Int((n - k) * Rnd) 'k + 1 <= m <= n            ' 9 bis[/COLOR]
             tmp = oDat(k, 1): oDat(k, 1) = oDat(m, 1): oDat(m, 1) = tmp [COLOR="SeaGreen"]'10[/COLOR]
          Next k                                                         [COLOR="SeaGreen"]'11[/COLOR]
          .Value = oDat                                                  [COLOR="SeaGreen"]'12[/COLOR]
       End With                                                          [COLOR="SeaGreen"]'13[/COLOR]
    End Sub[/COLOR]
    Commentaire ligne par ligne :
    _
    • [4] référence à la plage de données ;
    • [5] chargement des données dans le tableau unicolonne oDat ;
    • [6] n est le nombre de lignes du tableau ; c'est également le nombre de données à traiter ;
    • [7] classique initialisation du générateur pseudo-aléatoire ;
    • [8] démarrage d'une boucle où le compteur k sera l'index d'une ligne du tableau ;
    • [9 -9bis] affectation à m d'une valeur aléatoire telle que :
      k <= m <= n (ligne 9)​
      ou
      k + 1 <= m <= n (ligne 9bis).​
      Le choix de l'une des options influera sur le résultat final, comme on le verra plus loin ;
    • [10] échange des valeurs de oDat(k, 1) et oDat(m, 1).
      Si on a choisi l'option de la ligne [9], k et m peuvent avoir la même valeur : on a, le cas échéant, l'échange d'une donnée avec elle-même, autrement dit aucun changement dans le tableau.
      Si on a choisi l'option de la ligne [9bis], k et m ne peuvent avoir la même valeur et le tableau est nécessairement modifié ;
    • [11] à la fin de la boucle, la donnée contenue en oDat(k, 1) a été échangée (éventuellement) avec une données située plus loin dans le tableau (au rang m). Aucune donnée située au rang k ou à un rang inférieur ne sera plus modifiée.
      Poursuite des opération jusqu'au rang n - 1 ;
    • [12] les données du tableau remplacent les données originelles.
    _
    Dans la procédure que j'ai donnée précédemment, j'ai utilisé le même schéma. Mais j'ai introduit les paramètres l0 et c0 pour "convertir" l'index k en index de ligne et de colonne du tableau. De même l1 et c1 transcrivent m en index de ligne et de colonne du tableau.
    Par ailleurs, lorsque le tableau est multidimensionnel, le nombre de données n n'est plus le nombre de lignes. C'est pourquoi j'ai introduit le paramètre c qui est le nombre de colonnes du tableau.
    _
    Remarque théorique :
    Le choix d'une des options proposées en [9] et [9bis] a des conséquences importantes.
    Si on choisit la première, la probabilité pour qu'une donnée reste à sa place est 1 / n. C'est la même probabilité pour qu'une donnée déterminée soit déplacée sur une position déterminée.
    Si on choisit la seconde, cette probabilité est 0. La probabilité pour qu'une donnée déterminée soit déplacée sur une position déterminée est 1/(n - 1). Si n est petit, le résultat est très différent du précédent !​
    Il faut en tenir compte en fonction du but que l'on poursuit avec cette procédure. Notre ami n'ayant rien dit de ses intentions, nous ne pouvons savoir quelle solution lui convient.
    _
  2. Quel dommage en effet ! Quand je serai grand, c'est moi qui déciderai...
Cordialement,​
ROGER2327
_
_
Note : (*) C'est un abus de langage. Un tableau possédant une seule colonne est en réalité multidimensionnel : mais sa deuxième dimension étant 1, on peut d'une certaine manière le considérer comme "unidimensionnel'.[/B]​
 
Dernière édition:
Re : Grille de chiffres en ...

Re

Merci ROGER

L'idée de permutation des valeurs de chacune des cellules avec une autre prise au hasard est effectivement geniale
Dans cette optique et avec ma facon de coder cela donnerait

Code:
Set plage = Range("C3:K22")
For Each cel In plage
Randomize
alea1 = Int(plage.Rows.Count * Rnd)
alea2 = Int(plage.Columns.Count * Rnd)
temp = cel.Value
cel.Value = Cells(plage.Row + alea1, plage.Column + alea2)
Cells(plage.Row + alea1, plage.Column + alea2) = temp
Next cel

Il va sans dire que votre solution a base de tableau est certainement plus rapide
 
Re : Grille de chiffres en ...

Re...
Bonjour pierrejean
J'ai étudié votre procédure avec intérêt : elle a l'avantage de rendre son déroulement visible dans la feuille. Il faut compter une petite vingtaine de secondes.
En empêchant le rafraîchissement de l'affichage (Application.ScreenUpdating = False), on perd la visualisation mais la durée d'exécution est ramené à cinq ou six dixièmes de seconde.
Comme vous le supposez justement, c'est évidement très lent comparé aux procédures qui traitent les données dans une variable : ma procédure s'exécute en deux à trois millièmes de seconde (i.e. de l'ordre de 220 fois plus vite).
J'ai remarqué toutefois que nos procédures ne suivent pas exactement le même principe. Lorsque vous traitez la nième cellule du tableau, vous l'échangez avec n'importe quelle autre. Dans mon cas, lorsque je traite la nième cellule, je l'échange avec une cellule située plus loin dans le tableau, jamais avec un cellule précédant la nième. J'ai fait quelques tests qui ne m'ont pas permis de voir si cela influe sur le caractère aléatoire des déplacements. (Répéter des dizaines de milliers de fois le traitement pour établir une statistique est long...)
J'aurai tout de même un suggestion à faire pour améliorer la qualité du tirage : placer l'instruction Randomize avant la boucle. En principe, le générateur aléatoire fournit une série de valeurs consécutives aléatoires. Si vous le réinitialisez à chaque début de boucle, je ne suis pas certain que vous obteniez une suite réellement aléatoire. Car il n'y a a priori aucune raison pour que la suite obtenue en prenant seulement la première valeur après réinitialisation soit aléatoire.
A ce sujet, si quelqu'un passant par ici a des lumières sur la question, ça m'intéresse...​
Bonne journée.
ROGER2327
 
Re : Grille de chiffres en ...

Re
Bonjour ROGER

Juste pour une petite contestation:
Le chiffre de 220 me parait quelque peu exagéré
Un test pratiqué avec mon code (Sans rafraichissement d'ecran) sur un tableau de 86400 cellules me donne un temps de l'ordre de 0,5 seconde
Le même test avec le votre oscille entre 0,03 et 0,04 secondes
L'ecart ,deja tres important, n'est toutefois que de l'ordre de 15
Quant a l'emplacement du Randomize ,il a été deja abordé ici sans que l'on ait pu en tirer une evidence.C'est pourquoi par sécurité je le met systematiquement avant l'utilisation du Rnd
Bien evidemment je prefererais, comme vous, avoir une certitude sur ce sujet
 
Re : Grille de chiffres en ...

Re...
Bonjour pierrejean
J'ai repris les tests mais je n'ai pas approfondi (pas le temps : je rentre du travail à l'instant).
Toutefois je vous accorde que mes chiffres sont sujet à caution. Dans mon classeur de test (trop fouillis pour que je le communique) j'ai non seulement installé toutes les procédures proposées au cours de cette discussion mais aussi un certain nombre (élevé) de formules pour analyser les résultats. Par conséquent, toutes les procédures qui travaillent directement dans la feuille sont lourdement pénalisées par le recalcul incessant du reste du classeur. Il faut donc oublier ce que j'écrivais ce matin de bonne heure.
Pour ce qui est de l'utilisation de Randomize, je ne faisais que m'interroger : je suis comme vous, c'est à dire sans certitude...​
ROGER2327
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
15
Affichages
855
Réponses
5
Affichages
347
Réponses
23
Affichages
684
Réponses
15
Affichages
535
Réponses
19
Affichages
770
Retour