矩阵乘法求斐波那契数列

斐波那契数列的求解方法

方法一:递归
def fib(n)
    if n==1 or n==2
       1
    else
        fib(n-1)+fib(n-2)
    end
end
方法二:循环
def fib(n)
    if n==1 or n==2
        1
    else
        fx,fy,index = 1,1,3
        while index<= n
            fx,fy,index = fy,fx+fy,index+1
        end
        fy
    end
end

方法三:矩阵乘法(参考 斐波那契数列 矩阵求法 优化 )

斐波那契数列的递推公式为:

f(1)=1,f(2)=2,f(n)=f(n-1)+f(n-2)(n>=3)

用矩阵表示为:
矩阵表示递推关系
进一步推导得:
矩阵表示递推关系

$arr = [
    [3524578,2178309,2178309,1346269], #基础矩阵的32次幂
    [1597,987,987,610],                              #基础矩阵的16次幂
    [34,21,21,13],                                       #基础矩阵的8次幂
    [5,3,3,2],                                               #基础矩阵的4次幂
    [2,1,1,1],                                               #基础矩阵的2次幂
    [1,1,1,0]                                                    #基础矩阵的1次幂
]
def fib(k)
    if k<3
     return 1
    else
        t00,t01,t10,t11 = 1,1,1,0
        a,b,c,d = t00,t01,t10,t11
        k = k-2
        while k>=32 do                    #对于大于等于32次幂的k转换成最多个32次幂的乘方
            a = t00*$arr[0][0]+t01*$arr[0][2]
            b = t00*$arr[0][1]+t01*$arr[0][3]
            c = t10*$arr[0][0]+t11*$arr[0][2]
            d = t10*$arr[0][1]+t11*$arr[0][3]
            t00,t01,t10,t11 = a,b,c,d
            k = k-32
        end
        mi = 4
        while mi>=0 do                     #对于小于32次幂的k由大到小转换成最多个16次幂、8次幂、4次幂、2次幂、1次幂的乘方
            if k>=2**mi
                a = t00*$arr[5-mi][0]+t01*$arr[5-mi][2]
                b = t00*$arr[5-mi][1]+t01*$arr[5-mi][3]
                c = t10*$arr[5-mi][0]+t11*$arr[5-mi][2]
                d = t10*$arr[5-mi][1]+t11*$arr[5-mi][3]
                t00,t01,t10,t11 = a,b,c,d
                k = k-2**mi
            end
            mi = mi-1
        end
        return t00
    end
end

但是此代码的命中率并不是很高,这里给出我个人的代码(来自我的一篇博文:每日一道算法题004——再探矩阵算法求解斐波那契数列

def getArr(k)#把k分成最少个2的n次幂的形式  如:234=2××7+2××6+2××5+2××3+2××1 记录下[7,6,5,3,1]
        temp = []
        while k!=0
            mi = Math.log(k,2).to_i
            temp<<mi
            k = k-2**mi
        end
        temp
end
def fib(k)
    if k==0
        return 0
    end
    if k<3
     return 1
    else
        k = k-1
        arr = getArr k
        t00,t01,t10,t11 = 1,1,1,0 #基础矩阵
        a,b,c,d = t00,t01,t10,t11
        fa,fb,fc,fd = 1,0,0,1 #初始矩阵(处理getArr==[0])也作为最终结果的矩阵
        max = Math.log(k,2).to_i
        bgn = 0
        while bgn<=max  #计算基础矩阵的n次幂
            if arr.include?bgn #如果当前的bgn在getArr[k]中,则直接将其纳入最终结果的计算
                ta = fa*t00+fb*t10
                tb = fa*t01+fb*t11
                tc = fc*t00+fd*t10
                td = fc*t01+fd*t11
                fa,fb,fc,fd = ta,tb,tc,td
            end
            a = t00*t00+t01*t10
            b = t00*t01+t01*t11
            c = t10*t00+t11*t10
            d = t10*t01+t11*t11
            t00,t01,t10,t11 = a,b,c,d
            bgn = bgn+1
        end
        return fa
    end
end
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值