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