由斐波那契数列引述到矩阵快速幂技巧

简介: 由斐波那契数列引述到矩阵快速幂技巧

求斐波那契数列矩阵乘法的方法

1)斐波那契数列的线性求解(O(N))的方式非常好理解

2)同时利用线性代数,也可以改写出另一种表示:

|F(N),F(N-1)| = |F(2),F(1)| * 某个二阶矩阵的N-2次方

3)求出这个二阶矩阵,进而最快求出这个二阶矩阵的N-2次方

斐波那契数列的线性求解
public static int f1(int n){
        if(n<1){
            return 0;
        }
        if(n==1 || n==2){
            return 1;
        }
        return f1(n-1)+f1(n-2);
    }

    public static int f2(int n){
        if(n<1){
            return 0;
        }
        if(n==1 || n==2){
            return 1;
        }
        int pre=1;
        int res=1;
        int tmp=0;
        for(int i=3; i<=n; i++){
            tmp=res;
            res+=pre;
            pre=tmp;
        }
        return res;
    }
斐波那契数列的矩阵乘法求解

上述求解方式时间复杂度是O(N),但是可以优化到O(LogN)。

斐波那契数列的递归公式:F(n)=F(n-1)+F(n-2)。这个递归公式没有条件转移,是个严格的递推式,所以可以优化到O(LogN)

所以,接下来我们通过线性代数证明|F(N),F(N-1)| = |F(2),F(1)| * 某个二阶矩阵的N-2次方(线性代数就是为了解决严格递推第几项的问题而发明的)

在这里插入图片描述
在这里插入图片描述

新的问题:一个矩阵的n次方如何算得足够快?

