Solveur ou VBA
- Messages
- 70
- Excel
- 2016
- Inscrit
- 12/02/2016
- Emploi
- Dessinateur calculateur en bureau d'étude.
Bonjour,
Je suis face à un problème je voudrais résoudre une équation 210a +180b + 160c + 120d = 2500
Évidemment il y a plein de solution mais a, b, c, d sont >=0 et entier
j'arrive à trouver 1 résultat du solveur mais cela ne me suffit pas je voudrais qu'en priorité il maximise les "a" puis les "b" ainsi de suite par ordre décroissant. ou alors qu'il me présente plusieurs solutions.
Quelqu'un aurait-il un code Vba pour m'aider ou alors une autre solution?
Cordialement;
Bob
Bonjour,
Donc, si je comprend bien, tu préfères avoir comme résultat par exemple 4, 5, 4,1 plutôt que 2, 0, 13, 0 ?
Re,
Une piste qui va donner plusieurs résultats en fonction de la valeur de la borne 4, 5 ,4, 1 si la borne vaut 5, 8, 3, 1, 1 si la borne vaut 8, etc... :
Sub Test()
Dim A As Integer
Dim B As Integer
Dim C As Integer
Dim D As Integer
Dim Result As Integer
Dim Borne As Integer
Const Valeur As Integer = 2500
Const A1 As Integer = 210
Const B1 As Integer = 180
Const C1 As Integer = 160
Const D1 As Integer = 120
Borne = 8 'changer la valeur de la borne pour avoir des résultats différents
For A = Borne To 0 Step -1: For B = Borne To 0 Step -1: For C = Borne To 0 Step -1: For D = Borne To 0 Step -1
Result = A1 * A + B1 * B + C1 * C + D1 * D
If Result = Valeur Then GoTo Fin
Next D, C, B, A
Fin:
If A = B = C = D = -1 Then MsgBox "Pas bon !" Else MsgBox A & vbCrLf & B & vbCrLf & C & vbCrLf & D
End Sub
- Messages
- 70
- Excel
- 2016
- Inscrit
- 12/02/2016
- Emploi
- Dessinateur calculateur en bureau d'étude.
Ce n'est pas mal du tous, à la borne 8 le résultat est 8 3 1 1, il n'y a pas mieux je pense (était donner qu'il me faut un max de A puis B ainsi de suite) il n'y a pas une solution pour qu'il recherche ce résultat tout seul? sans saisir les bornes manuellement?
Un grand merci pour ton aide
Bonjour,
une autre proposition
Sub aargh()
a1 = 210
b1 = 180
c1 = 160
d1 = 120
cible = 2500
vda = Int(cible / a1)
For a = vda To 1 Step -1
Vdb = Int((cible - (a * a1)) / b1)
For b = Vdb To 1 Step -1
vdc = Int((cible - (a * a1) - (b * b1)) / c1)
For c = vdc To 1 Step -1
d = (cible - (a * a1) - (b * b1) - (c * c1)) / d1
If d = Int(d) Then
MsgBox a1 & "*" & a & "+" & b1 & "*" & b & "+" & c1 & "*" & c & "+" & d1 & "*" & d
Exit Sub
End If
Next c
Next b
Next a
End Sub
coefficients trouvés 10 0 1 2
- Messages
- 70
- Excel
- 2016
- Inscrit
- 12/02/2016
- Emploi
- Dessinateur calculateur en bureau d'étude.
Bonjour,
Oui c'est ça que je cherche à faire, par contre je ne trouve pas les mêmes coefficients que toi quand j'exécute de code, je trouve encore 8 3 1 1 et non 10 0 1 2. il y aurait pas un moyen de lui faire apparaitre plusieurs solutions? par ordre décroissant par rapport au coefficient A par exemple 10 0 1 2 puis 8 3 1 1 ainsi de suite pour 5 solutions par exemple?
L'autre chose est que si je ne veux pas la valeur 160 (ne pas l'utiliser) je suis obligé de retaper tous ton code avec une nouvelle formule, il n'y a pas une façon plus simple qui peut me faire sa?
Si cela demande trop de travail n'hésité pas à me le dire.
Merci pour votre aide à tous les deux
Bonjour,
pour afficher toutes les solutions (dans la feuille active)
Sub aargh()
a1 = 210
b1 = 180
c1 = 160
d1 = 120
cible = 2500
vda = Int(cible / a1)
For a = vda To 0 Step -1
Vdb = Int((cible - (a * a1)) / b1)
For b = Vdb To 0 Step -1
vdc = Int((cible - (a * a1) - (b * b1)) / c1)
For c = vdc To 0 Step -1
d = (cible - (a * a1) - (b * b1) - (c * c1)) / d1
If d = Int(d) Then
sol = sol + 1
Cells(sol, 1) = a1 & "*" & a & "+" & b1 & "*" & b & "+" & c1 & "*" & c & "+" & d1 & "*" & d
End If
Next c
Next b
Next a
End Sub
pour faire le calcul avec d'autres valeurs, il suffit d'adapter les valeurs de a1,b1,c1,d1 et cible.
- Messages
- 70
- Excel
- 2016
- Inscrit
- 12/02/2016
- Emploi
- Dessinateur calculateur en bureau d'étude.
Dernière chose tu pourrais me le faire pour seulement 3 valeurs afin que je puisse voir la différence entre les codes et que je puisse me débrouiller tous seuls? j’essaye mais je n'y arrive pas à chaque fois cela me mais par exemple: 210*1+180*0+160* il me manque le 160.
Aussi j'aimerais rajouter une condition par exemple un coefficient maximal à ne pas dépasser par exemple ne pas dépasser le coefficient 8 pour 210 cela est facilement possible?
encore une fois grand merci pour ton aide
Bonjour,
voici une adaptation du code.
lima=8 pour avoir une valeur maximum de 8 pour a
limc=0 pour avoir une valeur maximum de 0 pour c (équivalent à ignorer cette variable)
Sub aargh()
Cells.Clear
a1 = 210
lima = 8 'valeur limite pour a
b1 = 180
limb = 100 'valeur limite pour b
c1 = 160
limc = 0 'valeur limite pour c, 0 pour ne pas prendre cette valeur
d1 = 120
limd = 100 'valeur limite pour d
cible = 2500
sol = 0
vda = Int(cible / a1)
If vda > lima Then vda = lima
For a = vda To 0 Step -1
Vdb = Int((cible - (a * a1)) / b1)
If Vdb > limb Then Vdb = limb
For b = Vdb To 0 Step -1
vdc = Int((cible - (a * a1) - (b * b1)) / c1)
If vdc > limc Then vdc = limc
For c = vdc To 0 Step -1
d = (cible - (a * a1) - (b * b1) - (c * c1)) / d1
If d = Int(d) And d <= limd Then
sol = sol + 1
Cells(sol, 1) = a1 & "*" & a & "+" & b1 & "*" & b & "+" & c1 & "*" & c & "+" & d1 & "*" & d
End If
Next c
Next b
Next a
MsgBox IIf(sol = 0, "pas de", sol) & " solution" & IIf(sol > 1, "s", "") & " trouvée" & IIf(sol > 1, "s", "")
End Sub
- Messages
- 70
- Excel
- 2016
- Inscrit
- 12/02/2016
- Emploi
- Dessinateur calculateur en bureau d'étude.
Un grand merci a toi, maintenant que j'ai le code Vba je vais voir comment gérer mes résultats dans excel.
Un sujet de plus résolu
Bonjour,
Une piste en partant de l'idée de h2so4 de diviser le résultat voulu par le coefficient le plus élevé :
Sub Test()
Dim A As Integer
Dim B As Integer
Dim C As Integer
Dim D As Integer
Dim Result As Integer
Dim Borne As Integer
Const Valeur As Integer = 2500
Const A1 As Integer = 210
Const B1 As Integer = 180
Const C1 As Integer = 160
Const D1 As Integer = 120
Borne = 2500 / Int(Application.Max(A1, B1, C1, D1))
For A = Borne To 0 Step -1: For B = Borne To 0 Step -1: For C = Borne To 0 Step -1: For D = Borne To 0 Step -1
Result = A1 * A + B1 * B + C1 * C + D1 * D
If Result = Valeur Then GoTo Fin
Next D, C, B, A
Fin:
If A = B = C = D = -1 Then MsgBox "Pas bon !" Else MsgBox A & vbCrLf & B & vbCrLf & C & vbCrLf & D
End Sub
Re,
Pour répondre à ta question :
maintenant que j'ai le code Vba je vais voir comment gérer mes résultats dans excel
En transformant cette sub en fonction :
Function Coefficients(Valeur As Integer, A1 As Integer, B1 As Integer, C1 As Integer, D1 As Integer) As Integer()
Dim Tbl() As Integer
Dim A As Integer
Dim B As Integer
Dim C As Integer
Dim D As Integer
Dim Result As Integer
Dim Borne As Integer
Borne = Valeur / Int(Application.Max(A1, B1, C1, D1))
For A = Borne To 0 Step -1: For B = Borne To 0 Step -1: For C = Borne To 0 Step -1: For D = Borne To 0 Step -1
Result = A1 * A + B1 * B + C1 * C + D1 * D
If Result = Valeur Then GoTo Fin
Next D, C, B, A
Fin:
ReDim Tbl(1 To 4)
If A = B = C = D <> -1 Then Tbl(1) = A: Tbl(2) = B: Tbl(3) = C: Tbl(4) = D
Coefficients = Tbl()
End Function
Pour l'utiliser dans Excel, tu dois lui passer la valeur (ici 2500) puis les coefficients (210,180,160,120) ensuite, tu dois l'appeler dans une matrice c'est à dire que tu vas sélectionner 4 cellules en ligne puis dans la barre de formule saisir =Coefficients(A1;B1;C1;D1;E1)
et tu vas la valider en matricielle (Ctrl+Maj+Entrée)
Je te poste un classeur pour mieux comprendre :
- Messages
- 70
- Excel
- 2016
- Inscrit
- 12/02/2016
- Emploi
- Dessinateur calculateur en bureau d'étude.
Bonjour,
j'aime bien l'idée aussi mais il y a un truc qui me chagrine, quand je remplace 2500 dans ton fichier par 2000 je trouve comme valeur 0, 0, 0, 0 ou avec le code de h2so4 il me propose 27 solutions comme par exemple 8, 0, 2, 0. je suis une peu larguer en Vba et je suis incapable de retaper ton code, je sais à peu près lire ce qui sa passe et bidouiller quelque truc pour faire ce que je veux mais cela s'arrête ici.
Merci pour ton classeur car j'ai essayé de le faire tous seul au début et je ne comprenais rien
Je refais appel à h2so4 y a-t-il une solution dans ton code pour que si il n'y a pas de solution il renvoie à la solution inférieure, par exemple si je rentre 2505 il n'y a pas de solution, normal car mes valeurs 210, 180, 160, 120 termine uniquement par 0, j'aimerais qu'il prenne 2500 en solution s'il n'y a pas de solution pour 2505, cela pourrait m'arriver en limitant le nombre max de coefficient.
Pour info et pour vous: j'utilise ce code pour calepiner de l’étaiement (structure en acier qui sert à reprendre le béton le temps qu'il sèche et qu'il soi assez résistant pour se tenir tous seul)
Bob
Bonjour,
J'ai gardé la ligne de test dans la fonction alors qu'il ne fallait pas
a-t-il une solution dans ton code pour que si il n'y a pas de solution il renvoie à la solution inférieure, par exemple si je rentre 2505 il n'y a pas de solution, normal car mes valeurs 210, 180, 160, 120 termine uniquement par 0, j'aimerais qu'il prenne 2500 en solution s'il n'y a pas de solution pour 2505, cela pourrait m'arriver en limitant le nombre max de coefficient.
Il faut boucler sur la valeur cible en décroissant celle-ci. J'ai modifié la fonction pour qu'elle retourne la valeur immédiatement au dessous en fonction des coefficients dans le 5 ème élément du tableau :
Function Coefficients(Valeur As Integer, A1 As Integer, B1 As Integer, C1 As Integer, D1 As Integer) As Integer()
Dim Tbl(1 To 5) As Integer
Dim A As Integer
Dim B As Integer
Dim C As Integer
Dim D As Integer
Dim Cible As Integer
Dim Result As Integer
Dim Borne As Integer
Cible = Valeur
Reprise:
Borne = Cible / Int(Application.Max(A1, B1, C1, D1))
For A = Borne To 0 Step -1: For B = Borne To 0 Step -1: For C = Borne To 0 Step -1: For D = Borne To 0 Step -1
Result = A1 * A + B1 * B + C1 * C + D1 * D
If Result = Cible Then GoTo Fin
Next D, C, B, A
Fin:
If A = B = C = D = -1 Then Cible = Cible - 1: GoTo Reprise
Tbl(1) = A: Tbl(2) = B: Tbl(3) = C: Tbl(4) = D: Tbl(5) = Cible
Coefficients = Tbl()
End Function
Je te reposte le classeur avec cette modif car il faut prendre 5 cellules et non 4 pour avoir la valeur. J'ai mis une MFC qui colore la cellule en rouge si la valeur cible a été recalculée :
- Messages
- 70
- Excel
- 2016
- Inscrit
- 12/02/2016
- Emploi
- Dessinateur calculateur en bureau d'étude.
Bonjour,
Ce n'est pas vraiment ce que je veux, par exemple si je prends la valeur cible 1600 dans ton classeur il ne trouve pas de solution et prend donc 1590, alors qu'il existe 20 solutions quand je le fais avec le code h2so4
Bonjour,
voici une adaptation du code.
lima=8 pour avoir une valeur maximum de 8 pour a
limc=0 pour avoir une valeur maximum de 0 pour c (équivalent à ignorer cette variable)
Sub aargh() Cells.Clear a1 = 210 lima = 8 'valeur limite pour a b1 = 180 limb = 100 'valeur limite pour b c1 = 160 limc = 0 'valeur limite pour c, 0 pour ne pas prendre cette valeur d1 = 120 limd = 100 'valeur limite pour d cible = 2500 sol = 0 vda = Int(cible / a1) If vda > lima Then vda = lima For a = vda To 0 Step -1 Vdb = Int((cible - (a * a1)) / b1) If Vdb > limb Then Vdb = limb For b = Vdb To 0 Step -1 vdc = Int((cible - (a * a1) - (b * b1)) / c1) If vdc > limc Then vdc = limc For c = vdc To 0 Step -1 d = (cible - (a * a1) - (b * b1) - (c * c1)) / d1 If d = Int(d) And d <= limd Then sol = sol + 1 Cells(sol, 1) = a1 & "*" & a & "+" & b1 & "*" & b & "+" & c1 & "*" & c & "+" & d1 & "*" & d End If Next c Next b Next a MsgBox IIf(sol = 0, "pas de", sol) & " solution" & IIf(sol > 1, "s", "") & " trouvée" & IIf(sol > 1, "s", "") End Sub
Je trouve quand même intéressant de voir toutes les solutions d'une valeur cible cela me permet de m'adapter si j'ai besoin
Décidément, mon test n'est pas très bon
Voici le code corrigé avec des "And" plutôt que des "=" :
Function Coefficients(Valeur As Integer, A1 As Integer, B1 As Integer, C1 As Integer, D1 As Integer) As Integer()
Dim Tbl(1 To 5) As Integer
Dim A As Integer
Dim B As Integer
Dim C As Integer
Dim D As Integer
Dim Cible As Integer
Dim Result As Integer
Dim Borne As Integer
Cible = Valeur
Reprise:
Borne = Cible / Int(Application.Max(A1, B1, C1, D1))
For A = Borne To 0 Step -1: For B = Borne To 0 Step -1: For C = Borne To 0 Step -1: For D = Borne To 0 Step -1
Result = A1 * A + B1 * B + C1 * C + D1 * D
If Result = Cible Then GoTo Fin
Next D, C, B, A
Fin:
If A = -1 And B = -1 And C = -1 And D = -1 Then Cible = Cible - 1: GoTo Reprise
Tbl(1) = A: Tbl(2) = B: Tbl(3) = C: Tbl(4) = D: Tbl(5) = Cible
Coefficients = Tbl()
End Function
- Messages
- 70
- Excel
- 2016
- Inscrit
- 12/02/2016
- Emploi
- Dessinateur calculateur en bureau d'étude.
Bonjour,
Cette fois si cela a l'air bon
Ce serait trop long pour toi de rajouter des limites sur les coefficients et une boucle afin qu'il donne tous les résultats possibles? comme avait fait h2so4?
je suis incapable de le faire tous seul
Bonjour,
voici une adaptation du code.
lima=8 pour avoir une valeur maximum de 8 pour a
limc=0 pour avoir une valeur maximum de 0 pour c (équivalent à ignorer cette variable)
Sub aargh() Cells.Clear a1 = 210 lima = 8 'valeur limite pour a b1 = 180 limb = 100 'valeur limite pour b c1 = 160 limc = 0 'valeur limite pour c, 0 pour ne pas prendre cette valeur d1 = 120 limd = 100 'valeur limite pour d cible = 2500 sol = 0 vda = Int(cible / a1) If vda > lima Then vda = lima For a = vda To 0 Step -1 Vdb = Int((cible - (a * a1)) / b1) If Vdb > limb Then Vdb = limb For b = Vdb To 0 Step -1 vdc = Int((cible - (a * a1) - (b * b1)) / c1) If vdc > limc Then vdc = limc For c = vdc To 0 Step -1 d = (cible - (a * a1) - (b * b1) - (c * c1)) / d1 If d = Int(d) And d <= limd Then sol = sol + 1 Cells(sol, 1) = a1 & "*" & a & "+" & b1 & "*" & b & "+" & c1 & "*" & c & "+" & d1 & "*" & d End If Next c Next b Next a MsgBox IIf(sol = 0, "pas de", sol) & " solution" & IIf(sol > 1, "s", "") & " trouvée" & IIf(sol > 1, "s", "") End Sub
Bonjour,
voici une version adaptée inspirée du code de Theze
Sub aargh()
Cells.Clear
a1 = 210
lima = 8 'valeur limite pour a
b1 = 180
limb = 100 'valeur limite pour b
c1 = 160
limc = 0 'valeur limite pour c, 0 pour ne pas prendre cette valeur
d1 = 120
limd = 100 'valeur limite pour d
cible = 2505
sol = 0
Do
vda = Int(cible / a1)
If vda > lima Then vda = lima
For a = vda To 0 Step -1
Vdb = Int((cible - (a * a1)) / b1)
If Vdb > limb Then Vdb = limb
For b = Vdb To 0 Step -1
vdc = Int((cible - (a * a1) - (b * b1)) / c1)
If vdc > limc Then vdc = limc
For c = vdc To 0 Step -1
d = (cible - (a * a1) - (b * b1) - (c * c1)) / d1
If d = Int(d) And d <= limd Then
sol = sol + 1
Cells(sol, 1) = a1 & "*" & a & "+" & b1 & "*" & b & "+" & c1 & "*" & c & "+" & d1 & "*" & d & "=" & cible
End If
Next c
Next b
Next a
cible = cible - 1
Loop Until sol > 0
MsgBox sol & " solution" & IIf(sol > 1, "s", "") & " trouvée" & IIf(sol > 1, "s", "") & " pour une valeur cible de " & cible + 1
End Sub
- Messages
- 70
- Excel
- 2016
- Inscrit
- 12/02/2016
- Emploi
- Dessinateur calculateur en bureau d'étude.
Bonjour,
Merci beaucoup a tous les deux avec ce que vous m'avez fais je devrais pouvoir réussir a me débrouiller tous seul. si j'ai d'autre question je viendrais ouvrir un nouveau sujet sur le forum, sauf si elle porte sur ce code.
Bob
Bonjour,
Voici un classeur avec une matrice de 5 colonnes sur x lignes en fonction des valeurs limites des coefficients.
Si les résultats sont souhaités sur 5 colonnes et x lignes, ne rien faire, si les résultats son souhaités sur 5 lignes et x colonnes, supprimer ce qui est indiqué dans le code ci-dessous :
Function Coefficients(Valeur As Integer, Coeff As Range, TMax As Range) As Integer()
Dim Tbl() As Integer
Dim T() As Integer
Dim A As Integer
Dim B As Integer
Dim C As Integer
Dim D As Integer
Dim Cible As Integer
Dim Result As Integer
Dim I As Integer
Cible = Valeur
Reprise:
'TMax() impose les contraintes de début de boucle
For A = TMax(1) To 0 Step -1: For B = TMax(2) To 0 Step -1: For C = TMax(3) To 0 Step -1: For D = TMax(4) To 0 Step -1
Result = Coeff(1) * A + Coeff(2) * B + Coeff(3) * C + Coeff(4) * D
If Result = Cible Then
I = I + 1: ReDim Preserve Tbl(1 To 5, 1 To I)
Tbl(1, I) = A: Tbl(2, I) = B: Tbl(3, I) = C: Tbl(4, I) = D: Tbl(5, I) = Cible
End If
Next D, C, B, A
'si tous à -1, pas de solution trouvée donc, reprise du calcul avec valeur cible moins 1
If I = 0 Then Cible = Cible - 1: GoTo Reprise
'inversion des valeurs pour les avoir sur 5 colonnes et x lignes
'à supprimer si les valeurs sont sur 5 lignes et x colonnes !
ReDim T(1 To UBound(Tbl, 2), 1 To 5)
For I = 1 To UBound(Tbl, 2)
T(I, 1) = Tbl(1, I)
T(I, 2) = Tbl(2, I)
T(I, 3) = Tbl(3, I)
T(I, 4) = Tbl(4, I)
T(I, 5) = Tbl(5, I)
Next I
'si sur 5 lignes et x colonnes
'Coefficients = Tbl()
'sur 5 colonnes et x lignes
Coefficients = T()
End Function
Le classeur :