TUGAS AKHIR - KI141502
STUDI KINERJA WAVELET TREE PADA VARIASI
PERMASALAHAN RANGE QUERY
FENDY
NRP 5113 100 017 Dosen Pembimbing 1
Arya Yudhi Wijaya, S.Kom., M.Kom. Dosen Pembimbing 2
Rully Soelaiman, S.Kom., M.Kom. JURUSAN TEKNIK INFORMATIKA Fakultas Teknologi Informasi
TUGAS AKHIR - KI141502
STUDI KINERJA WAVELET TREE PADA VARIASI PERMASALAHAN RANGE QUERY
FENDY
NRP 5113 100 017
Dosen Pembimbing 1
Arya Yudhi Wijaya, S.Kom., M.Kom.
Dosen Pembimbing 2
Rully Soelaiman, S.Kom., M.Kom.
JURUSAN TEKNIK INFORMATIKA Fakultas Teknologi Informasi
UNDERGRADUATE THESES - KI141502
WAVELET TREE PERFORMANCE STUDY ON VARIOUS RANGE QUERY PROBLEMS
FENDY
NRP 5113 100 017
Supervisor 1
Arya Yudhi Wijaya, S.Kom., M.Kom.
Supervisor 2
Rully Soelaiman, S.Kom., M.Kom.
INFORMATICS DEPARTMENT
STUDI KINERJA WAVELET TREE PADA VARIASI PERMASALAHAN RANGE QUERY
Nama : FENDY
NRP : 5113 100 017
Jurusan : Teknik Informatika FTIF - ITS Pembimbing I : Arya Yudhi Wijaya, S.Kom., M.Kom. Pembimbing II : Rully Soelaiman, S.Kom., M.Kom.
Abstrak
Komputasi range query merupakan sebuah masalah yang melibat-kan sebuah rentang pencarian. Tipe query secara umum dibagi menjadi dua yaitu, operasi pencarian dan perubahan. Operasi per-ubahan pada suatu rentang akan menyebabkan perper-ubahan hasil pencarian selanjutnya. Dalam permasalahan range query ini cukup banyak operasi yang harus dilakukan sehingga dibutuhkan struktur data yang mampu mendukung operasi-operasi tersebut secara efi-sien.
Pada Tugas Akhir ini akan dirancang penyelesaian permasalahan variasi range query antara lain, operasi pencarian bilangan ter-kecil ke-k, menghitung jumlah elemen yang aktif, mengubah sta-tus dari sebuah elemen, dan menukar elemen yang bersebelahan. Struktur data klasik yang sering digunakan untuk permasalahan ini adalah balanced binary search tree atau segmented tree. Namun pada Tugas Akhir ini digunakan Wavelet Tree untuk menyelesaik-an operasi-operasi tersebut.
Hasil dari Tugas Akhir ini telah berhasil menyelesaikan permasalahan di atas dengan cukup efisien dengan komplek-sitas waktuO(lgN)per query.
Kata Kunci: range query, wavelet tree, rank query, quan-tile query
WAVELET TREE PERFORMANCE STUDY ON VARIOUS RANGE QUERY PROBLEMS
Name : FENDY
NRP : 5113 100 017
Major : Informatics Department Faculty of IT - ITS Supervisor I : Arya Yudhi Wijaya, S.Kom., M.Kom. Supervisor II : Rully Soelaiman, S.Kom., M.Kom.
Abstract
Range query computation is a problem which involves a specific range of data. Generally it is divided by two type of query, range search and update. An update operation would have an impact for the following range search query. Typically these kind of problems will have quite large number of queries. Thus, an efficient data structure is needed to support the operations.
This undergraduate thesis will design the problem solving for ra-nge query variation such as, find the k-th smallest element, count the number of active elements, toggle an element status, and swap contiguous element. Well known data structures, e.g. balanced bi-nary search tree and segmented tree, are commonly used for solving this problem. Yet, in this undergraduate thesis Wavelet Tree will be used instead for solving those range query variations.
The result shows that wavelet tree has been successfully solve the problem efficiently with overall complexity ofO(lgN)each query.
Keywords: range query, wavelet tree, rank query, quanti-le query
KATA PENGANTAR
Puji syukur penulis panjatkan kepada Tuhan Yang Maha Esa atas pimpinan, penyertaan, dan karunia-Nya sehingga penulis dapat me-nyelesaikan Tugas Akhir yang berjudul :
STUDI KINERJAWAVELET TREEPADA VARIASI PERMASALAHANRANGE QUERY.
Penelitian Tugas Akhir ini dilakukan untuk memenuhi salah satu syarat meraih gelar Sarjana di Jurusan Teknik Informatika Fakultas Teknologi Informasi Institut Teknologi Sepuluh Nopember. Dengan selesainya Tugas Akhir ini diharapkan apa yang telah diker-jakan penulis dapat memberikan manfaat bagi perkembangan ilmu pengetahuan terutama di bidang teknologi informasi serta bagi diri penulis sendiri selaku peneliti.
Penulis mengucapkan terima kasih kepada semua pihak yang te-lah memberikan dukungan baik secara langsung maupun tidak lang-sung selama penulis mengerjakan Tugas Akhir maupun selama me-nempuh masa studi antara lain:
• Ayah, Ibu dan keluarga penulis yang selalu memberikan per-hatian, dorongan dan kasih sayang yang menjadi semangat utama bagi diri penulis baik selama penulis menempuh masa kuliah maupun pengerjaan Tugas Akhir ini.
• Bapak Rully Soelaiman, S.Kom., M.Kom. selaku Dosen Pembimbing yang telah banyak meluangkan waktu untuk memberikan ilmu, nasihat, motivasi, pandangan dan bim-bingan kepada penulis baik selama penulis menempuh masa kuliah maupun selama pengerjaan Tugas Akhir ini.
• Bapak Arya Yudhi Wijaya, S.Kom., M.Kom. selaku dosen
pembimbing yang telah memberikan ilmu, dan masukan ke-pada penulis.
• Seluruh tenaga pengajar dan karyawan Jurusan Teknik Infor-matika ITS yang telah memberikan ilmu dan waktunya demi berlangsungnya kegiatan belajar mengajar di Jurusan Teknik Informatika ITS.
• Seluruh teman penulis di Jurusan Teknik Informatika ITS yang telah memberikan dukungan dan semangat kepada pe-nulis selama pepe-nulis menyelesaikan Tugas Akhir ini.
• Seluruh pihak yang tidak bisa penulis sebutkan satu-persatu yang telah memberikan dukungan selama penulis menyelesa-ikan Tugas Akhir.
Penulis mohon maaf apabila masih ada kekurangan pada Tugas Akhir ini. Penulis juga mengharapkan kritik dan saran yang membangun untuk pembelajaran dan perbaikan di kemudian hari. Semoga melalui Tugas Akhir ini penulis dapat memberikan kontribusi dan manfaat yang sebaik-baiknya.
Surabaya, Januari 2017
DAFTAR ISI
SAMPUL i
LEMBAR PENGESAHAN vii
ABSTRAK ix
ABSTRACT xi
KATA PENGANTAR xiii
DAFTAR ISI xv
DAFTAR TABEL xix
DAFTAR GAMBAR xxi
DAFTAR KODE SUMBER xxv
1 PENDAHULUAN 1
1.1 Latar Belakang . . . 1
1.2 Rumusan Masalah . . . 2
1.3 Batasan Masalah . . . 3
1.4 Tujuan . . . 3
1.5 Metodologi . . . 4
1.6 Sistematika Penulisan . . . 5
2 DASAR TEORI 7 2.1 Deskripsi Permasalahan . . . 7 2.1.1 Operasi Mencari Bilangan Terkecil ke-K . 8
2.1.2 Operasi Menghitung Jumlah Elemen yang
Aktif . . . 8
2.1.3 Operasi Mengubah Status dari Sebuah Ele-men . . . 8
2.1.4 Operasi Menukar Elemen yang Bersebelahan 10 2.2 Dataset yang Digunakan . . . 10
2.3 WaveletTrees . . . 12
2.3.1 Bit vector . . . 15
2.3.2 M apLef tdanM apRight . . . 15
2.3.3 Rank Query . . . 17
2.3.4 Quantile Query . . . 19
2.3.5 ToggleUpdate . . . 22
2.3.6 SwapUpdate . . . 25
3 DESAIN 29 3.1 Permasalahan I Love Kd-Trees . . . 29
3.1.1 Deskripsi Umum Sistem . . . 29
3.1.2 Desain Fungsi Init . . . 30
3.1.3 Desain Fungsi Build . . . 30
3.1.4 Desain Fungsi KthQuery . . . 32
3.2 Permasalahan I Love Kd-Trees II . . . 33
3.2.1 Deskripsi Umum Sistem . . . 33
3.2.2 Desain Fungsi Init . . . 34
3.2.3 Desain Fungsi Build . . . 34
3.2.4 Desain Fungsi ActiveElementRangeQuery 36 3.2.5 Desain Fungsi ActiveElementQuery . . . . 36
3.2.6 Desain Fungsi ToggleElementStatus . . . . 37
3.2.7 Desain Fungsi ToggleActualStatus . . . 39
3.2.8 Desain Fungsi BITUpdate . . . 39
3.2.9 Desain Fungsi BITQuery . . . 39
3.3 Permasalahan I Love Kd-Trees III . . . 40
3.3.1 Deskripsi Umum Sistem . . . 40
xvii
3.3.3 Desain Fungsi Build . . . 42
3.3.4 Desain Fungsi KthQuery . . . 43
3.3.5 Desain Fungsi SwapElement . . . 43
3.3.6 Desain Fungsi UpdateOccurence . . . 44
4 IMPLEMENTASI 47 4.1 Lingkungan Implementasi . . . 47
4.2 Permasalahan I Love Kd-Trees . . . 47
4.2.1 Implementasi Fungsi Main . . . 47
4.2.2 Implementasi Variabel Global . . . 48
4.2.3 Implementasi Fungsi Init . . . 49
4.2.4 Implementasi Fungsi Build . . . 49
4.2.5 Implementasi Fungsi KthQuery . . . 50
4.3 Permasalahan I Love Kd-Trees II . . . 51
4.3.1 Implementasi Fungsi Main . . . 51
4.3.2 Implementasi Variabel Global . . . 52
4.3.3 Implementasi Fungsi Init . . . 53
4.3.4 Implementasi Fungsi Build . . . 54
4.3.5 Implementasi Fungsi ActiveElementRa-ngeQuery . . . 55
4.3.6 Implementasi Fungsi ActiveElementQuery 55 4.3.7 Implementasi Fungsi ToggleElementStatus 56 4.3.8 Implementasi Fungsi ToggleActualStatus . 57 4.3.9 Implementasi Fungsi BITUpdate . . . 58
4.3.10 Implementasi Fungsi BITQuery . . . 58
4.4 Permasalahan I Love Kd-Trees III . . . 58
4.4.1 Implementasi Fungsi Main . . . 59
4.4.2 Implementasi Variabel Global . . . 60
4.4.3 Implementasi Fungsi Init . . . 60
4.4.4 Implementasi Fungsi Build . . . 61
4.4.5 Implementasi Fungsi KthQuery . . . 61
4.4.6 Implementasi Fungsi SwapElement . . . . 62
5 UJI COBA DAN EVALUASI 65
5.1 Lingkungan Uji Coba . . . 65
5.2 Uji Coba . . . 65
5.2.1 Uji Coba Kebenaran . . . 65
5.2.2 Uji Coba Generalisasi . . . 83
6 KESIMPULAN 85 6.1 Kesimpulan . . . 85
DAFTAR PUSTAKA 87
DAFTAR TABEL
5.1 Indeks kemunculan suatu simbol. . . 68 5.2 Tabel occurences yang telah diubah. . . 81
DAFTAR GAMBAR
2.1 Ilustrasi operasi mencari bilangan terkecil ke-K. . 8
2.2 Ilustrasi operasi menghitung jumlah elemen yang aktif. . . 9
2.3 Ilustrasi operasi mengubah status dari sebuah elemen. 9 2.4 Ilustrasi operasi menghitung jumlah elemen yang aktif setelah terjadi perubahan status dari sebuah elemen. . . 10
2.5 Ilustrasi operasi menukar elemen yang bersebelahan. 10 2.6 Pseudocode Build . . . 13
2.7 Strukturwavelet treeuntuk sequence awalS. . . . 14
2.8 Strukturwavelet treedenganM apLef t. . . 17
2.9 PseudocodeRank Query. . . 18
2.10 Eksekusirank(5,2). . . 19
2.11 Eksekusi akhirrank(5,2). . . 20
2.12 PseudocodeQuantile Query. . . 21
2.13 Eksekusiquantile4(4). . . 21
2.14 Proses penulusuran untuk operasiquantile4(4) . . 22
2.15 Strukturwaveletyang mendukung operasitoggle. . 23
2.16 Pseudocode ToggleUpdate. . . 24
2.17 Ilustrasi dari proses operasitoggle(3). . . 25
2.18 Pseudocode SwapUpdate. . . 26
2.19 Eksekusiswap(7). . . 26
3.1 Pseudocode Fungsi Main I Love Kd-Trees . . . 30
3.2 Pseudocode Fungsi Init I Love Kd-Trees . . . 31
3.3 Pseudocode Fungsi Build I Love Kd-Trees . . . 31
3.4 Pseudocode Fungsi KthQuery . . . 32
3.5 Pseudocode Fungsi Main I Love Kd-Trees II . . . . 34
3.6 Pseudocode Fungsi Init I Love Kd-Trees II . . . . 35 3.7 Pseudocode Fungsi Build I Love Kd-Trees II . . . 35 3.8 Pseudocode Fungsi ActiveElementRangeQuery . . 36 3.9 Pseudocode Fungsi ActiveElementQuery . . . 37 3.10 Pseudocode Fungsi ToggleElementStatus . . . 38 3.11 Pseudocode Fungsi ToggleActualStatus . . . 39 3.12 Pseudocode Fungsi BITUpdate . . . 39 3.13 Pseudocode Fungsi BITQuery . . . 40 3.14 Pseudocode Fungsi Main I Love Kd-Trees III . . . 41 3.15 Pseudocode Fungsi Init I Love Kd-Trees III . . . . 42 3.16 Pseudocode Fungsi Build I Love Kd-Trees III . . . 43 3.18 Pseudocode Fungsi UpdateOccurence . . . 44 3.17 Pseudocode Fungsi SwapElement . . . 45
5.1 Contoh kasus uji permasalahan I Love Kd-Trees. . 66 5.2 Pembentukanroot wavelet tree. . . 66 5.3 Pembentukanroot wavelet tree. . . 67 5.4 Pembentukanwavelet treepada tingkat 2. . . 68 5.5 Pembentukanwavelet treepada tingkat 3. . . 69 5.6 Strukturwavelet treeyang terbentuk. . . 70 5.7 Hasil luaran program pada contoh kasus uji
IL-KQUERY. . . 71 5.8 Hasil uji kebenaran ILKQUERY pada situs SPOJ. . 72 5.9 Grafik hasil uji kebenaran ILKQUERY pada situs
SPOJ sebanyak 20 kali. . . 72 5.10 Contoh kasus uji permasalahan I Love Kd-Trees II. 73 5.11 Struktur akhir dariwavelet tree. . . 74 5.12 Struktur node dengan indeks 9 setelah dilakukan
perubahan. . . 76 5.13 Hasil luaran program pada contoh kasus uji
xxiii
5.15 Grafik hasil uji kebenaran ILKQUERY2 pada situs SPOJ sebanyak 20 kali. . . 77 5.16 Contoh kasus uji permasalahan I Love Kd-Trees III. 78 5.17 Strukturwavelet treedengan informasi bitvector. . 79 5.18 Bagian dari strukturwavelet treeyang terkena
per-ubahan. . . 80 5.19 Isi dari rrayrev_occurence. . . 80
5.20 Hasil luaran program pada contoh kasus uji IL-KQUERYIII. . . 82 5.21 Hasil uji kebenaran ILKQUERYIII pada situs SPOJ. 82 5.22 Grafik hasil uji kebenaran ILKQUERYIII pada
DAFTAR KODE SUMBER
4.1 Implementasi Fungsi Main . . . 48 4.2 Implementasi Variabel Global . . . 48 4.3 Implementasi Fungsi Init . . . 49 4.4 Implementasi Fungsi Build . . . 50 4.5 Implementasi Fungsi KthQuery . . . 51 4.6 Implementasi Fungsi Main . . . 52 4.7 Implementasi Variabel Global . . . 53 4.8 Implementasi Fungsi Init . . . 53 4.9 Implementasi Fungsi Build . . . 54 4.10 Implementasi Fungsi ActiveElementRangeQuery . 55 4.11 Implementasi Fungsi ActiveElementQuery . . . 56 4.12 Implementasi Fungsi ToggleElementStatus . . . . 57 4.13 Implementasi Fungsi Toggle Actual Status . . . 57 4.14 Implementasi Fungsi BITUpdate . . . 58 4.15 Implementasi Fungsi BITQuery . . . 58 4.16 Implementasi Fungsi Main . . . 59 4.17 Implementasi Variabel Global . . . 60 4.18 Implementasi Fungsi Init . . . 60 4.19 Implementasi Fungsi Build . . . 61 4.20 Implementasi Fungsi SwapElement . . . 62 4.21 Implementasi Fungsi UpdateOccurence . . . 63
BAB 1 PENDAHULUAN
Pada bab ini akan dijelaskan latar belakang, rumusan masalah, ba-tasan masalah, tujuan, metodologi dan sistematika penulisan Tugas Akhir.
1.1 Latar Belakang
Memasuki abad ke-20 perkembangan teknologi informasi semakin cepat. Tidak dapat dipungkiri bahwa hampir semua aspek kehidup-an mulai terkomputerisasi. Tujukehidup-annya adalah konsistensi dkehidup-an aku-rasi. Dengan desain dan implementasi yang tepat sebuah program komputer dapat membantu manusia untuk melakukan sebuah pro-ses yang jika dikerjakan oleh manusia secara langsung akan mem-butuhkan waktu yang lama dan rentan terhadaperror. Keunggulan inilah yang menyebabkan semakin banyak penggunaan teknologi informasi pada aspek-aspek kehidupan manusia.
Kesadaran akan keunggulan komputer dalam melakukan suatu pe-kerjaan menyebabkan semakin besar pula keinginan manusia untuk menyelesaikan masalah-masalah yang sebelumnya tidak dapat dise-lesaikan tanpa bantuan komputer. Masalah-masalah ini seringkali berkaitan dengan data yang memiliki ukuran sangat besar. Dari data tersebut tentu terdapat informasi-informasi tertentu yang ingin di-ambil. Dengan metode yang tepat informasi yang diperlukan dapat diambil dengan waktu yang relatif singkat.
Besarnya ukuran data tentu menjadi sebuah masalah tersendiri bagi para ilmuwan. Perkembangan perangkat keras yang ada belum da-pat mengimbangi dengan kebutuhan komputasi yang semakin besar. Untuk inilah penyelesaian sebuah masalah membutuhkan
an yang tepat, sehingga dapat ditemukan algoritma dan struktur data yang sesuai dengan permasalahan yang ada.
Di era modern ini sudah banyak algoritma dan struktur data yang ditemukan oleh ilmuwan-ilmuwan ternama dunia. Masing-masing algoritma sering kali membutuhkan struktur data yang tepat yang dapat membantu kinerja algoritma tersebut. Permasalahan klasik yang cukup menarik pada topik struktur data adalah range query atau model pertanyaan yang melibatkan sebuah rentang tertentu. Penulis tertarik untuk melakukan penelitian untuk membandingkan performa beberapa struktur data yang memiliki kemampuan untuk menangani berbagai variasi dari permasalahan ini.
Topik Tugas Akhir ini mengacu pada sebuah permasalahan yang terdapat pada Online Judge SPOJ dengan kode ILKQUERY, IL-KQUERY2, dan ILKQUERYIII. Pada permasalahan ini terdapat sebuah kumpulan data berupa angka-angka yang diberikan di awal. Dari kumpulan angka ini akan dilakukan sejumlah pertanyaan dan perubahan atauupdatepada data awal yang diberikan. Struktur data yang diduga dapat membantu penyelesaian permasalahan ini ada-lahWavelet Tree. Selain dapat menjawab pertanyaan dengan be-nar, waktu juga menjadi salah satu faktor penting untuk memberik-an gambarmemberik-an tentmemberik-ang performa dari struktur data ini.
Hasil dari Tugas Akhir ini diharapakan dapat memberikan gambar-an mengenai performa dari struktur data Wavelet tree untuk me-nyelesaikan permasalahan di atas dan diharapkan dapat memberik-an kontribusi pada perkembmemberik-angmemberik-an ilmu pengetahumemberik-an dmemberik-an teknologi informasi.
1.2 Rumusan Masalah
Rumusan masalah yang diangkat dalam Tugas Akhir ini adalah se-bagai berikut:
3
data yang tepat untuk menjawab variasi dari permasalahan range query?
2. Bagaimana implementasi dari struktur data Wavelet Tree yang telah dirancang dalam penyelesaian permasalahan ra-nge query?
1.3 Batasan Masalah
Permasalahan yang dibahas pada Tugas Akhir ini memiliki bebera-pa batasan, yaitu sebagai berikut:
1. Batas jumlah maksimum data awal yang diberikan adalah 100.000 angka untuk permasalahan ILKQUERY dan IL-KQUERY2. Untuk ILKQUERYIII jumlah maksimum data awal mencapai 1.000.000.
2. Batas maksimum jumlah query dan/atau update adalah 100.000 perintah.
3. Dataset yang digunakan adalah dataset pada problem SPOJ I LOVE Kd-TREES (ILKQUERY, ILKQUERY2, ILKQU-ERYIII).
1.4 Tujuan
Tujuan dari Tugas Akhir ini adalah sebagai berikut:
1. Melakukan analisis dan mendesain algoritma dan struktur da-ta untuk menyelesaikan permasalahan variasirange query de-ngan pembuktian (proofing) yang jelas.
1.5 Metodologi
Metodologi yang digunakan dalam pengerjaan Tugas Akhir ini ada-lah sebagai berikut:
1. Penyusunan proposal Tugas Akhir
Pada tahap ini dilakukan penyusunan proposal tugas akhir yang berisi permasalahan dan gagasan solusi yang akan di-teliti pada permasalahan I Love Kd-Trees, I Love Kd-Trees II, dan I Love Kd-Trees III.
2. Studi literatur
Pada tahap ini dilakukan pencarian informasi dan studi litera-tur mengenai pengetahuan atau metode yang dapat digunak-an dalam penyelesaidigunak-an masalah. Informasi didapatkdigunak-an dari materi-materi yang berhubungan dengan algoritma dan struk-tur data yang digunakan untuk penyelesaian permasalahan ini, materi-materi tersebut didapatkan dari buku, jurnal, ma-upun internet.
3. Desain
Pada tahap ini dilakukan desain rancangan algoritma dan struktur data yang digunakan dalam solusi untuk pemecah-an masalah I Love Kd-Trees, I Love Kd-Trees II, dpemecah-an I Love Kd-Trees III.
4. Implementasi perangkat lunak
Pada tahap ini dilakukan implementasi atau realiasi dari ran-cangan desain algoritma dan struktur data yang telah diba-ngun pada tahap desain ke dalam bentuk program.
5. Uji coba dan evaluasi
5
6. Penyusunan buku Tugas Akhir
Pada tahap ini dilakukan penyusunan buku Tugas Akhir yang berisi dokumentasi hasil pengerjaan Tugas Akhir.
1.6 Sistematika Penulisan
Berikut adalah sistematika penulisan buku Tugas Akhir ini: 1. BABI: PENDAHULUAN
Bab ini berisi latar belakang, rumusan masalah, batasan ma-salah, tujuan, metodologi dan sistematika penulisan Tugas Akhir.
2. BAB II: DASAR TEORI
Bab ini berisi dasar teori mengenai permasalahan dan algori-tma penyelesaian yang digunakan dalam Tugas Akhir 3. BAB III: DESAIN
Bab ini berisi desain algoritma dan struktur data yang digu-nakan dalam penyelesaian permasalahan.
4. BAB IV: IMPLEMENTASI
Bab ini berisi implementasi berdasarkan desain algortima dan struktur data yang telah dilakukan pada tahap desain. 5. BAB V: UJI COBA DAN EVALUASI
Bab ini berisi uji coba dan evaluasi dari hasil implementasi yang telah dilakukan pada tahap implementasi.
6. BAB VI: KESIMPULAN
BAB 2
DASAR TEORI
Pada bab ini akan dijelaskan mengenai dasar teori yang menjadi da-sar pengerjaan Tugas Akhir ini.
2.1 Deskripsi Permasalahan
Range query merupakan sebuah permasalahan klasik dalam pe-ngembangan sebuah struktur data yang efisien. Pada Tugas Akhir ini diangkat permasalahan mengenai variasi range query. Sebuah range querymemiliki dua faktor yang penting yaitu, data yang ba-gaimana yang ingin dicari dan pada indeks mana pertanyaan ter-sebut akan dijawab. Sebagai contoh, query yang dikerjakan pa-da indeks [1..5] akan menghasilkan output yang berbeda dengan queryyang dikerjakan pada indeks[3..7]. Pertanyaan mengenai
da-ta bagaimana yang ingin dicari pada sebuah jenisqueryjuga sangat mempengaruhi struktur data apa yang dapat menanganiquery ter-sebut dengan efisien. Efisien yang dimaksud adalah efisien baik dari segiruntimemaupun dari segimemoryyang dibutuhkan untuk membangun struktur data tersebut.
Mula-mula terdapatNbuah bilangan sebagai data awal. Kemudian
terdapat serangkaian operasi yang akan dilakukan pada data awal yang telah diberikan. Suatu operasi dapat berupa sebuahqueryatau sebuah tindakan yang mengubah kondisi data. Variasi dari operasi-operasi yang menjadi permasalahan dalam Tugas Akhir ini akan di-jelaskan pada subbab-subbab di bawah.
2.1.1 Operasi Mencari Bilangan Terkecil ke-K
Terdapat 3 parameter pada operasi ini yaitu i, l, dan k. Dari
ti-ga parameter tersebut diajukan sebuah pertanyaan yaitu, misalkan sebuah bilangandmerupakan bilangan terkecil ke-kdari indeks1 hingga indeks ke-imaka pada indeks ke berapakah bilangand
mun-cul yang ke-lkali. Jika jumlah kemunculan bilangandkurang dari lmaka jawaban dari pertanyaan ini adalah−1.
Gambar 2.1: Ilustrasi operasi mencari bilangan terkecil ke-K.
2.1.2 Operasi Menghitung Jumlah Elemen yang Aktif Sama dengan operasi mencari bilangan terkecil ke-K operasi ini ju-ga memiliki 3 parameter yaitu,i,l, dank. Namun masing-masing
memiliki representasi yang berbeda. Parameteridanlmenyatakan rangedari pertanyaan ini dengan parameterisebagai batas kiri serta
parameterlsebagai batas kanan. Parameterkmenyatakan
bilang-an ybilang-ang ingin dicari. Sehingga pertbilang-anyabilang-an ybilang-ang harus dijawab pada operasi ini adalah berapa bilangankyang memiliki status aktif pada range[i..l].
2.1.3 Operasi Mengubah Status dari Sebuah Elemen
9
Gambar 2.2: Ilustrasi operasi menghitung jumlah elemen yang aktif.
menjadi tidak aktif dan sebaliknya jika status dari elemen tersebut adalah tidak aktif maka status dari elemen ini akan diubah menja-di aktif. Operasi ini sangat berkaitan dengan Operasi Menghitung Jumlah Elemen yang Aktif. Parameter yang diberikan untuk ope-rasi ini adalahryang menyatakan indeks elemen yang akan diubah
statusnya.
Pada Gambar 2.4 diperlihatkan bagaimana operasi ini dapat me-nyebabkan perubahan hasil pada operasi 2.1.2 walaupun parameter yang diberikan pada masing-masing operasi sama persis.
Gambar 2.4: Ilustrasi operasi menghitung jumlah elemen yang ak-tif setelah terjadi perubahan status dari sebuah elemen.
2.1.4 Operasi Menukar Elemen yang Bersebelahan
Operasi ini akan menukar sebuah elemen di indeksrdengan elemen
di sebelah kanannya atau dengan kata lain elemen yang memiliki indeksr+ 1.
Gambar 2.5: Ilustrasi operasi menukar elemen yang bersebelahan.
2.2 Dataset yang Digunakan
Variasi permasalahan range queryyang akan dibahas pada Tugas Akhir ini akan menggunakan dataset yang diambil dari situs peni-laian adaring SPOJ dengan judul,
11
Operasi yang diperbolehkan pada operasi ini adalah, (a) Operasi Mencari Bilangan Terkecil ke-K.
Dengan batasan masukan yang diperbolehkan pada permasalahan ini adalah,
• 1≤N ≤105 • 1≤Q≤105 • −109
≤ai≤109 • 0< k < i < N
• 1≤l≤N
Dimana,
• Nmerupakan jumlah data yang terdapat pada masukan.
• Qmerupakan jumlah operasi yang harus dikerjakan.
• aimerupakan data pada indeks ke-i.
• i, l, kmerupakan parameter untuk Operasi Mencari
Bi-langan Terkecil ke-K. 2. I Love Kd-Trees II
Operasi yang diperbolehkan pada operasi ini adalah, (a) Operasi Menghitung Jumlah Elemen yang Aktif. (b) Operasi Mengubah Status dari Sebuah Elemen.
Dengan batasan masukan yang diperbolehkan pada permasalahan ini adalah,
• 1≤N ≤105 • 1≤Q≤105 • −109
≤ai≤109 • 0< q <2 • 0≤i≤l < N
• −109
≤k≤109 • 0≤r < N
Dimana,
• Nmerupakan jumlah data yang terdapat pada masukan.
• Qmerupakan jumlah operasi yang harus dikerjakan.
• aimerupakan data pada indeks ke-i.
• i, l, kmerupakan parameter untuk Operasi Menghitung
Jumlah Elemen yang Aktif.
• rmerupakan parameter untuk Operasi Mengubah Status
dari Sebuah Elemen. 3. I Love Kd-Trees III
Operasi yang diperbolehkan pada operasi ini adalah, (a) Operasi Mencari Bilangan Terkecil ke-K (b) Operasi Menukar Elemen yang Bersebelahan
Dengan batasan masukan yang diperbolehkan pada permasalahan ini adalah,
• 1≤N ≤106 • 1≤Q≤105 • −109 ≤a
i≤109 • 0< q <2 • 0≤i < N
• 1≤l≤N
• 1≤k≤i+ 1 • 0≤r < N
Dimana,
• Nmerupakan jumlah data yang terdapat pada masukan.
• Qmerupakan jumlah operasi yang harus dikerjakan.
• aimerupakan data pada indeks ke-i.
• qmerupakan jenis operasi yang harus dikerjakan.
• i, l, kmerupakan parameter untuk Operasi Menghitung
Jumlah Elemen yang Aktif.
• rmerupakan parameter untuk Operasi Mengubah Status
dari Sebuah Elemen.
2.3 WaveletTrees
13
permasalahan mulai daritext-indexinghingga ke persoalan compu-tational geometry [3]. Secara umum,wavelet treedibangun pada sebuah sekuensSyang terdiri dari himpunan simbolΣ.
Struktur dasar dari wavelet tree merupakan sebuah compelete bi-narytree. Setiapnodepadawavelet tree mewakili sebuah rentang tertentu dari sekuens asal. Uniknya rentang ini selalu konsekutif namun selalu terurut atau yang biasa disebut dengan subsekuens. Simbol-simbol yang ada pada suatunodejuga merupakan himpun-an bagihimpun-an dari himpunhimpun-an semesta untukwavelet treeini.
Build(part) 1 if V isleaf
2 ΣL⊂ΣV 3 ΣR⊂ΣV
4 Lef tP artition= {Si|Si ∈ΣL} 5 RightP artition = {Si|Si>ΣR} 6 Build(Lef tP artition)
7 Build(RightP artition)
Gambar 2.6: Pseudocode Build
Setiapnodepadawavelet treeakan memiliki anak kiri dan kanan ji-ka dan hanya jiji-ka padanodetersebut masih merepresentasikan>1 simbol. Himpunan simbol tersebut kemudian dibagi menjadi dua sama besar. Semua simbol yang termasuk dalam himpunan bagi-an pertama akbagi-an dipartisi menjadi bagi-anak kiri dbagi-an sebaliknya semua simbol yang termasuk dalam himpunan bagian kedua akan dipartisi menjadi anak kanan.
secara implisit definisi darinode leaf telah dirumuskan yaitunode yang hanya merepresentasikan sebuah simbol.
ΣLmerupakan himpunan bagian dariΣV yang berisi simbol-simbol oada anak kiri begitu juga dengan ΣR yang akan berisi simbol-simbol pada anak kanan. Kedua himpunan ini saling mutually exclusive. Dimana sebuah elemen padaΣV hanya dapat tergabung pada salah satu himpunan bagian. Kemudian fungsi Build dipang-gil pada sekuens awalS yang akan menghasilkan strukturwavelet treeseperti pada Gambar 2.7.
Gambar 2.7: Strukturwavelet treesetelah proses build dengan sekuens awalS={1,2,1,4,3,2,3,1,2,4}. Pada ilustrasi ini ditampilkan elemen pada masing-masingnodeuntuk memberikan gambaran umum namun da-ta tersebut tidak disimpan pada strukturwavelet tree.
Teorema 2.1
JikaTadalah sebuahwavelet treedari sekuensSdengan himpunan
simbolΣmakawavelet treeT adalah sebuah complete binarytree
15
Proof MisalkanH(σ) adalah tinggi dari sebuahwavelet tree de-ngan totalσsimbol. Maka,
H(σ) = {
H(σ
2) + 1, ifσ >1. 1, ifσ = 1.
Dengan master theorm maka rekurens ini terselesaikan menjadi
H(lgσ).
2.3.1 Bit vector
Pada Gambar 2.7 tampak terdapat deret bilangan 0 dan 1 dibawah elemen masing-masingnode. Bilangan tersebut didefinisikan seba-gai bitvector. MisalkanBadalah sebuah bitvector maka,
Bi =
{
Bi= 1, ifSi ∈ΣL. Bi= 0, ifSi ∈ΣR.
Informasi ini merupakan informasi dasar yang diperlukan untuk me-lakukan penulusuran padawavelet tree. Berawal dari informasi ini dapat dibentuk informasi lain yang dapat membantu operasi-operasi yang ada padawavelet tree. Meskipun nantinya informasi ini tidak digunakan namun informasi ini akan terbukti esensial pada struktur data ini.
2.3.2 M apLef tdanM apRight
OperasiM apLef t(i)didefinisikan sebagai banyak elemen hingga indeksiatau pada rentang[0..i]yang memiliki nilaiBx= 1|x≤i. Melalui bitvector yang telah terbentuk dapat dilakukan iterasi dari indeks 0hingga iuntuk mencari banyak bitvector yang memiliki
Sebuah solusi sederhana adalah dengan membangun sebuah array yang merupakan prefix sum dari bitvector. MisalkanPadalah array
prefix sum dari bitvectorB maka,
Pi =
{
Pi =Bi+Pi−1, ifi >0. Pi =Bi, otherwise.
Dengan solusi ini maka M apLef t(i) dapat diselesaikan dengan kompleksitasO(1)dengan tambahan memori sebesarO(n)per le-vel dariwavelet tree. Sehingga memori total yang dibutuhkan ada-lahO(nlgσ).
Untuk menyelesaikan operasi M apRight(i) dapat dilakukan hal yang sama dengan membangun sebuah array prefix sum namun de-ngan menjumlahkan bit-bit yang bernilai 0. Menarik diperhatik-an bahwa sebenarnya hal ini tidak perlu dilakukdiperhatik-an karena operasi
M apRightini dapat diperoleh dari operasiM apLef tdengan
per-samaan,
M apRight(i) = (i+ 1)−M apLef t(i)
Seperti yang telah dijelaskan bahwa operasiM apLef t
mengem-balikan nilai luaran berupa banyak elemen hingga indeksidengan
bitvector bernilai1. Pada sembarang elemen dalam sekuens wave-let treebitvector untuk elemen tersebut hanya mungkin bernilai 1 atau0.
17
Gambar 2.8: Struktur wavelet tree dengan sekuens awal S = {1,2,1,4,3,2,3,1,2,4}. Dibawah setiap elemen merupakan array pre-fix sum yang merepresentasikan nilai luaran dariM apLef tuntuk semua indeks.
Lebih lanjut operasi ini dapat digunakan untuk mengetahui rentang pencarian saat melakukan traversal ke anak kiri atau kanan dari se-buahnodeV. OperasiM apLef t(i) dapat dilihat sebagai banyak elemen yang dipetakan pada anak kiri hingga indeks ke-i.
Jika pencarian dilanjutkan ke anak kiri dariV maka rentang
penca-rian berubah dari[0..i]menjadi[0..M apLef t(i)−1]atau sampai elemen ke-M apLef t(i)pada anak kiri. Sebaliknya jika pencarian dilanjutkan pada anak kanan dariV maka rentang pencarian
men-jadi[0..M apRight(i)−1].
2.3.3 Rank Query
menye-Rank(V, i, k) 1 ifV isleaf
2 returni+ 1 3 elseif k∈ΣL
4 Rank(V.lef t,MapLeft(i)−1, k) 5 else
6 Rank(V.right,MapRight(i)−1, k)
Gambar 2.9: PseudocodeRank Query.
lesaikan operasi ini dapat dilakukan strategi yang ditunjukkan pada Gambar 2.9.
Sebagai contoh akan dilakukan proses pencarian untukrank(5,2).
Simbol yang akan dicari adalah simbol2. Simbol ini dipetakan ke anak kiri sehingga pencarian akan dilanjutkan ke anak kiri. Pada Gambar 2.10 ditunjukkan bagian-bagian yang terlibat pada tahap ini. Seperti telah dipaparkan pada Subbab 2.3.2 bahwa ketika proses traversal padawavelet treedilanjutkan ke anak kiri atau kanan maka rentang pencarian akan mengalami perubahan.
Secara intuitif hal ini perlu dilakukan dikarenakan pada rentang pen-carian awal[0..i]terdapat elemen-elemen yang dipetakan ke anak kiri serta ada juga yang dipetakan ke anak kanan. Untuk contoh kasus ini pencarian akan dilanjutkan ke anak kiri dan rentang pen-carian berubah menjadi[0..3].
Pencarian dilanjutkan ke anak kanan karena2∈ΣR. Rentang pen-carian menjadi[0..1]karenaM apRight(i) = 2. Sehingga nilai dari rank(5,2) = 2. Perlu diingat bahwanode leaf hanya
merepresen-tasikan sebuah simbol yang dengan kata lainimenyatakan jumlah
kemunculan simbol tersebut muncul hingga indeksi. Sehingga
19
Gambar 2.10: Operasirank(5,2)dimulai padaroot. Bagian yang diarsir warna merah menunjukkan nilai dariM apLef t(i).
akibat penggunan 0-based indeks. Pada Gambar 2.11 ditunjukkan proses pencarian dari awal hingga akhir.
Modifikasi sederhana dari operasi ini adalah perubahan dari indeks pencarian menjadi[i..j]. Modifikasi ini tidak mengubah proses dari
operasirankitu sendiri dikarenakan modifikasi ini dapat
diselesa-ikan denganrank(j)−rank(i−1). Hal ini dapat dilakukan karena
berlakunya prinsip inklusi-eksklusi.
Dari algoritma yang telah dipaparkan terlihat bahwa pada proses tra-versal untuk operasirankini memiliki kompleksitasO(lgσ).
Pa-da saat mencapai sembarangnodepadawavelet treeTmaka proses
akan dilanjutkan ke anak kiri atau anak kanan yang menunjukkan bahwa proses traversal hanya akan mengunjungi paling banyak lgσ node.
2.3.4 Quantile Query
Operasiquantilek(i)didefinisikan sebagai pencarian simbol ke-k pada rentang[0..i]. Strategi untuk menyelesaikan permasalahan ini
Gambar 2.11: Setelah dicapai node leaf maka jawaban untuk operasi rank(5,2)adalah2, operasi berhenti ketika pemanggilanrank(5,1). Se-lainnode leafstruktur yang ditampilkan merupakan representasi dari array M apLef t.
Sebagai contoh operasiquantile4(4)akan mengembalikan simbol 3 dimana elemen-elemen hingga indeks 4 adalah1,2,1,4,3 jika ditulis terurut menjadi1,1,2,3,4maka simbol ke-4adalah3. Mula-mula proses diawali pada node root dari wavelet tree ke-mudian dilakukan perbandingan antara nilaikyang dicari dengan M apLef t(i). Maksud dari tahapan ini adalah mengetahui
sim-bol yang dicari berada pada subtree kiri atau subtree kanan dengan membandingkan nilaikdenganM apLef t(i).
Jika nilaik≤M apLef t(i)maka diketahui terdapat cukup elemen pada subtree kiri untuk mencari elemen ke-kpada rentang yang
21
Quantile(V, i, k) 1 if V isleaf
2 returnV
3 elseif k≤MapLeft(i)
4 Quantile(V.lef t,MapLeft(i)−1, k) 5 else
6 Quantile(V.right,MapRight(i)−1, k−MapLeft(i))
Gambar 2.12: PseudocodeQuantile Query.
Jika traversal dilanjutkan ke subtree kanan maka pencarian ti-dak lagi mencari elemen ke-k melainkan menjadi elemen
ke-(k−M apLef t(i)). Hal ini dikarenakan sudah terdapat sejumlah M apLef t(i)elemen yang telah masuk pada subtree kiri dan tidak mungkin menjadi jawaban dari operasi ini.
Pada contohk = 4danM apLef t(4) = 3maka pencarian dilan-jutkan ke anak kanan dariroot. Ilustrasi pencarian ini ditunjukkan pada Gambar 2.13.
Selanjutnya secara rekursif dilanjutkan proses dari operasiquantile
ke anak kanan. Nilai dariksekarang adalah4−3 = 1serta nilai darii=M apRight(4)−1 = 1. Kondisik≤M apLef t(i) terpe-nuhi sehingga pencarian dilanjutkan pada anak kiri yang merupakan node leaf. Sehingga jawaban dariquantile4(4)adalah3. Ilustra-si lengkap untuk operaIlustra-si quantile4(4) ditunjukkan pada Gambar 2.14.
Gambar 2.14: Proses penulusuran untuk operasiquantile4(4)
Kompleksitas dari operasiquantileadalahO(lgσ)yang merupak-an tinggi dariwavelet treeitu sendiri. Dari proses pencarian yang telah dipaparkan di atas secara intuitif jelas bahwa proses traver-sal hanya dapat bergerak ke anak kiri atau kanan. Sehingga banyak nodeyang dikunjungi dalam satu operasi adalahO(lgσ).
2.3.5 ToggleUpdate
Operasi ini membutuhkan informasi tambahan yang didefinisikan terlebih dahulu sebelumnya yaitu, status dari setiap elemen. Ope-rasitoggle(i)melakukan perubahan status elemen pada posisi ke-i.
23
sekarang adalah non-aktif dan sebaliknya.
Gambar 2.15: Struktur dariwavelet treesetelah modifikasi untuk mendu-kung operasitoggledenganA = {0,1,0,1,1,0,1,0,1,0}. DimanaA adalah status dari masing-masing elemen. Array dengan bingkai menya-takan data yang disimpan pada setiapnode.
R. Castro, et. al telah menujukkan bahwa operasi ini dapat mem-berikan pengaruh pada operasi rank danquantile yang telah
di-bahas sebelumnya [4]. Solusi yang ditawarkan adalah dengan me-nambahkan sebuah informasi tambahan pada setiapnodedari wa-velet treeyaitu,ActiveLef t. Informasi ini menyerupai informasi M apLef tnamun ditambahkan bitvector ke-iakan bernilai satu jika
status elemen tersebut adalah aktif. Dengan penambahan informa-si ini operainforma-sirankdanquantileakan memiliki kompleksitas tetap O(lgσ).
Pada permasalahan yang telah dipaparkan operasitoggle ini akan
digabungkan hanya dengan operasi rank. Penggabungan kedua
di-mana ketika mencapainode leaf operasiranktidak dapat langsung
mengembalikan nilai luarani+ 1melainkan perlu melakukan per-hitungan elemen yang aktif pada rentang[0..i].
Permasalahan ini dapat dilihat kembali sebagai bitvector yang akan bernilai1jika elemen tersebut dalam kondisi aktif dan bernilai0jika elemen tersebut dalam kondisi non-aktif. Representasi ini menun-jukkan bahwa dapat pula dibangun sebuah array prefix sum bitve-cor untuk menyatakan jumlah elemen yang aktif pada rentang[0..i].
Namun kelemahan dari prefix sum adalah tidak dapat mendukung operasiupdatedengan cukup efisien. Operasiupdate mengharusk-an mengubah semua data dari posisiihingga posisi terakhir.
Toggle(V, i, k) 1 ifV isleaf
2 BITupdate(i) 3 elseif k∈ΣL
4 Toggle(V.lef t,MapLeft(i)−1, k) 5 else
6 Toggle(V.right,MapRight(i)−1, k)
Gambar 2.16: Pseudocode ToggleUpdate.
Binary IndexedTree atau FenwickTreemerupakan sebuah struk-tur data yang memiliki karakteristik mirip dengan array prefix sum yang juga mendukung operasiupdate. Kedua operasi ini dapat di-selesaikan dengan kompleksitas waktu O(lgn) dan kompleksitas memoriO(n)dengannadalah jumlah data.
25
Gambar 2.17: Ilustrasi dari proses operasitoggle(3).
Secara garis besar algoritma yang digunakan untuk melakukan per-ubahan status adalah dengan melakukan traversal padawavelet tree, bertujuan untuk menemukannode leaf yang menyimpan simbol pa-da elemen ke-i. Setelah mencapainode leaf maka dilakukanupdate
pada struktur BIT. Proses traversal sangat menyerupai proses tra-versal pada operasirank. Sebagai contoh operasitoggle(3) ditun-jukkan pada Gambar 2.17.
2.3.6 SwapUpdate
Pada operasiupdate(i) dilakukan penukaran elemen pada indeks ke-idani+ 1. Hal ini dapat memberikan pengaruh yang besar pada queryyang ditanyakan setelah operasiupdateini dilakukan. Mes-kipun demikian perubahan struktur padawavelet treeakibat operasi ini hanya akan berpengaruh pada nilai dari operasiM apLef t(i) ji-ka dan hanya jiji-ka simbol pada posisi ke-idani+ 1berbeda satu sama lain.
Swap(V, i)
1 ifSi ∈ΣLandSi+1∈ΣL
2 Swap(V.lef t,MapLeft(i)−1) 3 elseif Si ∈ΣRandSi+1 ∈ΣR 4 Swap(V.lef t,MapRight(i)−1) 5 else
6 ifSi ∈ΣL
7 MapLeft(i) =MapLeft(i)−1
8 else
9 MapLeft(i) =MapLeft(i) + 1
Gambar 2.18: Pseudocode SwapUpdate.
atau kanan tergantung simbol tersebut masuk ke himpunan yang mana. Pseduocode untuk operasi ini ditunjukkan pada Gambar 2.18.
Gambar 2.19: (a) Ilustrasi dari eksekusi operasiswap(7). (b) Struktur akhir darinodeyang mengalami perubahan.
27
himpunanΣLyang menyatakan kedua simbol tersebut merupakan anggota dari subtree kiri. Maka nilaii = M apLef t(i)−1 = 4.
Kemudian pada anak kiri ternyata simbol pada indeks4dan5sudah tidak lagi tergabung pada subtree yang sama sehingga pasti terdapat perubahan pada nilaiM apLef t.
Simbol pada indeks ke-4 merupakan anggota dari subtree kiri se-hingga dapat dipastikan bahwa nilai pada indeks ke-5 merupakan anggota dari subtree kanan. Hal ini menyebabkan pada indeks ke-4 simbol tersebut akan tergabung pada subtree kanan yang secara ti-dak langsung menyatakan bahwa nilaiB4 = 0dan menyebabkan nilai M apLef t(4) = 2. Proses dihentikan karena kedua elemen
BAB 3
DESAIN
Pada bab ini akan dijelaskan desain sistem yang digunakan un-tuk menyelesaikan permasalahan-permasalahan pada Tugas Akhir ini.
3.1 Permasalahan I Love Kd-Trees
Pada permasalahan ini sistem akan dibangun untuk menyelesaikan hanya satu jenis operasi yaitu, Operasi Mencari Bilangan Terkecil ke-K.
3.1.1 Deskripsi Umum Sistem
Kemudian untuk membantu menyelesaikan Operasi Mencari Bi-langan Terkecil ke-K maka array globaloccurencesdiinisialisasi
dengan posisi kemunculan masing-masing elemen terurut dari kiri ke kanan. Penggunaan array ini telah dijabarkan pada 2.1.1.
Selanjutnya Operasi Mencari Bilangan Terkecil ke-K akan mene-rima 3 bilangan bulati,l, dankyang masing-masing menyatakan
batas kanan dari rentang pencarian, elemen terkecil ke-kyang harus
dicari, dan kemunculan ke berapa dari elemen tersebut. Pseudocode Fungsi Main ditunjukkan pada Gambar 3.1.
1 letelementsbe a newdynamicarray
2 letmap_lef tbe adynamicarrays ofdynamicarrays
3 letoccurences[1..size]be an array ofdynamicarrays 4 letsymbolsbe a new dictionary
5 N = Input()//Number of elements 6 Q = Input()//Number of operations 7 fori = 0toN−1
8 elements[i] = Input() 9 Init(elements)
10 fori = 0toN−1
11 occurences[elements[i]].push(i) 12 Build(elements,1,0, size)
13 forq = 0toQ−1 14 i =Input() 15 l = Input() 16 k = Input()
17 Print(KthQuery(i, l, k))
Gambar 3.1: Pseudocode Fungsi Main I Love Kd-Trees
3.1.2 Desain Fungsi Init
Fungsi Init ini menerima satu parameter array yang berisi bilangan bulat yaituelements. Berdasarkan array ini nantinya akan dibuat
sebuah kamus symbols yang menyimpan simbol-simbol apa saja
yang muncul pada data awal. Pseudocode Fungsi Init ditunjukkan pada Gambar 3.2.
3.1.3 Desain Fungsi Build
31
1 sorted = elements.copy()
2 sort(sorted)
3 forelement∈elements
4 symbols.insert(element) 5 foritoN−1
6 elements[i] = symbols[elements[i]] 7 map_lef t.assign(3∗size)
Gambar 3.2: Pseudocode Fungsi Init I Love Kd-Trees
ukuran yang dinamis. nodemerupakan pointer yang menunjuk
pa-da node mana struktur pada wavelet tree itu sedang dibuat. Se-dangkan, lef t danright merupakan bilangan bulat yang
menun-jukkan batas kiri dan kanan dari rentang nilai sebuah partisi. Fung-si ini digunakan untuk membangun struktur awal dari struktur da-tawavelet treeitu sendiri yang algoritmanya telah dijelaskan pada Subbab 2.3. Pseudocode Fungsi Build ditunjukkan pada Gambar 3.3.
1 if partition.isEmpty()
2 return
3 mid = (lef t+right)/2
4 lef t_part = CreateLeftPartition(partition, mid) 5 right_part= CreateRightPartition(partition, mid) 6 map_lef t[node] = CreateMapping(partition, mid) 7 Build(lef t_part, node.lef t_child, lef t, mid)
8 Build(right_part, node.right_child, mid+ 1, right)
3.1.4 Desain Fungsi KthQuery
1 node = ROOT 2 lef t = 0
3 right =size−1 4 whilelef t < right
5 until_i =map_lef t[node][i] 6 mid= (lef t+right)/2 7 ifk≤until_i
8 node = node.lef t_child
9 right =mid
10 i = until_i−1
11 else
12 node = node.right_child
13 lef t = mid+ 1 14 i = i−until_i
15 k = k−until_i
16 if l≤occurences[lef t].size()
17 returnoccurences[lef t][l−1] 18 return−1
Gambar 3.4: Pseudocode Fungsi KthQuery
Fungsi ini akan menerima 3 parameter seperti yang telah dijelaskan pada Subbab 2.1.1 yaitui,l, dankdimana ketiganya merupakan
bi-langan bulat. Fungsi ini akan mengembalikan sebuah nilai yang me-rupakan dari jawaban dari pertanyaan pada subbab tersebut.
node merupakan sebuah pointer yang menunjukkan node manaa
yang sedang ditelusuri padawavelet treeyang telah dibangun mula-mula nilainya berada padaROOT. lef tdanrightmasing-masing
33
kanan dari rentang node sekarang, nilai awal dari kedua variabel ini adalah batas kiri dan kanan darirootyang kemudian akan ber-ubah sesuai dengan algoritma penelurusan yang telah dibahas pa-da Subbab 2.3.4. ocurrencesadalah sebuah array bilangan bulat
yang telah diinisialisasi pada Fungsi Main. Pseudocode dari Fungsi KthQuery ditunjukkan pada Gambar 3.1.4.
3.2 Permasalahan I Love Kd-Trees II
Pada permasalahan ini sistem akan dibangun untuk menyelesaikan 2 jenis operasi yaitu, Operasi Menghitung Jumlah Elemen yang Aktif dan Operasi Mengubah Status dari Sebuah Elemen.
3.2.1 Deskripsi Umum Sistem
Sampai dengan baris ke-10 pseudocode dari fungsi main untuk permasalahan ini memiliki penjelasan yang sama dengan subbab 3.1.1. Perbedaan hanya terletak pada arraystatusyang digunakan
untuk menyimpan status terkini dari masing-masing elemen.
Selanjutnya sistem akan menerima masukan bilangan bulattype
un-tuk menenun-tukkan operasi mana yang akan dikerjakan. Jika type
bernilai 0 maka Operasi Menghitung Jumlah Elemen yang Aktif akan menerima 3 masukan berupa bilangan bulat yaitu i, l, dank
kemudian sistem akan menampilkan luaran sebuah bulangan bulat yang menyatakan banyak elemen bernilaikyang aktif pada rentang
[i..l].
Operasi Mengubah Status dari Sebuah Elemen akan menerima se-buah bilangan bulatr yang kemudian sistem akan melakukan
per-ubahan status elemen pada indeksr. Pseudocode Fungsi Main
1 letelementsbe a newdynamicarray
2 letstatus[0..MAXN]be a new array
3 letmap_lef tbe adynamicarrays ofdynamicarrays
4 letsymbolsbe a new dictionary
5 N = Input()//Number of elements 6 Q = Input()//Number of operations 7 fori = 0toN−1
8 elements[i] = Input() 9 Init(elements)
10 Build(elements,1,0, size) 11 forq = 0toQ−1
12 type = Input() 13 iftype = 0
14 i = Input(),l =Input(),k = Input() 15 Print(ActiveElementRangeQuery(i, l, k))
16 else
17 r = Input()
18 ToggleElementStatus(r)
Gambar 3.5: Pseudocode Fungsi Main I Love Kd-Trees II
3.2.2 Desain Fungsi Init
Fungsi ini memiliki penjelasan yang sama dengan Subbab 3.1.2 de-ngan tambahan inisialisasi array statusmenjadi aktif pada
mula-mula. Pseudocode Fungsi Init ditunjukkan pada Gambar 3.6.
3.2.3 Desain Fungsi Build
di-35
1 status =ACTIVE
2 sorted = elements.copy()
3 sort(sorted)
4 forelement∈elements
5 symbols.insert(element) 6 foritoN−1
7 elements[i] = symbols[elements[i]] 8 map_lef t.assign(3∗size)
Gambar 3.6: Pseudocode Fungsi Init I Love Kd-Trees II
gunakan untuk melakukan penghitungan jumlah elemen aktif pada rentang yang telah diberikan. Penjelesan lebih detil mengenai Fung-si BITUpdate terdapat pada Subbab 3.2.8. Pseudocode FungFung-si Build ditunjukkan pada Gambar 3.7.
1 ifpartition.isEmpty()
2 sz = partition.size()
3 map_lef t[node].assign(sz,0) 4 fori = 1topartition.size()
5 BITUpdate(map_lef t[node], sz, i,1) 6 mid= (lef t+right)/2
7 lef t_part = CreateLeftPartition(partition, mid) 8 right_part =CreateRightPartition(partition, mid) 9 map_lef t[node] = CreateMapping(partition, mid) 10 Build(lef t_part, node.lef t_child, lef t, mid)
11 Build(right_part, node.right_child, mid+ 1, right)
3.2.4 Desain Fungsi ActiveElementRangeQuery
Fungsi ini menerima 3 buah bilangan bulat sebagai parameteri,l,
dank, masing-masing telah dijelaskan pada Subbab 2.1.2. Fungsi
ini akan mengeluarkan nilai balikan berupa hasil dari perhitungan dari Fungsi ActiveElementQuery dengan parameterldani−1.
Pen-jelasan lebih lanjut pada Subbab 3.2.5. Pseudocode Fungsi Active-ElementRangeQuery ditunjukkan pada Gambar 3.8.
1 ifsymbols.find(k)
2 returnActiveElementQuery(l, symbols[k])−
ActiveElementQuery(i−1, symbols[k]) 3 else
4 return0
Gambar 3.8: Pseudocode Fungsi ActiveElementRangeQuery
3.2.5 Desain Fungsi ActiveElementQuery
Fungsi ini menerima 2 buah bilangan bulat sebagai parameter i
dank. Fungsi ini nantinya akan mengembalikan sebuah nilai yang
menyatakan banyak elemen k yang aktif pada rentang [1 .. i].
Algoritma untuk mendapatkan nilai ini dijelaskan pada Subbab 2.3.3.
node merupakan sebuah pointer yang menunjukkan node manaa
yang sedang ditelusuri padawavelet treeyang telah dibangun mula-mula nilainya berada padaROOT. lef tdanrightmasing-masing
merupakan sebuah bilangan bulat yang menunjukkan batas kiri dan kanan dari rentangnodesekarang, nilai awal dari kedua variabel ini adalah batas kiri dan kanan dariroot.
ActiveEle-37
mentQuery ditunjukkan pada Gambar 3.9.
1 node =ROOT 2 lef t = 0
3 right = size−1 4 ifx <0
5 return0 6 whilelef t < right
7 mid = (lef t+right)/2 8 until_i = map_lef t[node][x] 9 ifk≤mid
10 node =node.lef t_child
11 right = mid
12 x = until_i−1
13 else
14 node =node.right_child
15 lef t = mid+ 1 16 x = x−until_i
17 ifx <0
18 return0
19 x = min(x+ 1, map_lef t[node].size())
20 returnBITQuery(map_lef t[node], x)
Gambar 3.9: Pseudocode Fungsi ActiveElementQuery
3.2.6 Desain Fungsi ToggleElementStatus
Fungsi ini menerima sebuah bilangan bulatryang menyatakan
in-deks dari elemen yang akan diubah statusnya. Fungsi ini akan me-manggil Fungsi ToggleActualStatus yang dijelaskan pada Subbab 3.2.7 untuk melakukan perubahan pada arraystatusserta
dijelaskan pada Subbab 2.3.5.
node merupakan sebuah pointer yang menunjukkan node manaa
yang sedang ditelusuri padawavelet treeyang telah dibangun mula-mula nilainya berada padaROOT. lef tdanrightmasing-masing
merupakan sebuah bilangan bulat yang menunjukkan batas kiri dan kanan dari rentangnodesekarang, nilai awal dari kedua variabel ini adalah batas kiri dan kanan dariroot. Pseudocode Fungsi Toggle-ElementStatus ditunjukkan pada Gambar 3.10.
1 status =ToggleActualStatus(r) 2 node = ROOT
3 lef t = 0
4 right =size−1 5 val =elements[r] 6 whilelef t < right
7 mid= (lef t+right)/2 8 until_i =map_lef t[node][r] 9 ifval≤mid
10 node = node.lef t_child
11 right =mid
12 r = until_i−1
13 else
14 node = node.right_child
15 lef t = mid+ 1 16 r = r−until_i
17 sz = map_lef t[node].size()
18 BITUpdate(map_lef t[node], sz, r+ 1, status)
39
3.2.7 Desain Fungsi ToggleActualStatus
Fungsi ini menerima sebuah bilangan bulat r sebagai
parameter-nya, kemudian melakukan perubahan status untuk elemen ke-r.
Pseudocode Fungsi ToggleActualStatus ditunjukkan pada Gambar 3.11.
1 status[r] =!status[r] 2 returnstatus[r]?1 :−1
Gambar 3.11: Pseudocode Fungsi ToggleActualStatus
3.2.8 Desain Fungsi BITUpdate
Fungsi ini menerima tiag buah parameter, sebuah arrayarrdan dua
buah bilangan bulatiddanval. arrmerupakan array dari struktur
BIT yang ingin dilakukan perubahan nilai. id merupakan indeks
dari elemen yang nilainya akan ditambahkan. Perlu diingat bah-wa dalam struktur BIT ini hanya dapat dilakukan operasi penam-bahan. Pseudocode Fungsi BITUpdate ditunjukkan pada Gambar 3.12.
1 whileid≤size(arr)
2 arr[id] = arr[id] +val
3 id = id+ (id&(−id))
Gambar 3.12: Pseudocode Fungsi BITUpdate
3.2.9 Desain Fungsi BITQuery
Fungsi ini menerima duah parameter, sebuah arrayarrdan sebuah
dii-nginkan danidmerupakan batas kanan dariqueryyang diinginkan.
Operasiqueryyang didukung oleh struktur data ini adalah penjum-lahan dengan rentang [1 .. id]. Nilai ini sendiri merupakan nilai
balikan dari fungsi ini. Pseudocode Fungsi BITQuery ditunjukkan pada Gambar 3.13.
1 ret = 0 2 whileid >0
3 ret = ret+arr[id] 4 id = id−(id&(−id)) 5 returnret
Gambar 3.13: Pseudocode Fungsi BITQuery
3.3 Permasalahan I Love Kd-Trees III
Pada permasalahan ini sistem akan dibangun untuk menyelesaikan 2 jenis operasi yaitu, Operasi Mencari Bilangan Terkecil ke-K dan Operasi Menukar Elemen yang Bersebelahan.
3.3.1 Deskripsi Umum Sistem
Desain sistem untuk permasalahan ini merupakan pengembangan dari sistem untuk permasalahan I Love Kd-Trees yang telah dije-laskan pada Subbab 3.1.1. Operasi Menukar Elemen yang Bersebe-lahan akan ditambahkan pada permasaBersebe-lahan ini.
Arraybitvectormenyimpan data boolean. Nilai pada indeks
terten-tu bernilaitruejika nilai pada elemen tersebut≤mT(S)dan akan bernilaif alsejika sebaliknya.
Array rev_occurence meyimpan indeks yang menyatakan posisi
41
Selanjutnya sistem akan menerima masukan bilangan bulat type
untuk menentukkan operasi mana yang akan dikerjakan. Opera-si Mencari Bilangan Terkecil ke-K memiliki penjelasan yang sama pada subbab 3.1.1.
1 letelementsbe a newdynamicarray
2 letmap_lef t[be adynamicarrays ofdynamicarrays 3 letbitvectorbe adynamicarrays ofdynamicarrays
4 letoccurences[1..size]be an array ofdynamicarrays 5 letrev_occurence[0..MAXN]be a new array
6 letsymbolsbe a new dictionary
7 N =Input()//Number of elements 8 Q= Input()//Number of operations 9 fori= 0toN −1
10 elements[i] = Input() 11 Init(elements)
12 fori= 0toN −1
13 occurences[elements[i]].push(i)
14 rev_occurence[i] = occurences[elements[i]].size()
15 Build(elements,1,0, size) 16 forq = 0toQ−1
17 type =Input() 18 iftype= 0
19 i= Input()l =Input()k =Input() 20 Print(KthQuery(i, l, k)
21 else
22 i= Input()
23 SwapElement(i) 24
Operasi Menukar Elemen yang Bersebelahan akan menerima sebu-ah bilangan bulati sebagai masukan. Elemen pada indeks posisi
ke i dani+ 1akan ditukar posisinya. Pseudocode Fungsi Main ditunjukkan pada Gambar 3.14.
3.3.2 Desain Fungsi Init
Penjelasan fungsi ini sama dengan Fungsi Init untuk permasalahan I Love Kd-Trees yang telah dijelaskan pada Subbab 3.1.2. Perbedaan terdapat pada baris 8 khusus dibutuhkan untuk permasalahan ini. Pseudocode Fungsi Init ditunjukkan pada Gambar 3.15.
1 sorted =elements.copy()
2 sort(sorted)
3 forelement∈elements
4 symbols.insert(element) 5 foritoN−1
6 elements[i] = symbols[elements[i]] 7 map_lef t.assign(3∗size)
8 bitvector.assign(3∗size)
Gambar 3.15: Pseudocode Fungsi Init I Love Kd-Trees III
3.3.3 Desain Fungsi Build
Fungsi ini memiliki penjelasan yang sama dengan Subbab 3.1.3. Baris ke7sedikit berbeda dengan fungsi sebelumnya karena perlu dilakukan pembentukan dari struktur arraybitvector. Pseudocode
43
1 if partition.isEmpty()
2 return
3 mid = (lef t+right)/2
4 lef t_part = CreateLeftPartition(partition, mid) 5 right_part= CreateRightPartition(partition, mid) 6 map_lef t[node] = CreateMapping(partition, mid) 7 bitvector[node] = CreateBitvector(partition, mid) 8 Build(lef t_part, node.lef t_child, lef t, mid)
9 Build(right_part, node.right_child, mid+ 1, right)
Gambar 3.16: Pseudocode Fungsi Build I Love Kd-Trees III
3.3.4 Desain Fungsi KthQuery
Fungsi ini sama persis dengan Fungsi KthQuery yang telah dijelask-an pada Subbab 3.1.4. Pseudocode Fungsi KthQuery ditunjukkdijelask-an pada Gambar 3.4.
3.3.5 Desain Fungsi SwapElement
Fungsi ini menerima satu buah parameter bilangan bulatiyang
me-nyatakan elemen pada posisi berapa yang akan ditukar dengan ele-men di sebelah kanannya. Fungsi ini akan melakukan perubahan yang diperlukan untuk menjaga struktur dariwavelet tree.
Perubahan ini juga menyebabkan indeks kemunculan suatu ang-ka juga berubah maang-ka aang-kan dilakuang-kan perubahan pada array
occurences danrev_occurence yang akan dijelaskan pada
bagi-an Subbab 3.3.6.
node merupakan sebuah pointer yang menunjukkannode manaa
merupakan sebuah bilangan bulat yang menunjukkan batas kiri dan kanan dari rentang node sekarang, nilai awal dari kedua variabel ini adalah batas kiri dan kanan darirootyang kemudian akan ber-ubah sesuai dengan algoritma penelurusan yang telah dibahas pada Subbab 2.3.6. Selama penulurusan ini berlangsung juga akan dila-kukan perubahan pada arraymap_lef t. Pseudocode Fungsi
Swa-pElement ditunjukkan pada Gambar 3.17.
3.3.6 Desain Fungsi UpdateOccurence
Fungsi ini akan menerima sebuah parameter bilangan bulatiyang
menyatakan pada posisi mana penukaran elemen akan dilakukan. Pada kondisi sebelumnyaoccurence[x][y]menyimpan indeks ke-munculan ke-y dari elemenx. Ketika penukaran dengan elemen
pada indeksi+ 1terjadi maka struktur tersebut hanya berubah keti-ka elemen pada indeksidani+ 1merupakan elemen yang berbeda. Array rev_occurence merupakan struktur bantu yang
menyimp-an indeks dari elemen ke-ipada arrayoccurence[x]. Pseudocode
Fungsi UpdateOccurence ditunjukkan pada Gambar 3.18.
1 ifelements[i]̸=elements[i+ 1] 2 j = i+ 1
3 occurences[elements[i]][rev_occurence[i]] = j
4 occurences[elements[j]][rev_occurence[j]] = i
5 swap(elements[i], elements[j])
6 swap(rev_occurence[i], rev_occurence[j])
45
1 UpdateOccurence(i) 2 node =ROOT 3 lef t = 0
4 right = size−1 5 whilelef t < right
6 ifbitvector[node][i]̸=bitvector[node][i+ 1] 7 if!bitvector[node][i]
8 map_lef t[node][i]++
9 else
10 map_lef t[node][i
]--11 swap(bitvector[node][i], bitvector[node][i+ 1])
12 return
13 else
14 mid= (lef t+right)/2 15 until_i= map_lef t[node][i] 16 ifbitvector[node][i])
17 node = node.lef t_child
18 i = until_i−1
19 right = mid
20 else
21 node = node.right_child
22 i = i−until_i
23 lef t =mid+ 1
BAB 4 IMPLEMENTASI
Pada bab ini akan dijelaskan implementasi dari algoritma dan struk-tur data berdasarkan desain yang telah dilakukan.
4.1 Lingkungan Implementasi
Lingkungan implementasi dan pengembangan yang dilakukan ada-lah sebagai berikut:
1. Perangkat Keras
• Processor Intel Core i3-3217U CPU @ 1.80GHz x 4. • Memory9.8 GB.
2. Perangkat Lunak
• Sistem operasi Linux Mint 17.1 Rebecca KDE 64 bit. • Sublime Text 3.
4.2 Permasalahan I Love Kd-Trees
Subbab ini akan menjelaskan implementasi dari algoritma dan struktur data untuk menyelesaikan permasalahan I Love Kd-Trees.
4.2.1 Implementasi Fungsi Main
Fungsi Main diimplementasikan sesuai dengan pseudocode 3.1.1. Mula-mula fungsi ini membaca masukan dengan menggunakan fungsi scanf, membangun struktur datawavelet treekemudian men-jawab queryberdasarkan parameter yang diberikan. Luaran yang dihasilkan adalah hasil dari operasi quantile. Implementasi dari
Fungsi Main dapat dilihat pada Kode Sumber 4.1.
1 int main() {
2 int n, q;
3 scanf("%d%d", &n, &q);
4 for (int i = 0; i < n; i++) {
5 scanf("%d", &elements[i]);
6 }
7 init();
8 build(elements, 1, 0, symbols.size() - 1);
9 for (int i = 0; i < n; i++) {
10 occurences[elements[i]].emplace_back(i);
11 }
12 while (q--) {
13 int k, i, l;
14 scanf("%d%d%d", &k, &i, &l);
15 printf("%d\n", kthQuery(i, l, k));
16 }
17 return 0;
18 }
Kode Sumber 4.1: Implementasi Fungsi Main
4.2.2 Implementasi Variabel Global
Variabel digunakan untuk mempermudah masing-masing fungsi untuk mengakses data yang sama. Penggunaan variabel global pa-da implementasi ini diterapkan papa-da elements yang menyimpan
data masukan, map_lef t yang menyimpan struktur dari wavelet treeitu sendiri, variabelsymbolsyang menyimpan simbol-simbol
yang muncul pada data, sertaoccurencesyang menyimpan index
kemunculan untuk masing-masing symbols. Implementasi dari Va-riabel Global dapat dilihat pada Kode Sumber 4.2.
1 vector<int> elements;
2 vector<vector<int> > map_left;
3 vector<int> occurences[100002];
4 unordered_map<int, int> symbols;
49
4.2.3 Implementasi Fungsi Init
Pada awalnya fungsi ini akan membangun sebuah array baru yang disimpan pada variabel sorted. Tujuannya adalah untuk membentuk simbol-simbol yang ada pada data secara terurut tanpa mengubah data awal. Dilanjutkan dengan menginisialisasi variabel-variabel global yang dibutuhkan. Implementasi dari Fungsi Init dapat dilihat pada Kode Sumber 4.3.
1 void init() {
2 vector<int> sorted(elements);
3 sort(sorted.begin(), sorted.end());
4 for (int i = 0; i < elements.size(); i++) {
5 symbols.insert({sorted[i], symbols.size()});
6 }
7 for (int i = 0; i < elements.size(); i++) {
8 elements[i] = symbols[elements[i]];
9 }
10 for (int i = 0; i < 3 * symbols.size(); i++) {
11 map_left.emplace_back(vector<int>());
12 }
13 }
Kode Sumber 4.3: Implementasi Fungsi Init
4.2.4 Implementasi Fungsi Build
Fungsi ini akan membentuk struktur awal dari struktur datawavelet tree. Algoritma pembentukan secara detil telah dijelaskan pada Su-bbab 2.3 dengan desain yang telah dibuat pada SuSu-bbab 3.1.3. Fungsi CreateRightPartition(), CreateLeftPartition(), dan CreateMapping() dijabarkan pada baris6sampai15.
kemudian anak kiri terletak pada indeksnode∗2, dan anak kanan
terletak pada indeks node∗2 + 1. Hal ini dimungkinkan karena
struktur dariwavelet treemenyerupai complete binarytree. Strategi pengindeksan ini akan digunakan juga untuk permasalahan I Love Kd-Trees II dan III. Implementasi dari Fungsi Build dapat dilihat pada Kode Sumber 4.4.
1 void build(vector<int> &arr, int id,\
2 int left, int right) {
3 if (left == right) return;
4
5 int mid = (left + right) >> 1;
6 vector<int> arr_left, arr_right;
7
8 for (int i = 0; i < arr.size(); i++) {
9 int temp = i ? map_left[id].back() : 0;
10 if (arr[i] <= mid) {
11 temp++;
12 arr_left.emplace_back(arr[i]);
13 } else {
14 arr_right.emplace_back(arr[i]);
15 }
16 map_left[id].emplace_back(temp);
17 }
18
19 build(arr_left, id << 1, left, mid);
20 build(arr_right, (id << 1) | 1, mid + 1, right);
21 }
Kode Sumber 4.4: Implementasi Fungsi Build
4.2.5 Implementasi Fungsi KthQuery
kemuncul-51
an ke-l dari elemen tersebut pada array awal. Implementasi dari
Fungsi KthQuery dapat dilihat pada Kode Sumber 4.5. 1 int kthQuery(int i, int l, int k) {
2 int id = 1;
3 int left = 0;
4 int right = symbols.size() - 1;
5
6 while (left < right) {
7 int until_i = map_left[id][i];
8 int mid = (left + right) >> 1;
9 id <<= 1;
10 if (k <= until_i) {
11 right = mid;
12 i = until_i - 1;
13 } else {
14 id++;
15 left = mid + 1;
16 i -= until_i;
17 k -= until_i;
18 }
19 }
20 if (l <= occurences[left].size())
21 return occurences[left][l - 1];
22 return -1;
23 }
Kode Sumber 4.5: Implementasi Fungsi KthQuery
4.3 Permasalahan I Love Kd-Trees II
Subbab ini akan menjelaskan implementasi dari algoritma dan struktur data untuk menyelesaikan permasalahan I Love Kd-Trees II.
4.3.1 Implementasi Fungsi Main
saat mengatasi operasi-operasi yang ada untuk permasalahan ini. Implementasi dari Fungsi Main dapat dilihat pada Kode Sumber 4.6.
1 int main() {
2 int n, q;
3 scanf("%d%d", &n, &q);
4 for (int i = 0; i < n; i++) {
5 scanf("%d", &elements[i]);
6 }
7 init();
8 build(elements, 1, 0, symbols.size() - 1);
9 while (q--) {
10 int type;
11 getnum<int>(type);
12 if (!type) {
13 int i, l, k;
14 scanf("%d%d%d", &i, &l, &k);
15 printf("%d\n",\
16 activeElementRangeQuery(i, l, k));
17 } else {
18 int r;
19 scanf("%d", &r);
20 toggleElementStatus(r);
21 }
22 }
23 return 0;
24 }
Kode Sumber 4.6: Implementasi Fungsi Main
4.3.2 Implementasi Variabel Global
Variabel global yang diimplementasikan pada permasalahan ini adalah array dinamiselements,status,map_lef t, dansymbols.
Penggunaan array elements, map_lef t, dan symbols memiliki
penjelasan yang sama dengan Subbab 4.2.2. Arraystatus
53
indeks. Implementasi dari variabel global dapat dilihat pada Kode Sumber 4.7.
1 vector<int> elements;
2 vector<bool> status;
3 vector<vector<int> > map_left;
4 unordered_map<int, int> symbols;
Kode Sumber 4.7: Implementasi Variabel Global
4.3.3 Implementasi Fungsi Init
Fungsi ini memiliki implementasi yang hampir sama dengan Su-bbab 4.2.3. Namun pada permasalahan ini membutuhkan sebuah ar-ray tambahan,status, yang menyimpan status terkini dari
masing-masing elemen. Mula-mula diinisialisasi dengan nilai true atau
1. Implementasi dari Fungsi Init dapat dilihat pada Kode Sumber 4.8.
1 void init() {
2 status.assign(n, 1);
3
4 vector<int> sorted(elements);
5 sort(sorted.begin(), sorted.end());
6
7 for (int i = 0; i < elements.size(); i++) {
8 symbols.insert({sorted[i], symbols.size()});
9 }
10
11 for (int i = 0; i < elements.size(); i++) {
12 elements[i] = symbols[elements[i]];
13 }
14
15 for (int i = 0; i < 3 * symbols.size(); i++) {
16 map_left.emplace_back(vector<int>());
17 }
18 }
4.3.4 Implementasi Fungsi Build
Implementasi dari Fungsi Build ini memiliki kemiripan dengan im-plementasi Fungsi Build pada Subbab 4.2.4. Perbedaannya terletak pada saat mencapainode leaf. Pada permasalahan ini dibutuhkan cara untuk menghitung elemen yang aktif pada suatu rentang, oleh karena itu diimplementasikan struktur data BIT untuk membantu menyelesaikan permasalahan ini. Implementasi dari Fungsi Build dapat dilihat pada Kode Sumber 4.9.
1 void build(vector<int> &arr, int id,\
2 int left, int right) {
3 if (left == right) {
4 m