PENGERTIAN REKURSI
Rekursi adalah kemampuan suatu rutin untuk memanggil dirinya Sendiri. Jadi
dengan rekursi memungkinkan untuk memanggil suatu prosedur/fungsi dari
dalam prosedur/fungsi itu sendiri. Rekursi diperlukan karena ada beberapa
permasalahan yang akan jauh lebih mudah diselesaikan dengan rekursi.
Masalah yang umum muncul dalam rekursi adalah adanya eksekusi yang tidak
pernah berhenti yang berakibat pada habisnya memori tumpukan sehingga
komputer menjadi Hang.
Faktorial
Salah satu contoh yang paling sering digunakan untuk menjelaskan rekursi
adalah fungsi faktorial. Fungsi faktorial dari bilanngan bulat positif n
didefinisikan sebagai berikut :
Contoh :
4! = 4.3!
4! = 4.3.2!
4! = 4.3.2.1
4! = 24
Sesuai dengan definisinya, sub rutin fungsi penghitung faktorial dapat ditulis
sebagai berikut :
Atas : 4
Atas : 3
Atas : 2
Atas : 1
Bawah 1
Bawah 2
Bawah 3
Bawah 4
Penjelasan mengenai keluaran sub rutin di atas adalah sebagai berikut. Mula-
mula N = 4, fungsi Faktorial dipanggil, berarti di layar muncul „Atas:4‟. Karena N
tidak sama dengan 0 atau 1, maka fungsi Faktorial dipanggil dengan parameter
3. Karena N juga tidak sama dengan 0 atau1, maka di layar muncul „Atas : 3‟.
Demikian seterusnya sampai N = 1 dan di layar muncul „Atas:1‟.
Setelah N = 1, tidak ada lagi proses rekursi, jadi di layar akan tertulis „Bawah 1‟.
Berikutnya fungsi Faktorial (1) akan mengembalikan proses pada
pemanggilnya, yaitu Faktorial (2), dan pada layar akan tertulis „Bawah 2‟.
Demikian seterusnya sampai proses kembali pada Faktorial (4) yang tidak lain
adalah pemanggil fungsi rekursi yang pertama kali.
Untuk lebih jelasnya, dapat dilihat aliran proses seperti yang terlihat pada
Gambar 1.
Faktorial (4) 4 * 6 = 24
Faktorial (4)
Faktorial (3)
Faktorial (2)
2*faktorial (1) 1
Faktorial (1)
Bilangan Fibonacci
Fungsi lain yang dapat di ubah ke bentuk rekursi adalah penghitung bilangan
Fibonacci. Bilangan Fibonacci dapat didefinisikan sebagai berikut :
Fn 1 Fn 2 , untuk N 2
Fn 1, untuk N = 1
0, untuk N = 0
1 1 2 3 5 8 13 21 …
F4 = f3 +f2
F4 = (f2+f1) + (f1+f0)
F4 = (f1+f0)+f1) + (f1+f0)
F4 = ((1+0) +1) + (1+0)
F4 = 3
Sub rutin fungsi untuk bilangan Fibonacci yang dituliskan dalam bahasa Pascal
dapat ditulis sebagai berikut :
Perhatikan bahwa ada dua kali pemanggilan fungsi Fibonacci, yaitu Fibonacci
(n-1) dan Fibonacci (n-2). Berikut proses penghitungan bilangan Fibonacci
untuk n = 4 (Gambar.2.).
Fibonacci (4)
terjadi dua kali pemanggilan fungsi Fibonacci. Sementara itu, untuk n=3 terjadi
4 kali pemanggilan fungsi Fibonacci. Demikian juga untuk n=4 terjadi 8 kali
pemanggilan fungsi Fibonacci. Dengan demikian, untuk n=5, dapat dihitung
bahwa jumlah pemanggilan fungsi Fibonacci adalah sebanyak 8+4+2 = 14 kali.
Algoritma FPB
Diberikan dua buah bilangan bulat tak-negatif m dan n (m n). Carilah pembagi
bersama terbesar (pbt), dari kedua bilangan tersebut, yaitu bilangan bulat positif
terbesar yang habis membagi m dan n.
DESKRIPSI:
1. Jika n = 0 maka
FPB = m adalah jawabannya; stop.
tetapi jika m 0,
lanjutkan ke langkah 2.
2. Bagilah m dengan n dan misalkan FPB adalah sisanya.
3. Ganti nilai m dengan nilai n dan nilai n dengan nilai FPB, lalu ulang kembali ke
langkah 1.
Penjelasan jalannya proses pencarian FPB untuk bilangan bulat positif 228 dan
90 adalah sebagai berikut:
Pertama-tama, terjadi pemanggilan fungsi FPB (228,90). Karena m>n, maka
terjadi pemanggilan fungsi FPB (228 mod 90,90) atau FPB (48,90). Karena
m<n, maka terjadi pemanggilan fungsi FPB (90,48). Demikian seterusnya
sampai pemanggilan fungsi FPB (0,6), yang artinya proses selesai karena m
bernilai 0. Dengan demikian FPB yang dicari sama dengan n atau 6. Ilustrasi
proses di atas dapat dilihat dalam Gambar 3. berikut ini.
FPB (228,90)
FPB (48,90)
FPB (90,48)
FPB (42,48)
FPB (48,42)
FPB (6,42)
FPB (0,6)
FPB (42,6)
Kasus 1. Permutasi
Untuk menampilkan semua permutasi dari N karakter ‟A‟, ‟B‟, ‟C‟, dan
seterusnya, diperlukan rekursi karena proses permutasi akan menampilkan
karakter yang sama secara berulang. Sebagai contoh, untuk n=2, permutasi
yang ada adalah :
A B
B A
Buatlah subrutin untuk menghitung permutasi yang ada dari sejumlah karakater
sebagaimana dimaksudkan di atas.
Penyelesaian:
Algortima
Bentuk algoritma dan sub rutin prosedur untuk membangkitkan permutasi dari
N karakter adalah sebagai berikut
Algoritma PERMUTASI
{ Diberikan nilai N suatu bilangan bulat tak-negatif. Carilah permutasi N karakter
Alpahabet. }
DEKLARASI
Const Max = 10
Type TPermutasi = array [ 1..10 ] of char
DEKLARASI
i : byte;
Temp : char;
DESKRIPSI
If ( mulai = N ) then
for i ← 1 to N do
write ( A [ i ] )
endfor
else
for i ← mulai to N do
temp ← A [ i ]
A[i] ← A [ mulai ]
A [ mulai ] ← temp
DoPermutasi (A, mulai +1)
endfor
endif
Const
Max = 10;
Type
TPermutasi = array[ 1..10 ] of char;
Var
Ax : TPermutasi;
i, N : byte;
Begin
for i := 1 to N do
write ( A [ i ] );
writeln;
end;
else
begin
for i : = mulai to N do
begin
temp := A [ i ];
A [ i ] := A [ mulai ];
A [ mulai ] := temp;
DoPermutasi (A, mulai +1);
end;
end;
end;
begin
write ( ‘Masukkan N : ‘ );
readln ( N );
for i := 1 to N do
Ax [ i ] := chr ( i + 64 );
DoPermutasi ( Ax, 1 );
end.
Masukkan N : 2
AB
BA
Masukkan N : 3
ABC
ACB
BAC
BCA
CAB
CBA
DoPermutasi (A,1)
ABC
DoPermutasi (A,3) DoPermutasi (A,3) DoPermutasi (A,2) DoPermutasi (A,3) DoPermutasi (A,3) DoPermutasi (A,3)
16 2 3 13 46 56 3 25 32 6 49 43
5 11 10 8 63 37 18 12 13 23 36 58
9 7 6 12 17 11 64 38 35 57 14 24
4 14 15 1 4 26 45 55 50 44 31 5
60 34 21 15 10 20 39 61
Bujur Sangkar Ajaib 4 x 4. 41 51 8 30 27 1 54 48
7 29 42 52 53 47 28 2
22 16 59 33 40 62 9 19
Penyelesaian:
Algoritma
Algoritma penyusunan bujur sangkar ajaib 2m x 2m secara umum dapat
dituliskan sebagai berikut :
1. Isi bujur sangkar dengan nilai 1 sampai dengan 22m secara berurutan.
2. Bagi bujur sangkar menjadi berukuran 2m / 2 x 2m / 2.
3. Beri nama elemen-elemen bujur sangkar dengan kode X11, X12, X13, …..,
X44.
4. Lakukan penukaran berikut : X11 X44, X14 X41,
X22 X33 dan X23 X32.
5. Apabila setiap elemen bujur sangkar masih terdiri dari bujur sangkar lagi,
artinya m > 1, kerjakan lagi baris 2.
const
Max = 128;
Valid : set of byte = [ 4, 8, 16, 32, 64, 128 ];
var
i, j, N : byte;
A : array [ 1..Max, 1..Max ] of word;
begin
center2 := dimensi div 2;
center4 := dimensi div 4;
for i := 1 to center4 do
for j := 1 to center4 do
begin
Tukar ( A [ ofsy + j, ofsx + i ],
A [ dimensi + ofsy – center4 + j,
dimensi + ofsy – center4 + i ] );
Tukar ( A [ ofsy + center4 + j,ofsx+center4 + i ],
A [ ofsy + center2 + j,ofsx+center2 + i ] );
Tukar ( A [ ofsy + center2 + j,ofsx+center2 + i ],
A [ ofsy + center4 + j,ofsx+center4 + i ] );
Tukar ( A [ ofsy + j,dimensi + ofsx – center4 + i ],
A [ dimensi + ofsy–center4 + j, ofsx + i ]);
end;
if ( center2 > 2 ) then
begin
TukarKotak ( Center2, ofsx, ofsy );
TukarKotak ( Center2, ofsx + center2, ofsy );
TukarKotak ( Center2, ofsx, ofsy + center2 );
TukarKotak ( Center2, ofsx + center2,
ofsy + center2 );
end;
end;
begin
write ( ‘Masukkan dimensi bujur sangkar : ‘ );
readln ( N );
if ( not ( N in Valid )) then
begin
writeln ( ‘Dimensi bujur sangkar tidak valid’ );
halt;
end;
fillchar ( a, sizeof ( a ), 0 );
for i := 1 to N do
for j := 1 to N do
A [ i, j ] := ( i – 1 ) = N + j;
TukarKotak ( N, 0, 0 );
for i := 1 to N do
begin
for j := 1 to N do
write ( A [ i, j ] : 3, ‘ ‘ ); writeln;
end;
end.
46 56 3 25 32 6 49 43
63 37 18 12 13 23 36 58
17 11 64 38 35 57 14 24
4 26 45 55 50 44 31 5
60 34 21 15 10 20 39 61
41 51 8 30 27 1 54 48
7 29 42 52 53 47 28 2
22 16 59 33 40 62 9 19
Penyelesaian :
Algoritma
Algoritma penyelesaian persoalan 8 ratu dapat dituliskan secara garis besar
seperti berikut :
1. i 1. x 1.
2. Ulangi baris 3 sampai dengan 8 sampai semua posisi sudah diserang ratu
lain atau ( i > 8 ).
3. Cari posisi yang masih mungkin ditempati pada kolom ke-x.
4. Jika masih ada posisi yang mungkin kerjakan baris 5 sampai dengan 8.
5. Letakkan ratu pada posisi yang mungkin tersebut.
6. Jika ( x < 8 ) kerjakan baris 7 dan 8.
7. Kerjakan kembali baris 2 untuk kolom berikutnya, yaitu x + 1.
8. Jika ratu tidak dapat diletakkan pada kolom berikutnya, hapus ratu pada
posisi ini.
const
Max = 8;
var
procedure InitData;
var
i : byte;
begin
Hor := 0;
Ver := 0;
Dia1 := 0;
Dia2 := 0;
FillChar ( Pos, sizeof ( Pos ), 0 );
end;
if ( x < 8 ) then
begin
penuh := DoProcess ( x + 1 );
if ( not penuh ) then
AmbilRatu ( i, x );
end
else
penuh := true;
end;
inc ( i );
until ( i > 8 ) or ( penuh );
DoProcess := penuh;
end;
procedure TulisHasil;
var
i, j : integer;
begin
for i := 1 to Max do
begin
for j := 1 to Max do
if ( Pos [ i ] = j ) then
write ( ‘ 1 ‘ )
else
write ( ‘ 0 ‘ );
writeln;
end;
end;
begin
InitData;
DoProcess ( 1 );
TulisHasil;
end.
Kasus 4. Labirin
Permasalahan Labirin merupakan permasalahan untuk mencari jalan terpendek
dari titik tertentu ke titik lain melalui labirin.
Cara termudah untuk menyimpan labirin adalah dengan membuat suatu larik
dua dimensi dengan ukuran NumRow untuk baris dan NumCol untuk kolom.
Masing-masing elemen larik bertipe rekaman yang memiliki empat anggota,
yaitu Utara, Barat, Selatan, Timur. Keempat anggota rekaman ini masing-
masing digunakan untuk menyimpan ada tidaknya tembok di sebelah Utara,
Barat, Selatan, dan Timur.
Di sini, akan digunakan metode trial and error. Prinsipnya, mula-mula di coba
satu arah, misalkan ke utara. Jika gagal di coba arah lain, misalkan ke timur.
Jika masih gagal di coba lagi arah lain. Demikian seterusnya.
Berikut ini adalah contoh program untuk memecahkan labirin yang disimpan
pada file maze.in.
Program Labirin;
Uses Crt, Dos;
Const
MaxMaze = 20;
MaxRoute = 1000;
type
TRoute = record
Row, Col : byte;
end;
TDirection = record
Utara, Selatan, Barat, Timur : boolean;
end;
var
NumRow, NumCol : byte;
StartX, StartY : byte;
StopX, StopY :byte;
procedure InitData;
var
i, j, : integer;
FileA : text;
Ch : char;
Buffer : array [1..2*MaxMaze + 1,
1..2 * MaxMaze + 1 ] of char;
begin
Assign ( FileA, ‘Maze.in’ );
Reset ( FileA );
Readln ( FileA, NumRow, NumCol );
Readln ( FileA, StartY, StartX );
Readln ( FileA, StopY, StopX );
for i := 1 to 2 * NumRow + 1 do
begin
for j := 1 to 2 * NumCol + 1 do
begin
Read ( FileA, ch );
if ( ch <> #13 ) then
Buffer [ i, j ] := ch
else
break;
end;
repeat
Read ( FileA, ch );
until ( ch <> #13 );
end;
for i := 1 to 2 * NumRow + 1 do
begin
for j := 1 to 2 * NumCol + 1 do
begin
if ( i mod 2 = 0 ) and ( j mod 2 = 0 ) then
begin
Maze [ i div 2, j div 2 ] . Utara := (
Buffer [ i – 1, j ] = ‘-‘ );
Maze [ i div 2, j div 2 ] . Selatan :=
( Buffer [ i + 1, j ] = ‘-‘ );
Maze [ i div 2, j div 2 ] . Timur := (
Buffer [ i, j + 1 ] = ‘ | ‘ );
Maze [ i div 2, j div 2 ] . Barat := (
Buffer [ i, j - 1 ] = ‘ | ‘ );
end;
end;
end;
Close ( FileA );
end;
DoRecursive ( x, y, 0, 1 );
dec ( NumRoute );
end;
Visit [ y, x ] := false;
pocedure PrintRoute;
var
i : integer;
begin
Writeln;
if ( MinNumRoute = MaxRoute ) then
Writeln ( ‘ Tidak dapat diselesaikan’ )
else
begin
Write ( MinRoute[1].Row, ‘,’, MinRoute[1].Col);
for i := 2 to MinNumRoute do
Write (‘–‘, MinRoute[i].Row, ‘,‘ , MinRoute[i].Col);
end;
end;
begin
InitData;
DoRecursive ( 1, 1, 1, 0 );
PrintRoute;
end.
1,1 - 1, 2 - 1,3 - 2,3 - 3,3 - 3,4 - 3,5 - 4,5 - 5,5 - 6,5 - 6,6
Const
Max = 100;
var
A, B, C : byte;
Ax, Bx : byte;
i : byte;
Gerak : array [ 1..Max ] of byte;
Buffer : array [ 1..Max ] of byte;
Minimum : byte;
Jumlah : byte;
Sukses : boolean;
inc ( Jumlah );
Gerak [ Jumlah ] := g;
case ( g ) of
1 : if ( Ax = 0 ) and ( Bx <> B ) then
Ax := A
else
exit;
2 : if ( Ax = A ) and ( Bx > 0 ) then
Ax := 0
else
exit;
3 : if ( Ax > 0 ) then
begin
Bx := Bx + Ax;
if ( Bx > B ) then
begin
Ax := Bx – B;
Bx := B;
end
else
Ax := 0;
end
else
exit;
if ( Ax = C ) or ( Bx = C ) then
Sukses := true
begin
A := 5;
B := 3;
C := 4;
Fillchar ( Gerak, sizeof ( Gerak ), 0 );
Minimum := Max;
Fillchar ( Buffer, sizeof ( Buffer ), 0 );
i := 1;
while ( i <= 6 ) do
begin
Ax := 0;
Bx := 0;
Jumlah := 0;
Sukses := false;
DoProcess ( i );
if ( Sukses ) and ( Minimum > Jumlah ) then
begin
Minimum := Jumlah;
Move ( Gerak, Buffer, sizeof ( Gerak ) );
end;
inc ( i );
end;
end;
end;
end;
end.
Isi A
Pindah A ke B
Buang B
Pindah A ke B
Isi A
Pindah A ke B
Sebenarnya program ini juga dapat digunakan untuk memecahkan kasus lain,
misalnya bagaimana cara mendapatkan air 9 liter dari botol 10 dan 13 liter.
Untuk itu ubahlah tiga baris pertama dari program utama di atas, yaitu pada
pemberian nilai A, B, dan C, menjadi seperti berikut :
A := 10;
B := 13;
C := 9;
Isi B
Pindah B ke A
Buang A
Pindah B ke A
Isi B
Pindah B ke A
Buang A
Pindah B ke A
Isi B
Pindah B ke A