斐波那契数列有一个封闭形式,可以通过生成函数获得。它是:
f_n = 1/sqrt(5) (phi^n-\psi^n)
有关术语的含义,请参阅上面的链接或此处。
但是,here 讨论了这种封闭形式在实践中并未真正使用,因为当 n 变为大约 100 或更大时,它开始产生错误的答案。
但是在答案here中,似乎采用的方法之一是快速矩阵求幂,它可以用来在 O(log(n)) 时间内非常有效地获得第 n 个斐波那契数。
但是,封闭式表达式涉及一堆 n 次方项。因此,您可以通过快速求幂来计算所有这些项,并以这种方式有效地获得结果。为什么对矩阵进行快速求幂比对封闭式表达式中显示的标量进行快速求幂更好?此外,寻找如何有效地对矩阵进行快速求幂,公认的答案here建议我们转换为对角形式并无论如何在标量上进行。
接下来的问题是 - 如果矩阵的快速求幂适合在 O(log(n)) 时间内计算第 n 个斐波那契数,那么当涉及标量的快速求幂时,为什么封闭形式不是一个好方法呢?
在计算斐波那契数的“封闭式”公式中,您需要对无理数进行n次幂,这意味着您必须接受仅使用近似值(通常是双精度浮点运算),因此结果不准确对于大量。
相反,在计算斐波那契数的“矩阵幂”公式中,您要计算的矩阵n次方是一个整数矩阵,因此您可以使用“big int”进行整数计算而不会损失精度用于使用任意大整数进行算术运算的库(或者如果您使用像 Python 这样的语言,“大整数”是默认值)。
所以区别在于,你不能用无理数进行精确算术运算,但可以用整数进行精确算术运算。
请注意,这里的“实践”指的是竞争性编程(实际上,你基本上永远不想计算大量的斐波那契数)。因此,第一个原因是计算斐波那契数的正常方法输入速度更快,不会出现任何错误,并且代码更少。另外,对于小数字来说,它比奇特的方法更快。
当涉及到大数时,如果不关心精度,快速矩阵乘法是 O(log(n))。然而,在竞争性编程中,我们几乎总是关心精度并希望得到正确的答案。为此,我们需要提高数字的精度。 n 越大,所需的精度就越高。我不知道确切的公式,但我想由于所需的精度增加,仅需要 O(log n) 次乘法的矩阵乘法将需要 O(log n) 位精度,因此时间复杂度将实际上最终会有些糟糕(也许是 O(log^3 n) ?)。更不用说,编码更加困难并且速度非常慢,因为您要乘以任意精度的数字。