Differences
This shows you the differences between two versions of the page.
courses:cs211:winter2014:journals:stephen:home:chapter-5.3 [2014/03/11 00:34] โ created rowleys | courses:cs211:winter2014:journals:stephen:home:chapter-5.3 [2014/03/11 17:43] (current) โ rowleys | ||
---|---|---|---|
Line 1: | Line 1: | ||
**__Chapter 5.3: Counting Inversions__** | **__Chapter 5.3: Counting Inversions__** | ||
+ | |||
+ | Consider comparing two rankings of the same set of n movies. | ||
+ | |||
+ | **Designing/ | ||
+ | |||
+ | We can count the number of inversions in O(nlogn) time since there can be a quadratic number of inversions and therefore there must be such an algorithm to compute the total number without ever looking at each inversion individually. | ||
+ | |||
+ | Now the hard part. Merge-and-Count is the process we use once we have recursively sorted the first and second halves of the list and counted the inversions in each. We now have two sorted lists A and B, and we want to produce a single sorted list C from their union, while also counting the number of pairs (a,b) with a in A, b in B, and a > b. Merging is very similar to mergesort, however we also need to count the inversions. | ||
+ | |||
+ | Here is the algorithm in full: | ||
+ | |||
+ | Merge-and-Count(A, | ||
+ | Maintain a //Current// pointer into each list, initialized to point to the front elements | ||
+ | Maintain a variable //Count// for the number of inversions = 0 | ||
+ | While both lists are nonempty: | ||
+ | Let a(i) and j(j) be the elements pointed to by the //Current// pointer | ||
+ | Append the smaller of these two two the output list | ||
+ | If b(j) is the smaller element then | ||
+ | Increment //Count// by the number of elements remaining in A | ||
+ | Advance the //Current// pointer in the list from which the smaller element was selected | ||
+ | Once one list is empty, append the remainder of the other list to the output | ||
+ | Return //Count// and the merged list | ||
+ | | ||
+ | This runtime is O(n). | ||
+ | |||
+ | The whole algorithm is as follows: | ||
+ | |||
+ | Sort-and-Count(L) | ||
+ | If the list has one element then there are no inversions | ||
+ | Else | ||
+ | Divide the list into two halves: | ||
+ | A contains the first [n/2] elements | ||
+ | B contains the remaining [n/2] elements | ||
+ | (r(a), A) = Sort-and-Count(A) | ||
+ | (r(b), B) = Sort-and-Count(B) | ||
+ | (r, L) = Merge-and-Count(A, | ||
+ | | ||
+ | Return r = r(a) + r(b) + r, and the sorted list L | ||
+ | |||
+ | Since merge-and-count takes O(n) the running time of the full Sort-and-Count takes O(nlogn) due to its sorting. | ||
+ | |||
+ | This is a very easily understood chapter and a very useful algorithm. | ||
+ |