我想计算一个序列的大数,这由下面的递归描述:
x(0,w)=1
x(1,w)=w
x(n+1,w)= 2*w*x(n,w)-x(n-1)
我的项目已经用Java实现了,就是我需要一个解决这个问题的Java解决方案。
目的是计算x(k,w),其中w之前已经计算过,k,w是BigIntegers。由于k和w是如此之大的数字,计算需要很多时间。
我已经使用BigIntegers的ArrayList实现了一个解决方案,该解决方案仅适用于小数字。然后,因为我只需要x(k,w)而不是序列的所有数字,我可以提出以下解决方案,这仍然有很多要慢:
BigInteger TWO = new BigInteger("2");
BigInteger x_2 = BigInteger.ONE;
BigInteger x_1 = w;
BigInteger x_0 = BigInteger.ZERO;
for(BigInteger i = BigInteger.ONE; i.compareTo(k) < 0; i = i.add(BigInteger.ONE)) {
x_0 = w.multiply(TWO).multiply(x_1).subtract(x_2);
x_2 = x_1;
x_1 = x_0;
}
return x_0;
您知道如何提高该算法的速度吗?
一个想法是计算序列的显式函数,该函数应为
x(n,w)=1/2*((w+sqrt(w^2-1)^n+(w-sqrt(w^2-1)^n)
但Java没有提供实现的方法来计算BigInteger / BigDecimal对象的功率或平方根。人们可以在实际上避免计算平方根,因为它们稍后会被取消。但是,必须计算二项式系数。因此,我不确定应该采用哪种方法。
你能告诉我,你认为哪种(最确切地)计算x(k,w)是最快最有效的方法吗?
答案 0 :(得分:3)
n
- th项是前两项的线性组合,系数对于所有n
都相同,因此您可以找到矩阵的n
次幂[[2 * w, -1], [1, 0]]
并将其乘以向量[x_1, x_0]
。如果使用二进制矩阵求幂,则需要O(log n)
次乘法和加法。此解决方案仅使用整数,因此它绝对精确。