Selasa, 17 Januari 2023

Implementasi Algoritma Branch & Bound

Metode Branch and Bound

Metode Branch and Bound adalah sebuah teknik algoritma yang secara khusus mempelajari bagaimana caranya memperkecil Search Tree menjadi sekecil mungkin.

Sesuai dengan namanya, metode ini terdiri dari 2 langkah yaitu :

  1. Branch yang artinya membangun semua cabang tree yang mungkin menuju solusi. 
  2. Bound yang artinya menghitung node mana yang merupakan active node (E-node) dan node mana yang merupakan dead node (D-node) dengan menggunakan syarat batas constraint (kendala).

Teknik Branch and Bound

Ada beberapa teknik dalam Branch and Bound yaitu: 

  1. FIFO Branch and Bound
    Adalah teknik Branch and Bound yang menggunakan bantuan queue untuk perhitungan Branch  and Bound secara First In First Out.

  2. LIFO Branch and Bound
    Adalah teknik Branch and Bound yang menggunakan bantuan stack untuk perhitungan Branch and Bound secara Last In First Out.

  3. Least Cost Branch and Bound
    Teknik ini akan menghitung cost setiap node. Node yang memiliki cost paling kecil dikatakan memiliki kemungkinan paling besar menuju solusi. 

Masalah yang dapat dipecahkan with Branch and Bound

Branch and Bound dapat digunakan untuk memecahkan berbagai masalah yang menggunakan Search Tree :
–Traveling Salesman Problem
–N-Queen Problem
–15 Puzzle Problem
–0/1 Knapsack Problem
–Shortest Path

Knapsack Problem

Knapsack problem adalah suatu masalah bagaimana cara menentukan pemilihan barang dari sekumpulan barang dimana setiap barang tersebut mempunyai berat dan profit masing masing, sehingga dari pemilihan barang tersebut didapatkan profit yang maksimum. Penyelesaian masalah dengan menggunakan algoritma exhaustive search adalah mengenumerasikan semua kemungkinan barang-barang yang layak atau memenuhi syarat yaitu tidak melebihi batas daya angkut gerobak untuk dijual setiap harinya , kemudian menghitung tiap-tiap keuntungan yang diperoleh dan memilih solusi yang menghasilkan keuntungan terbesar. 

Berbeda dengan algoritma exhaustive search yang cukup memakan waktu dan dapat menghasilkan solusi yang optimum, penyelesaian masalah dengan menggunakan algoritma greedy dilakukan dengan memasukan objek satu persatu kedalam gerobak dan tiap kali objek tersebut telah dimasukan kedalam gerobak maka objek tersebut tidak dapat lagi dikeluarkan dari gerobak. Pencarian solusi akan dilakukan dengan memilih salah satu jenis greedy (greedy by weight, greedy by profiit or greedy by density) yang diperkirakan dapat menghasilkan solusi yang optimum. Algoritma Branch and Bound juga merupakan salah satu strategi yang dapat digunakan dalam pencarian solusi optimum dari permasalahan knapsack ini.

Algoritma Branch and Bound

Sebagaimana pada algortima runut-balik, algoritma Branch & Bound juga merupakan metode pencarian di dalam ruang solusi secara sistematis. Ruang Solusi diorganisasikan ke dalam pohon ruang status. Pembentukan pohon ruang status. Pembentukan pohon ruang status pada algoritma B&B berbeda dengan pembentukan pohon pada algoritma runutbalik. Bila pada algoritma runut-balik ruang solusi dibangun secara Depth-First Search(DFS), maka pada algoritma B&B ruang solusi dibangun dengan skema Breadth-First Search (BFS).

Pada algoritma B&B, pencarian ke simpul solusi dapat dipercepat dengan memilih simpul hidup berdasarkan nilai ongkos (cost). Setiap simpul hidup diasosiasikan dengan sebuah ongkos yang menyatakan nilai batas (bound). Pada prakteknya, nilai batas untuk setiap simpul umumnya berupa taksiran atau perkiraan. Fungsi heuristik untuk menghitung taksiran nilai tersebut dinyatakan secara umum sebagai :

(i) = (i) + (i)

yang dalam hal ini,

(i) = ongkos untuk simpul i
(i) = ongkos mencapai simpul i dari akar
(i) = ongkos mencapai simpul tujuan dari simpul akar i (perkiraan)

