Algorithms homework #2 Solutions
Exercise 2.2. Suppose you have algorithms with the six running times listed below. (Assume these are the exact number of operations performed as a function of the input size n.) Suppose you have a computer that can perform 10^10 operations per second, and you need to compute a result in at most an hour of computation. For each of the algorithms, what is the largest input size n for which you would be able to get the result within an hour?
Total # of operations that can be performed in an hour: 10^10 operations/second * (60 seconds / 1 minute) * (60 minutes / 1 hour) = 3.6 × 10^13 operations
a) n^2
largest input size: n^2 = 3.6 * 10^13 operations --> n = 6,000,000 operations
b) n^3
n^3 = 3.6 * 10^13 operations --> n = 33 019.2725 --> 33019 operations
c) 100n^2
100n^2 = 3.6 * 10^13 operations --> n = ((3.6 * 10^13 operations) / 100) ^ .5 = 600,000 operations
d) n log n
n log n = 3.6 * 10^13 operations --> n = 1.29 * 10^12 operations - from class using Maple
e) 2^n
2^n = 3.6 * 10^13 operations --> log(2^n) = log(3.6 * 10^13 operations) --> n log 2 = log(3.6 * 10^13 operations) --> n = log(3.6 * 10^13) / log(2) = 45.0330621 --> 45 operations
f) 2^2^n
2^2^n = 3.6 * 10^13 operations --> log(2^2^n) = log(3.6 * 10^13 operations) --> 2^n log(2) = log(3.6 * 10^13 operations) --> 2^n = log(3.6 * 10^13 operations) / log(2) --> log(2^n) = n log(2) = log(log(3.6 * 10^13 operations) / log(2)) --> n = (log(log(3.6 * 10^13 operations) / log(2)) / log(2) = 5.49291268 --> 5 operations
Exercise 2.6. Consider the following basic problem. You're given an array A consisting of n integers A[1], A[2], ..., A[n]. You'd like to output a two-dimensional n-by-n array B in which B[i, j] (for i < j) contains the sum of array entries A[i] through A[j] -- that is, the sum A[i] + A[i+1] + ... + A[j]. (the value of array entry B[i, j] is left unspecified whenever i >= j, so it doesn't matter what is output for these values.)
Here's a simple algorithm to solve this problem.
For i=1, 2, ..., n
For j = i+1, i+2, ..., n
Add up array entries A[i] through A[j]
Store the result in B[i, j]
Endfor
Endfor
a) For some function f that you should choose, give a bound of the for O(f(n)) on the running time of this algorithm on an input of size n (i.e., a bound on the number of operations performed by the algorithm).
O(n^3) since the outer for-loop goes n times (O(n)), the inner for-loop goes up to n times (and an average of n/2 times) for each iteration of the outer loop (another O(n)), and then adding up the array entries is O(n) time inside the loops, so the total time is O(n^3)
b) For this same function f, show that the running time of the algorithm on an input of size n is also lower bounded by f(n). (This shows an asympototically tight of f(n) on the running time).
Outer loop goes through n times
Total iterations of inner loop: (n-1) + (n-2) + ... + 1 + 0 = (1/2) (n-1) ((n+1) - 1) = (1/2)(n-1)(n) = ((1/2)n - 1/2)n = (1/2)n^2 - (1/2)n
Number of operations on adding for n iterations of inner loop:
-1 operation for storing result in B[i, j]
-1 operation to add entries A[t] and A[t+1] for each A[t], A[t+1] combination A[i] through A[j]
-1 operation for j=i+1, 2 operations for
j=i+2, ..., n-i operations for j = n
For i = 1:
# of addition operations = 1 + 2 + ... + n-1 = .5(n-1)(n) = .5n^2 - .5n
For i = 2:
# of addition
operations = 1 + 2 + ... + n - 2 = .5(n-2)(n-1)
For i = 3:
# of addition operations = 1 + 2 + ... + n - 3 = .5(n-3)(n-2)
For i = k:
# of addition operations = 1 + 2 + ... + n - k = .5(n - k)(n -k + 1)
So for i = n-2:
# of addition operations = 1 + (n - (n - 2)) = 1 + 2
For i = n/2 # of addition operations = 1 + 2 +
... + (n - n/2) = .5(n - (n/2))(n - (n/2) + 1)) >= .5 * (n/2)(n/2) -->
.5*(n^2/4) --> n^2 / 8
all i <= n/2 have at least as many addition operations as i = n/2 and therefore have at least n^2 / 8 addition operations
There are n/2 iterations where i<= n/2, and each one has at least n^2 / 8 addition operations.
Therefore, there are >= (n/2 iterations where i <= n/2)) (at least n^2 / 8 addition operations in each such iteration) --> there are at least n^3 / 16 addition operations in the algorithm for all n >= 2, and therefore T(n) >= n^3 / 16 --> T(n) >= (1/16) * n^3 for all n_o > 1 and e = 1/16 here, so therefore the algorithm is lower bounded by n^3.
c. Although the algorithm you analyzed in parts (a) and (b) is the
most natural way to solve the problem--after all, it just iterates through the
relevant entries of the array B, filling in a value for each--it contains some
highly unnecessary sources of inefficiency. Give a different algorithm
to solve the problem, with an asymptotically better running time. In
other words, you should design an algorithm with running time O(g(n)), where
lim_n->infinity(g(n) / f(n)) = 0
Pseudo-code of algorithm
currentSum = 0;
For i=1, 2, ..., n
currentSum = A[i];
For j = i+1, i+2, ..., n
currentSum = currentSum +
A[j]
Store the current sum in B[i, j]
Endfor
Endfor
Exercise 2.8 (I thought about this problem for awhile and honestly did not think of the solution, so good job to those who did):
Idea is to divide the rungs into groups of sqrt(n). There are sqrt(n) of these groups, and each group has sqrt(n) rungs. Then, start at the bottom "rung group" and drop the jar from the highest rung of the group, then if the jar doesn't break, try the highest rung of the second "rung group", and keep going up "rung groups" until the first jar breaks. Then, once the first jar breaks, you know which "rung group" the "highest safe rung" is in, since the first jar didn't break at the highest level of the previous rung group, and then did break at the highest level of the "current" rung group. Now, start from the bottom of the current rung group and continue up until the second jar breaks, and the rung below that is the "highest safe rung".
Since there are sqrt(n) rung groups, the first jar will be
dropped a maximum of sqrt(n) times, and since there are sqrt(n) rungs in each
rung group, the second jar will be dropped a maximum of sqrt(n) times, for a
total of 2*sqrt(n) drops maximum, which better than linear.