DEPTH, BREADTH, DAN BEST FIRST SEARCH PADA SIMULASI KOTAK - 8
KONFIGURASI KOTAK-8 Disusun menggunakan array 1 dimensi atau vektor yang dideklarasikan dengan : type vektor : array[1..9] of byte Type ini merepresentasikan sel-sel dalam kotak-8 sebagai susunan angka (1,2,3,4,5,6,7,8,0) dengan nol menyatakan sel kosong Contoh : ( 1, 2, 3, 8, 0, 4, 7, 6, 5 )
KONFIGURASI KOTAK-8 const SelAdj : array[1..9,1..4] of integer = Perpindahan sel-sel ke tempat kosong diatur dalam sebuah konstanta array 2 dimensi, yaitu: const SelAdj : array[1..9,1..4] of integer = ( (4,2,0,0), (5,3,1,0), (6,2,0,0), (7,5,1,0), (8,6,4,2), (9,5,3,0), (8,4,0,0), (9,7,5,0), (8,6,0,0) ); dimensi ke-1 menyatakan posisi nol (kosong) dan dimensi ke-2 menyatakan sel-sel yang bisa digeser yang dinyatakan oleh angka selain nol Contoh jika posisi nol ada pada sel ke-9 maka angka yang bisa digeser adalah 8 atau 6
REPRESENTASI STRUKTUR POHON Ruang pelacakan direpresentasikan dalam struktur pohon Struktur pohon dibentuk dengan menggunakan triple linked list, dimana setiap simpulnya memiliki 3 medan informasi dan 3 buah pointer TREE = ^simpul; simpul = record heur : byte; state : vektor; level : byte; induk : TREE; anak_pertama : TREE; saudara : TREE; end; heur state level anak_pertama induk saudara
CONTOH REPRESENTASI POHON 123450786 root 123456780 1 123405786 1 120453786 1 123485706 2 123045786 2 103425786 2
PEMBENTUKAN SIMPUL ANAK Algoritma : 1. Persiapan a. tentukan state 1 tkt di atas b. hitung jumlah anak SIMPUL YANG DIPERIKSA 123450786 123405786 1 120453786 root 2. Bentuk simpul anak pertama 3. Bentuk sisa simpul anak melalui anak pertama 123485706 2 123045786 2 103425786 2
Metode Best First Search procedure GENERATE_ANAK( var node:TREE; best:Boolean; lev : byte); var i,jAnak,c : integer; anak, saudara : TREE; state_baru,state_2tkt_diatas : vektor; begin //1.a. menentukan state 1 tingkat di atasnya if node^.induk <> nil then state_1tkt_diatas := node^.induk^.state; //1.b. menghitung jumlah simpul anak jAnak:= jlh_anak(posisi_0(node^.state)); // 2. pembentukan anak pertama c:=1; repeat state_baru := AMBIL_STATE(node^.state,c); inc(c); until node_berbeda(state_1tkt_diatas,state_baru); Baru(anak,state_baru,heuristik(state_baru,bobot1, bobot2),lev); anak^.induk:=node; node^.anak_pertama:=anak; if Best then MASUK(opened,anak); // 3. pembentukan sisa simpul anak melalui pointer saudara for i:= c to jAnak do begin state_baru:= AMBIL_STATE(node^.state,i); if node_berbeda(state_1tkt_diatas,state_baru) then saudara:=sambung(node,state_baru,lev); if best then MASUK(opened,saudara); anak^.saudara:=saudara; anak:=anak^.saudara; end end; Digunakan untuk Metode Best First Search Jika Best = TRUE
PROSES PELACAKAN 1 2 3 8 4 5 7 0 6 1 2 3 8 0 4 7 6 5 METODE PELACAKAN
METODE PELACAKAN DEPTH FIRST SEARCH Pelacakan secara vertikal BREADTH FIRST SEARCH Pelacakan secara horizontal BEST FIRST SEARCH Pelacakan pada simpul-simpul yang lebih dekat dengan goal state
DEPTH FIRST SEARCH P Algoritma : 1. P = akar = Goal_State ? 2. Periksa simpul dan telusuri semua simpul anak pertama sampai kedalaman – 1. Selama penelusuran periksa, apakah P^.State = Goal_State? ya : Goal_State ditemukan dan keluar tidak : Bentuk semua simpul anak 123450786 akar 123405786 1 120453786 123456780 3. Periksa seluruh simpul pada batas kedalaman dalam satu induk = Goal_State ? = Goal_State ? 4. Jika belum ditemukan, cari simpul di atas terdekat dg induk 123456708 2 123485706 2 103425786 123045786 5. Kembali ke langkah 2 sampai ditemukan atau P = akar = Goal_State ? = Goal_State ? = Goal_State ? = Goal_State ? = RESULT batas kedalaman = 2 Initial_State = 123450786 MATCH Goal_State = 103425786
procedure DEPTH_FIRST_SEARCH ( var akar : TREE; var ditemukan : boolean; var res : TREE ); P : TREE; pos,i : integer; level_terdalam : boolean; BEGIN if node_berbeda(initial_state,goal_state) then begin P:=Akar; pos:=0; repeat { pemeriksaan dan pembentukan simpul anak sampai kedalaman – 1 } for i:=pos to kedalaman-1 do if node_berbeda(P^.state,goal_state) then generate_anak(P, false,i+1) else res:=P; ditemukan:=true; inc(jNode); break; end; if level_terdalam=false then inc(level); P:=P^.anak_pertama; { pemeriksaan pada simpul pada batas kedalaman } while (not ditemukan) do begin inc(jNode); if not node_berbeda(P^.state,goal_state) then res:=P; ditemukan:=true; break; end; if P^.saudara <> nil then P:=P^.saudara else { jika belum ditemukan, pelacakan menuju simpul di atas yang terdekat } if not ditemukan then begin level_terdalam:=true; P:=P^.induk; pos:=kedalaman-1; while (P<>akar) and (P^.saudara=nil) do dec(pos); end; if P^.saudara<>nil then P:=P^.saudara; until (P=akar) or (ditemukan); end else ditemukan:=true; jNode:=1; END;
BREADT FIRST SEARCH P Algoritma : 1. Periksa apakah Akar^.State = Goal_State? ya : Goal_State ditemukan dan keluar tidak : Bentuk semua simpul anak P 2. P = akar 3. Pindahkan P pada level yang belum diperiksa 123450786 akar = Goal_State ? 4. Telusuri setiap simpul dalam satu level, periksa apakah P^.State = Goal_State ya : Goal_State ditemukan dan keluar tidak : Bentuk semua simpul anak jika level ≠ kedalaman 123405786 1 120453786 123456780 = Goal_State ? = Goal_State ? = Goal_State ? 5. Ulangi langkah 2 – 4 sampai level = kedalaman 123456708 2 123485706 2 103425786 123045786 103425786 2 123045786 = Goal_State ? = Goal_State ? = Goal_State ? = RESULT = Goal_State ? MATCH batas kedalaman = 2 Initial_State = 123450786 Goal_State = 103425786
procedure BREADTH_FIRST_SEARCH ( var akar : TREE; var ditemukan : boolean; var res : TREE ); var i, j : integer; Q : TREE; ada_saudara :boolean; BEGIN if node_berbeda(akar^.state,goal_state) then begin level:=0; inc(jNode); generate_anak(akar,false,1); { pelacakan pada semua simpul dalam satu level mulai level ke-1 sampai kedalaman } for i:=1 to kedalaman do Q:=akar; for j:=1 to i do Q:=Q^.anak_pertama; inc(level); ada_saudara:=true; repeat if node_berbeda(Q^.state,goal_state) then if i<kedalaman then generate_anak(Q, False, i+1); if Q^.saudara<>nil then Q:=Q^.saudara else ada_saudara:=ada_saudara_jauh(Q); end else begin ditemukan := true; res:=Q; end; until (ditemukan) or (not ada_saudara); if ditemukan then break; end ketemu:=true; jNode:=1; END;
BEST FIRST SEARCH d a t a next Dalam pelacakannya selain menggunakan struktur data pohon juga menggunakan struktur data antrian. Antrian ini digunakan untuk menyimpan simpul-simpul yang telah dibentuk dan dievaluasi nilai heuristiknya, tetapi belum diperiksa. ANTRIAN = ^point; point = record data : TREE; next : ANTRIAN end; next heur state level anak_pertama induk saudara d a t a
BEST FIRST SEARCH Initial state Goal state Nilai Heuristik H1 : Jumlah sel atau angka yang tidak match dengan goal_state H2 : Jumlah jarak vertikal-horizontal dari sel atau angka yang tidak match Initial state Goal state Contoh : H1 = 3, yaitu angka 1, 4 dan 5 H2 = 4, yaitu : angka 1 = 1 posisi angka 4 = 1 posisi angka 5 = 2 posisi
BEST FIRST SEARCH A D B C E F G P A B C D E F G = Goal_State ? Antrian 2 Digunakan untuk menyimpan simpul yang sudah diperiksa Digunakan untuk menyimpan simpul yang akan diperiksa Antrian1 MATCH 1. Masukan akar ke dalam antrian1 2. P = Antrian1^.data dan periksa apakah P^.state = Goal_State ? ya : ditemukan dan keluar tidak : - move (antrian1, antrian2) - Bentuk simpul-simpul anak dan masukan ke dalam antrian1 123450786 4 akar A A 123405786 2 1 120453786 6 123456780 B C D 3. P=Antrian1^.data D B C 123485706 4 2 103425786 123045786 E F G batas kedalaman = 2 Heuristik : H1 + H2 Initial_State = 123450786 E F G Goal_State = 103425786 RESULT
procedure BEST_FIRST_SEARCH(var akar : TREE; var ketemu: boolean; procedure BEST_FIRST_SEARCH(var akar : TREE; var ketemu: boolean; var res: TREE); var P :TREE; BEGIN antrian1:=nil; antrian2:=nil; MASUK(antrian1,akar); P:=antrian1^.data; if node_berbeda(P^.state,goal_state) then begin inc(jNode); MOVE(antrian1,antrian2); kepala:=antrian2; level:=1; generate_anak(akar, true,1); repeat if (node_berbeda(P^.state,goal_state)) and (P^.level <kedalaman) then if P^.level+1 > level then level:=P^.level+1; generate_anak(P,true,P^.level+1); end else if not node_berbeda(P^.state,goal_state) then begin ketemu:=true; inc(jNode); res:=P; break; end; until (ketemu=true)or(antrian1=nil); end else jNode:=1; END;