1 of 49

Announcements

Upcoming Deadlines:

  • Project 2 basics autograder due 3/2 at 11:59 PM.
  • Project 2 due 3/7 at 11:59 PM. Autograder will be minimal since it largely will involve manual testing.
  • No lab this week: It will be project 2 office hours instead.

Lecture today/friday somewhat more slowly paced (given project).

  • Today: Practice with what we learned Monday.

See study guides for each lecture starting Monday:

  • Webcast viewers, do all B-level problems in guide before watching this lecture.

2 of 49

CS61B

Lecture 18: Asymptotics II: Analysis of Algorithms

  • Review of Asymptotic Notation
  • Examples 1-2: For Loops
  • Example 3: A Basic Recurrence
  • Example 4: Binary Search
  • Example 5: Mergesort

3 of 49

Summary of Asymptotic Notations

Informal meaning:

Family

Family Members

Big Theta

Θ(f(N))

Order of growth is f(N).

Θ(N2)

N2/2

2N2

N2 + 38N + N

Big O

O(f(N))

Order of growth is less than or equal to f(N).

O(N2)

N2/2

2N2

lg(N)

Big Omega

Ω(f(N))

Order of growth is greater than or equal to f(N).

Ω(N2)

N2/2

2N2

eN

From discussion

4 of 49

Example 1/2:For Loops

5 of 49

Monday’s Lecture

We discussed ways to analyze algorithm performance. To understand how code scales, we symbolically count number of executions of a representative operation as a function of input size N.

  • Focus on behavior for large N: ignore lower order terms.
  • Ignore constant multiplicative factors.

int count = 0, N = a.length;

for (int i = 0; i < N; i++) {

if (a[i] == k) {

count += 1;

}

}

a[k] += count;

Big Theta formalizes our intuitive simplifications.

operation

count

simplified count

increment

N+1 to 2N+1

Θ(N)

6 of 49

Example 1: Nested For Loops

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)) in the worst case.

0

1

2

3

4

5

i

j

0 1 2 3 4 5

7 of 49

Example 1: Nested For Loops

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)) in the worst case.

Worst case number of j += 1 calls:

1 + 2 + 3 + … + (N - 3) + (N - 2) + (N - 1)

(N-1)/2 of these combinations

Overall worst case runtime: Θ(N2)

0

1

2

3

4

5

0 1 2 3 4 5

i

j

1 + (N-1) = N

N

N

= N(N-1)/2

8 of 49

Example 1: Nested For Loops

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)) in the worst case.

Worst case number of j += 1 calls:

1 + 2 + 3 + … + (N - 3) + (N - 2) + (N - 1)

Overall worst case runtime: Θ(N2)

0

1

2

3

4

5

0 1 2 3 4 5

i

j

= N(N-1)/2

Overall worst case runtime: Θ(N2)

9 of 49

Nested For Loops II: PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)). By simple, we mean there should be no unnecessary multiplicative constants or additive terms.

  1. 1
  2. log N
  3. N

D. N log N

E. N2

F. Something else

10 of 49

Nested For Loops II: PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

Cost model, println(“hello”) calls:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

0

1

2

3

4

5

0 1 2 3 4 5

j

i

n=1

11 of 49

Nested For Loops II: PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

Cost model, println(“hello”) calls:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

0

1

2

3

4

5

0 1 2 3 4 5

j

i

n=1

12 of 49

Nested For Loops II: PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

Cost model, println(“hello”) calls:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

0

1

2

3

4

5

0 1 2 3 4 5

j

i

n=1

n=2

,3

13 of 49

Nested For Loops II: PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

Cost model, println(“hello”) calls:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

0

1

2

3

4

5

0 1 2 3 4 5

j

i

n=1

n=2

,3

n=4

,5,6,7

14 of 49

Nested For Loops II: PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

Cost model, println(“hello”) calls:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

0

1

2

3

4

5

0 1 2 3 4 5

j

i

n=1

n=2

,3

n=4

,5,6,7

n=8,9,10, …, 15

15 of 49

Nested For Loops II: PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

Cost model, println(“hello”) calls:

“Worst case” here is irrelevant, all cases the same.

