|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jul 1999
Città: Roma
Messaggi: 614
|
[C++] Fibonacci tramite prodotto di matrici
Allora appunto stavo cercando di risolvere il problema di fibonacci tramite l'uso del metodo dei quadrati ripetuti applicato alle matrici, il problema e' che dopo aver scritto il mio bell codice che qui allego:
****************************************************** Codice:
#include <iostream>
using namespace std;
unsigned long Fibonacci6(unsigned long [][2], int);
void PotenzaMatrice(unsigned long[][2], int);
void Prodotto(unsigned long [][2], unsigned long[][2]);
unsigned long J[2][2] = {{1,1},{1,0}};
unsigned long app[2][2];
int main() {
int n;
unsigned long nesimo;
unsigned long M[2][2]={{1,0},{0,1}};
cout << "Inserisci l'n-esimo numero di fibonacci che vuoi calcolare: ";
cin >> n;
nesimo = Fibonacci6(M,n);
cout << "L'n-esimo numero di fibonacci e': " << nesimo << endl;
system("pause");
return 0;
}
unsigned long Fibonacci6(unsigned long M[][2], int n) {
PotenzaMatrice(M,n-1);
return M[0][0];
}
void PotenzaMatrice(unsigned long M[][2], int n) {
if (n > 1) {
PotenzaMatrice(M,n/2);
Prodotto(M,M);
M = app;
}
if ((n%2) == 1) {
Prodotto(M,J);
M = app;
}
}
void Prodotto(unsigned long Mat1[][2], unsigned long Mat2[][2]) {
for (int i=1; i>=2; i++)
for (int j=1; j>=2; j++) {
app[i][j] = 0;
for (int k=1; k>=2; k++) {
app[i][j]=app[i][j]+Mat1[i][k]*Mat2[k][j];
}
}
}
non mi funziona una mazza Poi un' altra domanda che non ha che vedere direttamente con il codice...teoricamente questo dovrebbe essere l'algoritmo piu' veloce per trovare i numeri di fibonacci o almeno piu' veloce rispetto all'algoritmo ricorsivo ed a quello iterativo...ma perche'?nella moltiplicazione di matrici non perdo molto piu' tempo rispetto soprattutto ad un algoritmo iterativo fatto in questo modo: Codice:
algoritmo fibonacci(intero n) -> intero
a <- 1; b <- 1;
for i=3 to n do
c <- a + b;
a <- b; b <- c;
return b
__________________
...What you know that you time is close at hand, maybe then you'll begin to understand, life down there is just a strange illusion. Ultima modifica di andrea : 24-10-2004 alle 11:18. |
|
|
|
|
|
#2 |
|
Member
Iscritto dal: Aug 2004
Messaggi: 39
|
Se è la velocità che ti interessa, avevo trovato questa soluzione:
Codice:
double fibo(register double n) {
register double F[3] = {1.0, 1.0, 0.0};
register long long i;
if ((n < 0) || (fmod(n, 1.0))
return(-1);
if (n <= 2)
return(1);
for (i=2; i<(long long)n; i++)
F[i%3] = F[(i+4)%3] + F[(i+5)%3];
return(F[(i-1)%3]);
}
|
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Jul 1999
Città: Roma
Messaggi: 614
|
Intanto grazie per la risposta, dando un occhiata al codice da te scritto, mi sono accorto che in finale non e' altro che l'algoritmo in pseudocodice che avevo scritto prima trasposto in c ed ottimizzato naturalmente. Il fatto e' che quel tipo di algoritmo andandolo a studiare non e' piu' veloce rispetto quello con le matrici...visto che come tempo di esecuzione e' nell'ordine O(n) mentre quello con le matrici e di ordine O(log(N))! Poi naturalmente potrei sbagliare lo studio degli algoritmi pero' sinceramente non mi sembra.
__________________
...What you know that you time is close at hand, maybe then you'll begin to understand, life down there is just a strange illusion. |
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Nov 2002
Città: Singularity
Messaggi: 894
|
Complimenti a SnakePlissken per il codice molto compatto ed elegante
Un algoritmo più efficiente di quello non lo conosco. In che cosa consiste il metodo dei quadrati ripetuti? |
|
|
|
|
|
#5 | ||
|
Senior Member
Iscritto dal: Jul 1999
Città: Roma
Messaggi: 614
|
Quote:
Quote:
nel seguente pseudo codice appunto e' applicato al'uso di matrici, per effettuare la serie di fibonacci: Codice:
algoritmo fib(int n) -> n
M <- [1,0;0,1] (matrice identita')
PotenzaDiMatrice(M,N-1)
return M[0][0]
procedura PotenzaDiMatrice(matrice M, int n/2)
if ( n > 1) then
PotenzaDiMatrice(M,n/2)
M <- M * M
if ( n e' dispari) then M <- M * [1,1;1,0]
__________________
...What you know that you time is close at hand, maybe then you'll begin to understand, life down there is just a strange illusion. |
||
|
|
|
|
|
#6 |
|
Member
Iscritto dal: Jul 2003
Città: pisa
Messaggi: 141
|
esiste anche una formula per calcolarli, non so quanto sia efficiente (ci sono le potenze):
Codice:
Fn = 1/sqrt(5)*(((1+sqrt(5))/2)^(n+1)-((1-sqrt(5))/2)^(n+1)) |
|
|
|
|
|
#7 | |
|
Senior Member
Iscritto dal: Jul 1999
Città: Roma
Messaggi: 614
|
Quote:
__________________
...What you know that you time is close at hand, maybe then you'll begin to understand, life down there is just a strange illusion. |
|
|
|
|
|
|
#8 |
|
Senior Member
Iscritto dal: Nov 2002
Città: Singularity
Messaggi: 894
|
Le formule approssimate ovviamente hanno complessità costante ma si paga con poca accuratezza... O(log(n)) mi pare un risultato soddisfacente per la soluzione esatta
Ho controllato il codice del primo post e ho visto che è sbagliata la funzione che calcola il prodotto fra matrici: for (int i=1; i>=2; i++) se ci ragioni un attimo la condizione non è mai vera. Forse volevi scrivere: for (int i=1; i<=2; i++) ma dal momento che le matrici sono di dimensione fissa e piccole (2x2) ti conviene codificarle con un vettore scrivendo esplicitamente la formula del prodotto per ciascun elemento. Dovrebbe essere anche più veloce, dal momento che non ha indici da incrementare. Il resto del programma mi sembra corretto. Ultima modifica di Banus : 24-10-2004 alle 16:59. |
|
|
|
|
|
#9 | ||
|
Senior Member
Iscritto dal: Jul 1999
Città: Roma
Messaggi: 614
|
Quote:
ehm piccola svista Quote:
__________________
...What you know that you time is close at hand, maybe then you'll begin to understand, life down there is just a strange illusion. |
||
|
|
|
|
|
#10 | |||
|
Member
Iscritto dal: Aug 2004
Messaggi: 39
|
Re: [C++] Fibonacci tramite prodotto di matrici
Quote:
Quote:
Anzi devo riconoscere che il tuo, tradotto "letteralmente", è pure più veloce del mio perché non fa uso di matrici e si risparmia tutte quelle operazioni per determinare gli indici Proprio per questo non capisco come quello che usa la moltiplicazione delle matrici (che ammetto che non conoscevo) possa essere più veloce. Quello che hai codificato in pseudo-codice si riduce ad operazioni di addizione e assegnamento e sarà per questo senz'altro più veloce. Tutto questo credo sia proprio dal punto di vista operativo, in termini di velocità oggettiva. Purtroppo non ho un compilatore montato su questo PC. Prova a fare un confronto "sperimentale" tra le prestazione tra le due versioni e facci sapere. Anche quello mio comunque (che a questo punto sembra essere la meno efficiente delle tre... Quote:
Ma poi cos'è tutta sta mania di velocità Il mio calcola il massimo numero calcolabile che rientra nei double (fibo(1476)) in un batter d'occhio! (che rozzezza di spirito sto ragionamento... Voglio dire che comunque a livello operativo le differenze sono quasi impercettibili tra queste versioni. Ciauz! Ultima modifica di SnakePlissken : 24-10-2004 alle 22:06. |
|||
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Nov 2002
Città: Singularity
Messaggi: 894
|
Il metodo con le matrici è sicuramente più veloce del metodo iterativo perchè log(n) cresce molto più lentamente.
http://en.wikipedia.org/wiki/Fibonacci_number Più che la velocità si cerca l'accuratezza nei calcoli. L'algoritmo con le matrici trova il risultato in meno passaggi. |
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 02:58.











ehm piccola svista








