Solveur ou VBA

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

12classeur1.xlsx (8.47 Ko)

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

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

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.

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

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 :

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 c'est la première fois que j'utilise une fonction en Vba.

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 . Maintenant, si tu veux toutes les combinaisons possibles, il faut jouer avec la borne de début de boucle et dans ce cas, la fonction va retourner un tableau à deux dimensions (en lignes et colonnes) mais je ne suis pas sûr que ça te soit d'une grande utilité. En ce qui concerne ta question :

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 :

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

Bonjour,

Cette fois si cela a l'air bon merci beaucoup.

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

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 :

Rechercher des sujets similaires à "solveur vba"