Anda di halaman 1dari 17

MODUL PRAKTIKUM RANCANGAN DAN ANALISA ALGORITMA

UNTUK KELAS 3A

TOPIK : ALGORITMA GREEDY

DISAMPAIKAN OLEH : MUHAMMAD ARHAMI

A. PENGKODEAN HUFFMAN (HUFFMAN CODING)

1. Pegantar
Pengodean Huffman adalah salah satu metode kompresi dasar, yang telah
terbukti bermanfaat dalam standar kompresi gambar dan video. Saat menerapkan
teknik penyandian Huffman pada Gambar, simbol sumber dapat berupa intensitas
piksel Gambar, atau output dari fungsi pemetaan intensitas.
Kode Huffman sebagai algoritma kompresi data menggunakan teknik greedy
untuk implementasinya. Algoritma didasarkan pada frekuensi karakter yang muncul
dalam file.
Kita tahu bahwa file kita disimpan sebagai kode biner di komputer dan setiap
karakter dari file tersebut diberi kode karakter biner dan biasanya, kode karakter ini
memiliki panjang tetap untuk karakter yang berbeda.
Kode Awalan, berarti kode (urutan bit) ditetapkan sedemikian rupa sehingga
kode yang ditetapkan untuk satu karakter bukan awalan kode yang ditugaskan untuk
karakter lain. Ini adalah bagaimana Huffman Coding memastikan bahwa tidak ada
ambiguitas ketika decoding bitstream yang dihasilkan.
Jika diketahui ada empat karakter a, b, c dan d, dan kode panjang variabel yang
sesuai adalah 00, 01, 0 dan 1. Pengkodean ini mengarah pada ambiguitas karena kode
yang ditugaskan ke c adalah awalan dari kode yang ditugaskan ke a dan b. Jika bit
stream terkompresi adalah 0001, output de-kompresi mungkin "cccd" atau "ccb" atau
"acd" atau "ab".
Ada dua bagian utama dalam Huffman Coding
1. Membangun Pohon Huffman dari karakter input.
2. Melintasi Pohon Huffman dan menetapkan kode ke karakter.

1|Praktikum Rancangan dan Analisa Algoritma


3. Langkah-langkah untuk membangun Pohon Huffman
Input adalah array karakter unik beserta frekuensi kemunculannya dan
outputnya adalah Huffman Tree.
1. Buat simpul daun untuk setiap karakter unik dan buat tumpukan min dari
semua simpul daun (Min Heap digunakan sebagai antrian prioritas. Nilai bidang
frekuensi digunakan untuk membandingkan dua simpul dalam tumpukan
minimum. Awalnya, karakter yang paling jarang muncul adalah root)
2. Ekstrak dua node dengan frekuensi minimum dari min heap.
3. Buat simpul internal baru dengan frekuensi yang sama dengan jumlah dari dua
node frekuensi. Jadikan simpul yang diekstraksi pertama sebagai anak kirinya
dan simpul yang diekstrak lainnya sebagai anak kanannya. Tambahkan simpul
ini ke tumpukan min.
4. Ulangi langkah # 2 dan # 3 hingga heap hanya berisi satu node. Node yang
tersisa adalah node root dan pohon sudah selesai.

Berikut contoh untuk pemahaman penggunaan melalui algoritmanya:


character Frequency
a 5
b 9
c 12
d 13
e 16
f 45
Langkah 1. Bangun heap min yang berisi 6 node di mana setiap node mewakili root
dari pohon dengan node tunggal.
Langkah 2 Ekstrak dua node frekuensi minimum dari min heap. Tambahkan simpul
internal baru dengan frekuensi 5 + 9 = 14 .:

2|Praktikum Rancangan dan Analisa Algoritma


