Anda di halaman 1dari 31

Algoritma dan Struktur Data Lanjut

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

Ada 3 metode yang digunakan dalam


kompresi:
- Kompresi Lossy
- Kompresi Lossless
- Kompresi Delta

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.

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.

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.

Algoritma Huffman
Algoritma LZW (Lempel-Ziv-Welch)
Algoritma DMC (Dynamic Marcov
Compression)
Dsb

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

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.

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.

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

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.

1.

Hitung statistik (frekuensi) jumlah kemunculan


masing-masing simbol.

2.

Simpan hasil informasi bobot masing-masing


simbol.

3.

Membangun pohon huffman berdasarkan larik


bobot dari masing-masing simbol.

4.

Konversi pohon huffman menjadi kode spesifik


untuk tiap simbol.

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
A
B
C
A
B
C

= 01000001
= 01000001
= 01000010
= 01000011
= 01000001
= 01000010
= 01000011

Berdasarkan algoritma yang telah disebutkan


sebelumnya, maka kita pertama kali akan
menghitung frekuensi kemunculan dari setiap
karakater.
String: AABCABC

Simbol

Frekuensi

Berdasarkan tabel maka dapat disusun model


pohon Huffman-nya:

Berdasarkan pohon Huffman yang ditunjukan


pada hasil di atas maka dapat ditentukan kode
huffman untuk masing-masing setiap simbol
yang dalam string AABCABC.

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

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.

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

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.

Buatlah kelas-kelas:
Simbol
Node
HuffmanCode

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

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.

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;

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.removeElementAt(listBuff.size() - 1);
listBuff.add(parent);
}
return parent;

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);
}

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());

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.

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.

Anda mungkin juga menyukai