Running Time of Programslucifer
Running Time of Programslucifer
49
Course notes for csc 165 h
We can extend the idea, and imitate the decimal point (with a \binary point"?) from base 10:
(1011:101)2 = 19 58
How did we do that?2 Here are some questions:
How do you multiply two base 10 numbers?3 Work out 37 43.
How do you multiply two binary numbers?4
What does \right shifting" (eliminating the right-most digit) do in base 10?5
What does \right shifting" do in binary?6
What does the rightmost digit tell us in base 10? In binary?
Convert some numbers from decimal to binary notation. Try 57. We'd like to represent 57 by adding either
0 or 1 of each power of 2 that is no greater than 57. So 57 = 32 + 16 + 8 + 1 = (111001)2 . We can also ll
in the binary digits, systematically, from the bottom up, using the % operator from Python (the remainder
after division operator, at least for positive arguments):
57 % 2 = 1 so (?????1)2
(57 1)=2 = 28 % 2 = 0 so (????01)2
28=2 = 14 % 2 = 0 so (???001)2
14=2 = 7 % 2 = 1 so (??1001)2
(7 1)=2 = 3 % 2 = 1 so (?11001)2
(3 1)=2 = 1 % 2 = 1 so (111001)2
Addition in binary is the same as (only dierent from. . . ) addition in decimal. Just remember that (1)2 +
(1)2 = (10)2 . If we add two binary numbers, this tells us when to \carry" 1:
1011
+ 1011
10110
5.3 log2
How many 5-digit binary numbers are there (including those with leading 0s)? These numbers run from
(00000) through (11111) , or 0 through 31 in decimal | 32 numbers. Another way to count them is to
2 2
consider that there are two choices for each digit, hence 2 strings of digits. If we add one more digit we get
5
twice as many numbers. Every digit doubles the range of numbers, so there are two 1-digit binary numbers
(0 and 1), four 2-digit binary numbers (0 through 3), 8 3-digit binary numbers (0 through 7), and so on.
Reverse the question: how many digits are required to represent a given number. In other words, what
is the smallest integer power of 2 needed to exceed a given number? log x is the power of 2 that gives
2
2 2 = x. You can think of it as how many times you must multiply 1 by 2 to get x, or roughly the number
log x
of digits in the binary representation of x. (The precise number of digits needed is dlog (x + 1)e | which
2
happens to be equal to b(log x) + 1c for all positive values of x).
2
50
Chapter 5. Algorithm Analysis and Asymptotic Notation
def mult(m,n):
""" Multiply integers m and n. """
# Precondition: m >= 0
x = m
y = n
z = 0
# loop invariant: z = mn - xy
while x != 0:
if x % 2 == 1: z = z + y # x is odd
x = x >> 1 # x = x / 2 (right shift)
y = y << 1 # y = y * 2 (left shift)
# post condition: z = mn
return z
After reading this algorithm, there is no reason you should believe it actually multiplies two integers: we'll
need to prove it to you. Let's consider the precondition rst. So long as m is a positive natural number, and
n is an integer, the program claims to work. The postcondition states that z , the value that is returned, is
equal to the product of m and n (that would be nice, but we're not convinced).
Let's look at the stated loop invariant. A loop invariant is a relationship between the variables that is
always true at the start and at the end of a loop iteration (we'll need to prove this). It's sucient to verify
that the invariant is true at the start of the rst iteration, and verify that if the invariant is true at the start
of any iteration, it must be true at the end of the iteration. Before we start the loop, we set x = m, y = n
and z = 0, so it is clear that z = mn xy = mn mn = 0. Now we need to show that if z = mn xy
before executing the body of the loop, and x 6= 0, then after executing the loop body, z = mn xy is still
true (can you write this statement formally?). Here's a sketch of a proof:
Assume x ; y ; z ; x +1 ; y +1 ; z +1 ; m; n 2 Z, where x represents the value of variable x at the beginning
i i i i i i i
of the ith iteration of the loop, and similarly for the other variables and subscripts. (Note that there
is no need to subscript m; n, since they aren't changed by the loop.)
Assume z = mn x y .
i i i
So
mn x +1 y +1 = mn (x 1)=2 2y i i (since x is odd)
i i i
= mn x y + y i i i
=z +y i i
= z +1 i
So
mn x +1 y +1 = mn x =2 2y i i i i
= mn x y i i
=z i
= z +1 i
51
Course notes for csc 165 h
Thus mn x y = z ) mn x +1 y +1 = z +1 .
i i i i i i
8x ; x +1 ; y ; y +1 ; z ; z +1 ; m; n 2 Z; mn x y = z ) mn x +1 y +1 = z +1 .
i i i i i i i i i i i i
We should probably verify the postcondition to fully convince ourselves of the correctness of this algorithm.
We've shown the loop invariant holds, so let's see what we can conclude when the loop terminates (i.e.,
when x = 0). By the loop invariant, z = mn xy = mn 0 = mn, so we know we must get the right
answer (assuming the loop eventually terminates).
We should now be fairly convinced that this algorithm is in fact correct. One might now wonder, how
many iterations of the loop are completed before the answer is returned?
Also, why is it necessary for m > 0? What happens if it isn't?
specify what we mean by a \step." A \step" typically corresponds to machine instructions being executed,
or some indication of time or resources expended.
Consider the following (somewhat arbitrary) accounting for common program steps:
method call: 1 step + steps to evaluate each argument + steps to execute the method.
Notice that none of these \steps" (except for method calls) depend on the size of the input (sometimes
denoted with the symbol n). The smallest and largest steps above dier from each other by a constant of
about 5, so we can make the additional simplifying assumption that they all have the same cost | 1.
52
Chapter 5. Algorithm Analysis and Asymptotic Notation
2, 3, and 5 once for each index from 0 to j 1 (j indices), and then count lines 2, 3, 4 for index j , and so
t (A; x) will be 1 + 3j + 3.
LS
If x does not appear in A, then t (A; x) = 1 + 3 len(A) + 2, because line 1 executes once, lines 2, 3, and
LS
5 executes once for each index from 0 to len(A) 1, and then lines 2 and 6 execute.
We want a measure that depends on the size of the input, not the particular input. There are three
standard ways. Let P be a program, and let I be the set of all inputs for P . Then:
Average-case complexity: the weighted average over all possible inputs of size n.
In general X
A (n) =
P t (x) p(x)
P
x of size n
(Mostly useless.)
Worst-case complexity: max(t (x)), where x is an input of size n.
P
53
Course notes for csc 165 h
ignoring (\to within") constant factors (the time required always grows according to a quadratic function
in terms of the size of the input n).
To view this another way, think back to the linear search example in the previous section. The worst-case
running time for that algorithm was given by the function
W (n) = 3n + 3
But what exactly does the constant \3" in front of the \n" represent? Or the additive \+3"? Neither value
corresponds to any intrinsic property of the algorithm itself; rather, the values are consequences of some
arbitrary choices on our part, namely, how many \steps" to count for certain Python statements. Someone
counting dierently (e.g., counting more than 1 step for statements that access list elements by index) would
arrive at a dierent expression for the worst-case running time. Would their answer be \more" or \less"
correct than ours? Neither: both answers are just as imprecise as one another! This is why we want to come
up with a tool that allows us to work with functions while ignoring constant multipliers.
The nice thing is that this means that lower order terms can be ignored as well! So f (n) = 3n2 and
g (n) = 3n2 + 2 are considered \the same," as are h(n) = 3n2 + 2n and j (n) = 5n2 . Notice that
Saying g 2 O(f ) says that \g grows no faster than f " (or equivalently, \f is an upper bound for g"), so
long as we modify our understanding of \growing no faster" and being an \upper bound" with the practice
of ignoring constant factors. Now we can prove some theorems.
54
Chapter 5. Algorithm Analysis and Asymptotic Notation
Suppose g(n) = 3n2 + 2 and f (n) = n2 . Then g 2 O(f ). To be more precise, we need to prove the
statement 9c 2 R+ ; 9B 2 N; 8n 2 N; n > B ) 3n2 + 2 6 cn2 . It's enough to nd some c and B that \work"
in order to prove the theorem.
Finding c means nding a factor that will scale n2 up to the size of 3n2 + 2. Setting c = 3 almost works,
but there's that annoying additional term 2. Certainly 3n2 +2 < 4n2 so long as n > 2, since n > 2) n2 > 2.
So pick c = 4 and B = 2 (other values also work, but we like the ones we thought of rst). Now concoct a
proof of
9c 2 R+ ; 9B 2 N; 8n 2 N; n > B ) 3n2 + 2 6 cn2 :
Let c0 = 4 and B 0 = 2.
Then c0 2 R+ and B 0 2 N.
Assume n 2 N and n > B 0 . # direct proof for an arbitrary natural number
Then n2 > B 0 2 = 4. # squaring is monotonic on natural numbers
Then n2 > 2.
Then 3n2 + n2 > 3n2 + 2. # adding 3n2 to both sides of the inequality
Then 3n2 + 2 6 4n2 = c0 n2 # re-write
Then 8n 2 N; n > B 0 ) 3n2 + 2 6 c0 n2 # introduce 8 and )
Then 9c 2 R+ ; 9B 2 N; 8n 2 N; n > B ) 3n2 + 2 6 cn2 . # introduce 9 (twice)
So, by denition, g 2 O(f ).
Let's prove that 2n3 5n4 + 7n6 is in O(n2 4n5 + 6n8 ). We begin with:
Let c0 = . Then c0 2 R+ .
Let B 0 = . Then B 0 2 N.
Assume n 2 N and n > B 0 . # arbitrary natural number and antecedent
Then 2n3 5n4 + 7n6 6 : : : 6 c0 (n2 4n5 + 6n8 ).
Then 8n 2 N; n > Bi0 ) 2n3 5n4 + 7n6 6 c0 (n2 4n5 + 6n8 ). # introduce ) and 8
Hence, 9c 2 R+ ; 9B 2 N; 8n 2 N; n > B ) 2n3 5n4 + 7n6 6 c(n2 4n5 + 6n8 ). # introduce 9
To ll in the we try to form a chain of inequalities, working from both ends, simplifying the expressions:
2n3 5n4 + 7n6 6 2n3 + 7n6 (drop 5n4 because it doesn't help us in an important way)
6 2n6 + 7n6 (increase n3 to n6 because we have to handle n6 anyway)
= 9n6
6 9n8 (simpler to compare)
= 2(9=2)n8 (get as close to form of the simplied end result: now choose c0 = 9=2)
= 2cn8
= c0 ( 4n8 + 6n8 ) (reading bottom up: decrease 4n5 to 4n8 because we have to
handle n8 anyway)
6 c0 ( 4n5 + 6n8 ) (reading bottom up: drop n2 because it doesn't help us in an
important way)
0
6 c (n 4n + 6n )
2 5 8
We never needed to restrict n in any way beyond n 2 N (which includes n > 0), so we can ll in c0 = 9=2,
B 0 = 0, and complete the proof.
Let's use this approach to prove n4 2= O(3n2 ). More precisely, we have to prove the negation of the
statement 9c 2 R+ ; 9B 2 N; 8n 2 N; n > B ) n4 6 c3n2 .
55
Course notes for csc 165 h
Other bounds
In analogy with O(f ), consider two other denitions:
Definition: For any function f : N ! R
> , let
0
(f ) = g : N ! R> j 9c 2 R ; 9B 2 N; 8n 2 N; n > B ) g(n) > cf (n) :
0 +
To say \g 2
(f )" expresses the concept that \g grows at least as fast as f " (f is a lower bound on g).
Definition: For any function f : N ! R
>0 , let
(f ) = g : N ! R>0 j 9c1 2 R+ ; 9c2 2 R+ ; 9B 2 N; 8n 2 N; n > B ) c1 f (n) 6 g(n) 6 c2 f (n) :
To say \g 2 (f )" expresses the concept that \g grows at the same rate as f " (f is a tight bound for g, or
f is both an upper bound and a lower bound on g ).
56
Chapter 5. Algorithm Analysis and Asymptotic Notation
Induction interlude
Suppose P (n) is some predicate of the natural numbers, and:
() P (0) ^ (8n 2 N; P (n) ) P (n + 1)):
You should certainly be able to show that () implies P (0), P (1), P (2), in fact P (n) where n is any natural
number you have the patience to follow the chain of results to obtain. In fact, we feel that we can \turn the
crank" enough times to show that () implies P (n) for any natural number n. This is called the Principle
of Simple Induction (PSI). It isn't proved, it is an axiom that we assume to be true.
Here's an application of the PSI that will be useful for some big-Oh problems.
P (n): 2 > 2n.
n
I'd like to prove that 8n; P (n), using the PSI. Here's what I do:
Prove P (0): P (0) states that 2 = 1 > 2(0) = 0, which is true.
0
Then 2 +1 > 2(n + 1), which is P (n + 1). # true in both possible cases
n
Here's a big-Oh problem where we can use P (n). Let g(n) = 2 and f (n) = n. I want to show that
n
g 62 O(f ).
Assume c 2 R+ , assume B 2 N. # arbitrary values
Let k = max(0; dlog2 (c)e) + 1 + B , and let n0 = 2k.
Then n0 2 N. # dxe; 1; 2; B 2 N, N closed under max; +;
Then n0 > B . # at least twice B
Then 2 > c. # choice of k, 2 is increasing function
k x
Then
g (n0 ) = 2
n0
= 2 2 # by choice of k
k k
> 2 2k # by P (2k)
k
57
Course notes for csc 165 h
What happens to induction for predicates that are true for all natural numbers after a certain point, but
untrue for the rst few natural numbers? For example, 2 grows much more quickly than n2 , but 23 is not
n
You can't prove this for all n, when it is false for n = 2; n = 3, and n = 4, so you'll need to restrict the
domain and prove that for all natural numbers greater than 4, P (n) is true. We don't have a slick way to
restrict domains in our symbolic notation. Let's consider three ways to restrict the natural numbers to just
those greater than 4, and then use induction.
Restrict by set difference: One way to restrict the domain is by set dierence:
Now our task is to prove Q(0) is true and that for all n 2 N, Q(n)) Q(n +1). This is simple induction.
Restrict using implication: Another method of restriction uses implication to restrict the domain where
58
Chapter 5. Algorithm Analysis and Asymptotic Notation
Some theorems
Here are some general results that we now have the tools to prove.
f 2 O(f ).
(f 2 O(g) ^ g 2 O(h)) ) f 2 O(h).
g 2
(f ) , f 2 O(g).
g 2 (f ) , g 2 O(f ) ^ g 2
(f ).
Test your intuition about Big-O by doing the \scratch work" to answer the following questions:
Are there functions f; g such that f 2 O(g) and g 2 O(f ) but f 6= g? 8
that satisfy:
8n 2 N; n > B ) f (n) 6 ch(n):
Since we have constants that scale h to g and then g to f , it seems clear that we need their product to scale
g to f . And if we take the maximum of the two starting points, we can't go wrong. Making this precise:
Theorem 5.1: For any functions f; g; h : N ! R
> , we have (f 2 O(g ) ^ g 2 O(h)) ) f 2 O(h).
0
Proof:
So g 2 O(h).
So 9c 2 R+ ; 9B 2 N; 8n 2 N; n > B ) g(n) 6 ch(n). # by def'n of g 2 O(h)
Let c 2 R+ ; B 2 N be such that 8n 2 N; n > B ) g(n) 6 c h(n).
h h h h
So f (n) 6 c0 h(n).
Hence, 8n 2 N; n > B 0 ) f (n) 6 c0 h(n).
Therefore, 9c 2 R+ ; 9B 2 N; 8n 2 N; n > B ) f (n) 6 ch(n).
So f 2 O(g), by denition.
So (f 2 O(g) ^ g 2 O(h)) ) f 2 O(h).
To show that g 2
(f ) , f 2 O(g), it is enough to note that the constant, c, for one direction is positive,
so its reciprocal will work for the other direction.10
Theorem 5.2: For any functions f; g : N ! R
>0 , we have g 2
(f ) , f 2 O(g ).
Proof:
g 2
(f )
() 9c 2 R+ ; 9B 2 N; 8n 2 N; n > B ) g(n) > cf (n) (by denition)
() 9c0 2 R+ ; 9B 0 2 N; 8n 2 N; n > B 0 ) f (n) 6 c0 g(n) (letting c0 = 1=c and B 0 = B )
() f 2 O(g) (by denition)
To show g 2 (f ) , g 2 O(f ) ^ g 2
(f ), it's really just a matter of unwrapping the denitions.
59
Course notes for csc 165 h
g 2 (f )
, (by denition)
9c1 2 R+ ; 9c2 2 R+ ; 9B 2 N; 8n 2 N; n > B ) c1 f (n) 6 g(n) 6 c2 f (n).
, (combined inequality, and B = max(B1 ; B2 ))
9c1 2 R+ ; 9B1 2 N; 8n 2 N; n > B1 ) g(n) > c1 f (n) ^
9c2 2 R+ ; 9B2 2 N; 8n 2 N; n > B2 ) g(n) 6 c2 f (n)
, (by denition)
g 2
(f ) ^ g 2 O(f )
Here's an example of a corollary that recycles some of the theorems we've already proven (so we don't have to
do the grubby work). To show g 2 (f ), f 2 (g), I re-use theorems proved above and the commutativity
of ^:
Corollary: For any functions f; g : N ! R
>0 , we have g 2 (f ) , f 2 (g ).
Proof:
g 2 (f )
() g 2 O(f ) ^ g 2
(f ) (by 5.3)
() g 2 O(f ) ^ f 2 O(g) (by 5.2)
() f 2 O(g) ^ g 2 O(f ) (by commutativity of ^)
() f 2 O(g) ^ f 2
(g) (by 5.2)
() f 2 (g) (by 5.3)
T 2 O(U )
P
So to show that T 2 O(U (n)), you need to nd constants c and B and show that for an arbitrary input x
P
60
Chapter 5. Algorithm Analysis and Asymptotic Notation
for which we can show that P takes at least cL(n) steps on input x
def IS(A):
""" Sort the elements of A in non-decreasing order. """
i = 1 # (line 1)
while i < len(A): # (line 2)
t = A[i] # (line 3)
j = i # (line 4)
while j > 0 and A[j-1] > t: # (line 5)
A[j] = A[j-1] # (line 6)
j = j-1 # (line 7)
A[j] = t # (line 8)
i = i+1 # (line 9)
Let's nd an upper bound for T (n), the maximum number of steps to Insertion Sort an array of size n.
IS
We'll use the proof format to prove and nd the bound simultaneously | during the course of the proof we
can ll in the necessary values for c and B .
We show that T (n) 2 O(n2 ) (where n = len(A)):
IS
Let c0 = . Let B 0 = .
Then c0 2 R+ and B 0 2 N.
Assume n 2 N, A is an array of length n, and n > B 0 .
Then lines 5{7 execute at most n 1 times, which we can overestimate at 3n steps, plus 1 step
for the last loop test.
Then lines 2{9 take no more than n(5 + 3n) + 1 = 5n + 3n2 + 1 steps.
So 3n2 + 5n + 1 6 c0 n2 (ll in the values of c0 and B 0 that makes this so | setting c0 = 9; B 0 = 1
should do).
Since n is the length of an arbitrary array A, 8n 2 N; n > B 0 ) T (n) 6 c0 n2 (so long as B 0 > 1).
IS
Let c0 = . Let B 0 = .
Then c0 2 R+ and B 0 2 N.
Assume n 2 N and n > B 0 .
Let A0 = [n 1; : : : ; 1; 0] (notice that this means n > 1).
Then at any point during the outside loop, A0 [0::(i 1)] contains the same elements as before but
sorted (i.e., no element from A0 [(i + 1)::(n 1)] has been examined yet).
Then the inner while loop makes i iterations, at a cost of 3 steps per iteration, plus 1 for the nal
loop check, since the value A0 [i] is less than all the values A0 [0::(i 1)], by construction of the
array.
Then the inner loop makes strictly greater than 2i + 1, or greater than or equal to 2i + 2., steps.
Then (since the outer loop varies from i = 1 to i = n 1 and we have n 1 iterations of lines 3
and 4, plus one iteration of line 1), we have that t (n) > 1+3+5+ +(2n 1)+(2n +1) = n2
IS
61
Course notes for csc 165 h
So T 2
(n2 ) (by denition of
(n2 )).
IS
(b) n + 165 2
(n )
2 4
(c) n! 2 O(n ) n
6n ; n > 165 5
3. Let F be the set of functions from N to R> . Prove the following theorems: 0
(a) For f; g 2 F, if g 2
(f ) then g 2
(f ). 2 2
Notice that (b) means that all logarithms eventually grow at the same rate (up to a multiplicative
constant), so the base doesn't matter (and can be omitted inside the asymptotic notation).
4. Let F be the set of functions from N to R> . Prove or disprove the following claims:
0
(i) 32 2 n
(a) O( 1 )
n
(ii) 2n4 +1
n3 +2n 1
2 (b) O(1)
(iii) (n + 7)(n5 7) 2
5
(c) O(log2 n)
(iv) 2
4
n log2
2 +1
n
n n
(d) O(n)
(v) n log2
n5
2 n
(e) O(n log2 n)
(vi) 8+ 2 2 1
n (f) O(n2 )
(vii) 23 +1 2
n
(g) O(n10 )
(viii) n! 2
(h) O(2 )
n
62
Chapter 5. Algorithm Analysis and Asymptotic Notation
Chapter 5 Notes
1
From 0 to (2 1), if we work in analogy with base 10.
2
To parse the 0:101 part, calculate 0:101 = 1(2 1 ) + 0(2 2 ) + 1(2 3 ).
3
You should be able to look up this algorithm in an elementary school textbook.
4
Same as the previous exercise, but only write numbers that have 0's and 1's, and do binary addition.
5
Integer divide by 10.
6
Integer divide by 2.
7
Better in the sense of time complexity.
8
Sure, f = n2 , g = 3n2 + 2.
9
Sure. f and g don't need to both be monotonic, so let f (n) = n2 and
(
n; n even
g ( n) =
n3 ; n odd
So not every pair of functions from N ! R>0 can be compared using Big-O.
10
Let's try the symmetrical presentation of bi-implication.
11
but not particularly ecient. . .
12
The claim is true.
Let c0 = 8. Then c0 2 R+ .
Let B 0 = 12. Then B 0 2 N.
Assume n 2 N and n > B 0 .
Then n3 = n n2 > 12 n2 = 11n2 + n2 > 11n2 + n. # since n > B 0 = 12
Thus c0 n3 = 8n3 = 7n3 + n3 > 7n3 + 11n2 + n.
So 8n 2 N, n > B 0 ) 7n3 + 11n2 + n 6 c0 n3 .
Since B 0 is a natural number, 9B 2 N; 8n 2 N; n > B ) 7n3 + 11n2 + n 6 c0 n3 .
Since c0 is a real positive number, 9c 2 R+ ; 9B 2 N; 8n 2 N; n > B ) 7n3 + 11n2 + n 6 cn3 .
By denition, 7n3 + 11n2 + n 2 O(n3 ).
13
Assume k 2 N and k > 1.
Assume d 2 R+ .
It suces to argue that d log n 2 (log2 n).
Let c01 = log2 . Since k > 1, log2 k 6= 0 and so c01 2 R+ .
k
d
k
Let B 0 = 1. Then B 0 2 N.
k
63
Course notes for csc 165 h
64