Sekarang min heap berisi 5 simpul di mana 4 simpul adalah akar pohon dengan
masing-masing elemen tunggal, dan satu simpul tumpukan adalah akar pohon dengan
3 elemen
character Frequency
c 12
d 13
Internal Node 14
e 16
f 45
Langkah 3: Ekstrak dua node frekuensi minimum dari heap. Tambahkan simpul
internal baru dengan frekuensi 12 + 13 = 25

Sekarang min heap berisi 4 simpul di mana 2 simpul adalah akar pohon dengan
masing-masing elemen, dan dua simpul tumpukan adalah akar pohon dengan lebih
dari satu simpul.
character Frequency
Internal Node 14
e 16
Internal Node 25
f 45
Langkah 4: Ekstrak dua node frekuensi minimum. Tambahkan simpul internal baru
dengan frekuensi 14 + 16 = 30

3|Praktikum Rancangan dan Analisa Algoritma


Sekarang min heap berisi 3 node.
character Frequency
Internal Node 25
Internal Node 30
f 45
Langkah 5: Ekstrak dua node frekuensi minimum. Tambahkan simpul internal baru
dengan frekuensi 25 + 30 = 55

Sekarang min heap berisi 2 node.


character Frequency
f 45
Internal Node 55
Langkah 6: Ekstrak dua node frekuensi minimum. Tambahkan simpul internal baru
dengan frekuensi 45 + 55 = 100

Sekarang min heap hanya mengandung satu node.

4|Praktikum Rancangan dan Analisa Algoritma


character Frequency
Internal Node 100
Karena heap hanya berisi satu node, algoritma berhenti di sini.
Langkah-langkah untuk mencetak kode dari Huffman Tree:
Lintasi pohon yang terbentuk mulai dari akar. Pertahankan array bantu. Saat bergerak
ke anak kiri, tulis 0 ke array. Saat pindah ke anak yang tepat, tulis 1 ke larik. Cetak
array saat simpul daun ditemukan.

Kode-kode tersebut adalah sebagai berikut:


character code-word
f 0
c 100
d 101
a 1100
b 1101
e 111
4. Listing Program
Listing berikut dengan bahasa pemrograman C++
Catatan ;
Listing boleh dirubah ke bahasa pemrograman lainnya
// C++ program untuk kode huffman
#include <iostream>
#include <cstdlib>
using namespace std;

// This constant can be avoided by explicitly


// calculating height of Huffman Tree
#define MAX_TREE_HT 100

// A Huffman tree node

5|Praktikum Rancangan dan Analisa Algoritma


struct MinHeapNode {

// One of the input characters


char data;

// Frequency of the character


unsigned freq;

// Left and right child of this node


struct MinHeapNode *left, *right;
};

// A Min Heap: Collection of


// min-heap (or Huffman tree) nodes
struct MinHeap {

// Current size of min heap


unsigned size;

// capacity of min heap


unsigned capacity;

// Attay of minheap node pointers


struct MinHeapNode** array;
};

// A utility function allocate a new


// min heap node with given character
// and frequency of the character
struct MinHeapNode* newNode(char data, unsigned freq)
{
struct MinHeapNode* temp
= (struct MinHeapNode*)malloc
(sizeof(struct MinHeapNode));

temp->left = temp->right = NULL;


temp->data = data;

return temp;
}

// A utility function to create


// a min heap of given capacity
struct MinHeap* createMinHeap(unsigned capacity)

struct MinHeap* minHeap


= (struct MinHeap*)malloc(sizeof(struct MinHeap));

6|Praktikum Rancangan dan Analisa Algoritma


// current size is 0
minHeap->size = 0;

minHeap->capacity = capacity;

minHeap->array
= (struct MinHeapNode**)malloc(minHeap->
capacity * sizeof(struct MinHeapNode*));
return minHeap;
}

// A utility function to
// swap two min heap nodes
void swapMinHeapNode(struct MinHeapNode** a,
struct MinHeapNode** b)

struct MinHeapNode* t = *a;


*a = *b;
*b = t;
}

// The standard minHeapify function.


void minHeapify(struct MinHeap* minHeap, int idx)

