Générer toutes les combinaisons
Bonjour,
J'essai depuis plusieurs jours de générer toutes les combinaisons d'ordre de passage de différents projets.
J'ai essayé de m'inspirer de ce sujet mais rien de concluant : https://forum.excel-pratique.com/excel/macro-qui-fait-le-calcul-de-toute-les-combinaison-39829
J'ai ainsi deux colonnes, avec l'ordre allant de 1 au nombre maximum de projet. Et dans la deuxième le nom du projet. Je veux pouvoir avoir tous les ordres possibles, à savoir 19! et on ne peut pas avoir dans un tirage possible plusieurs fois le même nombre.
Aussi dans la boucle qui donnera ça, il y a aura un calcul qui sera fait,
on l'appellera [INSTRUCTION_CALCUL] et on récupérera la moyenne calculé sur cet ordre avant de passer à l'ordre suivant.
Je ne sais pas si mes explications sont assez claires.
Merci d'avance
Bonjour,
Un exemple de résultat attendu ?
Peux-tu préciser la version Excel utilisée et l'insrire dans ton profil ?
Cdlt.
Bonjour à tous,
Dans la question, on mentionne 19! (factorielle 19) soit environ : 121 645 100 408 832 000
Admettons que pour calculer un arrangement, le passage dans la boucle prend un millionième de seconde.
La calcul de tous les arrangements prendra 121 645 100 408 832 000 * 0,000001 secondes soit environ 121 645 100 408 secondes.
Une année correspond à 365 * (24 * 60 * 60) sec. soit environ 31 536 000 secondes.
La durée totale sera donc de 121 645 100 408 secondes divisé par 31 536 000 soit environ 3 857 années.
Vais p't'être prendre un p'tit café en attendant...
Re,
Bonjour mafraise,
Franck18 prépare un petit exemple avec un nombre de projets réduit !
Cdlt.
Voici un exemple avec que quatre projets. J'ai fait trois ordres possibles, mais il y en a d'autres.
Bonjour,
Je relance le sujet, car je ne suis toujours pas arrivé à trouver la solution.
Voici un fichier bien plus explicite.
Ici on a trois positions d'ordre possible donc cela fait 6 scénarios différents possibles.
J'aimerai pouvoir traiter le fait de générer dans un tableau() excel avec une macro VBA, c'est à dire un tableau : Dim tableau(5,2) soit 6 lignes et 3 colonnes
Aussi le nombre de projet est variable il peut en avoir 2 comme 20 et donc l'odre varie de 1 à Max de projet, et pour une combinaison chaque ordre est unique.
Merci d'avance.
bonsoir,
voici une proposition. S'agissant d'un accroissement factoriel du nombre de permutations, cela mobilise rapidement beaucoup de ressources. Et 9 projets est un maximum pour cette macro.
SI l'objectif est la recherche d'un optimum, il faudra plutôt utiliser des algorithmes d'optimisation en force brute (acceptable jusqu'à 13 projets) si plus il faut envisager d'autres algorithmes (tels algorithmes génétiques, ...)
Bonsoir,
Merci pour ta réponse h2so4. Ton code est très puissance et correspond à ce que je cherche à faire, mais j'ai essayé de rajouter un projet 3 et même 4 dans les en têtes après le 2 et de lancer le calcul mais ça ne place pas les ordres 3et 4... J'ai essayé de chercher en vain
Merci beaucoup concernant les méthodes alternatives lorsqu'on a de grands nombre je vais me renseigne sur ces deux autres méthodes ;)
Merci à toi ;)
En fait je n'avais pas vu l'encadré des instructions à droite de la feuille, c'est vrai que j'aurais pu réussir seul...
Tu marques que à partir de 10 et plus c'est la limite de la matrice VBA, la limite dû à l'affichage dans la feuille car 10! = 3628800 et donc supérieur au nombre max de ligne = 1048576. Mais si on ne veut pas afficher sur une feuille et tout stocker en virtuel dans un tableau on peut aller au delà de 10 ?
re-bonjour,
9 est la limite pour excel pour la raison d'affichage que tu as expliquée.
10 est la limite pour VBA car à partir de 11, on dépasse ce que l'on peut mettre dans une array vba (en tout cas sur mon PC, 16 GB).
Merci pour ces informations, j'ai essayé de modifier ton code pour ne plus afficher la matrice de résultat dans une feuille mais juste par l'appel du tableau lire les résultats en vain...
Par exemple j'aimerai que si je fais Msgbox(tableau(200,2) ça m'affiche la valeur dans la troisième colonne et la 201 ligne. Ainsi je pourrai monter à 10 projets voire plus en fonction des ressources de ma machine.
Aussi j'ai commencé à commenter le code pour ceux qui l'utiliserai pour d'autres projet ;)
bonjour,
voici le code modifié pour ne plus afficher tout le tableau des permutations.
Sub aargh()
Dim Tbl(), tabval 'Declaration du tableau
Dim i As Long, ne As Long, j As Long, dl As Long, dc As Long 'Declaration des variables
Dim Chaine As String 'Declaration de la variable "chaine" en tant que chaine de caracteres
With Sheets("sheet1") 'On fait référence à la feuille "sheet1"
dc = .Cells(1, Columns.Count).End(xlToLeft).Column 'On détermine le nombre de colonne utilisée en partant de la 1
tabval = .Cells(2, 2).Resize(1, dc - 1) 'On redimensionne le tableau avec une ligne et dc-1 colonnes
For i = 1 To UBound(tabval, 2) 'on parcours de 1 jusqu'à la valeur du plus dans indice de la matrice de tabval
Chaine = Chaine & Chr(i + 64) 'on ajoute le code unique à chaque iteration à la variable "chaine"
Next i
If Len(Chaine) > 12 Then ' adapter la limite en fonction du type du tbl et de la mémoire disponible.
MsgBox "trop de valeurs à permuter"
Exit Sub
End If
ne = Application.WorksheetFunction.Fact(Len(Chaine))
ReDim Tbl(1 To ne, 1 To Len(Chaine))
Call Permuter(Chaine, "", Tbl, j, tabval)
'MsgBox Tbl(201, 3) 'afficher le contenu du tableau (ligne 201, colonne 3)
End With
End Submais si tu veux faire une recherche d'optimum sur base de permutations, il n'est pas nécessaire de mettre toutes les permutations dans un tableau. Il "suffit" de vérifier pour chaque permutation générée si elle donne ou non un optimum et de retenir les valeurs qui ont généré cet optimum. Cela devrait se faire dans la fonction permuter.
Sub aargh()
Dim tabval 'Declaration du tableau
Dim i As Long, ne As Long, j As Long, dl As Long, dc As Long 'Declaration des variables
Dim Chaine As String 'Declaration de la variable "chaine" en tant que chaine de caracteres
With Sheets("sheet1") 'On fait référence à la feuille "sheet1"
dc = .Cells(1, Columns.Count).End(xlToLeft).Column 'On détermine le nombre de colonne utilisée en partant de la 1
tabval = .Cells(2, 2).Resize(1, dc - 1) 'On redimensionne le tableau avec une ligne et dc-1 colonnes
For i = 1 To UBound(tabval, 2) 'on parcours de 1 jusqu'à la valeur du plus dans indice de la matrice de tabval
Chaine = Chaine & Chr(i + 64) 'on ajoute le code unique à chaque iteration à la variable "chaine"
Next i
If Len(Chaine) > 12 Then ' adapter la limite en fonction du type du tbl et de la mémoire disponible.
MsgBox "trop de valeurs à permuter"
Exit Sub
End If
ne = Application.WorksheetFunction.Fact(Len(Chaine))
Call Permuter(Chaine, "", j, tabval)
MsgBox j & " permutations générées"
End With
End Sub
Sub Permuter(Chaine As String, Debut As String, j As Long, tabval)
Dim i As Long, texte As String
Dim tperm()
If Len(Chaine) = 1 Then
j = j + 1 'nombre de permutations générées
texte = Debut & Chaine 'texte contient une permutation valable (codée)
ReDim tperm(1 To Len(texte))
For i = 1 To Len(texte) 'décodage de la permutation valable
tperm(i) = tabval(1, Asc(Mid(texte, i, 1)) - 64) 'mise dans le tableau des permutations,
Next i
'endroit possible pour exploiter les valeurs de la permutation (tperm) et vérifier l'optimum
'code de calcul de l'optimum
Else
For i = 1 To Len(Chaine)
Permuter Mid(Chaine, 2, Len(Chaine) - 1), Debut & Left(Chaine, 1), j, tabval
Chaine = Mid(Chaine, 2, Len(Chaine) - 1) & Left(Chaine, 1)
Next
End If
End Sub