Optimisasi Algoritma: Mencari Bilangan Prima

Tulisan ini membahas bagaimana optimisasi algoritma sederhana dilakukan. Bahasan ini cocok bagi mereka yang baru belajar pemrograman dan ingin berkenalan dengan optimisasi algoritma. Setelah memahami ulasan ini, mereka diharapkan berkembang dari tahap “sudah bisa memrogram” menuju mulai “memikirkan efisiensi program”.

Pendahuluan

Bilangan prima merupakan “seni” dalam teori bilangan karena karakteristiknya yang mendasar tetapi tidak berpolai. Oleh karena tidak adanya pola tersebut, algoritma mencari bilangan prima menjadi menarik dimana kita tidak dapat memanfaatkan fungsi matematis atau prosedur sederhana. Di sinilah logika, analisa, dan strategi berpikir menjadi penting untuk mendapatkan efisiensi semaksimal mungkin.

Pengantar Permasalahan Bilangan Prima

Dalam Teori Bilangan, bilangan prima didefinisikan sebagai berikut:

Bilangan prima adalah bilangan bulat non-negatif yang hanya memiliki dua faktor, yaitu 1 dan bilangan itu sendiriii.

Persoalan bilangan prima yang paling mendasar adalah mencarinya. Dari himpunan bilangan bulat yang tak berhingga terdapat subhimpunan bilangan prima yang tak berhingga pulaiii.

Persoalan mencari bilangan prima dapat disederhanakan menjadi “apakah sebuah bilangan adalah prima?”. Dengan kata lain, kita ambil sebuah bilangan kemudian kita cek apakah bilangan tersebut prima atau tidak. Apabila kita ingin mencari bilangan prima dengan kebutuhan spesifik, misalkan mencari bilangan prima yang lebih besar dari 1000, maka kita tinggal mengulang pengecekan “apakah sebuah bilangan adalah prima” tersebut untuk setiap bilangan di atas 1000. Ini merupakan satu-satunya cara karena bilangan prima tidak berpola dan tidak ada fungsi matematis untuk mendaftar bilangan prima kecuali mentes setiap bilanganiv atau mendekatinya dengan aproksimasi yang pastinya tidak dijamin akurat 100%v.

Perbaikan Algoritma Mencari Bilangan Prima

Algoritma 1

Dari definisi bahwa bilangan yang hanya mempunyai dua faktor adalah bilangan prima, ide paling dasar untuk mengeceknya adalah sebagai berikut:

Bagi bilangan tersebut dengan setiap bilangan antara 1 dan bilangan itu. Setelah selesai, jika bilangan yang habis membaginya ada 2 maka bilangan itu prima.

Untuk mencatat jumlah bilangan yang habis membagi (faktor) kita gunakan sebuah variabel pencatat yang pada awalnya bernilai nol. Variabel ini akan ditambah satu setiap bilangan habis dibagi pencacah.

Ini merupakan ide yang paling banyak terpikirkan oleh semua orang. Namun, sebagaimana sangat dasar dan sederhananya ide ini, sangat buruk pula kompleksitas algoritmanya.

Pseudo-code Algoritma 1 adalah sebagai berikut:

isPrime1

isPrime1

Algoritma 2

Algoritma 2 merupakan penambahan ide dasar Algoritma 1 dengan sedikit konsep efisiensi. Pada Algoritma 1 kita terpancing untuk mencari faktor = 2 karena inti dari definisi bilangan prima mengatakan seperti itu. Kali ini kita akan lebih berorientasi hasil. Ide Algoritma 2 adalah sebagai berikut:

Karena semua bilangan bulat selian nol pasti habis dibagi satu dan bilangan itu sendiri, maka kita hilangkan pencacah sia-sia tersebut. Kita akan membagi bil dengan a dimana 1 ≤ abil-1. Bila tidak ada bilangan yang habis membagi bil maka bil adalah bilangan prima.

Pseudo-code Algoritma 2i adalah sebagai berikut:

isPrime2

isPrime2

Perbaikan efisiensi ini sangat kecil, hampir tak berarti bila dibandingkan dengan kinerja komputer saat ini.

Algoritma 3

Algoritma 3 merupakan perbaikan Algoritma 2 dengan analisis lebih dalam. Idenya adalah sebagai berikut:

Bila x = bil/2 maka membagi bil dengan x sampai bil-1 hanya menghasilkan nilai floating point kurang dari satu. Maka kita bisa melakukan efisiensi pada batas atas pencacahan.

Pseudo-code Algoritma 3 adalah sebagai berikut:

isPrime3

isPrime3

Dengan demikian, kompleksitas algoritma berkurang mendekati setengahnya, yaitu Θ(n)=½n. Perbaikan efisiensi ini cukup signifikan.

Algoritma 4

Algoritma 4 akan menggantikan Algoritma 3 dengan analisis masih pada batas atas pencacahan. Di sini kita berangkat dari Teori Faktorisasi Bilangan Bulati. Implikasi teori tersebut yaitu:

Untuk mengecek apakah n bilangan prima atau tidak, kita tidak butuh membagi sampai lebih dari √n

Pseudo-code Algoritma 4 adalah sebagai berikut:

isPrime4

isPrime4

Dengan demikian, kompleksitas algoritma berkurang menjadi Θ(n)=√n. Perbaikan efisiensi ini sangat signifikan.

Algoritma 5

Ide Algoritma 5 merupakan perbaikan dari ide di Algoritma 2, tetapi kita tetap memakai kemajuan efisiensi yang sudah dicapai sampai Algoritma 4. Ide yang ditambahkan adalah sebagai berikut:

Jika hanya butuh mengecek apakah bil dapat dibagi atau tidak, kita tidak butuh menghitung berapa buah bilangan yang dapat membagi bil. Bila ada sebuah saja bilangan yang dapat membaginya, maka bil langsung kita nyatakan bukan prima.

Untuk itu kita akan menambahkan sebuah variabel bertipe boolean yang akan menghentikan iterasi jika ditemukan bilangan dapat membagi habis bil.

Pseudo-code Algoritma 5 adalah sebagai berikut:

isPrime5

isPrime5

Dengan demikian, kompleksitas algoritma berkurang menjadi Θ(n) √n+c1. Perbaikan efisiensi ini sangat signifikan. Modifikasi ini akan sangat mengubah alur logika jalannya algoritma.

Algoritma 6

Meskipun algoritma 5 sudah sangat efisien [dibandingkan algoritma sebelum-sebelumnya], tetapi ternyata kita masih bisa melakukan optimisasi yang akan mengakibatkan perbaikan efisesiensi yang juga sangat signifikan. Algoritma 6 adalah perbaikan dari algoritma 5 dengan penambahan ide sebagai berikut:

Karena setiap bilangan genap kecuali 2 tidak mungkin prima, maka tidak perlu mentes bilangan genap.

Perbaikan ini menjadi bisa (enable) dilakukan karena di Algoritma 5 kita sudah menggunakan struktur perulangan while, increment terhadap variabel pencacah kita lakukan secara manual1. Ini memberikan kesempatan bagi kita memodifikasi jumlah increment sehingga kita bisa mengeliminasi pencacah yang tidak berguna.

Pseudo-code Algoritma 6i adalah sebagai berikut:

isPrime6

isPrime6

Dengan demikian, kompleksitas algoritma berkurang menjadi Θ(n) ≤ ½√n+c2 dimana c2 > c1. Perbaikan efisiensi ini cukup signifikan.

Ringkasan

Algoritma Optimisasi Kompleksitas
Algoritma 1 tidak ada: ide dasar yg paling mungkin terpikirkan

Θ(n) = n

Algoritma 2 mengganti konstanta syarat

Θ(n) = n-2

Algoritma 3 analisa batas atas dengan logika matematika biasa

Θ(n) = ½n

Algoritma 4 analisa batas atas dengan teori bilangan

Θ(n) = √n

Algoritma 5 pemanfaatan konsep flagging pada pemrograman Θ(n) √n+c1
Algoritma 6 membuang iterasi tak perlu dengan modifikasi iterasi Θ(n) ≤ ½√n+c2; c2 > c1

Eksperimen

Berikut saya sediakan procedure untuk melakukan eksperimen menghitung waktu proses (runtime) suatu algoritma

hitungRuntime

hitungRuntime

Kita akan menggunakan procedure ini untuk melakukan eksperimen terhadap keenam algoritma di atas. Dibagian ringkasan sebenarnya kita sudah menganalisa perbandingan kompleksitas keenam algoritma, namun eksperimen ini bertujuan untuk membuktikannya secara empirik.

Eksperimen 1: n Buah Bilangan Prima

Agar Efisiensi keenam algoritma bisa terlihat kontras, kita masukkan masing-masing fungsi isPrime ke dalam sebuah looping. Looping ini bertujuan mencek apakah x adalah bilangan prima dimana x dari 1 sampai n, sehingga kita bisa menghitung waktu proses algoritma bila dieksekusi tepat n kali dengan input n buah barisan bilangan asli.

Untuk itu, kita perlu modifikasi sedikit proceduer hitungRuntime. Misalnya, di bawah ini adalah program yang saya jalankan untuk mentes kinerja fungsi isPrime6:

program percobaan 6

Program Percobaan 6

yang akan menghasilkan data berikut (klik untuk memperbesar):

percobaan 2

percobaan 2

percobaan 3

percobaan 3

percobaan 4

percobaan 4

percobaan 5

percobaan 5

percobaan 6

Percobaan 6

1Lihat baris 14 pada Algoritma 5

iToby Herring. Determine if an Integer is a Prime Number (Fast, Efficient algorithm).

http://www.freevbcode.com/ShowCode.asp?ID=1059.
Ide Algoritma 6 sama dengan ide algoritma Hearring, tetapi dalam implementasinya terdapat perbedaan. Hearring menggunakan bahasa Visual Basic serta pengecekan apakah prima atau bukan ditandai dengan keluar dari loop atau tidak.

iDonald Knuth. The Art of Computer Programming, Volume 2: Seminumerical Algorithms, Third Edition. Addison-Wesley, 1997. ISBN 0-201-89684-2. Section 4.5.4: Factoring into Primes, pp. 379–417

ihttp://bytes.com/topic/c/answers/215055-prime-number-algorithm-c
Seorang tamu bytes.com bernama Chris menuliskan algoritma ini dalam bahasa C. Meskipun idenya sama namun implementasinya berbeda karena Chris mengimplementasikannya ke dalam fungsi yang langsung me-return nilai bila ditemukan pembagi habis pada iterasi, dalam hal ini termasuk juga ide dalam Algoritma 5.

iWells, David G.; Prime numbers: the most mysterious figures in math; John Wiley and Sons: 2005

iihttp://en.wikipedia.org/wiki/Prime_number

iiiEuclid, Euclid’s Theorem (around 300BC)

ivhttp://en.wikipedia.org/wiki/Trial_division

vhttp://en.wikipedia.org/wiki/Prime_number_theorem

7 Comments on “Optimisasi Algoritma: Mencari Bilangan Prima

  1. Pingback: soesay.info

  2. Wah mantap.. Dulu nggak kepikiran ada algoritma prime sampai sejauh ini.. hehe
    Terima kasih, semoga ilmunya bermanfaat.

Leave a Reply

%d bloggers like this: