zoukankan      html  css  js  c++  java
  • 矩阵快速幂基础

    刚开始学习矩阵快速幂,这水题花了好久才水,路漫漫且不易。。。。(51nod 1113)

    先来说下矩阵

     单位矩阵:

     矩阵乘法

    凭自己的理解 ,我认为矩阵问题解法可分为以下3个主要步骤(下面全凭自我感觉理解)

    1.main函数部分

    2.矩阵快速幂部分

    3.矩阵乘法部分

    刚接触这部分知识的时候,也是看了一个大牛的博客,感觉讲的挺好的,下面就献上

    2.矩阵快速幂引入篇

    整数快速幂:
    为了引出矩阵的快速幂,以及说明快速幂算法的好处,我们可以先求整数的幂。
    如果现在要算X^8:则 XXXXXXXX 按照寻常思路,一个一个往上面乘,则乘法运算进行7次。
    (X
    X)(XX)(XX)(XX)
    这种求法,先进行乘法得X^2,然后对X^2再执行三次乘法,这样去计算,则乘法运算执行4次。已经比七次要少。所以为了快速算的整数幂,就会考虑这种结合的思想。
    现在要考虑应该怎么分让计算比较快。接下来计算整数快速幂。例如:X^19次方。
    19的二进制为:1 0 0 1 1 。
    由(X^m)(X^n) = X^(m+n)
    则X^19 = (X^16)
    (X^2)*(X^1)
    那么怎么来求解快速幂呢。请看下列代码:
    求解X^N的值。
    ///整数快速幂,计算x^N

    int QuickPow(int x,int N)
    {
        int res = x;
        int ans = 1;
        while(N)
        {
            if(N&1)
            {
                ans = ans * res;
            }
            res = res*res;
            N = N>>1;
        }
        return ans;
    }

    那么让我们来看看下面这段代码到底对不对:
    对于X^19来说:
    19的二进制为:1 0 0 1 1
    初始:

    ans = 1; res = x;

    则10011最后一位是1,所以是奇数。

     ans = res*ans = x; 
    res = res*res = x^2;

    然后右移一位,1 0 0 1
    则1001最后一位是1,所以是奇数

        ans = res*ans = x*(x^2) = x^3     
    res = res*res = x^2*x^2 = x^4

    然后右移一位,1 0 0
    则最后一位是0,所以当前的数为偶数。

        res = res*res = x^4*x^4 = x^8

    然后右移一位,1 0
    最后一位是0,当前数是偶数。

        res = res*res =x^8*x^8= x^16

    然后右移一位,1
    最后一位是1,当前数是奇数

        ans = ans*res = (x^3)*(x^16) = x^19
        res = res*res = x^32

    可以看出res = X^m,m 始终是与二进制位置上的权值是相对应的。当二进制位为0时,我们只让resres使幂指数2.对应下一个二进制位的权值,当二进制位为1时,ans = ans*res 。则乘上了该乘的X幂次。
    2.矩阵快速幂算法篇

    看了一个整数数的快速幂,现在我们就正式介绍矩阵快速幂算法。假如现在有一个n*n的方阵A。所谓方阵就是行数和列数相等的矩阵,先给出一个数M,让算矩阵A的M次幂,A^M.在此只要求计算并不需要去深究这个矩阵到底是什么含义。则上面代码可以化为。

    注:上面代码有一处错误,即Mul中少了一个变量,,,,这也是我看了好久才发现的,心累心累

    上面只是简单的计算矩阵的幂,大家会感觉很抽象,因为上述矩阵并没有具体的含义,
    现在就举例说明矩阵快速幂在实际运用中的意义:
    以最常见的斐波那契数列为例:众所周知:斐波那契数列递推公式为:
    F[n] = F[n-1] + F[n-2]. 由f[0]=0,f[1]=1,可以递推后面的所有数。
    在以前,我们会常常用for循环,这是最直接的算法。
    POJ 3070 题目,让求斐波那契数列,其n更是高达10亿。
    直接递推的局限性:
    (1)本题让你递推的斐波那契数n高达10亿。测试时间仅1秒的时间,for循环用递推公式递归导致超时。
    (2)想要打表实现随机访问根本不可能,先把斐波那契数列求到10亿,然后想去进行随机访问。题目未给出那么多内存,数组也开不到10亿。
    因此它可以用矩阵快速幂来写。
    观察f[n] = f[n-1]+f[n-2] 第n相是由第n-1项和第n-2项递推而来。
    同理,第n+1项由第n项和第n-1项递推而来。
    因此可以用矩阵表示:

    则,知道f[n-1]、f[n-2]则乘上左方矩阵,就能得到等号左侧矩阵,第一个位置
    即为要求的f[n]。

  • 相关阅读:
    SpringCloud学习总结(九)——微服务架构高并发问题
    SpringCloud学习总结(八)——服务调用Feign
    SpringCloud学习总结(七)——服务注册中心Consul
    SpringCloud学习总结(六)——服务调用和负载均衡Ribbon
    Hadoop综合大作业
    分布式文件系统HDFS练习
    安装Hadoop
    爬虫综合大作业(震惊!爬取了590位微信好友后竟然发现了)
    爬取全部的校园新闻
    理解爬虫原理
  • 原文地址:https://www.cnblogs.com/lklk/p/8810277.html
Copyright © 2011-2022 走看看