int smallest = idx;


int left = 2 * idx + 1;
int right = 2 * idx + 2;

if (left < minHeap->size && minHeap->array[left]->


freq < minHeap->array[smallest]->freq)
smallest = left;

if (right < minHeap->size && minHeap->array[right]->


freq < minHeap->array[smallest]->freq)
smallest = right;

if (smallest != idx) {
swapMinHeapNode(&minHeap->array[smallest],
&minHeap->array[idx]);
minHeapify(minHeap, smallest);
}
}

// A utility function to check


// if size of heap is 1 or not

7|Praktikum Rancangan dan Analisa Algoritma


int isSizeOne(struct MinHeap* minHeap)
{

return (minHeap->size == 1);


}

// A standard function to extract


// minimum value node from heap
struct MinHeapNode* extractMin(struct MinHeap* minHeap)

struct MinHeapNode* temp = minHeap->array[0];


minHeap->array[0]
= minHeap->array[minHeap->size - 1];

--minHeap->size;
minHeapify(minHeap, 0);

return temp;
}

// A utility function to insert


// a new node to Min Heap
void insertMinHeap(struct MinHeap* minHeap,
struct MinHeapNode* minHeapNode)

++minHeap->size;
int i = minHeap->size - 1;

while (i && minHeapNode->freq < minHeap->array[(i - 1) / 2]->freq) {

minHeap->array[i] = minHeap->array[(i - 1) / 2];


i = (i - 1) / 2;
}

minHeap->array[i] = minHeapNode;
}

// A standard function to build min heap


void buildMinHeap(struct MinHeap* minHeap)

int n = minHeap->size - 1;
int i;

for (i = (n - 1) / 2; i >= 0; --i)

8|Praktikum Rancangan dan Analisa Algoritma


minHeapify(minHeap, i);
}

// A utility function to print an array of size n


void printArr(int arr[], int n)
{
int i;
for (i = 0; i < n; ++i)
cout<< arr[i];

cout<<"\n";
}

// Utility function to check if this node is leaf


int isLeaf(struct MinHeapNode* root)

return !(root->left) && !(root->right);


}

// Creates a min heap of capacity


// equal to size and inserts all character of
// data[] in min heap. Initially size of
// min heap is equal to capacity
struct MinHeap* createAndBuildMinHeap(char data[], int freq[], int size)

struct MinHeap* minHeap = createMinHeap(size);

for (int i = 0; i < size; ++i)


minHeap->array[i] = newNode(data[i], freq[i]);

minHeap->size = size;
buildMinHeap(minHeap);

return minHeap;
}

// The main function that builds Huffman tree


struct MinHeapNode* buildHuffmanTree(char data[], int freq[], int size)

{
struct MinHeapNode *left, *right, *top;

// Step 1: Create a min heap of capacity


// equal to size. Initially, there are
// modes equal to size.
struct MinHeap* minHeap = createAndBuildMinHeap(data, freq, size);

9|Praktikum Rancangan dan Analisa Algoritma


// Iterate while size of heap doesn't become 1
while (!isSizeOne(minHeap)) {

// Step 2: Extract the two minimum


// freq items from min heap
left = extractMin(minHeap);
right = extractMin(minHeap);

// Step 3: Create a new internal


// node with frequency equal to the
// sum of the two nodes frequencies.
// Make the two extracted node as
// left and right children of this new node.
// Add this node to the min heap
// '$' is a special value for internal nodes, not used
top = newNode('$', left->freq + right->freq);

top->left = left;
top->right = right;

insertMinHeap(minHeap, top);
}

// Step 4: The remaining node is the


// root node and the tree is complete.
return extractMin(minHeap);
}

// Prints huffman codes from the root of Huffman Tree.


// It uses arr[] to store codes
void printCodes(struct MinHeapNode* root, int arr[], int top)

// Assign 0 to left edge and recur


if (root->left) {

arr[top] = 0;
printCodes(root->left, arr, top + 1);
}

