Algorithms

Foundations: correctness and asymptotic analysis

6 / 454
Contents

Contents

Algorithms

0 of 454 complete

13 min read

O, Omega and Theta, defined properly

Three statements about how one function compares with another once n is large enough, each with two constants you have to be able to produce.

Exact operation counts are unwieldy and, worse, dishonest about their own precision: the 5 in 5n+35n+3 came from a decision about whether an addition and an assignment are one action or two. What is worth keeping is the shape. The tool for keeping only the shape is asymptotic notation, and it is built on a comparison you can watch happening.

Take an exact count, f(n)=3n2+5n+100f(n) = 3n^2 + 5n + 100, and a candidate shape, g(n)=n2g(n) = n^2. Multiply the shape by 4 and print both columns.

Where 4n squared overtakes for goodPython

Change the 4 to a 3 and run it again. Now find the smallest whole number multiplier that ever works.

For small nn the 100 dominates and ff is far ahead. At n=13n = 13, f(13)=507+65+100=672f(13) = 507 + 65 + 100 = 672 and 4×169=6764 \times 169 = 676, so the comparison flips, and it never flips back: the gap between 4n24n^2 and 3n23n^2 grows like n2n^2 while 5n+1005n + 100 grows like nn.

Two numbers came out of that: the multiplier 4, and the point 13 after which the claim holds. Those two numbers are the whole content of the definition.

Big O

Read the following as: ff grows no faster than gg, apart from a constant factor, once nn is large enough.

f(n)=O(g(n))means∃ c>0, ∃ n0>0  such that  0≤f(n)≤c g(n)  for all n≥n0f(n) = O(g(n)) \quad\text{means}\quad \exists\, c > 0,\ \exists\, n_0 > 0 \ \text{ such that } \ 0 \le f(n) \le c\,g(n) \ \text{ for all } n \ge n_0
The symbol for there exists is a backwards E. Both c and n0 are fixed numbers, chosen once and never allowed to depend on n.

To claim f(n)=O(g(n))f(n) = O(g(n)) you must be able to produce a cc and an n0n_0 that work. The run above produced them: c=4c = 4 and n0=13n_0 = 13. That is a complete proof that 3n2+5n+100=O(n2)3n^2 + 5n + 100 = O(n^2), provided you also check the inequality never fails again after 13, which the algebra does.

Here is that check written out. The claim 3n2+5n+100≤4n23n^2 + 5n + 100 \le 4n^2 rearranges to n2−5n−100≥0n^2 - 5n - 100 \ge 0. The left side is increasing for n≥3n \ge 3, since raising nn by 1 adds 2n−42n - 4, which is positive there. At n=13n = 13 it equals 169−65−100=4169 - 65 - 100 = 4, which is at least 0. Being non-negative at 13 and increasing after it, it stays non-negative for every n≥13n \ge 13.

Choosing c, and finding where it starts working
f(n)=3n2+5n+100against4 n2f(n) = 3n^2 + 5n + 100 \qquad\text{against}\qquad 4\,n^2
-1556.092570.916697.9210824.9214951.92115.7530.545.2560
c times n squared
f(n)f(n)
672
c n2c\,n^2
676
c n2−f(n)c\,n^2 - f(n), which must be at least 0
4

Set cc to 3 and drag nn as far right as it goes: the difference never turns positive. Set cc to 4 and find the smallest nn where it does.

Omega and Theta

Big O is an upper bound and says nothing about how small ff might be. The mirror image gives a lower bound.

f(n)=Ω(g(n))means∃ c>0, ∃ n0>0  such that  0≤c g(n)≤f(n)  for all n≥n0f(n) = \Omega(g(n)) \quad\text{means}\quad \exists\, c > 0,\ \exists\, n_0 > 0 \ \text{ such that } \ 0 \le c\,g(n) \le f(n) \ \text{ for all } n \ge n_0
Omega is the capital Greek letter. Read it as: f grows at least as fast as g, apart from a constant factor.

For the same ff, take c=3c = 3 and n0=1n_0 = 1. Then c g(n)=3n2c\,g(n) = 3n^2 and f(n)−3n2=5n+100f(n) - 3n^2 = 5n + 100, which is positive for every n≥1n \ge 1. So 3n2+5n+100=Ω(n2)3n^2 + 5n + 100 = \Omega(n^2).

f(n)=Θ(g(n))means∃ c1,c2>0, ∃ n0>0  with  0≤c1g(n)≤f(n)≤c2g(n)  for all n≥n0f(n) = \Theta(g(n)) \quad\text{means}\quad \exists\, c_1, c_2 > 0,\ \exists\, n_0 > 0 \ \text{ with } \ 0 \le c_1 g(n) \le f(n) \le c_2 g(n) \ \text{ for all } n \ge n_0
Theta is both bounds at once: f is squeezed between two constant multiples of g.

Combining the two results above with c1=3c_1 = 3, c2=4c_2 = 4 and n0=13n_0 = 13 gives 3n2+5n+100=Θ(n2)3n^2 + 5n + 100 = \Theta(n^2). Theta is the strongest of the three and the one to aim for, because it pins the growth rather than bounding it on one side.