Cost model, println(“hello”) calls:

  • R(N) = Θ(1 + 2 + 4 + 8 + … + N)

D. N log N

E. N2

F. Something else

  1. 1
  2. log N
  3. N

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

n=1

n=2

,3

n=4

,5,6,7

n=8,9,10, …, 15

16 of 49

Nested For Loops II: PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

“Worst case” here is irrelevant, all cases the same.

Cost model, println(“hello”) calls:

  • R(N) = Θ(1 + 2 + 4 + 8 + … + N)

D. N log N

E. N2

F. Something else

  • 1
  • log N
  • N

N

R(N)

1

1

4

1 + 2 + 4 = 7

7

1 + 2 + 4 = 7

8

1 + 2 + 4 + 8 = 15

27

1 + 2 + 4 + 8 + 16 = 31

185

… + 64 + 128 = 255

715

… + 256 + 512 = 1023

17 of 49

Nested For Loops II: PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

N

R(N)

1 * N < R(N)

2 * N > R(N)

1

1

1

2

4

1 + 2 + 4 = 7

4

8

7

1 + 2 + 4 = 7

7

14

8

1 + 2 + 4 + 8 = 15

8

16

27

1 + 2 + 4 + 8 + 16 = 31

27

54

185

… + 64 + 128 = 255

185

370

715

… + 256 + 512 = 1023

715

1430

18 of 49

Nested For Loops II: PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

R(N) = Θ(1 + 2 + 4 + 8 + … + N)

= Θ(N)

  • 1
  • log N
  • N

D. N log N

E. N2

F. Something else

19 of 49

Repeat After Me...

There is no magic shortcut for these problems (well… usually)

  • Runtime analysis often requires careful thought.
  • CS70 and especially CS170 will cover this in much more detail.
  • This is not a math class, though we’ll expect you to know these:
    • 1 + 2 + 3 + … + N = N(N+1)/2 = Θ(N2)
    • 1 + 2 + 4 + 8 + … + N = 2N - 1 = Θ(N)

20 of 49

Repeat After Me...

There is no magic shortcut for these problems (well… usually)

  • Runtime analysis often requires careful thought.
  • CS70 and especially CS170 will cover this in much more detail.
  • This is not a math class, though we’ll expect you to know these:
    • 1 + 2 + 3 + … + N = N(N+1)/2 = Θ(N2)
    • 1 + 2 + 4 + 8 + … + N = 2N - 1 = Θ(N)
  • Strategies:
    • Write out examples
    • Draw pictures

QR decomposition runtime, from a numerical linear algebra textbook

21 of 49

Example 3: Recursion

22 of 49

Recursion (Intuitive): PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

Using your intuition, give the order of growth of the runtime of this code as a function of N?

  1. 1
  2. log N
  3. N
  4. N2
  5. 2N

3

2

2

1

1

1

1

3

2

2

1

1

1

1

4

23 of 49

Recursion (Intuitive): PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

Using your intuition, give the order of growth of the runtime of this code as a function of N?

  • 1
  • log N
  • N
  • N2
  • 2N

3

2

2

1

1

1

1

3

2

2

1

1

1

1

4

3

2

2

1

1

1

1

3

2

2

1

1

1

1

4

5

24 of 49

Recursion and Recurrence Relations

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

One approach: Count number of calls to f3, given by C(N).

  • C(1) = 1

3

2

2

1

1

1

1

3

2

2

1

1

1

1

4

25 of 49

Recursion and Recurrence Relations

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

One approach: Count number of calls to f3, given by C(N).

  • C(1) = 1
  • C(N) =

3

2

2

1

1

1

1

3

2

2

1

1

1

1

4

2C(N-1) + 1

26 of 49

Recursion and Recurrence Relations

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

One approach: Count number of calls to f3, given by C(N).

  • C(1) = 1
  • C(N) = 2C(N-1) + 1

C(N) = 1 + 2 + 4 + 8 + … + ???

3

2

2

1

1

1

1

3

2

2

1

1

1

1

4

Possible to solve mechanically (with algebra), but we won’t. Instead, we’ll use intuition in 61b.

27 of 49

