Kamis, 10 April 2014

REKURSIF


Rekursif

Salah satu konsep paling dasar dalam ilmu komputer dan pemrograman adalah pengunaan fungsi sebagai abstraksi untuk kode-kode yang digunakan berulang kali. Kedekatan ilmu komputer dengan matematika juga menyebabkan konsep-konsep fungsi pada matematika seringkali dijumpai. Salah satu konsep fungsi pada matematika yang ditemui pada ilmu komputer adalah fungsi rekursif: sebuah fungsi yang memanggil dirinya sendiri.
Kode berikut memperlihatkan contoh fungsi rekursif, untuk menghitung hasil kali dari dua bilangan:
def kali(a, b):
    return a if b == 1 else a + kali(a, b - 1)
Bagaimana cara kerja fungsi rekursif ini? Sederhananya, selama nilai b bukan 1, fungsi akan terus memanggil perintaha + kali(a, b - 1), yang tiap tahapnya memanggil dirinya sendiri sambil mengurangi nilai b. Mari kita coba panggil fungsi kali dan uraikan langkah pemanggilannya:
kali(2, 4)
  -> 2 + kali(2, 3)
  -> 2 + (2 + kali(2, 2))
  -> 2 + (2 + (2 + kali(2, 1)))
  -> 2 + (2 + (2 + 2))
  -> 2 + (2 + 4)
  -> 2 + 6
  -> 8
Perhatikan bahwa sebelum melakukan penambahan program melakukan pemanggilan fungsi rekursif terlebih dahulu sampai fungsi rekursif mengembalikan nilai pasti (2). Setelah menghilangkan semua pemanggilan fungsi, penambahan baru dilakukan, mulai dari nilai kembalian dari fungsi yang paling terakhir. Mari kita lihat contoh fungsi rekursif lainnya, yang digunakan untuk melakukan perhitungan faktorial:
def faktorial(n):
    return n if n == 1 else n * faktorial(n - 1)
Fungsi faktorial memiliki cara kerja yang sama dengan fungsi kali. Mari kita panggil dan lihat langkah pemanggilannya:
faktorial(5)
  -> 5 * faktorial(4)
  -> 5 * (4 * faktorial(3))
  -> 5 * (4 * (3 * faktorial(2)))
  -> 5 * (4 * (3 * (2 * faktorial(1))))
  -> 5 * (4 * (3 * (2 * 1)))
  -> 5 * (4 * (3 * 2))
  -> 5 * (4 * 6)
  -> 5 * 24
  -> 120
Dengan melihat kemiripan cara kerja serta kode dari fungsi faktorial dan kali, kita dapat melihat bagaimana fungsi rekursif memiliki dua ciri khas:
1.     Fungsi rekursif selalu memiliki kondisi yang menyatakan kapan fungsi tersebut berhenti. Kondisi ini harus dapat dibuktikan akan tercapai, karena jika tidak tercapai maka kita tidak dapat membuktikan bahwa fungsi akan berhenti, yang berarti algoritma kita tidak benar.
2.     Fungsi rekursif selalu memanggil dirinya sendiri sambil mengurangi atau memecahkan data masukan setiap panggilannya. Hal ini penting diingat, karena tujuan utama dari rekursif ialah memecahkan masalah dengan mengurangi masalah tersebut menjadi masalah-masalah kecil.
Setiap fungsi rekursif yang ada harus memenuhi kedua persyaratan di atas untuk memastikan fungsi rekursif dapat berhenti dan memberikan hasil. Kebenaran dari nilai yang dihasilkan tentu saja memerlukan pembuktian dengan cara tersendiri. Tetapi sebelum masuk ke analisa dan pembuktian fungsi rekursif, mari kita lihat kegunaan dan contoh-contoh fungsi rekursif lainnya lagi.


Rekursif adalah salah satu metode dalam dunia matematika dimana definisi sebuah fungsi mengandung fungsi itu sendiri.

Dalam dunia pemrograman, rekursi diimplementasikan dalam sebuah fungsi yang memanggil dirinya sendiri
n  Contoh fungsi rekursif misalnya adalah fungsi pangkat, faktorial, dan barisan fibonacci.
n  Dalam fungsi pangkat xy , kita tahu bahwa semua bilangan selain 0, jika dipangkatkan dengan 0 nilainya sama dengan 1. Jika x dipangkatkan dengan y, dengan y lebih dari 0, maka hasilnya sama dengan x dikalikan dengan x dipangkatkan y – 1.
Jika dituliskan dalam notasi matematika definisinya adalah sebagai berikut:





Kita lihat di atas pada definisi y > 0, bentuk pemangkatan muncul kembali di sisi kanan. Itulah yang disebut rekursif.
Definisi rekursif selalu dimulai dengan kasus penyetop, penghenti, atau kasus dasar dari suatu permasalahan, dalam hal ini terjadi ketika nilai y = 0.
Definisi rekursif yang lebih kompleks mengandung inti dari permasalahan yang akan dipecahkan, namun lebih sederhana. Dalam hal ini yang tadinya x dipangkatkan dengan y, kini bentuk pemangkatan menjadi lebih sederhana, yaitu y – 1.
Hal ini dimaksudkan untuk “menggiring” masalah kompleks ke kasus dasar atau penyetop rekursinya.
Definisi rekursif selalu dimulai dengan kasus penyetop, penghenti, atau kasus dasar dari suatu permasalahan, dalam hal ini terjadi ketika nilai y = 0.
Definisi rekursif yang lebih kompleks mengandung inti dari permasalahan yang akan dipecahkan, namun lebih sederhana. Dalam hal ini yang tadinya x dipangkatkan dengan y, kini bentuk pemangkatan menjadi lebih sederhana, yaitu y – 1.
Hal ini dimaksudkan untuk “menggiring” masalah kompleks ke kasus dasar atau penyetop rekursinya.

Ide dasar dalam memecahkan suatu masalah dengan rekursif adalah sebagai berikut:
Mari kita lihat contoh rekursif yang jauh lebih sederhana,Masalah yang akan dipecahkan adalah memotong roti tawar tipis-tipis sampai habis. Jika masalah ini akan dipecahkan secara rekursif, maka solusinya adalah:
1.     Jika roti sudah habis atau potongannya sudah  paling tipis, pemotongan roti selesai
2.     Jika roti masih bisa dipotong, potong tipis dari tepi roti tersebut, lalu lakukan prosedur 1 dan 2 untuk sisa potongannya.
Contoh Program
program faktorial;
uses wincrt;
var
    faktor :real;
    i,n :integer;
begin
    write('Masukkan bilangan n =');readln(n);
    faktor:=1;
    for i:= 2 to n do {Menghitung n faktorial}
    faktor:=faktor*i;
    writeln(n,' Faktorial = ',faktor:0:0);
end.
Hasil Program
Masukan Bilangan n = 3
3 Faktorial 6
Masukan Bilangan n = 2
2 Faktorial 1
Kita dapat menuliskan fungsi penghitung factorial seperti dibawah ini
1.     int Faktorial(int n)
2.     {
3.                 if ((n == 0) || (n == 1 ))
4.                          return (1);
5.                 else
6.                          return (n * Faktorial(n-1));
7.     }
n  Pada baris 3 dari fungsi diatas,
          nilai n dicek sama dengan 0 atau 1,
          jika ya, maka fungsi mengembalikan nilai 1 {baris 4},
          jika tidak, fungsi mengembalikan nilai n * Faktorial (n -1)
             {baris 6}
n  disinilah letak proses rekursif itu, perhatikan fungsi factorial ini memanggil dirinya sendiri tetapi dengan parameter (n-1)
Barisan yang didefinisikan secara rekursif
Contoh:
Barisan bilangan pangkat dari 2
an = 2n untuk n = 0, 1, 2, … .
Barisan ini dapat didefinisikan secara rekursif:
a0 = 1
an+1 = 2an     untuk  n = 0, 1, 2, …
Langkah-langkah untuk mendefinisikan barisan secara rekursif:
1.     Langkah basis: Spesifikasi anggota awal.
2.     Langkah rekursif: Berikan aturan untuk membangun anggota baru dari anggota yang telah ada.
Contoh barisan yang didefinisikan
secara rekursif
Berikan definisi rekursif dari an=rn, dengan rÃŽN, r≠0 dan n bilangan bulat positif.
Solusi:
Definisikan a0=r0=1
dan an+1=r . an untuk n = 0, 1, 2, …
n  Contoh: definisi rekursif himpunan Ekspresi Aritmatika EA
n  Basis:                   1, 2, 3, 4, 5  ÃŽ  EA
n  Rekursif:     jika a ÃŽ EA dan b ÃŽ EA, maka
n                               a + b  ÃŽ  EA
n                               a – b  ÃŽ  EA
n                               a ´ b  ÃŽ  EA
n                               a ¸ b  ÃŽ  EA

