XL 2013 crer une liste de nombres aleatoires entre un min et un max avec une fonction VBA méthode particulière

patricktoulon

XLDnaute Barbatruc
Bonsoir à tous
c'est juste pour le fun
perso pour créer une liste de nombres aléatoires je préfère mélanger une liste ordonné(dans l'ordre au départ)
on a la garantie de non doublons et c'est largement plus rapide
sauf que là l'exercice est encore plus intéressant
je demarre avec une liste (un array vide(sans valeur)
alors pour faire de 1 à max ca va ,mais pour faire de min à max ca devient compliqué avec cette méthode tout du moins sans transformé un code très simple à la base en en centrale nucléaire

voici la méthode avec un array vide sans doublons et de 1 à max
VB:
Function randomListNumber(maxi)
   Dim i&, X&, temp
   Randomize
    ReDim t(1 To maxi)
    For i = 1 To maxi
        If t(i) = "" Then t(i) = i
        temp = t(i)
        X = 1 + Int((Rnd * (maxi - 1)))
        If t(X) = "" Then t(X) = X
        t(i) = t(X)
        t(X) = temp
    Next
    randomListNumber = t
End Function

Sub test()
    MsgBox Join(randomListNumber(30), vbCrLf)
End Sub
 

mapomme

XLDnaute Barbatruc
Supporter XLD
Bonsoir à tous,

Il me semble qu'on peut éviter tous ces if qui alourdissent considérablement le code (voire ralentissent l'exécution) avec une simple boucle de remplissage.
VB:
Function randomListNumber(mini, maxi)
Dim i&, n&, k&, aux
   ReDim t(mini To maxi): n = maxi - mini + 1
   Randomize
   For i = mini To maxi: t(i) = i: Next
   For i = mini To maxi: k = mini + Int(Rnd * n): aux = t(i): t(i) = t(k): t(k) = aux: Next
   randomListNumber = t
End Function
 

patricktoulon

XLDnaute Barbatruc
Je sais pas trop comment ça marche car j'ai pas creusé les détails, mais ça le fait.
le fonctionnement est simple
à l'origine ma fonction crée un array dans l'ordre (1,2,3,4,5.....)comme @mapomme vient de le démontrer
ensuite je boucle for i= 1 to max .
a chaque tour je choisi un item(rnd*...)
et j’intervertis l'item(i) et l'item(rnd)

ce soir l'exercice et de se servir de cet array mais vide au départ
problème dans la boucle on peut tomber plusieurs fois dessus un item et si il a déja été utilisé on va avoir un doublons quand on va intervertir et c'est la que les if t(i) ou t(x)="" servent a alimenter l'item ou pas avant intervertir
voila voila
 

patricktoulon

XLDnaute Barbatruc
Y aurait-il une autre façon de faire ?
Sûrement ! A vous de jouer.
Mais cette méthode est très subtile et efficace car elle utilise à la fois l'indice et le Rnd pour valoriser 2 valeurs en 1 passage.
et elle est surtout très rapide car nul besoins de surveiller les doublons
autrement dit même si un item peut être interverti avec un [autre(pas forcement le même)] mais il n'y aura jamais de doublons
 

laurent950

XLDnaute Accro
Re @patricktoulon

je fais un autre essaie

VB:
Function randomListNumber3(mini, maxi, nb) As String()
    Dim i As Long, result() As String
    ReDim result(1 To nb)
    Randomize
    For i = 1 To nb
        result(i) = CStr(Int((maxi - mini + 1) * Rnd) + mini)
    Next
    randomListNumber3 = result
End Function

Sub test()
    MsgBox Join(randomListNumber3(-3, 20, 10), vbCrLf)
End Sub
 

mapomme

XLDnaute Barbatruc
Supporter XLD
Re
Sinon, on peut rester sur un tableau usuel de 1 à n et translater simplement à la fin :
VB:
Function AleaMinMaxUsineAgaz(mini, maxi)
Dim n&, i&, k&, aux&
   n = maxi - mini + 1: ReDim t(1 To n)
   Randomize
   For i = 1 To n: t(i) = i: Next
   For i = 1 To n: k = 1 + Int(Rnd * n): aux = t(i): t(i) = t(k): t(k) = aux: Next
   For i = 1 To n: t(i) = mini - 1 + t(i): Next
   AleaMinMaxUsineAgaz = t
End Function
 

patricktoulon

XLDnaute Barbatruc
re
la version de mapomme avec les 3 argument
VB:
Function randomListNumber(mini, maxi, nb)
Dim i&, n&, k&, aux, t()
   ReDim Preserve t(mini To maxi): n = maxi - mini + 1
   Randomize
   For i = mini To maxi: t(i) = i: Next
   For i = mini To maxi: k = mini + Int(Rnd * n): aux = t(i): t(i) = t(k): t(k) = aux: Next
   ReDim Preserve t(mini To mini + nb)
   randomListNumber = t
End Function

Code:
Sub test()
MsgBox Join(randomListNumber(-10, 20, 12), vbCrLf)
End Sub
 

patricktoulon

XLDnaute Barbatruc
Re
Sinon, on peut rester sur un tableau usuel de 1 à n et translater simplement à la fin :
VB:
Function AleaMinMaxUsineAgaz(mini, maxi)
Dim n&, i&, k&, aux&
   n = maxi - mini + 1: ReDim t(1 To n)
   Randomize
   For i = 1 To n: t(i) = i: Next
   For i = 1 To n: k = 1 + Int(Rnd * n): aux = t(i): t(i) = t(k): t(k) = aux: Next
   For i = 1 To n: t(i) = mini - 1 + t(i): Next
   AleaMinMaxUsineAgaz = t
End Function
non là ca va plus je vais prendre des mesure
diabolo.gif
 

Discussions similaires

Membres actuellement en ligne

Statistiques des forums

Discussions
312 505
Messages
2 089 070
Membres
104 020
dernier inscrit
Mzghal