Menghitung Inversion Pada Barisan Dengan Menggunakan

advertisement
Menghitung Inversion Pada Barisan Dengan
Menggunakan Modifikasi Bubble Sort, Insertion Sort,
dan Merge Sort
M Iqbal Tawakal - 0706271954
Abstract
Jumlah inversion memiliki nilai maksimal
pada sebuah baris bilangan ketika barisan
Paper ini akan menjelaskan mengenai cara tersebut terurut terbalik, dan nilainya nol
menghitung inversion dengan menggunakan ketika barisan tersebut terurut. Contoh:
beberapa algoritma sorting yang dimodi2 4 3 5 1
fikasi sehingga bisa untuk menghitung jumlah inversion di dalam sebuah baris bi- Pada barisan bilangan di atas, terdapat
langan. Algoritma sorting yang dimod- 5 buah inversion. Inversion terjadi pada
ifikasi adalah bubble sort, insertion sort, pasangan bilangan (2,1), (4,3), (4,1), (3,1),
dan merge sort.
Ketiga algoritma itu dan (5,1).
akan diujikan untuk menghitung jumlah
inversion pada beberapa list dengan panjang yang berbeda-beda untuk kemudian Definisi Masalah
dibandingkan sehingga dapat diketahui alInputnya adalah sebuah barisan bilangan
goritma terbaik.
yang elemen-elemennya unik satu sama
lain. Output adalah sebuah bilangan jumlah inversion yang terjadi pada barisan biLatar Belakang
langan tersebut.
Inversion adalah kondisi pada sebuah
barisan bilangan yang terjadi ketika sebuah bilangan yang letaknya lebih kiri namun memiliki nilai lebih besar dari bilangan di sebelah kanannya. Misalkan A[1..n]
adalah barisan/list dari n buah angka yang
berbeda, jika i < j dan A[i] > A[j], maka antara A[i] dengan A[j] terjadi inversion. Besarnya nilai inversion bisa menjadi indikator
seberapa acaknya sebuah baris bilangan.
Penjelasan Algoritma
Untuk menghitung inversion pada paper
ini algoritma yang digunakan adalah modifikasi dari algoritma bubble sort, insertion
sort, dan merge sort. Modifikasi yang dilakukan pada bubble sort adalah ditambahkan sebuah variabel untuk menghitung
berapa kali dilakukan pertukaran, karena
1
jika terjadi pertukaran ketika sorting maka akan dimasukkan ke dalam sub barisan sedapat dipastikan kalau itu adalah kondisi belah kiri yang sudah terurut.
inversion. Pseudo code-nya
Modifikasi yang dilakukan pada merge
sort adalah pada bagian merge-nya. Letak
INV-BUBBLE-SORT (A)
perubahannya adalah ketika dilakukan per1
inv := 0
bandingan antara nilai yang ditunjuk oleh
2
FOR i:= 0 TO length[A]-1
pointer kiri yang menunjuk elemen terke3
DO FOR j:= 0 TO length[A]-2
cil yang masih ada di sublist kiri dengan
4
DO IF A[j] > A[j+1] THEN
pointer kanan yang menunjuk elemen terke5
temp := A[j]
cil yang ada di sublist kanan. Jika nilai
6
A[j] := A[j+1]
yang ditunjuk pointer kiri lebih besar dari
7
A[j+1] := temp
yang ditunjuk pointer kanan, maka terjadi
8
inv := inv + 1
inversion. Nilai inversion-nya ditambah se9
END
banyak 1 plus semua sisa elemen di sebelah
10
END
kanan sublist kiri. Pseudo code-nya
11 return inv
INV-MERGE-SORT(A, p, r)
1
if p < r
2
then q <- floor (p+r)/2
3
a := INV-MERGE-SORT(A,p,q)
4
b := INV-MERGE-SORT(A,q+1,r)
5
c := INV-MERGE(A,p,q,r)
6
return a+b+c
7
else
8
return 0
Modifikasi yang dilakukan pada insertion
sort adalah menghitung sejauh mana setiap
nilai digeser ke kanan ketika melakukan insertion, karena jika suatu elemen masih digeser ke kanan berarti terjadi kondisi inversion di sana. Pseudo code-nya
INV-INSERTION-SORT(A)
1
inv := 0;
2
FOR j := 2 TO length[A]
INV-MERGE(A, p, q, r)
3
DO key := A[j]
1
n1 <- q-p+1; n2 <- r-q; inv <- 0
4
i := j-1;
//create L[1..n1+1] and R[1..n2+1]
5
WHILE i > 0 and A[i] > key 2
3
for i <- 1 to n1 do L[i] <- A[p+i-1]
6
DO A[i+1] := A[i];
4
for j <- 1 to n2 do R[j] <- A[q+j]
7
i := i-1;
5
L[n1+1] <- inf; R[n2+1] <- inf
8
inv := inv + 1;
6
i <- 1; j <- 1
9
END
7
for k <- p to r
10
A[i+1] := key
8
do if L[i] < R[j]
11
END
9
then A[k] <- L[i]
12
return inv;
10
i <- i + 1
Jika dibandingkan algoritma aslinya, pada 11
else A[k] <- R[j]
modifikasi ini cukup ditambahkan incre- 12
j <-j + 1
ment ke sebuah variabel setiap terjadi 13
inv <- inv + (length(L)-i-1)
pergeseran untuk meletakkan elemen yang 14
end
2
15
Hasil percobaan dapat
Waktu dalam sekon.
n
Bubble
1000 0.002371
10000 0.02566
100000 19.58041
1000000
201
return inv
Jika dibandingkan dengan algoritma
aslinya, algoritma modifikasi ini ditambahkan baris untuk menambah nilai
variabel inv jika terjadi inversion dengan
sebanyak elemen yang masih terdapat di
sublist kiri. Karena setelah pemanggilan
merge-sort, antar elemen dalam sublist
yang sama pasti terurut, maka semua
elemen yang ada di sebelah kanan elemen
yang sekarang ditunjuk oleh pointer kiri
nilainya pasti lebih besar dibandingkan
elemen yang sedang ditunjuk itu. Akibatnya, pasti terjadi inversion untuk
semua elemen di kanan. Karena itu cukup
ditambahkan sebanyak elemen yang ada di
sublist kiri, tidak perlu diperiksa satu-satu
perelemennya.
dilihat di tabel.
Insertion
Merge
0.000633 0.0008269
0.00736 0.006524
0.214274 0.011369
22.16636 0.152429
Analisis
Dari hasil percobaan penggunaan beberapa
algoritma sorting yang sudah dimodifikasi
untuk menghitung inversion, terlihat bahwa
waktunya mengikuti kompleksitas dari algoritma sorting-nya. Bubble sort yang
kompleksitas waktunya O(n2 ) performanya
kalah dibandingkan insertion sort yang juga
sama-sama O(n2 ) namun memiliki implementasi lebih efisien. Tetapi keduanya dibatasi batasan yang dimiliki oleh algoritma
sorting by comparison yang perbandingannya dilakukan side by side (dengan angka
disebelahnya). Sedangkan merge sort tidak
terkena batasan itu, dan kompleksitasnya
lebih bagus yaitu O(nlogn). Sehingga untuk perhitungan inversion dengan memakai
merge sort jauh lebih cepat dibandingkan
algoritma sorting lainnya, terutama untuk
jumlah data yang banyak. Hal lain yang
membuat merge sort lebih cepat dalam hal
menghitung inversion adalah tidak perlu
dibandingkan dengan semua elemen untuk
mengetahui apakah terjadi inversion.
Percobaan
Untuk percobaan perbandingan performa,
semua algoritma akan diuji dengan beberapa test case. Inputnya adalah barisan bilangan yang semua elemennya unik dengan
panjang bervariasi mulai dari 100, 1000,
10000, dan 100000. Contoh input dengan
panjang 100:
96, 90, 10, 20, 67, 28, 25, 4, 84, 48, 93,
19, 54, 3, 14, 11, 2, 59, 92, 22, 24, 51, 70,
31, 77, 64, 99, 1, 23, 72, 29, 85, 6, 91, 98,
61, 73, 38, 62, 36, 81, 58, 9, 68, 35, 71, 42,
76, 7, 66, 78, 16, 74, 63, 52, 53, 95, 75, 45,
17, 30, 86, 15, 21, 8, 83, 12, 27, 39, 94, 37,
65, 82, 47, 60, 18, 49, 50, 87, 32, 56, 33, 13,
40, 88, 41, 89, 44, 79, 97, 100, 43, 34, 26,
46, 57, 80, 55, 69, 5
Jumlah inversion pada barisan tersebut
adalah 2315.
Kesimpulan
Inversion dapat dihitung dengan melakukan
modifikasi terhadap beberapa algoritma
sorting, dan kompleksitas penghitungannya mengikuti dari algoritma sorting mana
3
yang dipakai. Dalam paper ini, algoritma
merge sort mengungguli algoritma bubble
sort dan insertion sort dalam hal menghitung inversion.
Referensi
Cormen, Thomas H., Leiserson, Charles E.,
and Rivest, Ronald L.: Introduction To Algorithm, Second Edition. MIT Press, Massachusetts (2001).
Lampiran - Source Code
Program
4
import java.util.List;
import java.util.ArrayList;
import java.util.Date;
public class DAA {
public static void main(String[] args)
int[] testcase = 100, 1000, 10000, 100000;
for(int i=0; i<testcase.length; i++)
System.out.println("Testcase "+(i+1)+": "+testcase[i]);
int[] li = generateList(testcase[i]);
System.out.println("Bubble Sort");
long start = System.nanoTime();
System.out.println(invbubblesort(li.clone()));
long end = System.nanoTime();
System.out.println("Waktunya "+(end-start));
System.out.println("Insertion Sort");
start = System.nanoTime();
System.out.println(invinsertionsort(li.clone()));
end = System.nanoTime();
System.out.println("Waktunya "+(end-start));
System.out.println("Merge Sort");
start = System.nanoTime();
System.out.println(invmergesort(li.clone()));
end = System.nanoTime();
System.out.println("Waktunya "+(end-start));
public static void cetak(int[] li)
for(int i=0; i<li.length; i++)
System.out.print(li[i]+", ");
System.out.println();
public static int[] generateList(int n)
int[] res = new int[n];
List<Integer> list = new ArrayList<Integer>();
for(int i=1; i<=n; i++)
list.add(i);
5
for(int i=0; i<n; i++)
int rand = (int)(Math.random()*list.size());
res[i] = list.remove(rand);
return res;
public static int invbubblesort(int[] A)
int inversion = 0;
for(int i=0; i<A.length; i++)
for(int j=0; j<A.length-1; j++)
if(A[j] > A[j+1])
int temp = A[j];
A[j] = A[j+1];
A[j+1] = temp;
inversion++;
return inversion;
public static int invinsertionsort(int[] A)
int inversion = 0;
for(int j=1; j<A.length; j++)
int key = A[j];
int i = j-1;
while(i>=0 && A[i] > key)
A[i+1] = A[i];
i--;
inversion++;
A[i+1] = key;
return inversion;
public static int invmergesort(int[] A)
return mergesort(A,0,A.length-1);
public static int mergesort(int[] A, int p, int r)
if(p < r)
int q = (p+r)/2;
6
int a = mergesort(A,p,q);
int b = mergesort(A,q+1,r);
int c = merge(A,p,q,r);
return a+b+c;
return 0;
public static int merge(int[] A, int p, int q, int r)
int n1 = q-p+1, n2 = r-q;
int inversion = 0;
int[] L = new int[n1+2];
int[] R = new int[n2+2];
for(int i=1; i<=n1; i++)
L[i] = A[p+i-1];
for(int j=1; j<=n2; j++)
R[j] = A[q+j];
L[n1+1] = Integer.MAX_VALUE;
R[n2+1] = Integer.MAX_VALUE;
int i = 1, j = 1;
for(int k=p; k<=r; k++)
if(L[i] < R[j])
A[k] = L[i];
i++;
else
A[k] = R[j];
j++;
int temp = L.length-i-1;
inversion += temp;
return inversion;
}
7
Download