Nilai digunakan untuk mengurutkan pencarian. Simpul berikutnya yang dipilih untuk diekspansi adalah simpul yang memiliki  minimum (Simpul-E). Strategi memilih simpul-E seperti ini dinamakan strategi pencarian berdasarkan biaya terkecil (least cost search).

Prinsip dari algoritma branch and bound ini adalah :

1. Masukkan simpul akar ke dalam antrian Q. Jika simpul akar adalah simpul solusi (goal node), maka solusi telah ditemukan. Stop.

2. Jika kosong, tidak ada solusi . Stop.

3. Jika tidak kosong, pilih dari antrian simpul yang mempunyai (i) paling kecil. Jika terdapatbeberapa simpul yang memenuhi, pilih satusecara sembarang.

4. Jika simpul adalah simpul solusi, berarti solusi sudah ditemukan, stop. Jika simpul bukan simpul solusi, maka bangkitkan semua anak-anaknya. Jika tidak mempunyai anak, kembali ke langkah 2.

5. Untuk setiap anak dari simpul i, hitung  (j), dan masukkan semua anak-anak tersebut ke dalam antrian Q.

6. Kembali ke langkah 2.

Knapsack Problem Solve

Untuk lebih memahami tahap-tahap penyelesaian permasalahan knapsack ini, kita ambil contoh persoalan seperti yang dituliskan pada bagian Abstrak yaitu dimana seorang pedagang keperluan rumah tangga keliling harus memilih barang-barang yang akan dijual setiap harinya dengan batas daya angkut gerobak yang dimilikinya. Untuk mempermudah, kita misalkan pedagang keliling tersebut hanya memiliki 4 jenis barang untuk dijual dengan berat dan keuntungan penjualan yang berbeda-beda untuk tiap jenisnya. 

Gerobak yang akan dipakai untuk mengangkut barang-barang tersebut hanya mampu menampuk beban seberat 16 kg. Berikut merupakan tebel penggambaran beratdan keeuntungan yang akan diperoleh untuk tiap penjualan barang tersebut.

Knapsack problem

dari tiap tiap simpul anak untuk dapat menentukan simpul mana yang kelak akan dibangkitkan yaitu simpul dengan cost tertinggi dalam penelusuran pohon unutk mencapai solusi dari permasalahan ini. Dalam permasalahan ini, kita akan mencari simpul-simpul yang akan membawa kita pada keuntungan terbesar oleh karena itu urutan pembangkitan simpul akan ditentukan oleh simpul mana yang memiliki cost tertinggi. Cost dari tiap simpul akan ditentukan dengan:

(i) = (i) + (i)

yang dalam hal ini,

(i) = cost untuk simpul i
(i) = cost untuk sampai ke simpul I, dalam hal ini merupakan keuntungan dari simpul akar ke simpul i
(i) = cost dari simpul i untuk sampai ke simpul tujuan, dalam hal ini dapat diperoleh dengan menggunakan

rumus : (P/W)max * daya angkut yang tersisa

pada tahap awal kita akan melakukan perhitungan dengan menggunakan rumus diatas untuk memperoleh batas awal atau akar dari pohon yang juga merupakan simpul pertama. Pada keadaan ini, batas dihitung dengan pemikiran bahwa belum ada satupun barang yang dimasukan kedalam alat pengangkut maka kita dapat memilih 6 sebagai (P/W) terbesar karena belum ada satu barangpun yang dimasukan kedalam alat pengangkut dan kapasitas daya angkutpun masih utuh yaitu seberat 16 kg.

(i) = (i) + (i)

(1) = keuntungan yang diperoleh sampai disimpul

awal + (P/W)max * daya angkut yang tersisa

= 0 + 6 *

= 96

Maka kita memperoleh 96 batas awal atau cost dari simpul awal.

Bangkitkan simpul-simpul anak dari akar pohon yaitu dengan membangkitkan simpul 1, simpul 2, simpul 3 dan simpul 4 sebagai gambaran dari 4 pilihan barang yang akan dimasukan pertama kali pada alat pengangkut dengan x1 merupakan keuntungan yang akan diperoleh pada penjualan tiap barang tersebut. Kemudian kita akan menghitung cost dari tiap simpul anak yang hidup dan juga kelayakannya untuk tetap hidup atau harus dibunuh. Dalam hal ini, simpul yang jumlah dari lintasannya tidak bisa lagi dibangkitkan (jika ditambah barang lagi kedalam alat pengangkut maka beratnya akan melebihi daya angkut) akan dibunuh.

(2) = 12 + 5*(16-2) = 82

