J'ai du mal à implémenter une fonction récursive partielle (du moins dans mon esprit).
pour tout p donné et maxsteps = 100 arbitraires, calculez L :
3 Réponses :
Vous pouvez passer les maxsteps à la fonction récursive et soustraire 1 à chaque étape jusqu'à atteindre 0, avec la condition de fin:
public double L(double p, int maxSteps)
{
if (maxSteps == 0)
{
return 1 / (p + 1);
}
return 1 / (p + L(p, maxSteps - 1));
}
Là, je vous ai laissé le code de l'approche récursive:
class Program
{
static void Main(string[] args)
{
double recursiveL = CalculateL(100, 100);
double notRecursiveLWrong = NotRecursiveCalculateLWrong(100, 100);
double notRecursiveLRight = NotRecursiveCalculateLRight(100, 100);
}
private static double CalculateL(double p, int maxSteps)
{
if (maxSteps == 0)
{
return (1 / (p + 1));
}
else
{
return (1 / (p + CalculateL(p, maxSteps - 1)));
}
}
private static double NotRecursiveCalculateLWrong(double p, int maxSteps)
{
double result = 0;
for (int i = 0; i < maxSteps; i++)
{
result = (1 / (p + result));
}
return result;
}
private static double NotRecursiveCalculateLRight(double p, int maxSteps)
{
double result = 1 / (p + 1);
for (int i = 0; i < maxSteps; i++)
{
result = (1 / (p + result));
}
return result;
}
}
En le faisant, je pensais au fait que pour ce problème, la récursivité n'est pas nécessaire et maintenant je peux voir que Je ne suis pas le seul.
J'ai ajouté mon approche non récursive.
Modifier:
Si vous essayez mon code, vous verrez que chaque méthode renvoie la même valeur, WATCHOUT, ceci est dû à la faible précision en virgule flottante.
L'approche correcte est NotRecursiveCalculateLRight qui est indiquée dans la réponse de @John.
En quoi est-ce différent de cette réponse ?
Je l'ai fait pendant qu'il publiait sa réponse. Quoi qu'il en soit, j'ai ajouté une autre solution.
@MarcoSalerno Eh bien, vous avez ajouté une autre solution qui est également déjà fournie. Cet article contient deux réponses qui sont déjà toutes deux proposées. Cette réponse n'ajoute rien et doit être supprimée.
J'apprécie que vous vouliez une fonction récursive, mais j'ai pensé que je fournirais une alternative non récursive au cas où cela s'avérerait être préféré:
private static double CalculateL(double p, int maxsteps)
{
double val = 1 / (p + 1);
for (int i = 1; i <= maxsteps; ++i)
{
val = 1 / (p + val);
}
return val;
}
Je ne suis pas sûr à 100% à propos de maxsteps , en fonction des autres réponses. Si la réponse n'est pas correcte, alors vous voulez probablement .
Veuillez également lire Le calcul en virgule flottante est-il cassé? si vous vous attendez à des résultats très précis.
J'irais certainement avec cette approche car je ne pense pas que ce problème nécessite une récursivité (pourquoi donner du temps à empiler)
Vous pouvez également envelopper l'expression dans une fonction (locale).
@Lasse Oups, oui. Vous avez raison. Je l'ai corrigé pour correspondre aux autres.
Eh bien, pour tout ce que nous savons, votre résultat était le bon.
@ LasseVågsætherKarlsen +/- 1 n'est peut-être pas si important. La fonction converge probablement vers un nombre réel. Plus vous faites d'étapes, moins la dernière étape est importante.
Vous avez peut-être raison, mais dans ce cas, je dirais que la bonne approche serait probablement de spécifier une limite epsilon à la place, en demandant à l'algorithme de s'arrêter lorsque la modification de la valeur est inférieure à une petite limite prédéfinie, au lieu de spécifier exactement comment plusieurs étapes pour l'exécuter. Mais oui, si vous fournissez un nombre suffisamment élevé, +/- 1 pas n'aura pas d'importance (tant que ça).
Et je ne suis pas un expert en mathématiques, mais je suppose qu'il n'y a aucun moyen de choisir un p pour qu'il ne converge pas? c'est à dire. chaque étape supplémentaire l'éloigne de quelque valeur, au lieu de se rapprocher?
@Marco En réponse à votre commentaire maintenant supprimé: L'équation d'origine indique que la calcul la plus interne est 1 / (p + 1) . En testant avec p = 5 et maxsteps = 0 , ma méthode (et les récursives présentées ci-dessous) donne 0,166666666666667 , mais la vôtre donne 0 . Le réglage du vôtre sur maxsteps = 1 donne 2 , ce qui semble également incorrect.
@John oui je l'ai dit après avoir demandé, c'est à cause de la précision en virgule flottante, avec la valeur que j'ai essayée cela ne fonctionne pas correctement
Comment savoir quand s'arrêter? La fonction est-elle toujours comme ça, avec ce nombre exact de niveaux?
Mise à jour de la question, il existe également un paramètre maxsteps.
Quelle est la valeur maxsteps pour l'exemple donné?
Je suppose que je ne comprends pas votre question alors, si l'exemple donné a un maximum de 100. Quelle est la relation entre cette valeur et les niveaux imbriqués de cette expression? Il semble que vous ayez fait 3 ou 4 étapes selon la façon dont vous interprétez la récursivité de celle-ci, mais comment cela se rapporte-t-il à 100?
Il ne dépend pas vraiment de 100, cette valeur doit être configurée à chaque exécution du code.
votre P reste le même tout au long des 100 itérations .. Je vois que c'est un cas de boucle et non de récursivité. Comme je pense que la récursion aurait dû dépendre de la valeur de P et P devrait déplacer le programme vers la condition de sortie.
Mon point était que je veux savoir quelle valeur maxsteps vous auriez pour votre expression particulière, celle qui va de 3 à 4 niveaux.
que 3 ou 4 fois c'est juste pour montrer la formule
Permettez-moi de clarifier, pour cette expression, maxsteps 3 ou 4 ou est-ce quelque chose de complètement différent? Si vous dites que c'est 100, je ne comprends vraiment pas votre question. Je demande des détails liés à votre exemple, pas ce que la fonction générale devrait faire. Je comprends que si vous spécifiez 100, il doit imbriquer 100 niveaux de profondeur, mais quelle est la valeur maxsteps de votre exemple spécifique? Est-ce 3 ou 4?
En utilisant la récursivité, vous pouvez atteindre des limites arbitraires imposées par le système d'exploitation (StackOverflowException). Sans récursion les limites ne sont que la précision du type numérique (double)
En gros, je me demande si maxsteps == 1 renverrait
1 / (p + 1)ou1 / (p + 1 / (p + 1)).Salut, y a-t-il quelque chose dont vous n'êtes toujours pas sûr avec cette question?