Recursion and Recurrence Relations: PollEv.com/jhug or JHUG to 37607

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

One approach: Count number of calls to f3, given by C(N).

  • C(1) = 1
  • C(N) = 2C(N-1) + 1

C(N) = 1 + 2 + 4 + 8 + … + 2 = ???

  1. 2N C. 2N+1
  2. 2N-1 D. 2N+1 + 1

3

2

2

1

1

1

1

3

2

2

1

1

1

1

4

Possible to solve mechanically (with algebra), but we won’t. Instead, we’ll use intuition in 61b.

N-1

28 of 49

Sums of Powers of 2 (Revisited)

C(N) = 1 + 2 + 4 + 8 + … + 2 = ???

This is just the same sum we saw before, where Q = 2 :

  • 1 + 2 + 4 + 8 + … + Q = 2Q - 1 = Θ(Q)

C(N) = 1 + 2 + 4 + 8 + … + 2 = 2(2 ) - 1 = 2 - 1

N-1

N-1

N-1

N

N-1

29 of 49

Recursion and Recurrence Relations

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

One approach: Count number of calls to f3, given by C(N).

  • C(1) = 1
  • C(N) = 2C(N-1) + 1

C(N) = 1 + 2 + 4 + 8 + … + 2 = 2 -1 = Θ(2N)

3

2

2

1

1

1

1

3

2

2

1

1

1

1

4

Possible to solve mechanically (with algebra), but we won’t. Instead, we’ll use intuition in 61b.

N-1

N

30 of 49

Recursion and Recurrence Relations (Extra)

Find a simple f(N) such that the runtime R(N) ∈ Θ(f(N)).

One approach: Count number of calls to f3, given by C(N).

This approach not covered in class. Provided for those of you who really want the algebra.

3

2

2

1

1

1

1

3

2

2

1

1

1

1

4

31 of 49

Example 4: Binary Search

32 of 49

