在分析我编写的一些代码时,我已经为它的运行时间提出了以下递归方程式 -
T(n)= n * T(n-1)+ n! + O(n ^ 2)。
最初,我假设O((n + 1)!)= O(n!),因此我解决了这个等式 -
T(n)= n! + O(n!)+ O(n ^ 3)= O(n!)
推理即使每次递归都会产生另一个n! (而不是(n-1)!,(n-2)!等),它仍然只能达到n * n! =(n + 1)! = O(n!)。最后一个参数是由于平方和。
但是,在考虑了一些之后,我不确定我的假设O((n + 1)!)= O(n!)是正确的,事实上,我很确定它不是
如果我认为我做出了错误的假设是正确的,我不确定如何实际解决上述递归方程,因为没有因子总和的公式......
非常感谢任何指导。
谢谢!!!
答案 0 :(得分:1)
由于您正在查看运行时,我认为O(n^2)
意味着该术语的操作数。根据该假设,n!
可以在O(n)
时间(1*2*3*...*n
)内计算。因此,与O(n^2)
术语相比,它可以被删除。然后在大约O((n-1)^ 2)时间内计算T(n-1)
,其大致为O(n ^ 2)。把它们放在一起你就有了一些在
O(n^2) + O(n) + O(n^2)
导致O(n^2)
算法。
答案 1 :(得分:0)
问题:
T(n) = n*T(n-1) + n! + O(n^2)
你是在混合两种不同类型的术语吗?最后+
遗留下来的所有内容都是指一个数字;加号的右边是O(n^2)
,它表示渐近增长的所有函数的类不比n^2
快。
假设你的意思是:
T(n) = n*T(n-1) + n! + n^2
然后 T(n) in O(n!)
因为n!
是总和中增长最快的术语。 (实际上,我不确定n*T(n-1)
生长速度不是很快 - 我的组合学不是那么强大。
扩展递归项,对 n*T(n-1)
的递归“调用”减少到某些函数,即 O((n!)!)
O(n!)
,所以作为一个整体的函数是O(n!)
。
完全扩展递归术语,这将是增长最快的术语。有关正确扩展的各种建议,请参阅注释。
答案 2 :(得分:0)
我明白了。
T(n)= n * T(n-1)+ n! + O(n ^ 2)= n * T(n-1)+ n! = n *((n-1)T(n-2)+(n-1)!)+ n! = n(n-1)T(n-2)+ 2n! = ... = n! = n * n! = O(n * n!)
答案 3 :(得分:0)
从我对源代码的理解来看:
https://github.com/python/cpython/blob/main/Modules/mathmodule.c#L1982-L2032
如果不是更快,它最多必须是 O(n)。