Вы находитесь на странице: 1из 6

Algorithms Counting Inversions using Haskell

Pi19404
July 30, 2013

Contents

Contents
Algorithms - Counting Inversions using Haskell 3

0.1 Introduction . . . . . . 0.2 Inversion . . . . . . . . . 0.2.1 Implementation 0.2.2 Code . . . . . . . References . . . . . . . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

3 3 3 6 6

2|6

Algorithms - Counting Inversions using Haskell

Algorithms - Counting Inversions using Haskell


0.1 Introduction
In this article we will look at Divide and conquer approach using merge sort algorithm to count the number of inversion in an array

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

Algorithms - Counting Inversions using Haskell

-- 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

Algorithms - Counting Inversions using Haskell

0.2.2 Code
The Haskell code can be found at https://github.com/pi19404/m19404/ blob/master/Algorithm/sort/sort.hs

6|6

Вам также может понравиться