// Assign 1 to right edge and recur


if (root->right) {

arr[top] = 1;
printCodes(root->right, arr, top + 1);
}
// If this is a leaf node, then
// it contains one of the input

10 | P r a k t i k u m R a n c a n g a n d a n A n a l i s a A l g o r i t m a
// characters, print the character
// and its code from arr[]
if (isLeaf(root)) {

cout<< root->data <<": ";


printArr(arr, top);
}
}

// The main function that builds a


// Huffman Tree and print codes by traversing
// the built Huffman Tree
void HuffmanCodes(char data[], int freq[], int size)

{
// Construct Huffman Tree
struct MinHeapNode* root
= buildHuffmanTree(data, freq, size);

// Print Huffman codes using


// the Huffman tree built above
int arr[MAX_TREE_HT], top = 0;

printCodes(root, arr, top);


}

// Driver program to test above functions


int main()
{

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };


int freq[] = { 5, 9, 12, 13, 16, 45 };

int size = sizeof(arr) / sizeof(arr[0]);

HuffmanCodes(arr, freq, size);

return 0;
}
Hasil
f: 0
c: 100
d: 101
a: 1100
b: 1101
e: 111

11 | P r a k t i k u m R a n c a n g a n d a n A n a l i s a A l g o r i t m a
Catatan :
Inputannya dibuat sebarang, artinya angka char arr dan int freq[]

diinputkan, tidak dideklarasikan, amati! Dan tuliskan apa yang ada


dapatkan.

Kompleksitas waktu: O (nlogn) di mana n adalah jumlah karakter unik. Jika ada n
node, extractMin () disebut 2 * (n - 1) kali. extractMin () membutuhkan waktu O (logn)
karena memanggil minHeapify (). Jadi, kompleksitas keseluruhan adalah O (nlogn).

B. ALGORITMA GREEDY UNTUK EGYPTIAN FRACTION (PECAHAN MESIR)


1. Pengantar
Setiap pecahan positif dapat direpresentasikan sebagai jumlah pecahan unit
unik. Pecahan adalah pecahan satuan jika pembilangnya adalah 1 dan penyebutnya
adalah bilangan bulat positif, misalnya 1/3 adalah pecahan satuan. Representasi seperti
itu disebut Fraksi Mesir karena digunakan oleh orang Mesir kuno.
Berikut ini beberapa contoh:
Egyptian Fraction Representation of 2/3 is 1/2 + 1/6
Egyptian Fraction Representation of 6/14 is 1/3 + 1/11 + 1/231
Egyptian Fraction Representation of 12/13 is 1/2 + 1/3 + 1/12 + 1/156
Kita dapat menghasilkan Fraksi Mesir menggunakan Algoritma Greedy. Untuk
jumlah tertentu dari bentuk ‘nr / dr’ di mana dr> nr, pertama-tama temukan fraksi unit
terbesar, kemudian ulangi untuk bagian sisanya. Sebagai contoh, perhatikan 6/14,
pertama-tama kita menemukan plafon 14/6, yaitu, 3. Jadi, fraksi satuan pertama
menjadi 1/3, kemudian berulang untuk (6/14 - 1/3) yaitu, 4/42.
2. Listing Program
Listing berikut dengan bahasa pemrograman C++
Catatan ;
Listing boleh dirubah ke bahasa pemrograman lainnya
// C++ program untuk fraction in Egyptian menggunakan Greedy

12 | P r a k t i k u m R a n c a n g a n d a n A n a l i s a A l g o r i t m a
// Algorithm
#include <iostream>
using namespace std;

void printEgyptian(int nr, int dr)