先解决:一个数的n次方如何算得足够快。(本质是利用二分,关键是利用二进制

10^75
=10^(64+8+2+1)
=10^(1001011)

所以一个矩阵的n次方也是这样算。

package com.harrison.class15;

/**
 * @author Harrison
 * @create 2022-03-27-18:37
 * @motto 众里寻他千百度,蓦然回首,那人却在灯火阑珊处。
 */
public class Code01_FibonacciProblem {
    public static int f1(int n) {
        if (n < 1) {
            return 0;
        }
        if (n == 1 || n == 2) {
            return 1;
        }
        return f1(n - 1) + f1(n - 2);
    }

    public static int f2(int n) {
        if (n < 1) {
            return 0;
        }
        if (n == 1 || n == 2) {
            return 1;
        }
        int pre = 1;
        int res = 1;
        int tmp = 0;
        for (int i = 3; i <= n; i++) {
            tmp = res;
            res += pre;
            pre = tmp;
        }
        return res;
    }

    public static int f3(int n){
        if (n < 1) {
            return 0;
        }
        if (n == 1 || n == 2) {
            return 1;
        }
        int[][] base={
                {1,1},
                {1,0}
                };
        int[][] res=matrixPower(base,n-2);
        // |F(N),F(N-1)| = |F(2),F(1)| * 某个二阶矩阵的N-2次方
        return res[0][0]+res[1][0];
    }

    // p:次方数
    public static int[][] matrixPower(int[][] m, int p) {
        int[][] res = new int[m.length][m[0].length];
        // 单位矩阵的概念:右对角线全是1,其余位置全是0
        // 一个单位矩阵 * a矩阵 = a矩阵
        for (int i = 0; i < res.length; i++) {
            res[i][i] = 1;
        }
        // res=矩阵中的1
        int[][] t = m;// 矩阵1次方
        // 有1就要乘上去,乘完就右移扔掉
        for (; p != 0; p >>= 1) {
            // (次方数 & 1) !=0 说明最末尾有1
            if ((p & 1) != 0) {
                res=muliMatrix(res,t);
            }
            t=muliMatrix(t,t);
        }
        return res;
    }

    /*
    两个矩阵乘完之后的结果返回,矩阵相乘得到的是一个新的矩阵
    新矩阵的第一行第一列的结果是由第一个矩阵的第一行分别与第二个矩阵的第一列相乘的和
     */
    public static int[][] muliMatrix(int[][] m1, int[][] m2) {
        int[][] res = new int[m1.length][m2[0].length];
        for (int i = 0; i < m1.length; i++) {
            for (int j = 0; j < m2[0].length; j++) {
                for (int k = 0; k < m2.length; k++) {
                    res[i][j] += m1[i][k] * m2[k][j];
                }
            }
        }
        return res;
    }

    public static void main(String[] args) {
        int n = 19;
        System.out.println(f1(n));
        System.out.println(f2(n));
        System.out.println(f3(n));
        System.out.println("===");
    }
}
最终推广的结论!!!

在这里插入图片描述

相关文章
|
Linux 芯片 开发者
|
存储 算法 安全
【密码学】非对称加密算法 - ECDH
由于 ECC 密钥具有很短的长度,所以运算速度比较快。到目前为止,对于 ECC 进行逆操作还是很难的,数学上证明不可破解,ECC 算法的优势就是性能和安全性高。实际应用可以结合其他的公开密钥算法形成更快、更安全的公开密钥算法,比如结合 DH 密钥形成 ECDH 密钥协商算法,结合数字签名 DSA 算法组成 ECDSA 数字签名算法。ECDH算法常常用来进行密钥的协商,协商好密钥后,用来解决上面的密钥分配问题,将对称加密的密钥安全的传到对端设备。算法加密/解密数字签名密钥交换RSA✅✅✅❌。
5026 0
|
6月前
|
人工智能 缓存 搜索推荐
手把手基于ModelScope MCP协议实现AI短视频创作:零代码自动化工作流
本文介绍了基于ModelScope MCP协议的AI视频生成解决方案,涵盖核心机制解析、零代码工作流搭建、性能优化策略及全链路异常处理。通过统一上下文描述符抽象异构AI服务,实现图像生成、语音合成与视频剪辑的自动化编排。结合缓存优化与错误重试机制,大幅提升生成效率(如5分镜视频从91.7s降至22.4s)。最后展示《夏日海滩》生成案例,并探讨个性化风格迁移与商业场景集成等进阶方向,揭示零代码本质为服务、流程与资源的三层抽象。
926 18
|
SQL 大数据 HIVE
电商项目之交易订单明细流水表 SQL 实现(上)|学习笔记
快速学习电商项目之交易订单明细流水表 SQL 实现(上)
电商项目之交易订单明细流水表 SQL 实现(上)|学习笔记
linux实用技巧:cp时自动将软链接所指定的文件实体也一起copy(软链接将会变成目标文件实体)
linux实用技巧:cp时自动将软链接所指定的文件实体也一起copy(软链接将会变成目标文件实体)
linux实用技巧:cp时自动将软链接所指定的文件实体也一起copy(软链接将会变成目标文件实体)
|
1月前
|
敏捷开发 小程序 API
个人开发者福音!免资质免签名,API开箱即用- 阿里云「短信认证」上线
个人开发者接入短信验证码遇资质、审核、稳定性三大难题。阿里云推出极简方案:免企业资质、免签名报备,仅需实名认证即可快速集成,双11特惠低至3.99元/年。
433 1
|
6月前
|
安全 开发工具 git
如何回滚Git中的提交?
如何回滚Git中的提交?
1437 0
|
数据采集 存储 JavaScript
如何使用Puppeteer和Node.js爬取大学招生数据:入门指南
本文介绍了如何使用Puppeteer和Node.js爬取大学招生数据,并通过代理IP提升爬取的稳定性和效率。Puppeteer作为一个强大的Node.js库,能够模拟真实浏览器访问,支持JavaScript渲染,适合复杂的爬取任务。文章详细讲解了安装Puppeteer、配置代理IP、实现爬虫代码的步骤,并提供了代码示例。此外,还给出了注意事项和优化建议,帮助读者高效地抓取和分析招生数据。
508 0
如何使用Puppeteer和Node.js爬取大学招生数据:入门指南
|
SQL 存储 分布式计算
Hive 3.x的安装部署 - Ubuntu
Hive 3.x的安装部署 - Ubuntu
1227 0