矩阵幂算法对于N大值矩阵、算法

由网友(这个夏天,就要说再见)分享简介:我要计算N个即非常大的价值的斐波那契数。 10 ^ 6与O(logN)的复杂性。这是我的code,但它给出结果为10 ^ 6 30秒,这是非常时期consuming.Help我指出了犯错误给输出模10 ^ 9 + 7。静态的BigInteger MOD =新的BigInteger(1000000007);BigInt...

我要计算N个即非常大的价值的斐波那契数。 10 ^ 6与O(logN)的复杂性。 这是我的code,但它给出结果为10 ^ 6 30秒,这是非常时期consuming.Help我指出了犯错误给输出模10 ^ 9 + 7。

 静态的BigInteger MOD =新的BigInteger(1000000007);

BigInteger的FIBO(N久){
    的BigInteger F [] [] = {{BigInteger.ONE,BigInteger.ONE},{BigInteger.ONE,BigInteger.ZERO}};
    如果(N == 0)
        返回BigInteger.ZERO;
    功率(F,N-1);
    返回F [0] [0]的.mod(MOD);
}

无效功率(BigInteger的F [] [],N久){
    如果(N == 0 ||ñ== 1)
        返回;
    的BigInteger M [] [] = {{BigInteger.ONE,BigInteger.ONE},{BigInteger.ONE,BigInteger.ZERO}};
    功率(F,N / 2);
    乘(F,F);
    如果(正%2!= 0)
        乘(F,M);
  }

无效乘法(BigInteger的F [] [],BigInteger的M [] []){
    的BigInteger X =(F [0] [0] .multiply(M [0] [0]))添加(F [0] [1] .multiply(M [1] [0]));
    的BigInteger Y = F [0] [0] .multiply(M [0] [1])添加(F [0] [1] .multiply(M [1] [1]));
    的BigInteger Z = F [1] [0] .multiply(M [0] [0])添加(F [1] [1] .multiply(M [1] [0]));
    的BigInteger瓦特= F [1] [0] .multiply(M [0] [1])添加(F [1] [1] .multiply(M [1] [1]));

    F [0] [0] = X;
    F [0] [1] = Y;
    F [1] [0] = Z;
    F [1] [1] =瓦特;
}
 

解决方案

使用这些复发:

  

F 的 2 N 1 = F 的 N 2 + F 的 N 1 2

     

F 的 2 N =(2 F N - 1 + F 的 N )的 F 的 N

与记忆化。例如,在Python中,你可以使用 @memoized 从 Python的装饰库的这样的装饰:

@memoized 高清fibonacci_modulo(N,M):     计算的第n个Fibonacci数模M     如果n&其中; = 3:         返回(0,1,1,2)[n]的%间     ELIF N%2 == 0:         A = fibonacci_modulo(N // 2 - 1,M)         B = fibonacci_modulo(N // 2,M)         返回((2 * A + B)* B)%间     其他:         A = fibonacci_modulo(N // 2,M)         B = fibonacci_modulo(正// 2 + 1,M)         回报(A * A + B * B)%M 计算下面矩阵的n次幂

该计算10 6 个Fibonacci数(模10 9 + 7),在不到一毫秒:

 >>>从timeit进口timeit
>>> timeit(拉姆达:fibonacci_modulo(10 ** 6,10 ** 9 + 7),数量= 1)
0.0004661083221435547
 

I want to calculate the Fibonacci of very large value of N ie. 10^6 with a complexity of O(logN). Here is my code but it gives the result for 10^6 in 30 seconds which is very time consuming.Help me point out the mistake.I have to give the output in modulo 10^9+7.

static BigInteger mod=new BigInteger("1000000007");

BigInteger fibo(long n){
    BigInteger F[][] = {{BigInteger.ONE,BigInteger.ONE},{BigInteger.ONE,BigInteger.ZERO}};
    if(n == 0)
        return BigInteger.ZERO;
    power(F, n-1);
    return F[0][0].mod(mod);
}

void power(BigInteger F[][], long n) {
    if( n == 0 || n == 1)
        return;
    BigInteger M[][] = {{BigInteger.ONE,BigInteger.ONE},{BigInteger.ONE,BigInteger.ZERO}};
    power(F, n/2);
    multiply(F, F);
    if( n%2 != 0 )
        multiply(F, M);
  }

void multiply(BigInteger F[][], BigInteger M[][]){
    BigInteger x =  (F[0][0].multiply(M[0][0])).add(F[0][1].multiply(M[1][0])) ;
    BigInteger y =  F[0][0].multiply(M[0][1]).add(F[0][1].multiply(M[1][1])) ;
    BigInteger z =  F[1][0].multiply(M[0][0]).add( F[1][1].multiply(M[1][0]));
    BigInteger w =  F[1][0].multiply(M[0][1]).add(F[1][1].multiply(M[1][1]));

    F[0][0] = x;
    F[0][1] = y;
    F[1][0] = z;
    F[1][1] = w;
}

解决方案

Use these recurrences:

F2n−1 = Fn2 + Fn−12

F2n = (2Fn−1 + Fn) Fn

together with memoization. For example, in Python you could use the @memoized decorator from the Python Decorator Library like this:

@memoized
def fibonacci_modulo(n, m):
    """Compute the nth Fibonacci number modulo m."""
    if n <= 3:
        return (0, 1, 1, 2)[n] % m
    elif n % 2 == 0:
        a = fibonacci_modulo(n // 2 - 1, m)
        b = fibonacci_modulo(n // 2, m)
        return ((2 * a + b) * b) % m
    else:
        a = fibonacci_modulo(n // 2, m)
        b = fibonacci_modulo(n // 2 + 1, m)
        return (a * a + b * b) % m

this computes the 106th Fibonacci number (modulo 109 + 7) in less than a millisecond:

>>> from timeit import timeit
>>> timeit(lambda:fibonacci_modulo(10 ** 6, 10 ** 9 + 7), number=1)
0.0004661083221435547

阅读全文

相关推荐

最新文章