Três métodos para resolver a sequência de Fibonacci e calcular a complexidade do tempo

Uma breve introdução sobre a sequência de Fibonacci:

  A sequência de Fibonacci, também conhecida como sequência da seção áurea, refere-se a tal sequência: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... Em matemática, a sequência de Fibonacci É definido recursivamente da seguinte forma: F (0) = 0, F (1) = 1, F (n) = F (n-1) + F (n-2) (n≥2, n∈N * ) Na física moderna, na estrutura quase-cristalina, na química e em outros campos, a sequência de Fibonacci tem aplicações diretas. Por essa razão, a American Mathematical Society publicou uma matemática intitulada "Fibonacci Sequence Quarterly" desde 1963. Revista, utilizada para publicar resultados de pesquisas na área.

Tópico especifico:

Existem três algoritmos comumente usados ​​para resolver o F (n) da sequência de Fibonacci: algoritmo recursivo e algoritmo não recursivo e potência rápida de matriz. Tente analisar a complexidade de tempo dos três algoritmos.

1. Algoritmo recursivo

O processo de chamada recursiva de Fib (5)

#include<iostream>
using namespace std;

long Fibonacci(int n) {
    if (n == 0)
        return 0;
    else if (n == 1)
        return 1;
    else
        return Fibonacci(n - 1) + Fibonacci(n-2);
}

int main() {
    cout << "Enter an integer number:" << endl;
    int N;
    cin >> N;
    cout << Fibonacci(N) << endl;
    system("pause");
    return 0;
}

Análise de complexidade de tempo:

  Para resolver F (n), F (n-1) e F (n-2) devem ser calculados primeiro, F (n-1) e F (n-2) devem ser calculados, e F (n-3) e F devem ser calculados primeiro (n-4). . . . . . E assim por diante, até que você tenha que calcular F (1) e F (0) primeiro, e então inversamente obter os resultados de F (n-1) e F (n-2), de modo a obter F (n) para calcular muitos valores repetidos , Causou muita perda de tempo, a complexidade do tempo do algoritmo aumenta exponencialmente com o aumento de N, a complexidade do tempo é O (2 ^ n), ou seja, a enésima potência de 2

2. Algoritmo não recursivo

#include<iostream>
using namespace std;

long Fibonacci(int n) {
    if (n <= 2)
        return 1;
    else {
        long num1 = 1;
        long num2 = 1;
        for (int i = 2;i < n - 1;i++) {
            num2 = num1 + num2;
            num1 = num2 - num1;
        }
        return num1 + num2;
    }
}

int main() {
    cout << "Enter an integer number:" << endl;
    int N;
    cin >> N;
    cout << Fibonacci(N) << endl;
    system("pause");
    return 0;
}

Análise de complexidade de tempo:

   Calcule a partir de n (> 2) e use a adição de F (n-1) e F (n-2) para encontrar o resultado. Isso evita muitos cálculos repetidos e sua eficiência é muito mais rápida que o algoritmo recursivo , A complexidade de tempo do algoritmo é proporcional an, ou seja, a complexidade de tempo do algoritmo é O (n).

3. Multiplicação de matrizes + potência rápida

Escreva a descrição da imagem aqui

Portanto, o cálculo de f (n) é simplificado para calcular a potência (n-2) da matriz, e para calcular a potência (n-2) da matriz, podemos decompô-la, ou seja, calcular a potência (n-2) / 2 da matriz O quadrado de, decompõe-se passo a passo, e a complexidade do tempo é O (log n) devido ao cálculo da potência da matriz pela metade

#include <iostream>
using namespace std;

class Matrix
{
public:
    int n;
    int **m;
    Matrix(int num)
    {
        m=new int*[num];
        for (int i=0; i<num; i++) {
            m[i]=new int[num];
        }
        n=num;
        clear();
    }
    void clear()
    {
        for (int i=0; i<n; ++i) {
            for (int j=0; j<n; ++j) {
                m[i][j]=0;
            }
        }
    }
    void unit()
    {
        clear();
        for (int i=0; i<n; ++i) {
            m[i][i]=1;
        }
    }
    Matrix operator=(const Matrix mtx)
    {
        Matrix(mtx.n);
        for (int i=0; i<mtx.n; ++i) {
            for (int j=0; j<mtx.n; ++j) {
                m[i][j]=mtx.m[i][j];
            }
        }
        return *this;
    }
    Matrix operator*(const Matrix &mtx)
    {
        Matrix result(mtx.n);
        result.clear();
        for (int i=0; i<mtx.n; ++i) {
            for (int j=0; j<mtx.n; ++j) {
                for (int k=0; k<mtx.n; ++k) {
                    result.m[i][j]+=m[i][k]*mtx.m[k][j];
                }   
            }
        }
        return result;
    }
};
int main(int argc, const char * argv[]) {
    unsigned int num=2;
    Matrix first(num);
    first.m[0][0]=1;
    first.m[0][1]=1;
    first.m[1][0]=1;
    first.m[1][1]=0;
    int t;
    cin>>t;
    Matrix result(num);
    result.unit();
    int n=t-2;
    while (n) {
        if (n%2) {
            result=result*first;
            }
        first=first*first;
        n=n/2;
    }
    cout<<(result.m[0][0]+result.m[0][1])<<endl;
    return 0;
}

Este artigo é uma integração de recursos, entre em contato comigo se houver alguma violação.

Acho que você gosta

Origin blog.csdn.net/hbhhhxs/article/details/105187494
Recomendado
Clasificación