(3) = 15 + 6*(16-5) = 81

(3) = 50 + 6*(16-10)=86

(4) = 10 + 6*(16-5)=76

Dari simpul-simpul yang telah dibangkitkan dan dihitung cost nya, maka diperoleh bahwa simpul lah yang memiliki cost tertinggi oleh karena itu maka simpul 4 akan di perluas lagi. Simpul 6 ,7,8 akan dibangkitkan sebagai perluasan dari simpul 4 dengan barang yang mungkin dimasukan kedalam alat pengangkut adalah barang ke 1,2 dan 4. kemudian kita akan mengkitung cost dari simpul 6,7dan 8.

(6) = (50+12) + 3*(16-10-2) = 74

(7) = (50+15) + 6*(16-10-5) = 71

(8) = (50+10) + 6*(16-10-5) = 66

Sejarah, Definisi dan Cara Kerja Algoritma Divide and Conquer

Algoritma Divide and Conquer

Sejarah divide and conquer Divide and Conquer dulunya adalah strategi militer yang dikenal dengan nama divide ut imperes. Sekarang strategi tersebut menjadi strategi fundamental di dalam ilmu komputer dengan nama Divide and Conquer. pengertian
  • Divide: membagi masalah menjadi beberapa upa-masalah yang memiliki kemiripan dengan masalah semula namun berukuran lebih kecil (idealnya berukuran hampir sama),
  • Conquer: memecahkan (menyelesaikan) masing-masing upa-masalah (secara rekursif), dan
  • Combine: mengabungkan solusi masing-masing upa-masalah sehingga membentuk solusi masalah semula.
Obyek permasalahan yang dibagi : masukan (input) atau instances yang berukuran n seperti: - tabel (larik), - matriks, - eksponen, - dll, bergantung pada masalahnya. Tiap-tiap upa-masalah mempunyai karakteristik yang sama (the same type) dengan karakteristik masalah asal, sehingga metode Divide and Conquer lebih natural diungkapkan dalam skema rekursif. Perkembangan Algoritma Divide and Conquer Algoritma divide and conquer sudah lama diperkenalkan sebagai sumber dari pengendalian proses paralel, karena masalah-masalah yang terjadi dapat diatasi secara independen. Banyak arsitektur dan bahasa pemrograman paralel mendesain implementasinya (aplikasi) dengan struktur dasar dari algoritma divide and conquer. Untuk menyelesaikan masalah-masalah yang besar, dan dibagi (dipecah) menjadi bagian yang lebih kecil dan menggunakan sebuah solusi untuk menyelesaikan problem awal adalah prinsip dasar dari pemrograman/strategi divide and conquer.


Divide and conquer adalah varian dari beberapa strategi pemrograman topdown, tetapi keistimewaannya adalah membuat sub-sub problem dari problem yang besar, oleh karena itu strategi ini ditunjukkan secara berulang-ulang (recursively), didalam menerapkan algoritma yang sama dalam sub-sub problem seperti yangditerapkan pada masalah aslinya (original problem). Sebagaimana prinsip dasar algoritma perulangan dibutuhkan sebuah kondisi untuk mengakhiri perulangan tersebut. Biasanya untuk mengecek apakah problem sudah cukup kecil untuk diselesaikan dengan metode secara langsung. Mungkin dari segi ilustrasi kita, bahwa proses-proses pada komputer paralel tentunya memiliki proses/problem/job yang cukup kompleks sehingga harus dipecah-pecah menjadi sub-sub problem. Selain dibutuhkan sebuah “kondisi”, juga diperlukan “fase divide” untuk membagi/memecah problem menjadi sub-sub problem yang lebih kecil, dan “fase combine“ untuk menggabungkan kembali solusi dari sub-sub problem kedalam solusi dari problem awalnya.

Berikut pseudocode dari strategi divide and conquer




Pseudocode diatas adalah sebagai acuan dari strategi divide and conquer, tetapi dalam implementasinya ada beberapa diferensiasi dari bentuk diatas yang akan digunakan. Sebelum masuk ke pokok pemrograman dengan “Divide and Conquer strategy/algorithm”, ada 4 hal penting yang harus dipahami dalam strategi ini yaitu branching factorbalancedata dependence of divide function dan sequentiality.

Branching Factor

