我正在尝试获取以下代码段的正确Big-O:
s = 0
for x in seq:
for y in seq:
s += x*y
for z in seq:
for w in seq:
s += x-w
根据我从(Python算法)得到这个例子的书,他们解释如下:
z循环运行一系列线性迭代,并且 它包含一个线性循环,所以总复杂度有二次方或Θ(n 2 )。 y环显然是Θ(n)。 这意味着x循环内的代码块是Θ(n + n 2 )。每个都执行整个块 循环x循环,运行n次。我们使用乘法规则得到Θ(n(n + n 2 ))=Θ(n 2 + n 3 ) =Θ(n 3 ),即立方。
我不明白的是:O(n(n + n 2 ))如何变成O(n 3 )?数学是否正确?
答案 0 :(得分:8)
这里完成的数学运算如下。当你说O(n(n + n 2 ))时,这相当于简单地分配O(n 2 + n 3 )整个产品中的n。
O(n 2 + n 3 )= O(n 3 )的原因来自big-O的正式定义符号,如下:
函数f(n)= O(g(n))iff存在常数n 0 和c使得对于任何n≥n 0 ,| f (N)| ≤c| g(n)|。
非正式地说,当n变得任意大时,f(n)从上面以g(n)的常数倍为界。
为了正式证明n 2 + n 3 是O(n 3 ),考虑任何n≥1。然后我们得到
n 2 + n 3 ≤n 3 + n 3 = 2n 3
所以我们得到n 2 + n 3 = O(n 3 ),n 0 = 1和c = 2.因此,我们有
O(n(n + n 2 ))= O(n 2 + n 3 )= O(n 3 )。
要真实地说明这一点,我们需要证明如果f(n)= O(g(n))和g(n)= O(h(n)),那么f(n)= O (H(N))。让我们来看看这个证明。如果f(n)= O(g(n)),则存在常数n 0 和c,使得对于n≥n 0 ,| f(n)| ≤c| g(n)|。类似地,由于g(n)= O(h(n)),有常数n' 0 ,c'使得对于n≥n' 0 ,g( n)≤c'| h(n)|。所以这意味着对于任何n≥max(c,c'),我们都有
| F(N)| ≤c| g(n)| ≤c| c'h(n)| = c x c'| h(n)|
所以f(n)= O(h(n))。
更准确一点 - 在这里描述的算法的情况下,作者说运行时是Θ(n 3 ),这比运行时更强是O(n 3 )。 Θ符号表示紧密的渐近界,意味着运行时以与n 3 相同的速率增长,而不仅仅是它从上面以n 3 的某个倍数为界。为了证明这一点,你还需要证明n 3 是O(n 2 + n 3 )。我会将此作为练习留给读者。 : - )
更一般地说,如果你有任何阶数为k的多项式,那么该多项式使用类似的参数为O(n k )。为了看到这一点,让P(n)=Σ i = 0 k (a i n i )。那么,对于任何n≥1,我们都有
Σ i = 0 k (a i n i )≤Σ i = 0 k (a i n k )=(Σ i = 0 k < / SUP>(一<子> I 子>))N ķ
所以P(n)= O(n k )。
希望这有帮助!
答案 1 :(得分:7)
O(n(n+n^2)) = O(n^2 + n^3)
由于n^3
字词在n^2
字词中占主导地位,n^2
字词可忽略不计,因此为O(n^3)
。
答案 2 :(得分:6)
n(n + n 2 )== n 2 + n 3
Big-O表示法仅关注主导项,因为n变为无穷大,因此整个算法被认为是Θ(n 3 )。
答案 3 :(得分:1)
由于z循环(O(n)+ O(n ^ 2) - > O(n ^ 2)),y循环可以打折 算了算术。 然后你留下了三个嵌套循环,它们遍历'seq'的全长,所以它是O(n ^ 3)