Algorithm N的大值矩阵求幂算法

Algorithm N的大值矩阵求幂算法,algorithm,matrix,fibonacci,Algorithm,Matrix,Fibonacci,我想计算非常大的值N的斐波那契函数,即复杂度为O(logN)的10^6。 这是我的代码,但它在30秒内给出了10^6的结果,这非常耗时。请帮助我指出错误。我必须以模10^9+7的形式给出输出 static BigInteger mod=new BigInteger("1000000007"); BigInteger fibo(long n){ BigInteger F[][] = {{BigInteger.ONE,BigInteger.ONE},{BigInteger.ONE,BigI

我想计算非常大的值N的斐波那契函数,即复杂度为O(logN)的10^6。 这是我的代码,但它在30秒内给出了10^6的结果,这非常耗时。请帮助我指出错误。我必须以模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;
}

我使用您的代码获得了一个更合理的时间(尽管仍然非常慢)
real 0m2.335s

计算斐波那契数的算法还可以(有一些调整可以在一定程度上提高速度,但没有什么戏剧性的变化),因此问题是对大的
biginger
s的运算速度很慢,
F(10^6)
有近700000位

由于您希望计算余数模
mod=10^9+7
,并且
(mod-1)^2
适合
long
,因此使用
long
s而不是
biginger
s,可以在每个步骤中计算余数,从而获得更快的实现。直接转录

public class FiboL {

    static final long mod = 1000000007L;

     static long fibo(long n){

          long F[][] = {{1,1},{1,0}};

          if(n == 0)
            return 0;
          power(F, n-1);
            return F[0][0]; //.mod(mod);
        }

    static void power(long F[][], long n){

          if( n == 0 || n == 1)
              return;
          long M[][] = {{1,1},{1,0}};

          power(F, n/2);
          multiply(F, F);

          if( n%2 != 0 )
             multiply(F, M);
        }

    static void multiply(long F[][], long M[][]){

          long x =  (F[0][0] * M[0][0]) % mod + (F[0][1] * M[1][0]) % mod;
          long y =  (F[0][0] * M[0][1]) % mod + (F[0][1] * M[1][1]) % mod;
          long z =  (F[1][0] * M[0][0]) % mod + (F[1][1] * M[1][0]) % mod;
          long w =  (F[1][0] * M[0][1]) % mod + (F[1][1] * M[1][1]) % mod;

          F[0][0] = x % mod;
          F[0][1] = y % mod;
          F[1][0] = z % mod;
          F[1][1] = w % mod;
    }
    public static void main(String[] args) {
        System.out.println(fibo(1000000));
    }
}
real 0m0.083s中运行

使用以下各项:

F2n−1=Fn2+Fn−十二,

F2n=(2Fn−1+Fn)Fn

连同。例如,在Python中,可以使用decorator,如下所示:

从functools导入lru\U缓存
@lru_缓存(最大大小=无)
def fibonacci_模(n,m):
“”“计算模为m的第n个斐波那契数。”

如果你不能用64位整数而不是大整数做任何事情?不管怎么说,你在做模~1e9。值得注意的是,第n个斐波那契数有一个闭式表达式,可以精确计算任意n,
>>> from timeit import timeit
>>> timeit(lambda:fibonacci_modulo(10 ** 6, 10 ** 9 + 7), number=1)
0.000083282997366