Rekursif berarti bahwa suatu proses bisa memanggil dirinya sendiri. Menurut definisi dalam Microsoft Bookshelf, Rekursif adalah kemampuan suatu rutin untuk memanggil dirinya sendiri. Dalam Rekursif sebenarnya terkandung pengertian prosedur dan fungsi. Perbedaannya adalah bahwa rekursif bisa memanggil ke dirinya sendiri, tetapi prosedur dan fungsi harus dipanggil lewat pemanggil prosedur dan fungsi. Rekursif merupakan teknik pemrograman yang penting dan beberapa bahasa pemrograman mendukung keberadaan proses rekursif ini. Dalam prosedur dan fungsi, pemanggilan ke dirinya sendiri bisa berarti proses berulang yang tidak bisa diketahui kapan akan berakhir.
            Contoh paling sederhana dari proses rekursif ini adalah proses menghitung nilai factorial dari suatu bilangan bulat positif dan mencari deret Fibbonacci dari suatu bilangan bulat.
1.     Nilai factorial secara rekursif dapat ditulis sebagai
0 ! = 1
N ! = N x (N-1) !

yang secara pemrograman dapat ditulis sebagai
Faktorial(0)  = 1                                     (1)
Faktorial(N) = N*Faktorial(N-1)                (2)

Persamaan (2) di atas adalah contoh hubungan rekurens (recurrence relation), yang berarti bahwa nilai suatu fungsi dengan argumen tertentu bisa dihitung dari fungsi yang sama dengan argumen yang lebih kecil. Persamaan (1) tidak bersifat rekursif, disebut nilai awal atau basis. Setiap fungsi rekursif paling sedikit  mempunyai satu nilai awal, jika tidak fungsi tersebut tidak bisa dihitung secara eksplisit.

2.     Bilangan Fibbonacci didefinisikan sebagai berikut
                 1    1    2    3    5    8    13    21    34    55    89   …
dari barisan tersebut dapat dilihat bahwa bilangan ke-N (N>2) dalam barisan dapat dicari dari dua bilangan sebelumnya yang terdekat dengan bilangan N, yaitu bilangan ke-(N-1) dan bilangan ke-(N-2), sehingga dapat dirumuskan sebagai
Fibbonacci(1) = 1                                            (1)
Fibbonacci(2) = 1                                            (2)
Fibbonacci(N) = Fibbonacci(N-1) + Fibbonacci(N-2)  (3)
            Dengan persamaan (1) dan (2) adalah basis dan persamaan (3) adalah rekurensnya


Rekursif Versus Iteratif
            Dalam beberapa situasi, pemecahan secara rekursif maupun secara iteratif mempunyai keuntungan dan kekurangan yang bisa saling diperbandingkan. Adalah cukup sulit untuk menentukan mana yang paling sederhana, paling jelas, paling efisien dan paling mudah disbanding yang lain. Boleh dikatakan pemilihan cara iterative maupun rekursif merupakan kesenangan seorang programmer dan tergantung konteks permasalahan yang akan dipecahkan sesuai dengan kesanggupan yang bersangkutan.

Perhatikanlah contoh berikut :
Contoh 1.
function FACT(N : integer) ® integer
{mengirimkan bilangan factorial dengan cara rekursif}

 Deklarasi
 Deskripsi
      if (N=0) then
          return 1                {Basis}
      else
          return(N*FACT(N-1)) {Rekurens}
      endif
Contoh 2.
function FIBO(N : integer) ® integer
{mengirimkan bilangan fibbonacci dengan cara rekursif}

Deklarasi
Deskripsi
     if ((N=1) or (N=2)) then
          return 1                {Basis}
     else
          return(FIBO(N-1)+ FIBO(N-2))      {Rekurens}
     endif

Contoh 3.
function FACT(N : integer) ® integer
{mengirimkan bilangan factorial dengan cara iteratif}

Deklarasi
          x,i : integer
Deskripsi
          x ¬ 1
                        for  i = 1 to N do
                                    x ¬ i*x
                        endfor
                         return x







Contoh 4.
function FIBO(N : integer) ® integer
{mengirimkan bilangan fibbonacci dengan cara iteratif}

Deklarasi
          Fibbonacci, Akhir, Bantu, i : integer
Deskripsi
If N=0 then
              return 0
          else
            i¬1
  Fibbonacci ¬1
  Akhir ¬0
  while (i¹N)do
              Bantu ¬ Fibbonacci
              i ¬ i + 1
              Fibbonacci ¬ Fibbonacci + Akhir
              Akhir ¬ Bantu
   Endwhile
        return Fibbonacci
      endif
Contoh program