Help calculating Big O

谁说我不能喝 提交于 2019-12-08 02:47:28

问题


I am trying to get the correct Big-O of the following code snippet:

s = 0
for x in seq:
  for y in seq:
    s += x*y
  for z in seq:
    for w in seq:
      s += x-w

According to the book I got this example from (Python Algorithms), they explain it like this:

The z-loop is run for a linear number of iterations, and it contains a linear loop, so the total complexity there is quadratic, or Θ(n2). The y-loop is clearly Θ(n). This means that the code block inside the x-loop is Θ(n + n2). This entire block is executed for each round of the x-loop, which is run n times. We use our multiplication rule and get Θ(n(n + n2)) = Θ(n2 + n3) = Θ(n3), that is, cubic.

What I don't understand is: how could O(n(n+n2)) become O(n3)? Is the math correct?


回答1:


The math being done here is as follows. When you say O(n(n + n2)), that's equivalent to saying O(n2 + n3) by simply distributing the n throughout the product.

The reason that O(n2 + n3) = O(n3) follows from the formal definition of big-O notation, which is as follows:

A function f(n) = O(g(n)) iff there exists constants n0 and c such that for any n ≥ n0, |f(n)| ≤ c|g(n)|.

Informally, this says that as n gets arbitrary large, f(n) is bounded from above by a constant multiple of g(n).

To formally prove that n2 + n3 is O(n3), consider any n ≥ 1. Then we have that

n2 + n3 ≤ n3 + n3 = 2n3

So we have that n2 + n3 = O(n3), with n0 = 1 and c = 2. Consequently, we have that

O(n(n + n2)) = O(n2 + n3) = O(n3).

To be truly formal about this, we would need to show that if f(n) = O(g(n)) and g(n) = O(h(n)), then f(n) = O(h(n)). Let's walk through a proof of this. If f(n) = O(g(n)), there are constants n0 and c such that for n ≥ n0, |f(n)| ≤ c|g(n)|. Similarly, since g(n) = O(h(n)), there are constants n'0, c' such that for n ≥ n'0, g(n) ≤ c'|h(n)|. So this means that for any n ≥ max(c, c'), we have that

|f(n)| ≤ c|g(n)| ≤ c|c'h(n)| = c x c' |h(n)|

And so f(n) = O(h(n)).

To be a bit more precise - in the case of the algorithm described here, the authors are saying that the runtime is Θ(n3), which is a stronger result than saying that the runtime is O(n3). Θ notation indicates a tight asymptotic bound, meaning that the runtime grows at the same rate as n3, not just that it is bounded from above by some multiple of n3. To prove this, you would also need to show that n3 is O(n2 + n3). I'll leave this as an exercise to the reader. :-)

More generally, if you have any polynomial of order k, that polynomial is O(nk) using a similar argument. To see this, let P(n) = ∑i=0k(aini). Then, for any n ≥ 1, we have that

i=0k(aini) ≤ ∑i=0k(aink) = (∑i=0k(ai))nk

so P(n) = O(nk).

Hope this helps!




回答2:


O(n(n+n^2)) = O(n^2 + n^3)

Since the n^3 term dominates the n^2 term, the n^2 term is negligible and thus it is O(n^3).




回答3:


n(n+n2) == n2 + n3

Big-O notation only cares about the dominant term as n goes to infinity, so the whole algorithm is thought of as Θ(n3).




回答4:


The y loop can be discounted because of the z loop (O(n) + O(n^2) -> O(n^2)) Forget the arithmetic. Then you're left with three nested loops that all iterate over the full length of 'seq', so it's O(n^3)



来源:https://stackoverflow.com/questions/7522463/help-calculating-big-o

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!