Algorithm Analysis (CSC 301 2015F) : EBoards
Primary: [Front Door] [Schedule] - [Academic Honesty] [Disabilities] [Email] [FAQ] [IRC] [Teaching & Learning]
Current: [Outline] [EBoard] [Reading] [Lab] [Assignment]
Sections: [Assignments] [EBoards] [Examples] [Handouts] [Labs] [Outlines] [Readings]
Reference: [Algorist]
Related Courses: [Walker (2014F)]
Misc: [SamR] [Glimmer Labs] [CS@Grinnell] [Grinnell] [Issue Tracker]
Overview
Basic strategy
What divide and conquer algorithms do you already know?
How do we normally analyze algorithms (informally)
Will this strategy work for divide and conquer?
define Quicksort(A)
if (small(A))
return
else
partition(A)
Quicksort(firsthalf(A))
Quicksort(secondhalf(A))
In general, we write equations to carefully specify the cost. Merge sort
define mergesort(A)
if (oneelement(A))
return
merge(sort(firsthalf(A)),sort(secondhalf(A)))
T(n) is supposed to be "bound on steps to sort an array
of size n using mergesort"
T(1) = 1
T(n) = T(n/2) ; sort(firsthalf(A))
+ T(n/2) ; sort(secondhalf(A))
+ Theta(n) ; merge
As mathematicians, we'd like to find an exact bound for that function. (As computer scientists, we're okay with an extra constant multiplier.) How do we do so?
T(n) <= 2*T(n/2) + c*n
T(1) = 1
Repeatedly expand the right-hand side using the recurrence relation and look for a pattern.
T(n) <= 2*T(n/2) + c*n
; T(n/2) <= 2*T(n/4) + c*n/2
<= 2*(2*T(n/4) + c*n/2) + c*n
= 4*T(n/4) + 2*c*n
; T(n/4) <= 2*T(n/8) + c*n/4
<= 4*(2*T(n/8) + c*n/4) + 2*c*n
= 8*T(n/8) + cn + 2cn
= 8*T(n/8) + 3cn
; T(n/8) <= 2*T(n/16) + c*n/8
<= 8*(2*T(n/16) + c*n/8) + 3cn
= 16*T(n/16) + 4cn
Look at the main results
T(n) <= 2*T(n/2) + c*n
<= 4*T(n/4) + 2*c*n
<= 8*T(n/8) + 3cn
<= 16*T(n/16) + 4cn
<= 2^k*T(n/2^k) + k*c*n
Solve for 2^k = n; k = log_2(n)
<= n*T(1) + log_2(n)*c*n
<= 1 + c*n*log_2(n)
Build up from T(1) to T(2) to T(4) to T(8) to .... And look for a pattern.
T(1) = 1
T(2) <= 2*T(1) + 2c = 2 + 2c
T(4) <= 2*T(2) + 4c <= 2*(2 + 2c) + 4c <= 4 + 8c
T(n) = 3*T(n/4) + Theta(n^2)