Fibonacci
Fermé
nabil
-
Modifié par nabil le 9/10/2011 à 06:33
nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 - 10 oct. 2011 à 12:59
nicocorico Messages postés 799 Date d'inscription dimanche 19 juin 2011 Statut Membre Dernière intervention 3 juillet 2018 - 10 oct. 2011 à 12:59
5 réponses
Reivax962
Messages postés
3672
Date d'inscription
jeudi 16 juin 2005
Statut
Membre
Dernière intervention
11 février 2021
1 011
9 oct. 2011 à 09:00
9 oct. 2011 à 09:00
Bonjour,
Il faudrait déjà que tu nous dises quel est le problèmes !
Ça ne compile pas ? Le résultat est faux ? Tu as un message d'erreur ?
À vue d'oeil, je vois déjà un problème : tu définis fib(2) comme valant 'b' et non pas comme valant 'ab'.
Xavier
Il faudrait déjà que tu nous dises quel est le problèmes !
Ça ne compile pas ? Le résultat est faux ? Tu as un message d'erreur ?
À vue d'oeil, je vois déjà un problème : tu définis fib(2) comme valant 'b' et non pas comme valant 'ab'.
Xavier
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
9 oct. 2011 à 10:04
9 oct. 2011 à 10:04
Regarde comment fonctionne strcat!
Il faudrait plutôt faire :
Mais attention à l'allocation de f, car tu vas très rapidement dépasser les 100 caractères.
De plus comme tout ce qui concerne les suites de Fibonacci et assimilés, les méthodes récursives sont exponentielles O(1.618^n), alors que les méthodes itératives sont linéaires !
Il faudrait plutôt faire :
strcat(f,fib(n-2)); strcat(f,fib(n-1)); return f;
Mais attention à l'allocation de f, car tu vas très rapidement dépasser les 100 caractères.
De plus comme tout ce qui concerne les suites de Fibonacci et assimilés, les méthodes récursives sont exponentielles O(1.618^n), alors que les méthodes itératives sont linéaires !
le probleme s'es réglé , mais mon probleme c'est que le programme éfféctue au moin (2 a la puissaance n/2 )/2 concatenations , et moi je veux un programme qui n'éffectue q'au plus 'n' concaténations , comment j peux faire , et qué ce que je devrai changé , peut etre la solution itertive ou bién quoi , et merci bién , merci..
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
9 oct. 2011 à 17:27
9 oct. 2011 à 17:27
Oui, la solution itérative serait beaucoup plus efficace, cependant à partir du moment ou tu assembles des chaines de 'A' et de 'B', tu vas très rapidement te retrouver avec une chaine interminable, donc à quoi bon optimiser ?
Es-tu obligé d'appliquer cette méthode ?
Es-tu obligé d'appliquer cette méthode ?
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
9 oct. 2011 à 19:08
9 oct. 2011 à 19:08
C'est vrai que la chaîne va être de plus en plus longue, mais ce sera toujours mieux d'en avoir maximum trois (on ne doit pas pouvoir faire beaucoup mieux) qu'en avoir fibo(n).
On sera rapidement limité en n mais l'optimisation a justement pour but de pouvoir augmenter n, même si ce n'est qu'un petit peu.
Sur ma machine j'ai fait quelques tests, et le malloc de concaténation plante à n=35 pour la méthode récursive, et n=44 pour la méthode itérative... Ce n'est pas sensiblement mieux mais c'est déjà ça ;-)
On sera rapidement limité en n mais l'optimisation a justement pour but de pouvoir augmenter n, même si ce n'est qu'un petit peu.
Sur ma machine j'ai fait quelques tests, et le malloc de concaténation plante à n=35 pour la méthode récursive, et n=44 pour la méthode itérative... Ce n'est pas sensiblement mieux mais c'est déjà ça ;-)
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
Modifié par KX le 9/10/2011 à 19:32
Modifié par KX le 9/10/2011 à 19:32
"Passe moi", "Passe moi"...
Ce n'est pas parce que je l'ai fait dans mon coin que ça doit t'empêcher de la trouver par toi même !
Le malloc je m'en sers pour la concaténation, vu que la taille de la chaîne augmente très rapidement, un char[100] est dépassé dès n=12, il faut donc t'arranger pour allouer dynamiquement l'espace nécessaire pour ton char*
Pour la méthode itérative tu en trouveras plein sur le forum, le principe est toujours le même, tu pars de fibo_0 et fibo_1, puis tu calcules fibo_2, fibo_3, ... fibo_n avec une petite boucle.
Ce n'est pas parce que je l'ai fait dans mon coin que ça doit t'empêcher de la trouver par toi même !
Le malloc je m'en sers pour la concaténation, vu que la taille de la chaîne augmente très rapidement, un char[100] est dépassé dès n=12, il faut donc t'arranger pour allouer dynamiquement l'espace nécessaire pour ton char*
Pour la méthode itérative tu en trouveras plein sur le forum, le principe est toujours le même, tu pars de fibo_0 et fibo_1, puis tu calcules fibo_2, fibo_3, ... fibo_n avec une petite boucle.
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
Modifié par nicocorico le 9/10/2011 à 21:26
Modifié par nicocorico le 9/10/2011 à 21:26
Je pense qu'il y aurait moyen d'optimiser nettement sans aucune concaténation, en voici la recette :
- On alloue un gros bloc de caractères, dont la taille définira la taille maximale de la chaine,
- On initialise la chaine avec 'ABB'
- à chaque itération, la chaine contient n-1, qui elle-même contient n-2, donc pour obtenir n, il suffit de copier le début de la chaine, qui correspond donc à n-2, à concurrence du nombre de caractères de n-2...
Il faut donc calculer la taille de n-2 à chaque itération et c'est bon.
Exemple sommaire :
Le chêne aussi était un gland, avant d'être un chêne
- On alloue un gros bloc de caractères, dont la taille définira la taille maximale de la chaine,
- On initialise la chaine avec 'ABB'
- à chaque itération, la chaine contient n-1, qui elle-même contient n-2, donc pour obtenir n, il suffit de copier le début de la chaine, qui correspond donc à n-2, à concurrence du nombre de caractères de n-2...
Il faut donc calculer la taille de n-2 à chaque itération et c'est bon.
Exemple sommaire :
var N1, N2, N3 : Integer; Bloc : Array[0..100000] of Char; Count1, Count2 : integer; Bloc:= 'ABB'; N1:= 02; N2:= 03; For Count1:= 0 to 20 do begin For Count2:= 0 to N1-01 do Bloc[Count2 + N2]:= Bloc[Count2]; N3:= N1 + N2; N1:= N2; N2:= N3; end;
Le chêne aussi était un gland, avant d'être un chêne
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
9 oct. 2011 à 21:57
9 oct. 2011 à 21:57
Idée intéressante (en théorie du moins). En pratique on ne gagnera que 2 itérations puisqu'au lieu d'avoir trois chaînes on en aura deux et que l'espace mémoire va quand même être limité, c'est surtout au niveau de la consommation de ressources pour l'allocation mémoire que l'on y gagnerai.
Calculer la taille du bloc final est "facile", il suffit de calculer la valeur du Nè terme de la suite de Fibonacci (donc 100000 sera dépassé pour n>25) et il serait alors préférable de stocker les valeurs de cette suite pour s'en servir comme "indices" lors des copies des blocs (et ainsi savoir quel est le pointeur destination de la copie)
Par contre je n'ai pas compris d'où sors ton 'ABB' dans ton code, de plus tu notes 01, 02, 03, est-ce des valeurs octales ?
Calculer la taille du bloc final est "facile", il suffit de calculer la valeur du Nè terme de la suite de Fibonacci (donc 100000 sera dépassé pour n>25) et il serait alors préférable de stocker les valeurs de cette suite pour s'en servir comme "indices" lors des copies des blocs (et ainsi savoir quel est le pointeur destination de la copie)
Par contre je n'ai pas compris d'où sors ton 'ABB' dans ton code, de plus tu notes 01, 02, 03, est-ce des valeurs octales ?
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
9 oct. 2011 à 22:32
9 oct. 2011 à 22:32
Une seule chaine en fait, puisqu'on copie n-2 à partir du début de l'unique chaine...
Et pour ABB, c'est que je partais de f(1) = A et f(2) = B donc f(3) = AB et f(4) = ABB, oui, c'est peut-être pas ce qui est demandé !
Et bien sûr les valeurs affichées ne sont pas en octal, qui n'a aucun intérêt pour moi, mais bien en décimal, c'est juste que j'ai toujours tendance à ajouter un zéro devant les décimaux, sans que je m'explique vraiment pourquoi !
Je crois que c'est dû à l'assembleur, où il est important de faire ressortir les nombres, et il n'y a pas de variation de couleur...
Et je ne comprend pas bien ce que tu veux dire sur les indices de copie ?
Car la chaine est constituée pas-à-pas, sans qu'aucun caractère ne soit copié deux fois, je ne vois pas trop comment faire mieux...
Après j'ai bien pensé à un autre principe, qui consisterait à retenir les tailles de chaines et ensuite reconstituer à la demande, mais c'est beaucoup plus compliqué, et pas spécialement à la portée d'un débutant...
Et pour ABB, c'est que je partais de f(1) = A et f(2) = B donc f(3) = AB et f(4) = ABB, oui, c'est peut-être pas ce qui est demandé !
Et bien sûr les valeurs affichées ne sont pas en octal, qui n'a aucun intérêt pour moi, mais bien en décimal, c'est juste que j'ai toujours tendance à ajouter un zéro devant les décimaux, sans que je m'explique vraiment pourquoi !
Je crois que c'est dû à l'assembleur, où il est important de faire ressortir les nombres, et il n'y a pas de variation de couleur...
Et je ne comprend pas bien ce que tu veux dire sur les indices de copie ?
Car la chaine est constituée pas-à-pas, sans qu'aucun caractère ne soit copié deux fois, je ne vois pas trop comment faire mieux...
Après j'ai bien pensé à un autre principe, qui consisterait à retenir les tailles de chaines et ensuite reconstituer à la demande, mais c'est beaucoup plus compliqué, et pas spécialement à la portée d'un débutant...
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
9 oct. 2011 à 23:21
9 oct. 2011 à 23:21
En fait si f(3)=f(1)+f(2)="A"+"B"="AB", on devrait avoir avoir f(4)=f(2)+f(3)="BAB" et non pas "ABB"
Pour mes indices, ce que je remarque c'est que pour tout k>2, les fibo(k) derniers caractères de fibo_ab(n) sont exactement la chaîne fibo_ab(k). Du coup je peux me servir des indices fibo(k) pour construire par copie les fibo_ab(k+2)... Enfin c'est sur cette idée que je partais ;-)
Pour mes indices, ce que je remarque c'est que pour tout k>2, les fibo(k) derniers caractères de fibo_ab(n) sont exactement la chaîne fibo_ab(k). Du coup je peux me servir des indices fibo(k) pour construire par copie les fibo_ab(k+2)... Enfin c'est sur cette idée que je partais ;-)
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
Modifié par KX le 9/10/2011 à 23:46
Modifié par KX le 9/10/2011 à 23:46
En C, ça donnerait à peu près ceci (je raccourci ^^)
int* fibo = fibonacci(n); // fibo[0]=fibo[1]=1, fibo[k]=fibo[k-2]+fibo[k-1] char* str = malloc(fibo[n]+1); str[fibo[n]-2]='a'; str[fibo[n]-1]='b'; str[fibo[n]-0]='\0'; for (i=3; i<=n; i++) strncpy(str+(fibo[n]-fibo[i]),str+(fibo[n]-fibo[i-2]),fibo[i-2]);
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
10 oct. 2011 à 06:43
10 oct. 2011 à 06:43
Ha oui, c'est pour ça que dans ma méthode j'inverse le résultat, ce qui n'est à priori pas très grave, ce qui permet de conserver chaque chaine ajoutée sans jamais recopier, et le tout dans une seule et unique chaine, ainsi on a : f(3) = f(2) + f(1), la chaine f(3) étant calculée en conservant f(2) à la position initiale, et en ajoutant f(1) à la suite de f(2).
Et puisque f(1) correspond au caractères initiaux de f(2), il suffit d'en connaitre la taille, et de copier du début de la chaine vers sa suite...
Et puisque f(1) correspond au caractères initiaux de f(2), il suffit d'en connaitre la taille, et de copier du début de la chaine vers sa suite...
ABB ---+AB -> Ajout des 2 1ers caractères ------+ABB -> Ajout des 3 1ers caractères -----------+ABBAB -> Ajout des 5 1ers caractères Résultat: ABBABABBABBAB ABB+AB+ABB+ABBAB
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
10 oct. 2011 à 06:52
10 oct. 2011 à 06:52
Alors que moi je voyais ça à l'envers, en copiant fibo(k-2) devant fibo(k-1) pour avoir fibo(k)
-------A -------B ------AB -----BAB ---ABBAB BABABBAB
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
10 oct. 2011 à 07:03
10 oct. 2011 à 07:03
Ce qui revient au même effectivement, ta méthode ayant l'avantage de garder l'ordre voulu !
En tous cas dans un sens comme dans l'autre, la méthode est fonctionnelle...
Mais je ne vois pas trop l'intérêt du résultat, difficile à visualiser et pas très pratique non plus pour effectuer des calculs.
De plus on pourrait pousser la méthode dans ses retranchements en passant au binaire, ce qui diviserait par 8 la taille de la chaine (A = 0 et B = 1)...
En tous cas dans un sens comme dans l'autre, la méthode est fonctionnelle...
Mais je ne vois pas trop l'intérêt du résultat, difficile à visualiser et pas très pratique non plus pour effectuer des calculs.
De plus on pourrait pousser la méthode dans ses retranchements en passant au binaire, ce qui diviserait par 8 la taille de la chaine (A = 0 et B = 1)...
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
10 oct. 2011 à 07:16
10 oct. 2011 à 07:16
Evidemment en passant binaire cela permettrait de diviser l'espace mémoire alloué, mais on se retrouve à devoir utiliser des opérateurs bit-a-bit et j'avoue ne pas les connaître suffisamment pour pouvoir faire des copies propres, d'autant que les opérateurs de déplacement se contrôlent surement avec des int, or ce sont eux qui vont désormais déborder à cause de la croissance exponentielle.
Le problème est très scolaire, mais son optimisation l'est un peu moins ^^
Le problème est très scolaire, mais son optimisation l'est un peu moins ^^
nicocorico
Messages postés
799
Date d'inscription
dimanche 19 juin 2011
Statut
Membre
Dernière intervention
3 juillet 2018
138
Modifié par nicocorico le 10/10/2011 à 21:49
Modifié par nicocorico le 10/10/2011 à 21:49
Hé bien, pour info, en binaire non optimisé ça donnerais ça, sommairement toujours :
Il serais évidement possible de copier 32 bits d'un seul coup pour dupliquer les chaines, en plus compliqué...
var N1, N2, N3 : Integer; Bloc : Array[0..100000] of Byte; Count1, Count2 : integer; Bloc[0]:= $6; N1:= 02; N2:= 03; FillChar(Bloc, SizeOf(Bloc), 0); For Count1:= 0 to 20 do begin For Count2:= 0 to N1-01 do If Boolean(((Bloc[Count2 shr 03]) shr (Count2 and 07)) and 01) then Inc(Bloc[(Count2 + N2) shr 03]) , 01 shl ((Count2 + N2) and 07); N3:= N1 + N2; N1:= N2; N2:= N3; end;
Il serais évidement possible de copier 32 bits d'un seul coup pour dupliquer les chaines, en plus compliqué...
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 019
10 oct. 2011 à 12:39
10 oct. 2011 à 12:39
Même en mettant 8 bits par byte, tes 100 000 cases ça fait un peu petit. Peut-être que le Pascal ne te permet pas de faire plus ? Il faudrait que je regarde ce que ça donne avec les bits en C.
Pour l'instant avec 1 octets par caractère, j'atteint n=44 (soit 1,13 milliards de caractères) et ça plante à n=45 (1,84 milliards), en divisant par 8 l'espace, ça permettrait d'atteindre n=48 (7,78 milliards)
Après pour faire plus (est-ce vraiment utile ?) il faudrait faire de la manipulation de fichiers, ce sera certes plus long, mais on soulagera la mémoire vive au détriment de la mémoire physique.
Mais il ne faut pas rêver, on n'ira pas beaucoup plus loin :p
Pour l'instant avec 1 octets par caractère, j'atteint n=44 (soit 1,13 milliards de caractères) et ça plante à n=45 (1,84 milliards), en divisant par 8 l'espace, ça permettrait d'atteindre n=48 (7,78 milliards)
Après pour faire plus (est-ce vraiment utile ?) il faudrait faire de la manipulation de fichiers, ce sera certes plus long, mais on soulagera la mémoire vive au détriment de la mémoire physique.
Mais il ne faut pas rêver, on n'ira pas beaucoup plus loin :p
9 oct. 2011 à 16:46