Salut,
fatal_error a écrit:je doute qu'on puisse faire mieux (sinon on aurait déjà des résultats en ligne sur wikipedia) et si on peut faire mieux als c'est probablement pas efficient d'un point de vu calculatoire...
Perso, je suis de l'avis... totalement contraire....
Ce type de formule de récurrence mathématique, il faut
absolument tout faire pour ne pas la taper telle quelle et
sous forme récursive dans un ordi.
Je m'explique : on a par exemple p(100,18)=11 087 828 (11 millions)
(1) Si tu tape un algo. purement récursif, c'est on ne peut plus simple d'avoir une idée du nombre d'appel à la fonction récursive (1) : chaque appel final renvoie 0 ou 1 donc le nombre 11 087 828 a été obtenu
uniquement en ajoutant des 0 et des 1 donc plus de dix million d'appel à la fonction (et a mon avis, c'est de l'ordre du double voire du triple : met un compteur avec une variable globale pour avoir une valeur exacte du nombre d'appel).
Et la raison de ce fait, elle est extrêmement simple : lors du calcul de p(100,18), la fonction p a été appelée un très très grand nombre de fois
avec exactement les mêmes paramètre et à chaque fois, ben elle à refait absolument toute la descente récursive pour recalculer exactement le même résultat : c'est indubitablement totalement idiot comme méthode (tu peut de même rajouter dans la procédure un compteur ou tu mémorise dans une variable globale de type tableau le nombre de fois qu'elle a été appelée avec tel ou tel paramètre : la redondance est effarante)
(2) Alors que, si tu as suffisamment de place mémoire pour faire les calculs comme le ferait un tableur sous forme non récursive en calculant ligne par ligne les p(n,k) et en mémorisant les résultat alors tu as 1 calcul à faire sur la première ligne(n=1) ; 2 pour la deuxième; 3 pour la troisième; etc.. et pour remplir les lignes jusqu'à la 100em afin d'avoir p(100,18), ça te demande 1+2+3+...+100=5 050 calculs soit 2200 fois moins qu'avec la récursivité.
Et ça devient évidement de pire en pire lorsque n augmente vu que la méthode "tableur" est en O(n²) alors que je suis persuadé que la méthode récursive est de complexité exponentielle
(par contre le
n'est pas complètement clair du fait de la référence à p(n-k,k))
Après, évidement,
LA question intéressante, c'est de savoir si on peut faire mieux que le temps totalement prohibitif de la méthode pure récursive
sans bouffer des tonnes de mémoire à stocker tout le tableau.
Et là, effectivement, si ce qui t'intéresse c'est le nombre total p(n) de partition, je pense qu'il faut un peu faire des math pour écrire la formule différemment, par exemple, comme Al-Kashi le signale, tu as le théorème des nombres pentagonaux d'Euler.
(1) c.f. les fonctions p(n,k) "brute récursive"de fatal_error ci dessus.
EDIT : Après test, pour calculer p(100,18), la procédure de Fatal est appelée 197 333 761 fois (200 millions) mais il y a un bug dedans : il faut mettre "Si k==n ou
k==1 alors . . ." et on passe à 25 651 079 appels (25 millions)
EDIT 2 : Vu la forme de la récursion, en plus sous la version "tableau", il te suffit d'avoir deux tableaux unidimensionnels correspondant à deux colonnes vu que le calcul de la k-ième colonne ne demande que la connaissance de la précédente. Et tu peut même t'en sortir avec un unique tableau unidimensionnel en grugeant un peu. Et bien évidement c'est nettement moins gourmand en place mémoire.