Three methods to solve the Fibonacci sequence and calculate the time complexity

A brief introduction about Fibonacci sequence:

  The Fibonacci sequence, also known as the golden section sequence, refers to such a sequence: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... In mathematics, the Fibonacci sequence It is defined recursively as follows: F(0)=0, F(1)=1, F(n)=F(n-1)+F(n-2) (n≥2, n∈N* ) In modern physics, quasi-crystal structure, chemistry and other fields, the Fibonacci sequence has direct applications. For this reason, the American Mathematical Society has published a mathematics titled "Fibonacci Sequence Quarterly" since 1963. Magazine, used to publish research results in this area.

Specific topic:

There are three commonly used algorithms for solving the F(n) of the Fibonacci sequence: recursive algorithm and non-recursive algorithm, and matrix fast power. Try to analyze the time complexity of the three algorithms.

1. Recursive algorithm

The recursive calling process of 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;
}

Time complexity analysis:

  To solve F(n), F(n-1) and F(n-2) must be calculated first, F(n-1) and F(n-2) must be calculated, and F(n-3) and F must be calculated first (n-4). . . . . . And so on, until you have to calculate F(1) and F(0) first, and then inversely get the results of F(n-1) and F(n-2), so as to get F(n) to calculate many repeated values , Caused a lot of waste in time, the time complexity of the algorithm increases exponentially with the increase of N, the time complexity is O(2^n), that is, the nth power of 2

2. Non-recursive algorithm

#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;
}

Time complexity analysis:

   Calculate from n(>2), and use the addition of F(n-1) and F(n-2) to find the result. This avoids a lot of repeated calculations, and its efficiency is much faster than the recursive algorithm , The time complexity of the algorithm is proportional to n, that is, the time complexity of the algorithm is O(n).

3. Matrix multiplication + fast power

Write picture description here

Therefore, the calculation of f(n) is simplified to calculate the (n-2) power of the matrix, and to calculate the (n-2) power of the matrix, we can decompose it, that is, calculate the matrix (n-2)/2 power The square of, decompose step by step, and the time complexity is O(log n) due to the calculation of the matrix power by half

#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;
}

This article is a resource integration, please contact me if there is any infringement.

Guess you like

Origin blog.csdn.net/hbhhhxs/article/details/105187494