Branching factor dalam algoritma divide and conquer adalah jumlah dari subproblem yang akan dibagi dari sebuah problem awal. Ini adalah langkah nyata dari algoritma divide and conquer, didalam proses pembagian yang sebenarnya, jumlah dari branching factor harus 2 atau lebih, karena jika tidak problem tidak bisa dibagi. Banyak jenis algoritma ini termasuk pula algoritma komputasi geometric yang memiliki branching factor berjumlah 2.

Balance

Sebuah algoritma divide and conquer dikatakan balance jika problem awal dibagi menjadi sub-sub problem dengan ukuran yang sama. Yang artinya jumlah dari keseluruhan ukuran subproblem sama dengan ukuran problem awal (initial problem). Algoritma Mergesort dan binary tree, dan sama halnya dengan algoritma reduksi & prefix sum adalah beberapa contoh algoritma divide and conquer yang seimbang (balance).

Data Dependence of Divide Function

Algoritma divide and conquer memiliki sebuah fungsi pembagian terhadap data yang memiliki ketergantungan, artinya jika ukuran relatif dari sebuahsubproblem tergantung pada proses input datanya. Ini adalah salah satu ciri dari algoritma yang tidak seimbang, salah satu contohnya adalah algoritma quicksort yang akan membagi subproblem dengan fungsi data-dependent divide.

Control Parallelism or Sequentiality

Algoritma divide and conquer dikatakan berurutan (sequential) jika subproblem dieksekusi sesuai dengan perintah program. Paralelisasi dari algoritma divide and conquer yang terurut pertama kali didefinisikan oleh Mou’s Divacon[Mou90], yang terjadi ketika hasil dari salah satu sub-eksekusi diperlukan oleh subeksekusi yang lain. Dalam kasus ini hasil dari subtree pertama diberikan (passing) kepada proses komputasi subtree kedua, supaya hasil akhir tersebut bisa digunakan sebagai nilai awalnya, tetapi sekarang ini contoh diatas tidak dapat dijadikan ilustrasi lagi karena teknologi komputer paralel yang semakin canggih dan kompleks.

Klasifikasi dari Algoritma/Strategi Divide and Conquer

Berikut klasifikasi algoritma divide and conquer, kita bisa melihat daftar dan karakteristik dari beberapa algoritma yang ditunjukkan dalam tabel :

Tabel karakteristik dari Algoritma divide and conquer. Catatan bahwa quicksort

dan quickhull bisa dikonversi kedalam algoritma yang balance dengan cara

menemukan median (titik tengah) yang tepat.

Penerapan Data-Parallel Divide and Conquer Algorithms

Sorting

Quick Sort, Binary Sort

Computational Geometry

Closest Pairs, Convex Hull, Delaunay Triangulation

Graph Theory

Travelling Salesman Problem (TSP), Graph Separators

Numerical

Matrix Multiplication, FFT

Not Data Parallel

Naïve Merge Sort

Rekursi Divide and Conquer

