Algorithms - Inversion Count Using Haskell
Algorithms - Inversion Count Using Haskell
Pi19404
July 30, 2013
Contents
Contents
Algorithms - Counting Inversions using Haskell 3
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
3 3 3 6 6
2|6
0.2 Inversion
The count of inversion in an array is the count of a[i] > a[j ] for i > j .This is basicially the number of comparisions required to arrage the elements in sorted order. The number of inversion for sorted array is 0 while for a re1 ,maximum number of inversions that can be verse array is nn 2 encountered for unsorted array. The naive way of counting iversion would be to count all instance of a[i] > a[j ] for i > j ,which is O(N 2 ). The merge sort can be used to count inversion.
0.2.1 Implementation
In the merge sort algorithm ,in the merge step we check instance x > y of the first element of array A with the first element of array B.And if x > y ,condition would require inversion. Thus in the merge step we count all the instances of x > y condition is statisfied. This applies to case when A and B are unsorted arrays. In the present implementation we have used a boolean flag to inform the merge step if the input arrays are sorted or unsorted.
3|6
Algorithms - Counting Inversions using Haskell Now if both A and B are sorted and inversion in encountered A(1) > B (1),then total number of inversion encountered in the union of A,B can be expressed as length(A). For examples A = [3; 5] and B = [1; 2] , the number of inversion required wrt element (3; 1) is 1,thus any element greater than 3 in sorted array A will also require the same number of inversions.Thus total number of inversions is counted as 2 for pairs (3; 1); (5; 1).Similarily in the next step for the array A = [3; 5] and B = [2] the total number of inversions are 2 for pairs (3; 2); (5; 2).Thus in general the number of inversion encoutered at each step are length(A). The implementation of algorithm in Haskel is provided.
--split -- split an array of size N into two arrays of size N/2 -- the computation of total length of the list is required split :: Ord a =>[a]->Int->([a],[a],Int) split s i= (l1,l2,(i+1)) where (l1,l2)=splitAt ( div (length(s)) 2 ) s --merge sort -- the function to merge the 2 sorted lists -- iput is the lists to be sorted and current number of inversions -- output is merger list + total number of computation required for merge -- flag is used to indicate if array is sorted or unsorted -- used for inversion count merge1 :: Ord a =>[a]->[a]->Int->Bool->([a],Int) merge1 [] xs i _ = (xs,i) merge1 xs [] i _ = (xs,i) merge1 (x:xs) (y:ys) i flag |x<y = (x:a1,a2) |otherwise = case flag of t|t==False->(y:b1,b2) |otherwise->(y:b1,b1) where (a1,a2)=merge1 xs (y:ys) (i) flag (b1,b2)=merge1 (x:xs) ys (i1) flag i1=case flag of -- inversion of single element considered for unsorted array t|t==False->(i+1) -- inversion of all elements >x considered is A,B sorted array |otherwise -> i+length(x:xs)
4|6
-- the recrsive for merge sort algorithm -- input is list ,output is merge sorted list and number of inversions merge_sort' :: Ord a=>[a]->Int->([a],Int) merge_sort' list i | length(list)==1=(list,i) | otherwise =(o1,o2) where (list1,list2,m5)=(split list 0) (list3,m3)=merge_sort' list1 (0) (list4,m4)=merge_sort' list2 (0) -- call merge with true flag for inversion count (o1,o2)=merge1 list3 list4 (m3+m4) True -- main function to be called for merge sort algoritm merge_sort :: Ord a =>[a]->([a],Int) merge_sort s = merge_sort' s 0 -- function to split array,if i is positive position from -- start of list,if i is negative position from end of list select :: Ord a=>[a]->Int-> ([a],[a]) select (n) i= case i of t| t<=0 -> splitAt (length(n)+t) n |otherwise -> splitAt t n
-- function to read input from a file,each element of line -- placed in a seperate line,if i=-1 the last line of file -- contains result of inversion and is displayed in the result readFile :: FilePath ->Int-> IO (Int,[Int]) readFile path int1 = do contents <- readFile path return(execute (select (map readInt1 (lines contents)) (int where execute (s,s1) =(snd(merge_sort s),s1) -- function to convert string to int readInt1 :: String -> Int readInt1 = read
5|6
0.2.2 Code
The Haskell code can be found at https://github.com/pi19404/m19404/ blob/master/Algorithm/sort/sort.hs
6|6