This is a question from Introduction to Algorithms By Cormen. But this isn't a homework problem instead self-study.
There is an array of length n
. Consider a modification to merge sort in which n/k
sublists each of length k
are sorted using insertion sort and then merged using merging mechanism, where k is a value to be determined.
The relationship between n
and k
isn't known. The length of array is n
. k
sublists of n/k
means n * (n/k)
equals n
elements of the array. Hence k
is simply a limit at which the splitting of array for use with merge-sort is stopped and instead insertion-sort is used because of its smaller constant factor.
I was able to do the mathematical proof that the modified algorithm works in Θ(n*k + n*lg(n/k))
worst-case time. Now the book went on to say to
find the largest value of
k
as a function ofn
for which this modified algorithm has the same running time as standard merge sort, in terms of Θ notation. How should we choose k in practice?
Now this got me thinking for a lot of time but I couldn't come up with anything. I tried to solve
n*k + n*lg(n/k) = n*lg(n)
for a relationship. I thought that finding an equality for the 2 running times would give me the limit and greater can be checked using simple hit-and-trial.
I solved it like this
n k + n lg(n/k) = n lg(n)
k + lg(n/k) = lg(n)
lg(2^k) + lg(n/k) = lg(n)
(2^k * n)/k = n
2^k = k
But it gave me 2 ^ k = k
which doesn't show any relationship. What is the relationship? I think I might have taken the wrong equation for finding the relationship.
I can implement the algorithm and I suppose adding an if (length_Array < k)
statement in the merge_sort
function here(Github link of merge sort implementation) for calling insertion sort would be good enough. But how do I choose k
in real life?
Well, this is a mathematical minimization problem, and to solve it, we need some basic calculus.
We need to find the value of k
for which d[n*k + n*lg(n/k)] / dk == 0
.
We should also check for the edge cases, which are k == n
, and k == 1
.
The candidate for the value of k
that will give the minimal result for n*k + n*lg(n/k)
is the minimum in the required range, and is thus the optimal value of k
.
Attachment, solving the derivitives equation:
d[n*k + n*lg(n/k)] / dk = d[n*k + nlg(n) - nlg(k)] / dk
= n + 0 - n*1/k = n - n/k
=>
n - n/k = 0 => n = n/k => 1/k = 1 => k = 1
Now, we have the candidates: k=n, k=1. For k=n we get O(n^2)
, thus we conclude optimal k
is k == 1
.
Note that we found the derivitives on the function from the big Theta, and not on the exact complexity function that uses the needed constants.
Doing this on the exact complexity function, with all the constants might yield a bit different end result - but the way to solve it is pretty much the same, only take derivitives from a different function.
来源:https://stackoverflow.com/questions/18104370/choosing-minimum-length-k-of-array-for-merge-sort-where-use-of-insertion-sort-to