Binary Search (demo: http://goo.gl/iSbyRV)

Trivial to implement?

  • Idea published in 1946.
  • First correct implementation in 1962.
    • Bug in Java’s binary search discovered in 2006.

See Jon Bentley’s book Programming Pearls.

33 of 49

Binary Search (Intuitive): PollEv.com/jhug or JHUG to 37607

Let N = hi - lo + 1.

  • What is the order of growth of the runtime of binarySearch?
  • 1
  • log N
  • N
  • N log N
  • 2N

N=15

N=7

N=3

N=1

for simplicity: assume N=2k-1 for some k

k

34 of 49

Binary Search

Approach: Measure number of string comparisons for N = hi - lo + 1.

  • C(0) = 0
  • C(1) = 1
  • C(N) = 1 + C((N-1)/2)

N=15

N=7

N=3

N=1

for simplicity: assume N=2k-1 for some k

k

35 of 49

Binary Search

Approach: Measure number of string comparisons for N = hi - lo + 1.

  • C(0) = 0
  • C(1) = 1
  • C(N) = 1 + C((N-1)/2)

Give C(N) in terms of k:

C(N) = ???

N=15

N=7

N=3

N=1

k

for simplicity: assume N=2k-1 for some k

36 of 49

Binary Search

Approach: Measure number of string comparisons for N = hi - lo + 1.

  • C(0) = 0
  • C(1) = 1
  • C(N) = 1 + C((N-1)/2)

C(N) = 1 + 1 + … + 1 + 0 = k

N=15

N=7

N=3

N=1

for simplicity: assume N=2k-1 for some k

k

k

37 of 49

Binary Search

Approach: Measure number of string comparisons for N = hi - lo + 1.

  • C(0) = 0
  • C(1) = 1
  • C(N) = 1 + C((N-1)/2)

C(N) = 1 + 1 + … + 1 + 0 = k

N=15

N=7

N=3

N=1

for simplicity: assume N=2k-1 for some k

k

k

k = lg N⌉ = Θ(log N)

lg is short for base 2

38 of 49

Unproven BigTheta Properties We’ve Just Used

Some easy-to-prove properties:

Base of logarithm doesn’t matter. We’ll usually omit it completely!

39 of 49

Log Time Is Really Terribly Fast

Throughout this course we will see ways of doings things in constant vs log time. In practice, the difference is minimal.

N

log2 N

Runtime (seconds)

100

6.6

1 nanosecond

100,000

16.6

2.5 nanoseconds

100,000,000

26.5

4 nanoseconds

100,000,000,000

36.5

5.5 nanoseconds

100,000,000,000,000

46.5

7 nanoseconds

40 of 49

A Note on Solving Recurrence Relations

The entire goal is to find a pattern that yields a closed form solution for C(N).

  • Use whatever tricks you’d like.
  • This is not CS70.
    • We’ll not deviate too terribly far from the patterns you’ll see today and in discussion 8 (summing very simple arithmetic and geometric series).
    • We will not write rigorous proofs.

41 of 49

Example 5: Merge Sort

42 of 49

Selection Sort: A Prelude to Example 5.

Earlier in class we discussed a sort called selection sort:

  • Find the smallest unfixed item, move it to the front, and ‘fix’ it.
  • Sort the remaining unfixed items using selection sort.

This algorithm requires Θ(N2) comparisons.

  • Look at all N unfixed items to find smallest.
  • Then look at N-1 remaining unfixed.
  • Look at last two unfixed items.
  • Done, sum is 2+3+4+5+...+N = Θ(N2)

N=64

~2048

compares

SS

43 of 49

Array Merging of N Total Items (A.length + B.length = N)

What is the runtime for merge? Θ(1), Θ(N), Θ(N2)???

  • Θ(N) compares and array accesses.

2

3

6

10

11

4

5

7

8

2

3

4

5

6

7

8

10

11

A

B

44 of 49

The Merge Operation

One way to sort N items:

  • Give half of the items away for sorting to one algorithm.
  • Give the other half to some other algorithm.
  • Merge the results: Θ(N) compares.

N=64

2048

SS

N=64

N=32

N=32

512

64

512

SS

SS

M

Suppose the other two algs are selection sort.

  • N=64:
    • Merge: ~64 compares.
    • Selection sort: ~512 each.
  • Still Θ(N2), but faster since N+2*(N/2)2 < N2
    • ~1088 vs. ~2048 compares for N=64.

how do we do better?

45 of 49

Example 5: Merge Sort

One way to sort N items:

  • Give half of the items away for sorting to one algorithm.
  • Give the other half to some other algorithm.
  • Merge the results: Θ(N) compares.

Suppose they each use merge sort.

  • N=64:

64

32

32

16

16

16

….

8

8

….

64

32

32

16

16

16

8

8

    • Top level: 64 compares
    • Next level: 64=32 + 32 compares.
    • Overall: 64*k compares.
    • k = ~lg(64), so ~384 compares.

k

46 of 49

Merge Sort: More General

Intuitive explanation:

  • Every level does N work
    • Top level does N work.
    • Next level does N/2 + N/2 = N.
    • One more level down: N/4 + N/4 + N/4 + N/4 = N.
  • Thus work is just Nk, where k is the number of levels.
    • How many levels? Goes until we get to size 1.
    • k = lg(N)
  • Overall runtime is N log N.

N

N/2

N/2

N/4

N/4

N/4

….

N/8

N/8

….

N/4

N/8

N/8

k

47 of 49

Merge Sort: Same Idea as Previous Slide, but Using Algebra

C(N): Number of items merged at each stage.

N

N/2

N/2

N/4

N/4

N/4

….

N/8

N/8

….

Only works for N=2k. Can be generalized at the expense of some tedium (e.g. separately prove big O and big Omega)

N/4

N/8

N/8

k

48 of 49

Linear vs. Linearithmic (N log N)

N log N is basically as good as N.

  • Only a tiny bit slower. N = 1,000,000, and the log N is only 20.

49 of 49

Summary

Theoretical analysis of algorithm performance requires careful thought.

  • Finding a simple expression for runtime is about finding patterns.
  • Know the patterns we’ve learned today (more in HW and discussion).

Different solutions to the same problem may have radically different runtimes. N2 vs. N log N kind of a big deal.

Next time:

  • Amortized analysis.
  • Empirical measurement of program runtime.
  • Sneak preview of complexity theory (extra).