Praktikum 1 Pengenalan struktur data dan kompleksitas waktu MODUL PRAKTIKUM BASIS DATA PENGENALAN STRUKTUR DATA DAN KOMPLEKSITAS WAKTU Deskripsi Singkat Praktikum struktur data dan algoritma adalah praktikum yang mendukung mata kuliah struktur data dan algoritma. Praktikum ini akan menggunakan bahasa pemrograman Java sehingga mata kuliah Pemrograman Berorientasi Objek merupakan prasyarat bagi mata kuliah ini. Dalam istilah ilmu komputer, sebuah struktur data adalah cara penyimpanan, penyusunan dan pengaturan data di dalam media penyimpanan komputer sehingga data tersebut dapat digunakan secara efisien. Dalam matematika dan komputasi, algoritma merupakan kumpulan perintah untuk menyelesaikan suatu masalah. Perintah-perintah ini dapat diterjemahkan secara bertahap dari awal hingga akhir. Masalah tersebut dapat berupa apa saja, dengan catatan untuk setiap masalah, ada kriteria kondisi awal yang harus dipenuhi sebelum menjalankan algoritma. Algoritma sering mempunyai langkah pengulangan (iterasi) atau memerlukan keputusan (logika Boolean dan perbandingan) sampai tugasnya selesai. Kompleksitas dari suatu algoritma merupakan ukuran seberapa banyak komputasi yang dibutuhkan algoritma tersebut untuk menyelesaikan masalah. Secara informal, algoritma yang dapat menyelesaikan suatu permasalahan dalam waktu yang singkat memiliki kompleksitas yang rendah, sementara algoritma yang membutuhkan waktu lama untuk menyelesaikan masalahnya mempunyai kompleksitas yang tinggi. Tujuan 1. Membuat class ArrayTerurut dan ArrayTakTerurut beserta dengan method searchingnya. 2. Membuktikan kompleksitas waktu sequential searching dan binary searching. Materi 1 : Class ArrayTerurut, class ArrayTakTerurut dan Method Searching Pertama sekali kita akan memanfaatkan konsep inheritance dan abstract class untuk membuat hirarki class Arrays yang kemudian akan kita bedakan menjadi class ArrayTerurut dan class ArrayTakTerurut. Class Arrays digunakan untuk memaksa class turunannya untuk meng-override method insert dan delete. Class Arrays juga digunakan untuk membuat method display yang akan berlaku bagi semua subclass. Berikut code class Arrays. public abstract class Arrays { // instance variables - replace the example below with your own //menampilkan semua data dalam array public void display(double[] a, int n) { Viska Mutiawani, M.IT, Irvanizam, M.Sc, Dr. Taufik Fuadi Abidin Jurusan Informatika Universitas Syiah Kuala Praktikum 1 Pengenalan struktur data dan kompleksitas waktu for(int i=0; i<n; i++) System.out.println(a[i]); } //method abstract untuk memasukkan data, //implementasinya pada subclass public abstract void insert(double value); //method abstract untuk menghapus data, //implementasinya pada subclass public abstract void delete(double value); } Class ArrayTakTerurut merupakan tempat untuk menyimpan data bertipe double yang tidak terurut. Class ini memiliki method sequential searching (linear searching). Class ArrayTakTerurut merupakan subclass dari class Arrays sehingga class ini harus meng-override method insert dan delete. Berikut code class ArrayTakTerurut. public class ArrayTakTerurut extends Arrays { // instance variables - replace the example below with your own private double[] a; // ref to array a private int nElems; // number of data items /** * Constructor for objects of class ArrayTakTerurut */ public ArrayTakTerurut(int max) { // initialise instance variables a = new double[max]; // create the array nElems = 0; // no items yet } //mengembalikan jumlah data yang ada dalam array public int size() { return nElems; } //menampilkan semua data dalam array public void display() { super.display(a, nElems); } //sequential searching. Mencari data dengan mencari data satu per satu public int sequentSearch(double searchKey) { Viska Mutiawani, M.IT, Irvanizam, M.Sc, Dr. Taufik Fuadi Abidin Jurusan Informatika Universitas Syiah Kuala Praktikum 1 Pengenalan struktur data dan kompleksitas waktu int n = nElems; int i = 0; while(i < n) { if(a[i] == searchKey) return i; i++; } return n; } @Override public void insert(double value) { a[nElems] = value; nElems++; } @Override public void delete(double value) { int posisiIndeks = this.sequentSearch(value); if(posisiIndeks == nElems) System.out.println("Posisi data yang ditemukan."); else { //hapus data dengan menurunkan semua data for(int i=posisiIndeks; i<nElems; i++) a[posisiIndeks] = a[posisiIndeks+1]; nElems--; } } } dihapus tidak Class ArrayTerurut merupakan tempat untuk menyimpan data bertipe double yang terurut. Untuk sementara class ini belum memiliki method sorting, sehingga saat class ini digunakan diharapkan data yang dimasukkan dalam keadaan terurut. Class ini memiliki method binary searching. Class ArrayTerurut merupakan subclass dari class Arrays sehingga class ini harus meng-override method insert dan delete. Berikut code class ArrayTerurut. public class ArrayTerurut extends Arrays { // instance variables - replace the example below with your own private double[] a; // ref to array a Viska Mutiawani, M.IT, Irvanizam, M.Sc, Dr. Taufik Fuadi Abidin Jurusan Informatika Universitas Syiah Kuala Praktikum 1 Pengenalan struktur data dan kompleksitas waktu private int nElems; // number of data items /** * Constructor for objects of class ArrayTerurut */ public ArrayTerurut(int max) { // initialise instance variables a = new double[max]; // create the array nElems = 0; // no items yet } //mengembalikan jumlah data yang ada dalam array public int size() { return nElems; } //menampilkan semua data dalam array public void display() { super.display(a, nElems); } //binary searching. Mencari data dengan membagi dua public int binarySearch(double searchKey) { int lowerBound = 0; int upperBound = nElems-1; int curIn; while(true) { curIn = (lowerBound + upperBound ) / 2; if(a[curIn]==searchKey) return curIn; // found it else if(lowerBound > upperBound) return nElems; // can't find it else // divide range { if(a[curIn] < searchKey) lowerBound = curIn + 1; // it's in upper half else upperBound = curIn - 1; // it's in lower half } // end else divide range } // end while } @Override public void insert(double value) { int j; Viska Mutiawani, M.IT, Irvanizam, M.Sc, Dr. Taufik Fuadi Abidin Jurusan Informatika Universitas Syiah Kuala Praktikum 1 Pengenalan struktur data dan kompleksitas waktu for(j=0; j<nElems; j++) // find where it goes if(a[j] > value) // (linear/sequential search) break; //naikkan ke atas dulu untuk memasukkan data for(int k=nElems; k>j; k--) a[k] = a[k-1]; a[j] = value; // insert it nElems++; // increment size } @Override public void delete(double value) { int posisiIndeks = this.binarySearch(value); if(posisiIndeks == nElems) System.out.println("Posisi data yang ditemukan."); else { //hapus data dengan menurunkan semua data for(int i=posisiIndeks; i<nElems; i++) a[posisiIndeks] = a[posisiIndeks+1]; nElems--; } } } dihapus tidak Kemudian kita buat class yang akan menggunakan class array tersebut di atas. Saat ini kita hanya akan mencoba memasukkan data (insert), menghapus data (delete) dan menampilkan data (display). Berikut contoh codenya. public class SearchingApp { public static void main(String[] args) { int maxSize = 20; //ukuran array //mencipta objek arrayterurut ArrayTerurut arr = new ArrayTerurut(maxSize); //mencipta objek arraytakterurut ArrayTakTerurut arrt = new ArrayTakTerurut(maxSize); //masukkan 5 data terurut ke dalam arr int k = 1; for(int i=0; i<5; i++) Viska Mutiawani, M.IT, Irvanizam, M.Sc, Dr. Taufik Fuadi Abidin Jurusan Informatika Universitas Syiah Kuala Praktikum 1 Pengenalan struktur data dan kompleksitas waktu { arr.insert(k); k++; } arr.display(); //masukkan 5 data acak ke dalam arrt for(int i=0; i<100000; i++) { int x = 1 + (int) (Math.random() * 10); arrt.insert(x); } arrt.display(); arr.delete(15.0); arr.display(); arrt.delete(15.0); arrt.display(); } } Materi 2 : Pembuktian Kompleksitas Waktu Dua Metode Searching Kali ini kita akan membuktikan kompleksitas waktu antara metode pencarian sekuensial dan pencarian binary. Secara teori, pencarian binary lebih cepat yaitu O(log n), sedangkan pencarian sekuensial O(n). Untuk pengujian tersebut kita akan membuat class TimeInterval yang berguna untuk menghitung interval waktu. Berikut code programnya. public class TimeInterval { // instance variables - replace the example below with your own private long startTime, endTime; private long elapsedTime; // Time Interval in milliseconds /** * Constructor for objects of class TimeInterval */ public TimeInterval() { // initialise instance variables } //method untuk memulai menghitung waktu public void startTiming() { elapsedTime = 0; startTime = System.currentTimeMillis(); } //method untuk mengakhir penghitungan waktu Viska Mutiawani, M.IT, Irvanizam, M.Sc, Dr. Taufik Fuadi Abidin Jurusan Informatika Universitas Syiah Kuala Praktikum 1 Pengenalan struktur data dan kompleksitas waktu public void endTiming() { endTime = System.currentTimeMillis(); elapsedTime = endTime - startTime; } //method untuk mengembalikan interval waktu public double getElapsedTime() { return (double) elapsedTime / 1000.0; } } Ubah method main pada class SearchingApp seperti code di bawah. int maxSize = 100; //ukuran array double nilaiDicari = 13.0; int posisi = 0; //mencipta objek arrayterurut ArrayTerurut arr = new ArrayTerurut(maxSize); //mencipta objek arraytakterurut ArrayTakTerurut arrt = new ArrayTakTerurut(maxSize); //mencipta objek timeinterval untuk menghitung interval waktu TimeInterval ti = new TimeInterval(); //masukkan 100 data terurut ke dalam arr int k = 1; for(int i=0; i<maxSize; i++) { arr.insert(k); k++; } //arr.display(); //masukkan 100 data acak ke dalam arrt for(int i=0; i<maxSize; i++) { int x = 1 + (int) (Math.random() * 10); arrt.insert(x); } //arrt.display(); //membuktikan kompleksitas waktu sequential search dan binary search ti.startTiming(); posisi = arrt.sequentSearch(nilaiDicari); ti.endTiming(); Viska Mutiawani, M.IT, Irvanizam, M.Sc, Dr. Taufik Fuadi Abidin Jurusan Informatika Universitas Syiah Kuala Praktikum 1 Pengenalan struktur data dan kompleksitas waktu System.out.println("Posisi +posisi); System.out.println("Waktu search: " +ti.getElapsedTime()); " +nilaiDicari+ yang diperlukan " di oleh posisi " sequential ti.startTiming(); posisi = arr.binarySearch(nilaiDicari); ti.endTiming(); System.out.println("Posisi " +nilaiDicari+ " di posisi " +posisi); System.out.println("Waktu yang diperlukan oleh binary search: " +ti.getElapsedTime()); LATIHAN 1 Untuk mencari interval waktu ini, kita akan memulai dari array dengan maxSize=100, cek hasilnya. Jika tidak ada perbedaan waktu, naikkan menjadi 1000, cek kembali. Naikkan kembali menjadi 10000, 100000, 1000000, 1000000. Catat perubahan waktu untuk masing-masing metode searching seperti tabel di bawah. Ukuran array (maxSize) 100 1000 10000 100000 1000000 10000000 Waktu sequential searching Waktu binary searching Apakah yang dapat anda simpulkan? LATIHAN 2 Kemudian hitung interval waktu untuk proses insert dan delete pada ArrayTerurut juga ArrayTakTerurut. Jika belum tampak perbedaan pada data yang kecil, ubah ukuran array (maxSize) menjadi lebih besar. Lalu amati perubahan pada masing-masing class ArrayTerurut dan ArrayTakTerurut. SOAL-SOAL 1. Viska Mutiawani, M.IT, Irvanizam, M.Sc, Dr. Taufik Fuadi Abidin Jurusan Informatika Universitas Syiah Kuala