不同种子的 O log(N) 中的斐波那契数列
Fibonacci in O log(N) with different seeds
此代码是从数学 wiki 中的伪代码翻译而来,用于解决 O log(n) 中的斐波那契问题。
当你想改变斐波那契 (1,0) 的种子时,问题就来了,这是最数学的问题,也是比编程更复杂的问题...
所以...将 A 和 B 放在哪里开始,例如种子 5,6?
感谢您的宝贵时间!
public static BigInteger Fib(int A, int B, int n)
{
if (n <= 0)
return 0;
n = n - 1;
_auxOne = 0;
_auxTwo = 1;
Matrix[0, 0] = _auxTwo; //a
Matrix[0, 1] = _auxOne; //b
Matrix[1, 0] = _auxOne; //c
Matrix[1, 1] = _auxTwo + _auxOne; //d
while (n > 0)
{
if (n % 2 != 0)
{
_auxOne = Matrix[1, 1] * Matrix[0, 1] + Matrix[1, 0] * Matrix[0, 0]; //(db+ca)
_auxTwo = Matrix[1, 1] * (Matrix[0, 1] + Matrix[0, 0]) + Matrix[1, 0] * Matrix[0, 1]; //(d(b+a)+cb)
Matrix[0, 0] = _auxOne;
Matrix[0, 1] = _auxTwo;
}
_auxOne = BigInteger.Pow(Matrix[1, 0], 2) + BigInteger.Pow(Matrix[1, 1], 2); //(c²+d²)
_auxTwo = Matrix[1, 1] * (2 * Matrix[1, 0] + Matrix[1, 1]); //(d*(2c+d))
Matrix[1, 0] = _auxOne;
Matrix[1, 1] = _auxTwo;
n = n / 2;
}
return Matrix[0, 0] + Matrix[0, 1];
}
好的,正如我之前在评论中所写的,实际上我们只需要 "normal" 斐波纳契矩阵乘以我们修改后的带种子矩阵,所以我的代码的一部分是现有 OP 代码的突变。我只做了 2 处更改——我需要整个矩阵而不是计算结果,并将 BigInteger 替换为 Int64 以避免额外的引用。
public static Int64 PerversationFib(int A, int B, int n)
{
if (n <= 0)
return 0;
if (n == 1)
return A + B;
else
{
Int64[,] myMatrix = new Int64[2, 2] { { A , B }, { B, A+B} };
Int64[,] fibMatrix = Fib(n);
//a11·b11 + a12·b21
return myMatrix[0, 0] * fibMatrix[0, 0] + myMatrix[0, 1] * fibMatrix[1, 0];
}
}
public static Int64[,] Fib( int n)
{
if (n <= 0)
return null;
//n = n - 1;
Int64 _auxOne = 0, _auxTwo = 1;
Int64[,] Matrix = new Int64[2, 2];
Matrix[0, 0] = _auxTwo; //a
Matrix[0, 1] = _auxOne; //b
Matrix[1, 0] = _auxOne; //c
Matrix[1, 1] = _auxTwo + _auxOne; //d
while (n > 0)
{
if (n % 2 != 0)
{
_auxOne = Matrix[1, 1] * Matrix[0, 1] + Matrix[1, 0] * Matrix[0, 0]; //(db+ca)
_auxTwo = Matrix[1, 1] * (Matrix[0, 1] + Matrix[0, 0]) + Matrix[1, 0] * Matrix[0, 1]; //(d(b+a)+cb)
Matrix[0, 0] = _auxOne;
Matrix[0, 1] = _auxTwo;
}
_auxOne = Matrix[1, 0] * Matrix[1, 0] +Matrix[1, 1]*Matrix[1,1]; //(c²+d²)
_auxTwo = Matrix[1, 1] * (2 * Matrix[1, 0] + Matrix[1, 1]); //(d*(2c+d))
Matrix[1, 0] = _auxOne;
Matrix[1, 1] = _auxTwo;
n = n / 2;
}
Matrix[1, 0] = Matrix[0, 1];
Matrix[1, 1] = Matrix[0, 0]+Matrix[0,1] ;
return Matrix;
}
此代码是从数学 wiki 中的伪代码翻译而来,用于解决 O log(n) 中的斐波那契问题。
当你想改变斐波那契 (1,0) 的种子时,问题就来了,这是最数学的问题,也是比编程更复杂的问题...
所以...将 A 和 B 放在哪里开始,例如种子 5,6?
感谢您的宝贵时间!
public static BigInteger Fib(int A, int B, int n)
{
if (n <= 0)
return 0;
n = n - 1;
_auxOne = 0;
_auxTwo = 1;
Matrix[0, 0] = _auxTwo; //a
Matrix[0, 1] = _auxOne; //b
Matrix[1, 0] = _auxOne; //c
Matrix[1, 1] = _auxTwo + _auxOne; //d
while (n > 0)
{
if (n % 2 != 0)
{
_auxOne = Matrix[1, 1] * Matrix[0, 1] + Matrix[1, 0] * Matrix[0, 0]; //(db+ca)
_auxTwo = Matrix[1, 1] * (Matrix[0, 1] + Matrix[0, 0]) + Matrix[1, 0] * Matrix[0, 1]; //(d(b+a)+cb)
Matrix[0, 0] = _auxOne;
Matrix[0, 1] = _auxTwo;
}
_auxOne = BigInteger.Pow(Matrix[1, 0], 2) + BigInteger.Pow(Matrix[1, 1], 2); //(c²+d²)
_auxTwo = Matrix[1, 1] * (2 * Matrix[1, 0] + Matrix[1, 1]); //(d*(2c+d))
Matrix[1, 0] = _auxOne;
Matrix[1, 1] = _auxTwo;
n = n / 2;
}
return Matrix[0, 0] + Matrix[0, 1];
}
好的,正如我之前在评论中所写的,实际上我们只需要 "normal" 斐波纳契矩阵乘以我们修改后的带种子矩阵,所以我的代码的一部分是现有 OP 代码的突变。我只做了 2 处更改——我需要整个矩阵而不是计算结果,并将 BigInteger 替换为 Int64 以避免额外的引用。
public static Int64 PerversationFib(int A, int B, int n)
{
if (n <= 0)
return 0;
if (n == 1)
return A + B;
else
{
Int64[,] myMatrix = new Int64[2, 2] { { A , B }, { B, A+B} };
Int64[,] fibMatrix = Fib(n);
//a11·b11 + a12·b21
return myMatrix[0, 0] * fibMatrix[0, 0] + myMatrix[0, 1] * fibMatrix[1, 0];
}
}
public static Int64[,] Fib( int n)
{
if (n <= 0)
return null;
//n = n - 1;
Int64 _auxOne = 0, _auxTwo = 1;
Int64[,] Matrix = new Int64[2, 2];
Matrix[0, 0] = _auxTwo; //a
Matrix[0, 1] = _auxOne; //b
Matrix[1, 0] = _auxOne; //c
Matrix[1, 1] = _auxTwo + _auxOne; //d
while (n > 0)
{
if (n % 2 != 0)
{
_auxOne = Matrix[1, 1] * Matrix[0, 1] + Matrix[1, 0] * Matrix[0, 0]; //(db+ca)
_auxTwo = Matrix[1, 1] * (Matrix[0, 1] + Matrix[0, 0]) + Matrix[1, 0] * Matrix[0, 1]; //(d(b+a)+cb)
Matrix[0, 0] = _auxOne;
Matrix[0, 1] = _auxTwo;
}
_auxOne = Matrix[1, 0] * Matrix[1, 0] +Matrix[1, 1]*Matrix[1,1]; //(c²+d²)
_auxTwo = Matrix[1, 1] * (2 * Matrix[1, 0] + Matrix[1, 1]); //(d*(2c+d))
Matrix[1, 0] = _auxOne;
Matrix[1, 1] = _auxTwo;
n = n / 2;
}
Matrix[1, 0] = Matrix[0, 1];
Matrix[1, 1] = Matrix[0, 0]+Matrix[0,1] ;
return Matrix;
}