{
// If either numerator or denominator is 0
if (dr == 0 || nr == 1)
return;

// If numerator divides denominator, then simple division


// makes the fraction in 1/n form
if (dr%nr == 0)
{
cout << "1/" << dr/nr;
return;
}

// If denominator divides numerator, then the given number


// is not fraction
if (nr%dr == 0)
{
cout << nr/dr;
return;
}

// If numerator is more than denominator


if (nr > dr)
{
cout << nr/dr << " + ";
printEgyptian(nr%dr, dr);
return;
}

// We reach here dr > nr and dr%nr is non-zero


// Find ceiling of dr/nr and print it as first
// fraction
int n = dr/nr + 1;
cout << "1/" << n << " + ";

// Recur for remaining part


printEgyptian(nr*n-dr, dr*n);
}

// Driver Program
int main()
{
int nr = 6, dr = 14;
cout << "Egyptian Fraction Representation of "
<< nr << "/" << dr << " is\n ";
printEgyptian(nr, dr);
return 0;
}

13 | P r a k t i k u m R a n c a n g a n d a n A n a l i s a A l g o r i t m a
Catatan :
Inputannya dibuat sebarang, artinya angka nr dan dr diinputkan, tidak
dideklarasikan
Output:
Egyptian Fraction Representation of 6/14 is
1/3 + 1/11 + 1/231
Algoritma Greedy bekerja karena sebagian kecil selalu direduksi menjadi bentuk
di mana penyebut lebih besar dari pembilang dan pembilang tidak membagi penyebut.
Untuk bentuk yang dikurangi seperti itu, panggilan rekursif yang disorot dibuat untuk
pembilang yang dikurangi. Jadi panggilan rekursif terus mengurangi pembilang
sampai mencapai 1.

Referensi:
http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fractions/egyptian.html

C. ALGORITMA GREEDY UNTUK MENDAPATKAN KOIN-KOIN PECAHAN


MINIMUM
1. Pengantar
Algoritma greedy merupakan algoritma yang digunakan untuk menemukan
solusi optimal untuk masalah yang diberikan. Algoritma greedy bekerja dengan
menemukan solusi optimal secara lokal (solusi optimal untuk sebagian masalah) pada
setiap bagian sehingga menunjukkan solusi optimal Global dapat ditemukan.

Dalam masalah ini, kita akan menggunakan algoritma greedy untuk


menemukan jumlah minimum koin /atau pengembalian coin yang dapat disesuaikan
dengan jumlah yang diberikan. Untuk ini, kita akan mempertimbangkan semua koin
atau catatan yang valid, yaitu denominasi {1, 2, 5, 10, 20, 50, 100, 200, 500, 2000}. Dan
kita perlu mengembalikan jumlah koin/uang kertas ini yang kita butuhkan untuk
membayar jumlahnya.

14 | P r a k t i k u m R a n c a n g a n d a n A n a l i s a A l g o r i t m a
Kita dapat mengambil beberapa contoh untuk memahami konteks dengan lebih
baik –
Contoh
Input: V = 70
Output: 2
Kita membutuhkan koin/uang kertas 50 dan 20 masing-masing 1.
Input: V = 121
Output: 3
Kita membutuhkan koin/uang kertas 100, 20 dan 1 masing-masing 1.

Input : V = 1231
Output : 7

Kita membutuhkan 2 coin/kertas 500, 2 coin/kertas 100 , 1 coin/kertas 20 , 1


coin/kertas 10 dan 1 2 coin/kertas
Sehingga jumlahnya adalah : 2+2+1+1+1 = 7
Untuk menyelesaikan masalah tersebut dengan menggunakan algoritma greedy,
maka kita akan menemukan denominasi terbesar yang dapat digunakan. selanjutnya
kita akan mengurangi denominasi terbesar dari jumlah dan lagi melakukan proses yang
sama sampai jumlahnya menjadi nol. Seperti yang ditunjukkan oleh algoritma berikut
ini

2. Algoritma
1. Inisialisasi hasil sebagai kosong.
2. Temukan denominasi terbesar yang lebih kecil dari V.
3. Tambahkan denominasi yang ditemukan ke hasil. Kurangi nilai denominasi
yang ditemukan dari V.
4. Jika V menjadi 0, maka hasil cetak.
5. Ulangi langkah 2 dan 3 untuk nilai V yang baru
Atau
1. Input: jumlah,
2. Inisialisasi koin = 0