Machiavelli menggunakan sintaks : Split (result1 = func (arg1), result2 = func (arg2) [, resultn = func (argn)]Untuk membentuk fungsi call dalam algoritma divide and conquervarn adalah hasil akhir yang kembali ke fungsi func dalam argument argn. Machiavelli membuat versi fungsi yang salah satunya mengaplikasikan reduksi menjadi sebuah “pengulangan sederhana” . Script berikut adalah contoh pemakaian fungsi fetch :

Penerapan fetch untuk integer

Script diatas dapat digunakan untuk meng-compile algoritma parallel dari versi serial. Script berikut menunjukkan contoh lain dimana lebih efisien dalam penerapannya yaitu Quicksort :



Contoh Penerapan Pada Binary Search

Temukan sebuah elemen atau bilangan pada array yang telah tersortir :

1. Divide : cek elemen tengah

2. Conquer : secara rekursif, cari disebuah subarray

3. Combine : trivial

Kasus :

Temukan bilangan 9 pada deret 3, 5, 7, 8, 9, 12, 15

Contoh Penerapan Bucket Sort Secara Paralel

Asumsikan sebuah p processor menangani setiap bucket (p bucket)


Penjelasan

Bagilah secara sekuen kedalam m bagian, bagian-bagian yang terbentuk akan ditangani oleh p processor, Masing-masing processor akan menangani p bucket dan memisahkan bilangan bilangan pada array ke dalam masing-masing bucket. Bucket-bucket akan dikosongkan kedalam p bucket akhir dari pengurutan yang membutuhkan masing-masing processor untuk mengirim sebuah bucket untuk setiap processor lainnya (bucket to processor )

Contoh Lain Penerapan Bucket Sort Secara Paralel

Pada contoh ini dikenalkan sebuah operasi message-passing yang baru all-to-all broadcast.


Penjelasan

Bagilah secara sekuen kedalam m bagian, bagian-bagian yang terbentuk akan ditangani oleh p processor, Masing-masing processor akan menangani p small bucket dan memisahkan bilangan-bilangan pada array ke dalam masing-masing small bucket. Masing-masing small bucket dari masing-masing processor akan dikosongkan, kemudian hasil perhitungan di small bucket akan ditampung ke masing-masing large buket. Di large bucket data diolah kembali untuk kemudian dihasilkan array yang telah tersortir dari masing-masing large bucket.

“all-to-all” broadcast routine

Mengkomunikasikan data dari masing-masing proses ke proses lainnya


all-to-all” routine pada dasarnya mentransfer baris-baris dari sebuah array ke kolomkolom yang dinamakan Transpose Matrix.

Kesimpulan :

Algoritma divide and conquer sudah lama diperkenalkan sebagai sumber dari pengendalian proses parallel, karena masalah-masalah yang terjadi dapat diatasi secara independent. Banyak arsitektur dan bahasa pemrograman parallel mendesain implementasinya (aplikasi) dengan struktur dasar dari algoritma divide and conquer.

Divide and Conquer secara umum terbagi dalam tiga fase, divide yakni membagi masalah kedalam sub-sub masalah yang lebih kecil, conquer yakni menyelesaikan sub-sub masalah secara rekursif, dan combine menggabungkan hasil dari penyelesian sub-sub masalah menjadi penyelesaian yang dikehendaki Terdapat empat hal pada strategi “divide and conquer” : branching factorbalancedata dependence of divide function dan sequentiality.

Implementasi Algoritma Divide and Conquer pada Sorting dan Searching

 Algoritma merupakan kumpulan perintah yang memiliki daya guna yang sangat besar bagi masyarakat. Algoritma biasanya digunakan sebagai kumpulan perintah untuk menyelesaikan suatu masalah. Algoritma ini memiliki aplikasi yang bermacam-macam dalam setiap masalah yang ada. Contohnya saja adalah algoritma cara menyelesaikan suatu aritmatika yang rumit, algoritma untuk menghitung luas penampang dari suatu kabel, atau bahkan untuk menghitung bayaran parkir di setiap mal. Salah satu aplikasi bentuk pemrograman ini adalah dalam bahasa permrograman yang disebut bahasa C. Dimana bahasa C ini memiliki suatu aturan-aturan tertentu yang sangat penting sehingga dalam penggunaanya kita harus memperhatikan cara menggunakan aturan tersebut. Salah satu cara penggunaannya adalah dengan array. Dimana array ini merupakan suatu data struktur yang berkoneksi satu sama lain dengan tipe yang sama. Aplikasi array ini banyak sekali, contohnya saja adalah menghitung golongan dari umur yang berjumlah 25 tahun hingga 55 tahun. Array ini juga bisa digunakan untuk mencari suatu elemen nilai dalam suatu struktur data, selain itu array ini juga bisa digunakan untuk mengurutkan data-data yang tidak berurutan. Hal –hal yang telah disebutkan disebut sebagai searching array dan sorting array.

    Sorting array merupakan salah satu aplikasi yang paling penting dalam suatu sistem aplikasi perhitungan data. Biasanya suatu bank memiliki komputasi sorting array yang sudah biasa digunakan dalam aplikasinya sehari-hari. Bahkan telephone juga mengurutkan suatu list yang terdiri dari nama akhir , nama awal agar bisa memudahkan dalam perhitungan dalam mencari nomor telephone.

    Searching array juga memiliki tak kalah pentingnya dibandingkan dengan sorting array. Pada searcing array kita biasa menggunakannya pada data yang sangat banyak. Sehingga sangat sulit bila kita ingin mencari suatu data atau suatu angka didalamnya satu per satu. Aplikasi searching array memudahkan kita dalam mencari suatu data atau angka yang kita inginkan dengan hanya memasukkan nilai input pada suatu data yang disikan.

1. Insertion sort

Salah satu algoritma sorting yang paling sederhana adalah insertion sort. Ide dari algoritma ini dapat dianalogikan seperti mengurutkan kartu. Penjelasan berikut ini menerangkan bagaimana algoritma insertion sort bekerja dalam pengurutan kartu. Anggaplah anda ingin mengurutkan satu set kartu dari kartu yang bernilai paling kecil hingga yang paling besar. Seluruh kartu diletakkan pada meja, sebutlah meja ini sebagai meja pertama, disusun dari kiri ke kanan dan atas ke bawah. Kemudian kita mempunyai meja yang lain, meja kedua, dimana kartu yang diurutkan akan diletakkan. Ambil kartu pertama yang terletak pada pojok kiri atas meja pertama dan letakkan pada meja kedua. Ambil kartu kedua dari meja pertama, bandingkan dengan kartu yang berada pada meja kedua, kemudian letakkan pada urutan yang sesuai setelah perbandingan. Proses tersebut akan berlangsung hingga seluruh kartu pada meja pertama telah diletakkan berurutan pada meja kedua. Algoritma insertion sort pada dasarnya memilah data yang akan diurutkan menjadi dua bagian, yang belum diurutkan (meja pertama) dan yang sudah diurutkan (meja kedua). Elemen pertama diambil dari bagian array yang belum diurutkan dan kemudian diletakkan sesuai posisinya pada bagian lain dari array yang telah diurutkan. Langkah ini dilakukan secara berulang hingga tidak ada lagi elemen yang tersisa pada bagian array yang belum diurutkan.
Algoritmanya :

void insertionSort(Object array[], int startIdx, int endIdx)
{
for (int i = startIdx; i < endIdx; i++) {
int k = i;
if(((Comparable) array[k]).compareTo(array[j])>0) {
for (int j = i + 1; j < endIdx; j++) {
k = j;
}
}
swap(array[i],array[k]);
}
}

 2. Selection sort

Jika anda diminta untuk membuat algoritma sorting tersendiri, anda mungkin akan menemukan sebuah algoritma yang mirip dengan selection sort. Layaknya insertion
sort, algoritma ini sangat rapat dan mudah untuk diimplementasikan. Mari kita kembali menelusuri bagaimana algoritma ini berfungsi terhadap satu paket kartu. Asumsikan bahwa kartu tersebut akan diurutkan secara ascending. Pada awalnya, kartu tersebut akan disusun secara linier pada sebuah meja dari kiri ke kanan, dan dari atas ke bawah. Pilih nilai kartu yang paling rendah, kemudian tukarkan posisi kartu ini dengan kartu yang terletak pada pojok kiri atas meja. Lalu cari kartu dengan nilai paling rendah diantara sisa kartu yang tersedia. Tukarkan kartu yang baru saja terpilih dengan kartu pada posisi kedua. Ulangi langkah – langkah tersebut hingga posisi kedua sebelum posisi terakhir dibandingkan dan dapat digeser dengan kartu yang bernilai lebih rendah.

Ide utama dari algoritma selection sort adalah memilih elemen dengan nilai paling rendah dan menukar elemen yang terpilih dengan elemen ke-i. Nilai dari dimulai dari 1 ke n, dimana adalah jumlah total elemen dikurangi 1.
Algoritmanya :

void selectionSort(Object array[], int startIdx, int endIdx)
{
int min;
for (int i = startIdx; i < endIdx; i++) {
if (((Comparable)array[min]).compareTo(array[j])>0) {
min = i;
for (int j = i + 1; j < endIdx; j++) {
min = j;
}
}
}
swap(array[min], array[i]);
}

3. Merge sort

Beberapa algoritma mengimplementasikan konsep rekursi untuk menyelesaikan permasalahan. Permasalahan utama kemudian dipecah menjadi sub-masalah, kemudian solusi dari sub-masalah akan membimbing menuju solusi permasalahan utama.

Pada setiap tingkatan rekursi, pola tersebut terdiri atas 3 langkah.

1. Divide

    Memilah masalah menjadi sub masalah

2. Conquer

    Selesaikan sub masalah tersebut secara rekursif. Jika sub-masalah tersebut cukup ringkas dan sederhana, pendekatan penyelesaian secara langsung akan lebih efektif

3. Kombinasi

    Mengkombinasikan solusi dari sub-masalah, yang akan membimbing menuju penyelesaian atas permasalahan utama

Seperti yang telah dijelaskan sebelumnya, Merge sort menggunakan pola divide and conquer. Dengan hal ini deskripsi dari algoritma dirumuskan dalam 3 langkahberpola divide-and-conquer. Berikut menjelaskan langkah kerja dari Merge sort.

1. Divide

    Memilah elemen – elemen dari rangkaian data menjadi dua bagian.

2. Conquer

    Conquer setiap bagian dengan memanggil prosedur merge sort secara rekursif

3. Kombinasi

    Mengkombinasikan dua bagian tersebut secara rekursif untuk mendapatkan rangkaian data berurutan

Proses rekursi berhenti jika mencapai elemen dasar. Hal ini terjadi bilamana bagian yang akan diurutkan menyisakan tepat satu elemen. Sisa pengurutan satu elemen tersebut menandakan bahwa bagian tersebut telah terurut sesuai rangkaian.
Algoritmanya :

void mergeSort(Object array[], int startIdx, int endIdx)
{

if (array.length != 1) {
mergeSort(leftArr, startIdx, midIdx);
//Membagi rangkaian data, rightArr dan leftArr

}
mergeSort(rightArr, midIdx+1, endIdx);

combine(leftArr, rightArr); }

                                         Gambar3.1. Diagram Merge Sort

4. Quick sort

Quicksort ditemukan oleh C.A.R Hoare. Seperti pada merge sort, algoritma ini juga berdasar pada pola divide-and-conquer. Berbeda dengan merge sort, algoritma ini hanya mengikuti langkah – langkah sebagai berikut :

1. Divide

    Memilah rangkaian data menjadi dua sub-rangkaian A[p…q-1] dan A[q+1…r] dimana setiap elemen A[p…q-1] adalah kurang dari atau sama dengan A[q] dan setiap elemen pada A[q+1…r] adalah lebih besar atau sama dengan elemen pada A[q]. A[q] disebut sebagai elemen pivot. Perhitungan pada elemen q merupakan salah satu bagian dari prosedur pemisahan.

2. Conquer

    Mengurutkan elemen pada sub-rangkaian secara rekursif

Pada algoritma quicksort, langkah “kombinasi” tidak di lakukan karena telah terjadi pengurutan elemen – elemen pada sub-array
Algoritmanya :

void quickSort(Object array[], int leftIdx, int rightIdx) {

int pivotIdx;

/* Kondisi Terminasi */
pivotIdx = partition(array, leftIdx, rightIdx);
if (rightIdx > leftIdx) {

quickSort(array, leftIdx, pivotIdx-1);
}

quickSort(array, pivotIdx+1, rightIdx); }

                    Gambar 3.2. Diagram Quick Sort

5. Counting sort

Adalah sebuah algoritma sorting linear yang digunakan untuk mengurutkan ‘item’ ketika urutannya telah ditentukan dan memiliki panjang yang terbatas. Bilangan interval yang telah tetap, katakana k1 ke k2 adalah contoh dari ‘item’ tersebut. Counting sort sebenarnya merupakan metode pengurutan yang memanfaatkan index variabel array. Hanya effektif pada data yang nilainya kecil.

Algoritma ini diproses dengan mendefinisikan sebuah hubungan urutan antara ‘item’ yang akan disorting. Katakana ‘item’ yang akan disorting adalah variable A. Maka, terdapat sebuah array tambahan dengan ukuran yang serupa dengan array A. katakana array tersebut adalah array B. untuk setiap element di A, sebut e, algoritma ini menyimpan jumlah ‘item’ di A lebih kecil dari atau sama dengan e di B(e). jika hasil sorting yang terakhir disimpan di array C, maka untuk masing-masing e di A, dibuat dalam arah yang sebaliknya, yaitu C[B(e)]=e. setelah step di atas, niali dari B(e) berkurang dengan 1.

Algoritma ini membuat 2 passover A dan passover B. Jika ukuran dari range k lebih kecil dari ukuran input n, maka time complexity = O(n). perhatikan juga bahwa algoritma ini stabil yang berarti bahwa sambungan diselesaikan dengan langsung mengabarkan element-element yang muncul pertama kali.

Adapun syarat algoritma ini berjalan dengan baik ialah:

  1. Data harus bilangan bulat yang bernilai lebih besar atau sama dengan nol
  2. Range data diketahui

Ada 3 macam array yang terlibat:

  1. Array untuk mengisi bilangan yang belum diurutkan.
  2. Array untuk mengisi frekuensi bilangan itu, sekaligus sebagai penghitung kejadian.
  3. Array untuk mengisi bilangan yang sudah diurutkan.
    Algoritmanya :
countingsort(A[], B[], min, max, n)
for i = min to max do
C[i] = 0

C[A[j]] = C[A[j]] + 1
for j = 1 to n do for i = min + 1 to max do
B[C[A[j]]] = A[j]
C[i] = C[i] + C[i-1] for j = n downto 1 do
C[A[j]] = C[A[j]] – 1

                                                        Gambar 3.3 Diagram Counting Sort

6. Radix Sort

Radix sorting bisa digunakan ketika masing-masing universal element bisa dilihat sebagai sebuah urutan digit (atau huruf atau symbol lainnya). Sebagai contoh, kita bisa membuat masing-masing bilangan bulat antar 0 sampai 99 sebagai sebuah urutan dengan dua digit (seperti “05”). Untuk menyorting sebuah array dari angka 2-digit, algoritma ini membuat dua ‘passing’ sorting melalui array tersebut. Pada ‘passing’ pertama, element array disorting pada least significant decimal digit. Kunci utama dari radix sort adalah pada passing yang kedua. Hasilnya, setelah kedua passing melewati array tersebut, data yang terisi telah disorting.
Algoritmanya :

source

List of bytes
source_n
number of bytes to sort
dest[256]
256 lists of bytes. each list should have enough space to hold source_n elements.
//——————-saving element in memory——————– int distribution[256] // fill the list with zeros.
for i=0 to source_n do
for i=0 to 255 do distribution[i]=0; // build a distribution history: distribution] = distribution] +1;
for i=0 to 255 do
endfor // Now we build a index-list for each possible element: int index[256]; index [0]=0;
for i = 0 to source_n do
index[i]=index[i-1]+distribution[i-1]; endfor //sorting dest: array of bytes with space for source_n bytes.
endfor
dest[index]]=source[i];
index] = index] +1;

