Boucle infini (VBA) - VB/VBA/VBS - Programmation
Marsh Posté le 27-09-2013 à 19:46:00
Bonjour,
merci d'utiliser la prochaine fois l'icône C dédiée au code … Une bonne indentation est aussi appréciée.
En regardant donc juste la condition de la boucle, epsilon est toujours supérieur à 0.1 empêchant la sortie de la boucle …
Prévoir peut-être un nombre maximum d'itérations, non ?
Ce serait judicieux de tout mettre à plat, entre un schéma en langage courant,
la sémantique de ce qu'est censé faire le code, et en comparant si chaque ligne de code correspond bien à ce schéma …
Marsh Posté le 27-09-2013 à 22:02:13
Désolé, effectivement, c'est la première fois que je poste.
ça m'étonne un peu d'avoir toujours epsilon>0.1 puisque je cherche à résoudre une équation dont je connais une solution approximative r=0.11 avec les paramètres que j'ai choisi.
(Je ne sais pas si on peut mettre du LaTeX ici.) Mais c'est:
P-c/(1+r)-...-c/((1+r)^5)- N / ((1 + r) ^ M)=0
Et ceci tend vers P>0 quand r tend vers l'infini et ça vaut P-5c-N<0 en r=0, alors cette valeur de r je suis sûr qu'elle existe.
Mais il est possible que ce soit mon algo qui soit faux.
Du coup mettre un nombre maximum d'itérations ne m'intéresse pas trop.
Marsh Posté le 28-09-2013 à 02:20:37
Epsilon reste bloqué vers les 55, donc méthode à revoir …
Pour pouvoir le vérifier, ajouter les deux lignes suivantes juste avant le Wend :
Code :
|
La progression d'epsilon en direct dans la fenêtre Exécution ! …
Marsh Posté le 28-09-2013 à 11:43:48
Bonjour,
Merci en fait j'ai reprogrammé ça dans un autre langage pour vérifier. Et j'ai vu que l'algo était bon.
L'erreur vient en fait parce que j'ai oublié de déclarer S.
J'ai un peu honte.
Marsh Posté le 28-09-2013 à 12:31:06
En double ? Sinon pas de honte à avoir …
L'instruction Option Explicit en début de module permet d'éviter ce problème en obligeant de déclarer les variables
ou encore en cochant la case Déclaration des variables obligatoire dans les Options de l'environnement VBA.
DoEvents permet de pouvoir garder la main pour interrompre la boucle …
Marsh Posté le 28-09-2013 à 13:59:04
Oui c'est ça il manque un:
Dim S As Double
Et dans le code que j'ai mis ici il y a une autre erreur, j'ai oublié de modifier le i en j.
Merci pour ces conseils, je vais les utiliser, ça va m'éviter des difficultés.
Marsh Posté le 29-09-2013 à 11:20:07
Avec seulement ces corrections, la boucle ne s'arrêtera pas plus avec le pas de r de 0.01
vu que r doit se trouver entre 0.10 & 0.11, donc obligation d'affiner le pas …
Qui plus est le résultat r de ton code est faussé de +0.01 à cause de la conception de la boucle,
l'ajout du pas s'effectuant avant le test de sortie …
J'aimerais bien voir ton code qui fonctionne. Combien d'itérations pour trouver la solution ?
De mon côté ma version avec la résolution de 0.1 n'a besoin que de 6 itérations pour la trouver, 9 pour 0.01 et 18 pour 0.001 …
Marsh Posté le 29-09-2013 à 14:49:19
Oui de toute façon je voulais une solution un peu plus précise, voici mon code, je ne l'ai pas du tout optimisé car je ne cherchais qu'à comparer une approximation grossière mais qui se fait à l'aide d'un simple calcul avec cette méthode qui me donne pratiquement la solution exact à mon équation.
Mais en tout cas, je vois que votre méthode semble très rapide, vous utilisez une dichotomie?
Mais, je me dis que dans ce cas là, il faut avoir une petite idée de ce que vaut r?
Sub Méthode1()
Dim epsilon As Double
Dim r As Double
Dim M As Integer
Dim c As Integer
Dim N As Integer
Dim P As Double
Dim j As Integer
Dim S As Double
r = 0
M = 5
c = 5
N = 100
P = 80
epsilon = 1
While (epsilon > 0.001)
S = 0
For j = 1 To M
S = S + c / ((1 + r) ^ j)
Next j
S = S + N / ((1 + r) ^ M)
epsilon = Abs(P - S)
r = r + 0.000001
Wend
MsgBox (r)
End Sub
Marsh Posté le 29-09-2013 à 17:45:47
Il y a pourtant une icône pour le code ‼
Sinon avec la résolution de 0.000001 de ton dernier code, 103 189 itérations sont nécessaires pour terminer le processus.
Pour éviter le souci de boucle sans fin, je n'autorise pas mes procédures de dépasser les 99 itérations !
Ton résultat est toujours faussé par la position de l'incrémentation de la variable r dans la boucle …
J'utilise la même méthode mais en partant d'un pas supérieur pour la variable r accélérant donc la procédure
tout en détectant évidemment le moment où cette variable est trop grande afin d'affiner ce pas.
Désactiver Option Explicit ou la Déclaration des variables obligatoire car les variables de mes procédures sont déclarées à la volée …
La variable D est la résolution de l'approximation des décimales, A est le pas de la variable r et F le résultat de la formule.
La ligne n°12 est la détection pour l'affinage du pas.
Code :
|
En modifiant la variable D la valeur de r en sera donc plus fine …
Cette procédure s'avère plus précise que la tienne pourtant avec une résolution moindre !
Mais au lieu de manuellement varier le pas, mieux vaut le faire automatiquement jusqu'à une approximation raisonnable !
Certes le raisonnable n'est pas toujours scientifique, mais pour des besoins courants,
une approximation du résultat de la formule de quatre décimales semble suffisante, comme par exemple en gestion / finances ...
La variable E est maintenant de type Currency :
Code :
|
Cette procédure n'a d'autre utilité avec l'augmentation de la résolution de démontrer l'affinage de r
jusqu'à atteindre une approximation raisonnable en comparant la progression des itérations nécessaires …
En combinant les deux codes précédents, cette approximation raisonnable est directement calculée en seulement 21 itérations !
Code :
|
La dichotomie est efficace en l'a contrôlant quelque peu !
Sinon je me demande même sans VBA si le Solveur intégré à Excel suffirait, une autre piste à explorer …
Marsh Posté le 29-09-2013 à 21:54:17
Marc L a écrit : Cette procédure s'avère plus précise que la tienne pourtant avec une résolution moindre ! |
J'ai confondu la résolution et le pas ! Il fallait l'entendre pourtant avec un pas supérieur …
Sinon voici une variante de la procédure Demo1 apportant une meilleure précision sur la dernière décimale vis à vis de la résolution :
Code :
|
Une fois la résolution atteinte, cette procédure va voir si l'Epsilon n'est pas inférieur en incrémentant encore d'un pas,
on n'est pas à deux / trois itérations près !
Marsh Posté le 27-09-2013 à 18:43:10
Bonjour,
Je suis débutant en VBA et voilà déjà ma première boucle infini, il semblerait que ma boucle for se passe mal.
Pouvez vous m'éclairer?
Sub Méthode1()
Dim epsilon As Double
Dim r As Double
Dim M As Integer
Dim c As Integer
Dim N As Integer
Dim P As Double
Dim j As Integer
r = 0
M = 5
c = 5
N = 100
P = 80
epsilon = 1
While (epsilon > 0.1)
S = 0
For j = 1 To 5
S = S + c / ((1 + r) ^ i)
Next j
S = S + N / ((1 + r) ^ M)
epsilon = Abs(P - S)
r = r + 0.01
Wend
MsgBox (r)
End Sub
//En tout cas je vous remercie.