It is equally important to be able to show a claim is false. Suppose someone asserts n2=O(n)n^2 = O(n). By the definition there would be fixed cc and n0n_0 with n2≤c nn^2 \le c\,n for every n≥n0n \ge n_0. Divide both sides by nn, which is positive, to get n≤cn \le c for every n≥n0n \ge n_0. Now take nn to be whichever of n0n_0 and c+1c + 1 is larger. That nn is at least n0n_0, so the inequality must apply to it, yet n≥c+1>cn \ge c + 1 > c. The two cannot both hold, so no such pair exists and the claim is false.

Little-o and little-omega

Big O allows ff and gg to grow at the same rate; n2=O(n2)n^2 = O(n^2) is true. The lower-case versions demand a strict gap by changing one quantifier from there exists a c to for every c.

f(n)=o(g(n))means∀ c>0, ∃ n0>0  such that  0≤f(n)<c g(n)  for all n≥n0f(n) = o(g(n)) \quad\text{means}\quad \forall\, c > 0,\ \exists\, n_0 > 0 \ \text{ such that } \ 0 \le f(n) < c\,g(n) \ \text{ for all } n \ge n_0
The symbol for for all is an upside-down A. Now n0 is allowed to depend on c, and usually must.

Here is the full argument that 5n=o(n2)5n = o(n^2). Fix any c>0c > 0, however small. The requirement 5n<c n25n < c\,n^2 divides through by nn to give 5<c n5 < c\,n, that is n>5/cn > 5/c. So take n0n_0 to be any whole number larger than 5/c5/c; for c=0.001c = 0.001 that is n0=5001n_0 = 5001. Since a suitable n0n_0 exists for every cc, the claim holds.

That is exactly what fails for n2n^2 against n2n^2: with c=0.5c = 0.5 the requirement n2<0.5n2n^2 < 0.5n^2 is false for every nn, so n2n^2 is not o(n2)o(n^2).

Little-omega, written with the lower-case Greek letter ω\omega, is the mirror image of little-o. It says ff grows strictly faster than gg: whatever multiple of gg you name, however large, ff is past it from some point on and stays past it.

f(n)=ω(g(n))means∀ c>0, ∃ n0>0  such that  0≤c g(n)<f(n)  for all n≥n0f(n) = \omega(g(n)) \quad\text{means}\quad \forall\, c > 0,\ \exists\, n_0 > 0 \ \text{ such that } \ 0 \le c\,g(n) < f(n) \ \text{ for all } n \ge n_0
Little-omega. As with little-o the c comes first, so n0 is allowed to depend on it, and usually must.

Here is the full argument that n2=ω(n)n^2 = \omega(n), in the same shape as the little-o one. Fix any c>0c > 0, however large. The requirement is c n<n2c\,n < n^2. Divide both sides by nn, which is positive for the values in question, to get c<nc < n. So any n0n_0 that is itself larger than cc will do.

To name one, write ⌈c⌉\lceil c \rceil for the ceiling of cc, meaning cc rounded up to the nearest whole number, so ⌈2.3⌉=3\lceil 2.3 \rceil = 3 and ⌈4⌉=4\lceil 4 \rceil = 4. Then n0=⌈c⌉+1n_0 = \lceil c \rceil + 1 is a whole number strictly greater than cc, and every n≥n0n \ge n_0 is greater than cc as well. With c=1000c = 1000 that gives n0=1001n_0 = 1001, and indeed 1000×1001=10010001000 \times 1001 = 1001000 while 10012=10020011001^2 = 1002001, which is larger. A suitable n0n_0 exists for every cc, so the claim holds.

And n2n^2 is not ω(n2)\omega(n^2), for the same reason it is not o(n2)o(n^2): with c=2c = 2 the requirement 2n2<n22n^2 < n^2 is false for every nn. Little-omega, like little-o, refuses two functions that grow at the same rate.

NotationIn wordsLike
f = O(g)f grows no faster than gless than or equal to
f = Omega(g)f grows at least as fast as ggreater than or equal to
f = Theta(g)f and g grow at the same rateequal to
f = o(g)f grows strictly slower than gstrictly less than
f = omega(g)f grows strictly faster than gstrictly greater than
The five relations, with the arithmetic comparison each one echoes.

When both functions are positive and the ratio settles down, a limit gives the answer faster than hunting for constants. If f(n)/g(n)f(n)/g(n) tends to a finite number that is not 0, then f=Θ(g)f = \Theta(g). If it tends to 0, then f=o(g)f = o(g), and in particular f=O(g)f = O(g). If it grows without bound, then f=ω(g)f = \omega(g), and in particular f=Ω(g)f = \Omega(g). The ratio (3n2+5n+100)/n2=3+5/n+100/n2(3n^2+5n+100)/n^2 = 3 + 5/n + 100/n^2 tends to 3, which confirms the Theta result in one line.

Is 4n + 7 = O(n squared)? And is it a useful thing to say?

It is true. Take c = 1 and n0 = 6: for n at least 6, n squared is at least 6n, which is at least 4n + 7 once n is at least 6 (since 6n - 4n = 2n is at least 12, and 12 is greater than 7). It is also a weak statement, because 4n + 7 = O(n) is true as well and rules out much more. O is an upper bound, so any looser bound above a true one is also true. When someone quotes a bound, the interesting question is whether it is tight, which is what Theta asserts.

Check yourself

Which of these is false?

All lessons in Algorithms