15 | P r a k t i k u m R a n c a n g a n d a n A n a l i s a A l g o r i t m a
3. Temukan denominasi terbesar yang dapat digunakan, yaitu lebih kecil dari
jumlah.
4. Tambahkan denominasi dua koin dan kurangi dari Jumlah
5. Ulangi langkah 2 hingga jumlahnya menjadi 0.
6. Cetak setiap nilai dalam koin.
3. Listing Program
Listing berikut dengan bahasa pemrograman C++
Catatan ;
Listing boleh dirubah ke bahasa pemrograman lainnya
#include <iostream>
using namespace std;

int deno[] = { 1, 2, 5, 10, 20};


int n = sizeof(deno) / sizeof(deno[0]);

void findMin(int V)
{
{
for (int i= 0; i < n-1; i++) {
for (int j= 0; j < n-i-1; j++){
if (deno[j] > deno[j+1])
swap(&deno[j], &deno[j+1]);
}
int ans[V];
for (int i = 0; i <n; i++) {
while (V >= deno[i]) {
V -= deno[i];
ans[i]=deno[i];
}
}

for (int i = 0; i < ans.size(); i++)


cout << ans[i] << “ “;
}

// Main Program
int main()
{
int a;
cout<<”Enter you amount “;
cin>>a;
cout << “Following is minimal number of change for “ << a<< “ is “;
findMin(a);
return 0;
}

Output:

16 | P r a k t i k u m R a n c a n g a n d a n A n a l i s a A l g o r i t m a
Enter you amount: 70
Following is minimal number of change for 70: 20 20 20 10

D. TUGAS :
Buatlah Algoritma dan Program untuk kasus berikut ini :
anda diberi wadah penuh air. Wadah dapat memiliki jumlah air yang terbatas. Anda
juga memiliki botol N untuk diisi. Anda perlu menemukan jumlah botol maksimum
yang dapat anda isi.
Input:
1. Baris pertama berisi satu bilangan bulat, T, jumlah kasus uji.
2. Baris pertama dari setiap test case berisi dua bilangan bulat, N dan X, jumlah botol
dan kapasitas wadah.
3. Baris kedua dari setiap test case berisi bilangan bulat yang dipisahkan ruang N,
kapasitas botol.
Keluaran:
Untuk setiap test case cetak jumlah botol maksimum yang dapat Anda isi.
Constraints:
1 ≤ T ≤ 100
1 ≤ N ≤ 104
1 ≤ X ≤ 109
1 ≤ kapasitas botol ≤ 106

17 | P r a k t i k u m R a n c a n g a n d a n A n a l i s a A l g o r i t m a

Anda mungkin juga menyukai

  • Permohonan Mengulang Div 1 Tahun
    Permohonan Mengulang Div 1 Tahun
    Dokumen1 halaman
    Permohonan Mengulang Div 1 Tahun
    Yunis Khalis
    Belum ada peringkat
  • Laporan 5
    Laporan 5
    Dokumen54 halaman
    Laporan 5
    Yunis Khalis
    Belum ada peringkat
  • Laporan 5
    Laporan 5
    Dokumen25 halaman
    Laporan 5
    Yunis Khalis
    Belum ada peringkat
  • Fani
    Fani
    Dokumen55 halaman
    Fani
    Yunis Khalis
    Belum ada peringkat
  • Fani Andika Sukma RIPNG
    Fani Andika Sukma RIPNG
    Dokumen10 halaman
    Fani Andika Sukma RIPNG
    Yunis Khalis
    Belum ada peringkat
  • Lap
    Lap
    Dokumen13 halaman
    Lap
    Yunis Khalis
    Belum ada peringkat
  • CV
    CV
    Dokumen5 halaman
    CV
    Yunis Khalis
    Belum ada peringkat