7. Searching

7.1 Linear Searching

Algoritma pencarian secara linear adalah algoritma untuk mencari sebuah nilai pada table sambarang dengan cara melakukan pass atau transversal. Transversal dari awal sampai akhir table. Ada dua macam cara pencarian pada table. Algoritma mempunyai dua jenis metode yaitu dengan Boolean dan tanpa Boolean.
Algoritmanya :

void SeqSearch1 (int T[], int Nmax,

int value, int *idx) {
/*Algoritma*/
/*kamus lokal*/ int i; i = 1;
i = i + 1;
while ((i<Nmax) && (T[i] != value)) { } if (T[i]==value)
}
{ *idx = i; } else { *idx = 0;
}

Algoritma di atas melakukan pengulangan sampai i sama dengan Nmax (ukuran tabel) atau harga value dalam tabel sudah ditemukan.    Kemudian harga i di-assign ke dalam variable idx. Elemen terakhir diperiksa secara khusus.

void SeqSearch2 (int T[],int Nmax,

int value, int *idx)

{ int i;
i = 1;
boolean found;

/*algoritma*/ found = false;
if (T[i] == value)
while ((i<=Nmax) && (!found))

{ { found = true; } else { i = i + 1;
}
}

} if (found) { *idx = i; } else { *idx = 0;

7.2 Binary Searching

Algoritma pencairan secara linear melakukan pengulangan sebanyak 1 kali untuk kasus terbaik (value sama dengan elemen pertama dalam tabel) dan Nmax kali untuk kasus terburuk. Sehingga algoritma ini mempunyai kompleksitas algoritma O(n).

Implementasi algoritma pencarian biner dalam bahasa C adalah sebagai berikut.

void BinSearch (int T[],int Nmax, int

value, int* idx)

int i,j,mid;
found = false;
boolean found;$

/*algoritma*/ i = 1;
mid = (i+j) div 2;
j = Nmax;

while ((!found) && (i<=j)) {

if (T[mid] == value)

{ found = true; } else {

if (T[mid]<value)

{ i = mid + 1; } else { j = mid – 1; } } }
}
if (found) { *idx = mid; } else { *idx = 0;
}

Algoritma pencarian biner adalah algoritma untuk mencari sebuah nilai pada tabel teurut dengan cara menghilangkan setengah data pada setiap langkah. Algoritma ini mencari nilai yang dicari dengan tiga langkah yaitu :

• Mencari nilai tengah dari tabel (median).
• Melakukan perbandingan nilai tengah dengan nilai yang dicari untuk menentukan apakah nilai yang dicari ada pada sebelum atau setelah nilai tengah.
• Mencari setengah sisanya dengan cara yang sama.

Implementasi Algoritma Branch & Bound

Metode Branch and Bound Metode Branch and Bound  adalah sebuah teknik algoritma yang secara khusus mempelajari bagaimana caranya memperkecil...