23 / \ / \ / \ / \ 18 12 / \ / \ / \ / \ 14 9 7 10 / \ / 6 5 8 Just check that every node is >= its left and right child.
After first step. (changed = green) 18 / \ / \ / \ / \ 14 12 / \ / \ / \ / \ 8 9 7 10 / \ 6 5 23 After second step. (changed = green) 14 / \ / \ / \ / \ 9 12 / \ / \ / \ / \ 8 5 7 10 / 6 18 23
23 / \ / \ / \ / \ 20 12 / \ / \ / \ / \ 14 18 7 10 / \ / \ 6 5 8 9 After inserting 20 and restoring heap property. (green = changed)
The Master Theorem:
T(1) = c, for c > 0 T(n) = a*T(n/b) + f(n), for n = bk, k = 1, 2, ...
Suppose f(n) is in Big-Theta(nd), where d >= 0 is a constant. Then the recurrence T(n) has the solution
T(n) is in Big-Theta(nd), if a < bd T(n) is in Big-Theta(nd log(n)), if a = bd T(n) is in Big-Theta(nlogba), if a > bd
T(n) = 2 * T(n/2) + n3 Here a = 2, b = 2, d = 3, so 2 = a < b^d = 2^3 = 8 and T(n) is in Big-Theta(n^3) T(n) = 4 * T(n/2) + n2 Here a = 4, b = 2, d = 2, so 4 = a = b^d = 2^2 = 4 and T(n) is in Big-Theta(n^2*log(n))
Consider the recurrence equations:
T(1) = 1 T(n) = 4 * T(n/2) + n
Here a = 4, b = 2, d = 1, so 4 = a > b^d = 2^1 = 2 and T(n) is in Big-Theta(n^(log24) = Big-Theta(n^2)
Basis: For n = 1, T(1) = 1 by definition, but the formula gives T(1) = 2*12 - 1 = 2*1 - 1 = 1. Check. Assume that T(k) = 2*k2 - k, for some k = 1, 2, 4, ... To show: T(2*k) = 2*(2*k)2 - 2*k = 8*k2 - 2*k Proof: T(2*k) = 4*T(k) + 2*k = 4*(2*k2 - k) + 2*k = 8*k2 - 4*k + 2*k = 8*k2 - 2*k
The "other algorithm" is quicksort, which has average-case performance of Big-Theta(n log n). Picking a nut or bolt at random at the start of the nut and bolt algorithm is similar to picking a pivot value at random in quicksort.
To produce each of the 16 terms in the product, you have to multiply a row of the first matrix times a column of the second, using 4 multiplications, or 4*16 = 64 altogether.
Break the 2 4-by-4's to be multiplied each into 4 2-by-2's. Then the 4-by-4's can be multiplied by Strassen's method using 7 multiplications of 2-by-2's. Each of these 7 multiplications can be done (again by Strassen's method) using 7 ordinary multiplications, or 7*7 = 49 ordinary multiplications altogether.
S(n, 0) = 0, for all n >= 0 S(n, n) = 1, for all n >= 0 S(n, k) = (n-1)*S(n-1, k) + S(n-1, k-1), otherwise
Here is a function to calculate these numbers:
int stirling(int n, int k) { int s1, s2; if (k == 0) return 0; if (n == k) return 1; s1 = stirling(n-1, k); s2 = stirling(n-1, k-1); return (n-1)*s1 + s2; }
Use the declaration int S[50][50]; and assume all the S values are initialized to -1. Add code to the function so that it will do a memoized computation.
int stirling(int n, int k) { int s1, s2; if (k == 0) return 0; if (n == k) return 1; if ( S[n][k] >= 0 ) { /* answer already in S */ return S[n][k]; } s1 = stirling(n-1, k); S[n-1][k] = s1; s2 = stirling(n-1, k-1); S[n-1][ k-1] = s2; S[n][k] = (n-1)*s1 + s2; return (n-1)*s1 + s2; }
Consider the function below:
int f(int m, int n) { // m >= 0 int i = m; int j = n; while (i > 0) { j = j + 2; i = i - 1; } return j; }
n + 2*m
You should use
j = n + 2*(m - i)
as the loop invariant. (There will be little if any credit if you don't follow the 4-step method taught in class.)
a. Prove that loop invariant is true initially. Given that i = m and j = n, we want to show that j = n + 2*(m - i). Substituting gives n = n + 2(m - m) or n = n, which is true. b. Prove that after each execution of one iteration of the loop, the loop invariant is still true. Assume that j = n + 2*(m - i) is true initially. Calculate new values j' and i' for j and i, using j' = j + 2 and i' = i - 1. Now we need to show that the loop invariant is true for the new values, that is, j' = n + 2*(m - i'), or we want to see if j + 2 = n + 2*(m - (i - 1)) is still true. This simplifies to j + 2 = n + 2*m - 2*i + 2 or just j = n + 2*(m - i), which we assumed was true. c. Prove that on termination, the equation for the loop invariant shows that the correct value is being calculated. On termination, we must have i = 0 true. Then the loop invariant formula: j = n + 2*(m - i) just becomes j = n + 2*(m - 0) = n + 2*m, which is what we needed to prove. d. Prove that the algorithm terminates. Since we assume m >= 0, this means that i >= 0. If i == 0, the algorithm terminates without executing the loop. Otherwise, if i > 0, the inside of the while subtracts 1 from i at each iteration, so eventually the algorithm must terminate.