Algoritma dan Struktur Data Lanjut Kompresi
Kompresi Kompresi merupakan proses pengubahan sekumpulan data menjadi suatu bentuk kode untuk menghemat kebutuhan tempat penyimpanan dan waktu untuk transmisi data. Kompresi dapat diterapkan untuk: - File Teks - File Gambar - File Audio - File Video
Metode dalam Kompresi Ada 3 metode yang digunakan dalam kompresi: - Kompresi Lossy - Kompresi Lossless - Kompresi Delta
Kompresi Lossy Suatu metode kompresi data yang menghilangkan sebagian “Informasi” dari file asli (file yang akan dimampatkan) selama proses kompresi berlangsung dengan tidak menghilangkan (secara signifikan) informasi yang ada dalam file secara keseluruhan. Contoh: pada kompresi file gambar. Merubah detail dan warna sebuah file gambar menjadi lebih sederhana dan mempunyai kapasitas file menjadi lebih kecil tanpa terlihat perbedaan mencolok dari pandangan manusia.
Kompresi Lossless Metode kompresi data di mana tidak ada “Informasi” / data yang hilang atau berkurang jumlahnya selama proses kompresi, sehingga pada proses dekompresi jumlah bit (byte) data atau informasi dalam keseluruhan file hasil sama persis dengan file aslinya.
Kompresi Delta Delta Comression mengirimkan semua informasi state, memungkinkan hanya mengirim perubahan/update (delta) dari state sebelumnya. Efeknya, membutuhkan pengiriman data yang reliable (contoh TCP). Efektif jika state game world besar, namun perubahan yang ada kecil.
Algortima Kompresi Algoritma Huffman Algoritma LZW (Lempel-Ziv-Welch) Algoritma DMC (Dynamic Marcov Compression) Dsb
Kompresi Data Teks Kompresi Teks menggunakan metode Lossless. Karena jika menghilangkan beberapa karakter akan merubah arti dari teks aslinya. Kompresi Teks ada 2 macam: Character-based Frequency counting Huffman Encoding, Arithmetic Encoding Word-based Frequency counting Lempel-Ziv (LZ) algorithm
Algoritma Huffman Dibuat oleh seorang mahasiswa MIT bernama David Huffman. Merupakan salah satu metode paling lama dan paling terkenal dalam kompresi teks. Metode ini adalah suatu teknik kompresi data secara statistik yang bekerja dengan mereduksi panjang kode rata-rata dan menghasilkan kode prefiks yang digunakan untuk merepresentasikan simbol-simbol dari suatu jenis huruf.
Pohon Huffman Algoritma Huffman menggunakan struktur pohon dalam prosesnya. Dalam struktur pohon dikenal dengan terminologi parent (orang tua) dan child (anak). Parent (orang tua) yaitu sebuah simpul yang memiliki lintasan ke simpul lain dengan tingkatan (level) di bawahnya. Child (anak) yaitu sebuah simpul yang memiliki lintasan ke simpul lain dengan tingktan (level) di atasnya.
Pohon Huffman (2) Beradasarkan jumlah anak pohon huffman dikategorikan : Uner : pohon dengan orang tua yang hanya memiliki satu anak Biner : pohon dengan orang tua yang memiliki dua anak
Algoritma Huffman Pengkodean dengan huffman coding menggunakan panjang bit yang bervariasi dalam pengkodean sebuah karakter. Karakter dengan frekuensi kemunculan lebih besar memiliki panjang bit yang lebih pendek. Berlaku kebalikannya.
Langkah-langkah Algoritma Huffman Hitung statistik (frekuensi) jumlah kemunculan masing-masing simbol. Simpan hasil informasi bobot masing-masing simbol. Membangun pohon huffman berdasarkan larik bobot dari masing-masing simbol. Konversi pohon huffman menjadi kode spesifik untuk tiap simbol.
Contoh Berikut ini adalah sebuah contoh cara pengkodean sebuah string. Misalkan kita akan mengkodekan sebuah string “AABCABC”. Dalam kode ASCII string 7 huruf “AABCABC” membutuhkan representasi 7 × 8 bit = 56 bit (7 byte), dengan rincian sebagai berikut: A = 01000001 B = 01000010 C = 01000011
Pemecahan Masalah Berdasarkan algoritma yang telah disebutkan sebelumnya, maka kita pertama kali akan menghitung frekuensi kemunculan dari setiap karakater. String: AABCABC Simbol Frekuensi A 3 B 2 C
Pemecahan Masalah (2) Berdasarkan tabel maka dapat disusun model pohon Huffman-nya:
Pemecahan Masalah (3) Berdasarkan pohon Huffman yang ditunjukan pada hasil di atas maka dapat ditentukan kode huffman untuk masing-masing setiap simbol yang dalam string “AABCABC”.
Hasil Kompresi Berdasarkan tabel Huffman maka rangkaian bit dari string AABCABC adalah: 0 0 10 11 0 10 11 Jadi jumlah bit yang dipakai hanya 11 bit (2 byte), lebih hemat dari jumlah bit sebelumnya (56 bit).
Analisa Dari Tabel Huffman tampak bahwa kode untuk sebuah simbol/karakter tidak boleh menjadi awalan dari kode simbol yang lain guna menghindari keraguan (ambiguitas) dalam proses dekompresi atau decoding. Karena tiap kode Huffman yang dihasilkan unik, maka proses dekompresi dapat dilakukan dengan mudah.
Dekompresi Saat membaca kode bit pertama dalam rangkaian bit: 0 0 10 11 0 10 11 yaitu bit 0, dapat langsung disimpulkan bahwa kode bit “0” merupakan pemetaan dari simbol “A”. Bit kedua juga “A”. Kemudian baca kode bit selanjutnya, yaitu bit “1”, tidak ada kode Huffman “1”, lalu baca kode Huffman selanjutnya yaitu “0” sehingga menjadi “10” yaitu karakter “B”. Begitu seterusnya…
Huffman Tree Hitung frekuensi untuk tiap simbol. Urutkan dari yang paling kecil ke yang paling besar. Setiap simbol mewakili satu node. Tambahkan kode ‘0’ untuk node terkecil pertama dan ‘1’ untuk node terkecil kedua. Gabungkan kedua node tersebut dan jumlahkan kedua frekuensinya. Maka akan didapat node parent. Hapus kedua node terkecil tadi dari dalam list node, lalu masukkan node parent tadi. Ulangi langkah ke-2 sampai ke-4 hingga semua simbol habis dibangkitkan.
Penerapan Algortima Huffman dalam Java Buatlah kelas-kelas: Simbol Node HuffmanCode
Kelas Simbol Tambahkan atribut char karakter, int frekuensi, String biner. Inisialisasi nilai biner dengan string kosong (“”). Buat setter dan getter-nya. Buat 3 konstruktor, 1 konstruktor tanpa parameter, 1 konstruktor dengan parameter char karakter dan int frekuensi, 1 konstruktor dengan parameter char karakter, int frekuensi, dan String biner. Inisialisasi nilai-nilai parameter dari konstruktor di dalam konstruktor.
Kelas Node Kelas Node adalah turunan dari kelas Simbol. Tambahkan 3 atribut Node left, right, dan parent. Buat setter dan getter-nya. Buat 3 konstruktor, 1 konstruktor tanpa parameter, 1 konstruktor dengan parameter Node left dan right, 1 konstruktor dengan parameter char karakter dan int frekuensi. Inisialisasi tiap nilai dari parameter. Untuk konstruktor ketiga, inisialisasi nilai kelas super dengan menggunakan fungsi setter dan getter dari kelas super tersebut
Kelas Node (2) Didalam fungsi setLeft dan setRight, tambahkan sintaks berikut: left.setParent(this); (untuk setLeft) right.setParent(this); (untuk setRight) Tambahkan fungsi hasChild untuk mengecek apakah node ini memiliki anak atau tidak. Tambahkan fungsi hasLeft dan hasRight untuk mengecek apakah node ini memiliki anak left atau right.
Kelas HuffmanCode Tambahkan sebuah atribut static Vector<Simbol> listSimbol ke dalamnya, lalu inisialisasi variabel tersebut. Buat sebuah fungsi static bernama urutSimbol dengan tipe Vector<Node> dan berparameter Vector<Node> listNode. Tambahkan kode berikut ke dalamnya: for (int i = 0; i < listNode.size() - 1; i++) { Node s = listNode.get(i); for (int j = i + 1; j < listNode.size(); j++) { Node s2 = listNode.get(j); if (s2.getFrekuensi() > s.getFrekuensi()) { Node nB; nB = listNode.get(i); listNode.set(i, listNode.get(j)); listNode.set(j, nB); } return listNode;
Kelas HuffmanCode (2) Buat sebuah fungsi static bernama getTopParent dengan tipe Node dan berparameter Vector<Node> listNode, lalu masukkan: Node parent = null; Vector<Node> listBuff = new Vector<Node>(); for (Node node : listNode) { listBuff.add(node); } while (true) { parent = new Node(); parent.setKarakter('p'); listBuff = urutSimbol(listBuff); Node n1 = listBuff.get(listBuff.size() - 1); Node n2 = listBuff.get(listBuff.size() - 2); parent.setFrekuensi(n1.getFrekuensi() + n2.getFrekuensi()); parent.setLeft(n2); parent.setRight(n1); if (listBuff.size() <= 2) { break; listBuff.removeElementAt(listBuff.size() - 1); listBuff.add(parent); return parent;
Kelas HuffmanCode (3) Buat sebuah fungsi static bernama getCode dengan tipe void dan berparameter Node parent, lalu masukkan: if (parent.hasLeft()) { parent.getLeft().setBiner(parent.getBiner() + "0"); getCode(parent.getLeft()); } if (parent.hasRight()) { parent.getRight().setBiner(parent.getBiner() + "1"); getCode(parent.getRight()); if (!parent.hasChild()) { listSimbol.add((Simbol) parent);
Kelas HuffmanCode (4) Buat sebuah fungsi main, lalu masukkan: String txt = "AABCABC"; Vector<Node> listNode = new Vector<Node>(); String buff = txt; while (buff.length() > 0) { char c = buff.charAt(0); int f = 0; String buff2 = ""; for (int j = 0; j < buff.length(); j++) { if (c == buff.charAt(j)) f++; else buff2 += buff.charAt(j); } buff = buff2; listNode.add(new Node(c, f)); } listNode = urutSimbol(listNode); Node topParent = getTopParent(listNode); getCode(topParent); for (Simbol simbol : listSimbol) System.out.println(simbol.getKarakter() + "|" + simbol.getFrekuensi() + "|" + simbol.getBiner());
Tugas Buat paper tentang algoritma kompresi: - Lempel-Ziv-Welch (LZW) - Dymanic Markov Compression (DMC) Jelaskan sejarahnya, aturannya, algoritma-nya. Beri contoh penerapannya: Misal untuk mengkompresi String/kalimat. Beri penjelasan langkah per langkah untuk kompresi dan dekompresi-nya. Kumpul hardcopy minggu depan saat kuliah. Dikerjakan maksimal 2 mahasiswa. Tiap kelompok untuk penerapan-nya harus beda.
Post Test Sebutkan 3 jenis metode kompresi! 1 byte berapa bit? Buatlah tabel Huffman untuk kompresi string ABACCDA (Kerjakan dengan lengkap tahap-tahapnya)! Tulis nama dan NIM.