Penggunaan Algoritma Hill Climbing Search Untuk Menyelesaikan permasalahan permasalahan 8 Puzzle Intan Solikhatul Mabruro
Muh. Rizki Irwanto
Rafsanjaya Mahaputra
Jl. Jombang Raya No. 19 081937051552
Jl. Sumber Sari Gg. 6 No.25 C 089675462516
Jl. Muharto Timur No. 7 081282793834
[email protected]
[email protected]
[email protected]
ABSTRACT Dengan semakin berkembangnya teknologi di dunia membuat perkembangan dunia informatika yang semakin semakin maju dan semakin banyak masalah yang ingin diselesaikan. Penyelesaian masalah merupakan bagian yang paling penting dalam membuat suatu aplikasi. Terutama pada aplikasi yang membutuhkan suatu solusi. Pencarian rute terpendek merupakan suatu permasalahan yang sering kita jumpai, masalah tersebut tidak hanya menyangkut tentang jarak terdekat, pencapaian tujuan, efektifitas, efektifitas, dan efisiensi waktu saja. Melainkan dalam mencari sebuah solusi masalah terdapat beberapa algoritma yang dapat digunakan. Salah satunya adalah algoritma Hill Climbing. Dimana proses pengujiannya dilakukan dengan menggunakan fungsi heuristik. Pembangkitan keadaan berikutnya sangat tergantung pada feedback dari prosedur pengetesan. Tes yang berupa fungsi heuristik ini akan menunjukkan seberapa baiknya nilai terkaan yang diambil terhadap keadaankeadaan lainnya yang mungkin.(Kusumadewi, 2003). Algoritma Hill Climbing merupakan suatu metode untuk mencari dan menentukan rute atau jalur yang paling pendek dengan cara memperkecil jumlah tempat yang disinggahi dengan mencari tempat terjauh yang mendekati dengan tujuan algortima tersebut dapat juga digunakan untuk menyelesaikan masalah pada 8 puzzle. Dalam pencarian jarak terpendek akan dihasilkan suatu jalur yang akan dilewati untuk mencapai suatu tujuan atau menemukan jalur menuju sasaran. Pada kasus ini solusi terbaik akan dicapai dengan menggeser kotak sampai didapatkan solusi dengan langkah yang sedikit mungkin. Pada permasalahan 8 puzzle ini kami menggunakan bahasa c++ untuk menyelesaikannya.
Keywords C++, Fungsi Heuristik, Algoritma Hill Climbing, 8 Puzzle
1. PENDAHULUAN Perkembangan teknologi yang sangat cepat harus didukung dengan perkembangan dan implementasi algoritma yang baik, sehingga teknologi yang ada tersebut dapat memberikan hasil yang baik, efektif dan efisien. Pada saat ini banyak algoritma yang berkembang untuk menemukan solusi sebuah permasalahan seperti permasalahan dalam permainan. Dalam sebuah permainan terdiri atas sekumpulan peraturan yang digunakan dalam permainan contohnya pada permainan 8Puzzle. 8Pu zzle merupakan permainan teka-teki yang diselesaikan dengan mengurutkan atau menyusun komponenkomponen sesuai untuk mencapai goal state. Komponenkomponen dalam permainan ini berupa kotak-kotak bernomor atau bergambar yang terdiri dari 8 kotak dan 1 tempat kosong
yang dapat digerakan sesuai dengan aturan dalam permainan yaitu: atas, bawah, kanan, dan kiri. Ukuran dalam permainan 8Puzzle adalah 3x3 sehingga 8 kotak yang tersedia hanya dapat bergerak dalam lingkup ukuran tersebut. 8-puzzle merupakan salah satu implementasi dari Artificial Intelegence. Dalam proses penyelesaianya banyak algoritma yang dapat diterapkan. Kali ini penulis akan menerapkan algoritma Hill Climbing pada penyelesaian 8 puzzle yang merupakan salah satu metode dari teknik pencarian yang berdasarkan pada fungsi heuristik.
2. DASAR TEORI 2.1 8 Puzzle The 8 puzzle consists of eight numbered, movable tiles set in a 3x3 frame. One cell of the frame is always empty thus making it possible to move an adjacent n umbered tile into the empty cell. Such a puzzle is illustrated in following d iagram.
The program is to change the initial configuration into the goal configuration. A solution to the problem is an appropriate sequence of moves, such as “move tiles 5 to the right, move tile 7 to the left ,move tile 6 to the down, etc”(Gurram, etc” (Gurram, 2010) Seperti yang dijelaskan pada kutipan di atas bahwa 8 Puzzle merupakan permainan yang terdiri dari 8 kotak yang memiliki nomor, yang terdapat dalam satu bingkai berukuran 3 x3. Salah satu kotak selalu kosong atau memiliki nomor 0 sehingga memungkinkan kotak tersebut untuk berpindah.. Tujuan akhir dari permainan 8 puzzle adalah mengatur kondisi awal (initial state) yang diperoleh secara acak menjadi dalam bentuk konfigurasi akhir (goal state). Solusi untuk masalah tersebut adalah dengan cara memindah kotak kosong ke kanan, ke kiri, ke atas, dank e bawah.
2.2 Fungsi Heuristik Heuristik berasal dari bahasa Yunani yaitu heuriskein yang yang berarti “mencari” atau “menemukan”. Di dalam mempelajari metode metode pencarian ini, kata heuristik diartikan sebagai
suatu fungsi yang memberikan suatu nilai berupa biaya perkiraan (estimasi) dari suatu solusi. (Suyanto, 2007). Terdapat beberapa metode yang menggunakan teknik pencarian dengan fungsi heuristik diantaranya: Hill Climbing, Best First Search, dan A* (A bintang). Ada dua jenis fungsi heuristik yang dapat digunakan: a.
H1 = jumlah kotak yang posisinya benar
b.
H2 = jarak antara initial state dan goal state. Cara menghitungnya dengan menjumlah harga mutlak selisih antara kolom dan baris pada masing-masing initial state dan goal state.
2.3 Algoritma Hill Climbing Search Algoritma Hill Climbing merupakan suatu metode yang digunakan untuk mencari dan menentukan rute atau jalur yang paling dekat dengan memperkecil jumlah tempat yang akan disinggahi dengan menggunakan metode pencarian dimana node tujuan didapat dari jarak paling pendek dari node parent, seperti contoh yang ada di bawah ini:
Jumlah dari H1 dan H2 adalah 9 yaitu H1 maksimal apabila posisi setiap angka dalam puzzle sudah sesuai dengan goal state. Sedangkan H2 = 0. Posisi heuristik dapat dilihat dengan menyamakan antara initial state dengan goal state. a.
Untuk jumlah angka yang menempati posisi yang benar: jumlah yang lebih tinggi adalah yang lebih baik. b. Untuk jumlah angka yang menempati posisi yang salah: jumlah yang lebih kecil adalah yang lebih baik. c. Untuk menghitung total gerakan untuk mencapai tujuan: jumlah yang lebih kecil adalah yang lebih baik. Contoh: K i
Bi
1
2
b.
Bg
K g
1
2
3
1
3
1
2
1
0
1
2
2
0
4
5
2
3
4
5
3
6
7
8
3
6
7
8
Initial State
a.
3
Goal State
Untuk jumlah angka yang menempati posisi yang benar adalah [1,2,4,5,6,7,8] yaitu H1 = 7 Untuk jumlah angka yang menempati posisi yang salah adalah [0,3] yaitu H2 = 2
Fungsi heuristik jarak yang diambil adalah yang bernilai 0 (nol) a. Heuristik jarak angka 6 adalah 0 yaitu: Initial state 6: kolom = 1; baris = 3 Goal state 6: kolom = 1; baris = 3 Maka Jarak |8| adalah |kolom goal state-kolom initial state| + |baris goal state-baris initial state| = |1-1| + |3-3| 0 b. Heuristik jarak angka 3 adalah 1 yaitu: Initial state 3: kolom = 1; baris = 1 Goal state 3: kolom = 1; baris = 2 Maka Jarak |3| adalah |kolom goal state-kolom initial state| + |baris goal state-baris initial state| = |1-1| + |2-1| 1 Setelah melihat posisi heuristik dan jarak maka akan ditemukan sebuah goal state yang menjadi tujuan.
Gambar 2.1 Metode Hill Climbing Search Pada gambar di atas menunjukkan bahwa jalur pencarian yang di peroleh yaitu dengan jarak yang terpendek dari parent = S – B – C – E sehingga ditemukan node tujuan yaitu Z pada jarak yang paling pendek dari parent.
2.4 C++ Apabila kita mendengar tentang C++ maka kita tidak lepas dari C yang merupakan bahasa pendahulu dari C++. C++ diciptakan satu decade setelah C. diciptakan oleh Bjarne Stroustrup, Laboratorium Bell, AT&T, pada tahun 1983. Bahasa ini memiliki sifat kompatibel dengan bahasa pendahulunya yaitu C. pada awalnya C++ disebut dengan “a better C”. Nama C++ in i diberikan oleh Rick Mascitti pada tahun 1983. C diambil sebagai dasar dari C++, mengingat keportabilitasan C yang memungkinkannya diterapkan pada berbagai mesin, seperti PC hingga mainframe, serta pada berbagai sistem operasi (DOS, UNIX, VMS dan sebagainya). Keistimewaan dari C++ adalah karena bahasa ini mendukung pemograman yang berorientasi obyek (PBO atau OOP / Object Oriented Programming ). Tujuan utama dari pembuatan C++ adalah untuk meningkatkan produktivitas pemogram dalam membuat aplikasi. Program C++ dapat ditulis menggunakan beberapa editor teks seperti EDIT (milik DOS), Wordstar, SideKick ataupun menggunakan editor bawaan dari compiler. Program C++ biasanya disimpan dengan menggunakan ekstensi .CPP (dari kata C plus plus). Supaya program ini nantinya dapat di jalankan atau dieksekusi.
3. 8 PUZZLE 3.1 Algoritma Pada penyelesaian 8 puzzle ini kami menggunakan algoritma heuristik, pada 8 puzzle ini nilai heuristik ditentukan berdasarkan kondisi kedekatan dengan goal state, karena kita tidak tau jarak dan langkah yang ditempuh dari state sekarang hingga ke goal state. Untuk menentukan nilai heuristik ini kita membutuhkan sebuah perhitungan, yaitu menggunakan perhitungan manhattan distance. Manhattan distance ini adalah penjumlahan jarak masing-masing kotak 8 puzzle terhadap posisi yang benar pada goal state. Jadi pada kondisi goal, heuristik pasti bernilai 0 karena
kemungkinan untuk tidak dapat mengulangi kembali sehingga memungkinkan akan terjebak dalam local maksimum.
berdasarkan p ada wesite 8 Puzzle yang sudah di sebutkan dalam program. void goalState(list *L) { if((*L).first == NULL) { // Jika list adalah list kosong. initialState(L); } else { // Cara menentukan Goal State berdasarkan: http://www.8puzzle.com/8_puzzle_algorithm.html. elemen *elmt; elmt = (elemen *) malloc (sizeof(elemen)); if(menentukanGoalState(*L) == 0)
This will ensure that the heuristics technique functions with minimal use of memory, least computation possible but still retain the advantage of an informed method of solution finding. The downside of Hill Climbing is that due to the absence of memory, resulting in the possibility of repeating the same states and getting stuck in some state of local maxima. (Kuruvilla Mathew and Mujahid Tabassum, 2014)
4. PEMBAHASAN 4.1 Pembahasan Program Program ini dibuat oleh Pipin Fitriadi, Mahasiswa S2 TMDG Teknik Elektro STEI ITB. Program ini merupakan tugas akhir mata kuliah Sistem Intelejen. Program ini dibangun menggunakan bahasa pemrograman Bahasa C, sehingga untuk menjalankannya dibutuhkan software Microsoft Visual C. Untuk mencari penyelesaian dari 8-puzzle, program membutuhkan waktu ± 30 detik. Waktu penyelesaian tergantung dari inputan acak yang dimasukkan, karena setiap angka berbeda beda banyak langkah penyelesaiannya. Berikut analisa program dan penjelasan source code : 1.
{ strcpy(elmt->elmt.puzzle[0][0].a, "1"); strcpy(elmt->elmt.puzzle[0][1].a, "2"); strcpy(elmt->elmt.puzzle[0][2].a, "3"); strcpy(elmt->elmt.puzzle[1][0].a, "4"); strcpy(elmt->elmt.puzzle[1][1].a, "5"); strcpy(elmt->elmt.puzzle[1][2].a, "6"); strcpy(elmt->elmt.puzzle[2][0].a, "7"); strcpy(elmt->elmt.puzzle[2][1].a, "8"); strcpy(elmt->elmt.puzzle[2][2].a, "0"); } else
Menentukan Initial State
Pada langkah ini program menginstruksikan untuk menentukan initial state yang akan di selesaikan, dengan menginputkan angka dari 0, 1, 2, 3, 4, 5, 6, 7, 8 secara acak kemudian angka tersebut akan di di tempatkan dari kiri ke kanan dan atas ke bawah. Dan disimpan dengan menggunakan linked list yang mirip dengan array yang memiliki alokasi memori yang dinamis.
{ strcpy(elmt->elmt.puzzle[0][0].a, "1"); strcpy(elmt->elmt.puzzle[0][1].a, "2"); strcpy(elmt->elmt.puzzle[0][2].a, "3"); strcpy(elmt->elmt.puzzle[1][0].a, "8"); strcpy(elmt->elmt.puzzle[1][1].a, "0"); strcpy(elmt->elmt.puzzle[1][2].a, "4"); strcpy(elmt->elmt.puzzle[2][0].a, "7"); strcpy(elmt->elmt.puzzle[2][1].a, "6"); strcpy(elmt->elmt.puzzle[2][2].a, "5"); } elmt->next = NULL; // Mencari elemen terakhir list. elemen *last = (*L).first; while(last->next != NULL) { // Iterasi. last = last->next; } last->next = elmt; elmt = NULL; }
void initialState(list *L) { printf("Silahkan isi puzzle terlebih dahulu\n"); eightPuzzle P; masukkanAngka(&P); printf("=================================== =======================\n"); elemen *elmt; elmt = (elemen *) malloc (sizeof (elemen)); salinPuzzle(elmt, P); hapusAngka(&P); elmt->next = ( *L).first; (*L).first = elmt; elmt = NULL; }
2.
Menentukan Goal State
Untuk menentukan goal state dari intial state yang telah di masukkan didalam program terdapat dua kemungkinan goal state, namun hanya aka nada satu kemungkinan yang akan menjadi sebuah goal state. Untuk menentuka goal state program ini
3.
Langkah Penggeseran Kotak kosong
Pada pergeseran kotak kosong dari 8 puzzle ini terdapat 4 kondisi yaitu geser ke atas, ke bawah, ke kanan dan ke kiri. Dengan 4
kondisi tersebut program menentukan arah penukaran kotak kosong.
void geserAtas(elemen *prec, short langkah, list *L) { elemen *elmt; elmt = (elemen *) malloc (sizeof (elemen)); for(short i=0; i<3; i++) { for(short j=0; j<3; j++) { if(((strcmp(prec->elmt.puzzle[i][j].a, "0")) == 0)&&(i != 0)) { strcpy(elmt->elmt.puzzle[i-1][j].a, prec>elmt.puzzle[i][j].a); strcpy(elmt->elmt.puzzle[i][j].a, prec->elmt.puzzle[i1][j].a); } else { strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i][j].a);}}}
strcpy(elmt->elmt.arahPenukaran, "atas"); elmt->elmt.langkah = langkah; // Proses mencari elemen kedua sebelum terakhir. elemen *before_last; while(prec->next != NULL) { // Proses. before_last = prec; // Iterasi. prec = prec->next; } elmt->next = b efore_last->next; before_last->next = elmt; elmt = NULL; heuristic(before_last->next, L); cekPuzzle(before_last->next, L); }
void geserBawah(elemen *prec, short langkah, list *L) { elemen *elmt; elmt = (elemen *) malloc (sizeof (elemen)); for(short i=2; i>-1; i--) { for(short j=2; j>-1; j--) { if(((strcmp(prec->elmt.puzzle[i][j].a, "0")) == 0)&&(i != 2)) { strcpy(elmt->elmt.puzzle[i+1][j].a, prec>elmt.puzzle[i][j].a); strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i+1][j].a); } else { strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i][j].a); } } } strcpy(elmt->elmt.arahPenukaran, "bawah"); elmt->elmt.langkah = langkah; // Proses mencari elemen kedua sebelum terakhir. elemen *before_last; while(prec->next != NULL) { // Proses. before_last = prec; // Iterasi. prec = prec->next; } elmt->next = before_last->next; before_last->next = elmt; elmt = NULL; heuristic(before_last->next, L); cekPuzzle(before_last->next, L); }
void geserKanan(elemen *prec, short langkah, list *L) { elemen *elmt; elmt = (elemen *) malloc (sizeof (elemen)); for(short i=2; i>-1; i--) { for(short j=2; j>-1; j--) { if(((strcmp(prec->elmt.puzzle[i][j].a, "0")) == 0)&&(j != 2)) { strcpy(elmt->elmt.puzzle[i][j+1].a, prec>elmt.puzzle[i][j].a); strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i][j+1].a); } else { strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i][j].a); } } } strcpy(elmt->elmt.arahPenukaran, "kanan"); elmt->elmt.langkah = langkah; // Proses mencari elemen kedua sebelum terakhir. elemen *before_last; while(prec->next != NULL) { // Proses. before_last = prec; // Iterasi. prec = prec->next; } elmt->next = b efore_last->next; before_last->next = elmt; elmt = NULL; heuristic(before_last->next, L); cekPuzzle(before_last->next, L);
void geserKiri(elemen *prec, short langkah, list *L) { elemen *elmt; elmt = (elemen *) malloc (sizeof (elemen)); for(short i=0; i<3; i++) { for(short j=0; j<3; j++) { if(((strcmp(prec->elmt.puzzle[i][j].a, "0")) == 0)&&(j != 0)) { strcpy(elmt->elmt.puzzle[i][j-1].a, prec>elmt.puzzle[i][j].a); strcpy(elmt->elmt.puzzle[i][j].a, prec->elmt.puzzle[i][j1].a); } else
strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i][j].a); } } } strcpy(elmt->elmt.arahPenukaran, "kiri"); elmt->elmt.langkah = langkah; // Proses mencari elemen kedua sebelum terakhir. elemen *before_last; while(prec->next != NULL) { // Proses. before_last = prec; // Iterasi. prec = prec->next; } elmt->next = before_last->next; before_last->next = elmt; elmt = NULL; heuristic(before_last->next, L); cekPuzzle(before_last->next, L); } 4.
Fungsi Heuristik
Pada program ini terdapat fungsi heuristik yang menggunakan manhattan distance untuk memberikan solusi perkiraan jarak terpendek yang akan di lalui untuk mencapai akhir dari penyelesaian 8 puzzle. Penghitungan dari penentuan jarak terpendek ini dapat diketahui dengan melihat posisi baris dan kolom angka dalam puzzle.
void heuristic(elemen *prec, list *L) { // Pencarian heuristic menggunakan Manhattan Distance. short tidakCocok = 0; elemen *last = (*L).first; // Proses mencari elemen terakhir. while(last->next != NULL) { // Proses dan Iterasi. last = last->next; } // Mencari nilai heuristic sebuah state terhadap Goal State. for(short i=0; i<3; i++) { for(short j=0; j<3; j++) { for(short k=0; k<3; k++) { for(short l=0; l<3; l++) {
2. if((strcmp(prec->elmt.puzzle[i][j].a, last>elmt.puzzle[k][l].a) == 0)&&(strcmp(prec>elmt.puzzle[i][j].a, "0") != 0 )) { tidakCocok = tidakCocok + abs(i-k) + abs(j-l); } } } } } prec->elmt.tidakCocok = tidakCocok; }
4.2 Manfaat Algoritma Hill Climbing Hill climbing ini sering disebut sebagai pencarian heuristik yang tercepat karena evaluasi yang dlakukan sederhana terhadap beberapa kemungkinan state yang dianggap paling baik, kemudian memilihnya dan meninggalkan kemungkinan lain yang berada di luar kondisi evaluatifnya.
This will ensure that the heuristics technique functions with minimal use of memory, least computation possible but still retain the advantage of an informed method of solution finding. The downside of Hill Climbing is that due to the absence of memory, resulting in the possibility of repeating the same states and getting stuck in some state of local maxima. (Kuruvilla Mathew and Mujahid Tabassum, 2014) Dari kutipan di atas dapat disimpulkan bahwa dalam fungsi heuristik yang digunakan oleh algoritma Hill Climbing ini dapat meminimalkan penggunaan memori dalam komputer. Selain itu algoritma Hill Climbing ini juga memiliki kelebihan yaitu dapat memberikan beberapa kemungkinan jalur atau lintasan yang akan dilalui sehingga dapat di dapatkan kemungkinan solusi yang terbaik dari beberapa kemungkinan yang lain. Tetapi kelemahan dari algoritma hill climbing ini karena tidak adanya memori yang digunakan mengakibatkan kemungkinan untuk tidak dapat mengulangi kembali sehingga memungkinkan akan terjebak dalam local maksimum.
5. KESIMPULAN 1.
Penggunaan Algoritma Hill Climbing pada 8 puzzle dapat memberikan solusi yang paling baik yaitu dengan memberikan beberapa kemungkinan jalur atau lintasan yang akan di lalui, dan jalur yang terpendek adalah yang paling baik.
Hill Climbing yang digunakan untuk memberikan solusi pada 8 puzzle menggunakan fungsi heuristik yaitu menghitung dengan menjumlah harga mutlak selisih antara kolom dan baris pada masing-masing initial state dan goal state.
6. REFERENSI [1] Fitriadi, Pipin. 2012. 8-Puzzle. (online), (http://pipinfitriadi.blogspot.com/search/label/Pemrograman) , diakses 1-12-2014. [2] Kadir, Abdul. 2003. Pemrograman C++. Yogyakarta: Andi [3] Kantz, Jason. 2005. The 8 Puzzle. (online), (http://www.kantz.com/htm/8-puzzle.htm). diakses pada tanggal 06-12-2014. [4] Livyanda. 2010. Metode Hill Climbing. (online), (http://lolivyanda.blogspot.com/2010/10/metode-hill-climbing.html), diakses pada tanggal 06-12-2014. [5] Mathew, Kuruvilla and Mujahid Tabassum. 2014. Experimental Comparison of Uniformed and Heuristic AI Algorithms for N Puzzle and 8 Queen Puzzle Solution. International Jurnal of Digital Information and Wirelles Communications [6] Muffaricha. 2010. Penyelesaian Travelling Salesman Problem (TSP) Dengan Menggunakan Algoritma Hill Climbing. (online), (http://karyailmiah.um.ac.id/index.php/matematika/article/view/8882) . diakses pada tanggal 06-12-2014 [7] Susanti, Anggraeni. 2014. Simple Hill Climbing . Universitas Airlangga. [8] Yudhi. 2008. Pemrograman Permainan Puzzle. (online), (http://yudhim.blogspot.com/2008/01/pemrograman permainan-puzzle-8.html) diakses pada tanggal 5/12/2014 [9] Zakiah, Azizah. 2012. Penyelesaian Masalah 8 Puzzle Dengan Algoritma Hill Climbing Stepest Ascent Logist Heuristik Berbasis Java. Yogyakarta.
Lampiran 1 – Coding Program
/* Bandung, 2 sampai 29 April 2012 Pipin Fitriadi (23211331) |
[email protected] Tugas Akhir Mata Kuliah Sistem Intelejen, S2 TMDG Teknik Elektro STEI ITB Penerapan algoritma pencarian untuk mengurutkan 8-Puzzle */ #include "stdafx.h" #include
#include #include #include //--------------------------------------struct isiPuzzle { char a[5000]; }; struct eightPuzzle { isiPuzzle puzzle[3][3]; short tidakCocok; short langkah; char arahPenukaran[5]; }; struct elemen { eightPuzzle elmt; struct elemen *next; }; struct list { struct elemen *first; }; //--------------------------------------void createList(list *L) { printf("===================================== =====================\n"); printf(" 8-PUZZLE\n"); printf(" Pipin Fitriadi\n"); printf(" 23211331\n"); printf("===================================== =====================\n"); FILE *f; f = fopen("8-Puzzle.txt", "w"); fprintf(f, "%s", "============================================ ==============\n"); fprintf(f, "%s", " 8PUZZLE\n"); fprintf(f, "%s", " Pipin Fitriadi\n"); fprintf(f, "%s", " 23211331\n");
fprintf(f, "%s", "============================================ ==============\n"); fclose(f); (*L).first = NULL; } //--------------------------------------int countElement(list L) { int hasil = 0; if(L.first != NULL) { // List tidak kosong. elemen *elmt = L.first; while(elmt != NULL) { // Proses. hasil = hasil + 1; // Iterasi. elmt = elmt->next; } } return hasil; } //--------------------------------------void masukkanAngka(eightPuzzle *P) { printf("---------------------------------------------------------\n"); printf(" Masukkan 0, 1, 2, 3, 4, 5, 6, 7, 8 secara acak,\n"); printf("angka akan ditempatkan dari kiri ke kanan & atas ke bawah.\n\n"); // Proses mengisi kotak puzzle pada setiap barisnya. for(short i=0; i<3; i++) { // Proses mengisi pada setiap kotak puzzle dalam baris yang sama. for(short j=0; j<3; j++) { printf("8-Puzzle %d.%d: ", i+1, j+1); scanf("%s", &(*P).puzzle[i][j].a); // Proses pengecekan apabila masukkan angka 0, 1, 2, 3, 4, 5, 6, 7, 8 tapi sudah ada, atau masukkan angka bukan 0, 1, 2, 3, 4, 5, 6, 7, 8. for(short m=0; m<127; m++) { // Pengecekan apakah angka yang diisikan sudah ada atau tidak pada setiap barisnya. for(short k=0; k<3; k++) { // Pengecekan apakah angka yang diisikan sudah ada atau tidak pada setiap kotak puzzle dalam baris yang sama. for(short l=0; l<3; l++) {
while((((strcmp((*P).puzzle[i][j].a, "0")) != 0)&&((strcmp((*P).puzzle[i][j].a, "1")) != 0)&&((strcmp((*P).puzzle[i][j].a, "2")) != 0)&&((strcmp((*P).puzzle[i][j].a, "3")) != 0)&&((strcmp((*P).puzzle[i][j].a, "4")) != 0)&&((strcmp((*P).puzzle[i][j].a, "5")) != 0)&&((strcmp((*P).puzzle[i][j].a, "6")) != 0)&&((strcmp((*P).puzzle[i][j].a, "7")) != 0)&&((strcmp((*P).puzzle[i][j].a, "8")) != 0))|| (((strcmp((*P).puzzle[i][j].a, (*P).puzzle[k][l].a)) == 0)&&((i != k)||((i == k)&&(j != l))))) { // Iterasi. printf("Tidak bisa, coba yang lain..\n\n" ); printf("8-Puzzle %d.%d: ", i+1, j+1); scanf("%s", &(*P).puzzle[i][j].a); } } } } } } } //--------------------------------------void hapusAngka(eightPuzzle *P) { for(short i=0; i<3; i++) { for(short j=0; j<3; j++) { long k = 0; while((*P).puzzle[i][j].a[k] == '\0') { // Proses. (*P).puzzle[i][j].a[k]; // Iterasi. k = k + 1; // Kondisi Terminasi. if((*P).puzzle[i][j].a[k] != '\0'){} } (*P).puzzle[i][j].a[k] = '\0'; } } } //--------------------------------------void salinPuzzle(elemen *prec, eightPuzzle P) { for(short i=0; i<3; i++) { for(short j=0; j<3; j++) { strcpy(prec->elmt.puzzle[i][j].a, P.puzzle[i][j].a); } } } //---------------------------------------
void hapusInitialState(list *L) { if((*L).first != NULL) { // Jika list tidak kosong. elemen *elmt = (*L).first; (*L).first = (*L).first->next; elmt->next = NULL; free(elmt); } } //--------------------------------------void initialState(list *L) { printf(" Silahkan isi puzzle terlebih dahulu\n"); eightPuzzle P; masukkanAngka(&P); printf("===================================== =====================\n"); elemen *elmt; elmt = (elemen *) malloc (sizeof (elemen)); salinPuzzle(elmt, P); hapusAngka(&P); elmt->next = (*L).first; (*L).first = elmt; elmt = NULL; } //--------------------------------------short menentukanGoalState(list L) { short hasil = 0; for(short i=0; i<3; i++) { for(short j=0; j<3; j++) { for(short k=0; k<3; k++) { for(short l=0; l<3; l++) { if((((strcmp(L.first->elmt.puzzle[i][j].a, "8") == 0)&&((strcmp(L.first>elmt.puzzle[k][l].a, "1") == 0)||(strcmp(L.first->elmt.puzzle[k][l].a, "2") == 0)||(strcmp(L.first>elmt.puzzle[k][l].a, "3") == 0)||(strcmp(L.first->elmt.puzzle[k][l].a, "4") == 0)||(strcmp(L.first>elmt.puzzle[k][l].a, "5") == 0)||(strcmp(L.first->elmt.puzzle[k][l].a, "6") == 0)||(strcmp(L.first>elmt.puzzle[k][l].a, "7") == 0)))|| ((strcmp(L.first->elmt.puzzle[i][j].a, "7") == 0)&&((strcmp(L.first->elmt.puzzle[k][l].a, "1") == 0)||(strcmp(L.first>elmt.puzzle[k][l].a, "2") == 0)||(strcmp(L.first->elmt.puzzle[k][l].a, "3") == 0)||(strcmp(L.first>elmt.puzzle[k][l].a, "4") ==
0)||(strcmp(L.first->elmt.puzzle[k][l].a, "5") == 0)||(strcmp(L.first>elmt.puzzle[k][l].a, "6") == 0)))|| ((strcmp(L.first->elmt.puzzle[i][j].a, "6") == 0)&&((strcmp(L.first->elmt.puzzle[k][l].a, "1") == 0)||(strcmp(L.first>elmt.puzzle[k][l].a, "2") == 0)||(strcmp(L.first->elmt.puzzle[k][l].a, "3") == 0)||(strcmp(L.first>elmt.puzzle[k][l].a, "4") == 0)||(strcmp(L.first->elmt.puzzle[k][l].a, "5") == 0)))|| ((strcmp(L.first->elmt.puzzle[i][j].a, "5") == 0)&&((strcmp(L.first->elmt.puzzle[k][l].a, "1") == 0)||(strcmp(L.first>elmt.puzzle[k][l].a, "2") == 0)||(strcmp(L.first->elmt.puzzle[k][l].a, "3") == 0)||(strcmp(L.first>elmt.puzzle[k][l].a, "4") == 0)))|| ((strcmp(L.first->elmt.puzzle[i][j].a, "4") == 0)&&((strcmp(L.first->elmt.puzzle[k][l].a, "1") == 0)||(strcmp(L.first>elmt.puzzle[k][l].a, "2") == 0)||(strcmp(L.first->elmt.puzzle[k][l].a, "3") == 0)))|| ((strcmp(L.first->elmt.puzzle[i][j].a, "3") == 0)&&((strcmp(L.first->elmt.puzzle[k][l].a, "1") == 0)||(strcmp(L.first>elmt.puzzle[k][l].a, "2") == 0)))|| ((strcmp(L.first->elmt.puzzle[i][j].a, "2") == 0)&&((strcmp(L.first->elmt.puzzle[k][l].a, "1") == 0))))&& (((i == k)&&(j < l))||(i < k))) { hasil = hasil + 1; } } } } } hasil = hasil % 2; return hasil; } //--------------------------------------void hapusGoalState(list *L) { if((*L).first != NULL) { // Jika list tidak kosong. if(countElement(*L) == 1) { // List terdiri dari satu elemen. hapusInitialState(L); } else { // Mencari elemen terakhir list. elemen *last = (*L).first; elemen *before_last;
while(last->next != NULL) { // Iterasi. before_last = last; last = last->next; } before_last->next = NULL; free(last); } } } //--------------------------------------void goalState(list *L) { if((*L).first == NULL) { // Jika list adalah list kosong. initialState(L); } else { // Cara menentukan Goal State berdasarkan: http://www.8puzzle.com/8_puzzle_algorithm.htm l. elemen *elmt; elmt = (elemen *) malloc (sizeof(elemen)); if(menentukanGoalState(*L) == 0) { strcpy(elmt->elmt.puzzle[0][0].a, "1"); strcpy(elmt->elmt.puzzle[0][1].a, "2"); strcpy(elmt->elmt.puzzle[0][2].a, "3"); strcpy(elmt->elmt.puzzle[1][0].a, "4"); strcpy(elmt->elmt.puzzle[1][1].a, "5"); strcpy(elmt->elmt.puzzle[1][2].a, "6"); strcpy(elmt->elmt.puzzle[2][0].a, "7"); strcpy(elmt->elmt.puzzle[2][1].a, "8"); strcpy(elmt->elmt.puzzle[2][2].a, "0"); } else { strcpy(elmt->elmt.puzzle[0][0].a, "1"); strcpy(elmt->elmt.puzzle[0][1].a, "2"); strcpy(elmt->elmt.puzzle[0][2].a, "3"); strcpy(elmt->elmt.puzzle[1][0].a, "8"); strcpy(elmt->elmt.puzzle[1][1].a, "0"); strcpy(elmt->elmt.puzzle[1][2].a, "4"); strcpy(elmt->elmt.puzzle[2][0].a, "7"); strcpy(elmt->elmt.puzzle[2][1].a, "6"); strcpy(elmt->elmt.puzzle[2][2].a, "5"); } elmt->next = NULL; // Mencari elemen terakhir list. elemen *last = (*L).first; while(last->next != NULL) { // Iterasi. last = last->next; } last->next = elmt;
elmt = NULL; } } //--------------------------------------void heuristic(elemen *prec, list *L) { // Pencarian heuristic menggunakan Manhattan Distance. short tidakCocok = 0; elemen *last = (*L).first; // Proses mencari elemen terakhir. while(last->next != NULL) { // Proses dan Iterasi. last = last->next; } // Mencari nilai heuristic sebuah state terhadap Goal State. for(short i=0; i<3; i++) { for(short j=0; j<3; j++) { for(short k=0; k<3; k++) { for(short l=0; l<3; l++) { if((strcmp(prec->elmt.puzzle[i][j].a, last>elmt.puzzle[k][l].a) == 0)&&(strcmp(prec>elmt.puzzle[i][j].a, "0") != 0)) { tidakCocok = tidakCocok + abs(i-k) + abs(jl); } } } } } prec->elmt.tidakCocok = tidakCocok; } //--------------------------------------void hapusCurrentState(elemen *prec, list *L) { elemen *elmt = prec->next; prec->next = elmt->next; elmt->next = NULL; free(elmt); } //--------------------------------------void cekPuzzle(elemen *prec, list *L) { short kesamaan = 0; elemen *elmt = (*L).first; while(elmt != prec) { // Proses pengecekan apakah puzzle terbaru sama dengan puzzle-puzzle sebelumnya. for(short i=0; i<3; i++) { for(short j=0; j<3;j++)
{ if(strcmp(prec->elmt.puzzle[i][j].a, elmt>elmt.puzzle[i][j].a) == 0) { kesamaan = kesamaan + 1; } } } // Iterasi. if(kesamaan != 9) { kesamaan = 0; elmt = elmt->next; } // Terminasi. else { // Mencari puzzle terakhir sebelum puzzle terbaru. elemen *before_prec = (*L).first; while(before_prec->next != prec) { // Proses dan Iterasi. before_prec = before_prec->next; } // Menghapus puzzle terbaru apabila ternyata sama dengan puzzle-puzzle sebelumnya. hapusCurrentState(before_prec, L); elmt = prec; } } } //--------------------------------------void geserKanan(elemen *prec, short langkah, list *L) { elemen *elmt; elmt = (elemen *) malloc (sizeof (elemen)); for(short i=2; i>-1; i--) { for(short j=2; j>-1; j--) { if(((strcmp(prec->elmt.puzzle[i][j].a, "0")) == 0)&&(j != 2)) { strcpy(elmt->elmt.puzzle[i][j+1].a, prec>elmt.puzzle[i][j].a); strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i][j+1].a); } else { strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i][j].a); } } } strcpy(elmt->elmt.arahPenukaran, "kanan"); elmt->elmt.langkah = langkah;
// Proses mencari elemen kedua sebelum terakhir. elemen *before_last; while(prec->next != NULL) { // Proses. before_last = prec; // Iterasi. prec = prec->next; } elmt->next = before_last->next; before_last->next = elmt; elmt = NULL; heuristic(before_last->next, L); cekPuzzle(before_last->next, L); } //--------------------------------------void geserKiri(elemen *prec, short langkah, list *L) { elemen *elmt; elmt = (elemen *) malloc (sizeof (elemen)); for(short i=0; i<3; i++) { for(short j=0; j<3; j++) { if(((strcmp(prec->elmt.puzzle[i][j].a, "0")) == 0)&&(j != 0)) { strcpy(elmt->elmt.puzzle[i][j-1].a, prec>elmt.puzzle[i][j].a); strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i][j-1].a); } else { strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i][j].a); } } } strcpy(elmt->elmt.arahPenukaran, "kiri"); elmt->elmt.langkah = langkah; // Proses mencari elemen kedua sebelum terakhir. elemen *before_last; while(prec->next != NULL) { // Proses. before_last = prec; // Iterasi. prec = prec->next; } elmt->next = before_last->next; before_last->next = elmt; elmt = NULL; heuristic(before_last->next, L); cekPuzzle(before_last->next, L); }
//--------------------------------------void geserAtas(elemen *prec, short langkah, list *L) { elemen *elmt; elmt = (elemen *) malloc (sizeof (elemen)); for(short i=0; i<3; i++) { for(short j=0; j<3; j++) { if(((strcmp(prec->elmt.puzzle[i][j].a, "0")) == 0)&&(i != 0)) { strcpy(elmt->elmt.puzzle[i-1][j].a, prec>elmt.puzzle[i][j].a); strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i-1][j].a); } else { strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i][j].a); } } } strcpy(elmt->elmt.arahPenukaran, "atas"); elmt->elmt.langkah = langkah; // Proses mencari elemen kedua sebelum terakhir. elemen *before_last; while(prec->next != NULL) { // Proses. before_last = prec; // Iterasi. prec = prec->next; } elmt->next = before_last->next; before_last->next = elmt; elmt = NULL; heuristic(before_last->next, L); cekPuzzle(before_last->next, L); } //--------------------------------------void geserBawah(elemen *prec, short langkah, list *L) { elemen *elmt; elmt = (elemen *) malloc (sizeof (elemen)); for(short i=2; i>-1; i--) { for(short j=2; j>-1; j--) { if(((strcmp(prec->elmt.puzzle[i][j].a, "0")) == 0)&&(i != 2)) { strcpy(elmt->elmt.puzzle[i+1][j].a, prec>elmt.puzzle[i][j].a);
strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i+1][j].a); } else { strcpy(elmt->elmt.puzzle[i][j].a, prec>elmt.puzzle[i][j].a); } } } strcpy(elmt->elmt.arahPenukaran, "bawah"); elmt->elmt.langkah = langkah; // Proses mencari elemen kedua sebelum terakhir. elemen *before_last; while(prec->next != NULL) { // Proses. before_last = prec; // Iterasi. prec = prec->next; } elmt->next = before_last->next; before_last->next = elmt; elmt = NULL; heuristic(before_last->next, L); cekPuzzle(before_last->next, L); } //--------------------------------------void algoritmaPencarian(list L, short *langkah, elemen *(*prec)) { // Mencari elemen terakhir. elemen *last = L.first; while(last->next != NULL) { // Proses dan Iterasi. last = last->next; } // Mencari heuristik terbaik dari puzzle terbaru. elemen *elmt = (*prec)->next; elemen *tmle; // Jika puzzle terbaik tidak buntu. if(elmt != last) { tmle = elmt->next; while(tmle != last) { // Proses iterasi menjadikan puzzle yg heuristiknya terbaik menjadi puzzle terpilih. if(elmt->elmt.tidakCocok >= tmle>elmt.tidakCocok) { elmt = tmle; tmle = tmle->next; } else {
tmle = tmle->next; } } *prec = elmt; *langkah = (*prec)->elmt.langkah + 1; } // Jika puzzle terbaik buntu. else { // Jika setelah puzzle terbaik adalah elemen terakhir. if((*prec)->next == elmt) { // Mencari puzzle terkahir, sebelum puzzle terbaik. tmle = L.first->next; while(tmle->next != *prec) { // Iterasi. tmle = tmle->next; } // Jika puzzle terakhir, sebelum puzzle terbaik, nilai langkahnya tidak sama. if(tmle->elmt.langkah != (*prec)>elmt.langkah) { // Pencarian mundur ke belakang, sampai ditemukan puzzle dengan nilai langkahnya sama. while(tmle->elmt.langkah != (*prec)>elmt.langkah) { // Proses. hapusCurrentState(tmle, &L); elemen *gple = L.first; while(gple->next != tmle) { gple = gple->next; } // Iterasi. *prec = tmle; tmle = gple; } } // Jika puzzle terakhir, sebelum puzzle terbaik, nilai langkahnya sama. else { // Mengubah heuristik puzzle terakhir sebelum elemen terakhir, jadi heuristik puzzle terbaik. tmle->elmt.tidakCocok = (*prec)>elmt.tidakCocok; hapusCurrentState(tmle, &L); *prec = tmle; *langkah = (*prec)->elmt.langkah + 1; } }
// Jika setelah puzzle terbaik adalah bukan elemen terakhir. else { // Mencari puzzle terakhir sebelum elemen terakhir. (*prec)->next = tmle; while(tmle->next != elmt) { // Iterasi. tmle = tmle->next; } // Mengubah heuristik puzzle terakhir sebelum elemen terakhir, jadi heuristik puzzle terbaik. tmle->elmt.tidakCocok = (*prec)>elmt.tidakCocok; // Mencari puzzle sebelum puzzle terbaik. elemen *gple = L.first; while(gple->next != *prec) { // Iterasi. gple = gple->next; } hapusCurrentState(gple, &L); *prec = tmle; *langkah = (*prec)->elmt.langkah + 1; } } } //--------------------------------------void currentState(list *L) { elemen *prec = (*L).first; heuristic(prec, L); // Proses jika puzzle belum sama dengan Goal State. short langkah = 1; while(prec->elmt.tidakCocok != 0) { geserKiri(prec, langkah, L); for(short i=0; i<3; i++) { // Mencari elemen terakhir dan elemen sebelum terakhir. elemen *last = (*L).first; elemen *before_last; while(last->next != NULL) { // Proses. before_last = last; // Iterasi. last = last->next; } // Proses jika puzzle terbaru belum sama dengan Goal State. if(before_last->elmt.tidakCocok != 0) { switch(i)
{ case 0: geserAtas(prec, langkah, L); break; case 1: geserBawah(prec, langkah, L); break; case 2: geserKanan(prec, langkah, L); break; } } } // Iterasi proses jika puzzle belum sama dengan Goal State. algoritmaPencarian(*L, &langkah, &prec); } } //--------------------------------------void hapusSemuaState(list *L) { if(countElement(*L) != 0) { for(int i=countElement(*L); i>=1; i--) { // Proses menghapus elemen. hapusGoalState(L); } } } //--------------------------------------void tampilanPuzzle(elemen *prec) { printf(" +-----+-----+----+\n"); for(short i=0; i<3; i++) { printf(" | | | |\n"); printf(" |"); for(short j=0; j<3; j++) { printf(" %s |", prec->elmt.puzzle[i][j].a); } printf("\n | | | |\n"); printf(" +-----+-----+----+\n"); } FILE *f; f = fopen("8-Puzzle.txt", "a"); fprintf(f, "%s", " +-----+----+-----+\n"); for(short i=0; i<3; i++) { fprintf(f, "%s", " | | | |\n"); fprintf(f, "%s", " |"); for(short j=0; j<3; j++) { fprintf(f, " %s |", prec>elmt.puzzle[i][j].a); } fprintf(f, "%s", "\n | | | |\n");
fprintf(f, "%s", " +-----+----+-----+\n"); } fclose(f); } //--------------------------------------void printElement(list L) { // Jika list tidak kosong. if(L.first != NULL) { // Tampilan apabila ternyata Initial State sudah terurut. if(L.first->elmt.tidakCocok == 0) { printf(" 8-Puzzle sudah terurut\n"); printf("---------------------------------------------------------\n"); FILE *f; f = fopen("8-Puzzle.txt", "a"); fprintf(f, "%s", " 8-Puzzle sudah terurut\n"); fprintf(f, "%s", "---------------------------------------------------------\n" ); fclose(f); // Tampilan Initial State. tampilanPuzzle(L.first); } // Tampilan Initial State menuju Goal State. else { printf(" Proses mengurutkan 8Puzzle\n"); printf("---------------------------------------------------------\n"); FILE *f; f = fopen("8-Puzzle.txt", "a"); fprintf(f, "%s", " Proses mengurutkan 8-Puzzle\n"); fprintf(f, "%s", "---------------------------------------------------------\n" ); fclose(f); // Mencari elemen terakhir. elemen *last = L.first; elemen *before_last; while(last->next != NULL) { // Proses. before_last = last; // Iterasi. last = last->next; } // Menampilkan puzzle terbaik di tiap langkahnya. elemen *prec = L.first; while(prec != last) {
// Proses menampilkan puzzle terbaik di tiap langkahnya. // Mencari heuristik terbaik dari puzzle terbaru setiap langkahnya. elemen *elmt = prec->next; while(prec->elmt.langkah == elmt>elmt.langkah) { // Proses mencari heuristik terbaik dari puzzle terbaru setiap langkahnya. if(prec->elmt.tidakCocok >= elmt>elmt.tidakCocok) { prec = elmt; } // Iterasi mencari heuristik terbaik dari puzzle terbaru setiap langkahnya. elmt = elmt->next; } f = fopen("8-Puzzle.txt", "a"); if(prec == L.first) { printf(" 8-Puzzle belum terurut\n"); fprintf(f, "%s", " 8-Puzzle belum terurut\n"); } else { printf(" Langkah %d: geser 0 ke %s\n", prec->elmt.langkah, prec>elmt.arahPenukaran); fprintf(f, " Langkah %d: geser 0 ke %s\n", prec->elmt.langkah, prec>elmt.arahPenukaran); } fclose(f); tampilanPuzzle(prec); //printf(" Heuristik = %d\n", prec->elmt.tidakCocok); f = fopen("8-Puzzle.txt", "a"); //fprintf(f, " Heuristik = %d\n", prec->elmt.tidakCocok); if(prec != before_last) { printf("\n"); fprintf(f, "%s", "\n"); } else { printf(" 8-Puzzle sudah terurut!\n"); fprintf(f, " 8-Puzzle sudah terurut!\n"); } fclose(f); // Iterasi menampilkan puzzle Curren State terbaik di tiap langkahnya. prec = elmt;
} } } else { // Proses jika list kosong. printf("Maaf, 8-Puzzle tidak ada.\n"); FILE *f; f = fopen("8-Puzzle.txt", "a"); fprintf(f, "%s", "Maaf, 8-Puzzle tidak ada.\n"); fclose(f); } printf("===================================== =====================\n"); FILE *f; f = fopen("8-Puzzle.txt", "a"); fprintf(f, "============================================ =============="); fclose(f); } //--------------------------------------int main() { struct list L; createList(&L); initialState(&L); goalState(&L); currentState(&L); printElement(L); hapusSemuaState(&L); // Proses untuk mengakhiri program. printf("Tekan ENTER.. "); getchar(); getchar(); return 0; }
4. Langkah ketiga pengurutan 8-puzzle:
Lampiran 2 – Screenshot Program
Implementasi program 8 puzzle menggunakan algoritma heuristik dan hill climbing serta bahasa pemrograman yang dipakai adalah bahasa C. Berikut langkah-langkah program 8 puzzle : 1. Program menampilkan tampilan awal dimana user harus menginputkan angka sebanyak 9, mulai 0 -8 secara acak. 5. Langkah keempat pengurutan 8-puzzle:
Program menampilkan State awal 8-puzzle diinputkan angka pada langkah 1 diatas :
setelah
6. Langkah kelima pengurutan 8-puzzle:
7. Goal state 8-puzzle berhasil ditemukan pada langkah ke-5. 8-puzzle berhasil terurut. 2. Setelah menginputkan angka secara acak, program akan memproses pencarian sampai mencapai goal state. Program menampilkan mulai langkah awal sampai langkah akhir goal state dicapai. Langkah pertama pengurutan 8-pu zzle:
3. Langkah kedua pengurutan 8-puzzle:
Dari jalannya implementasi program dapat dilihat bahwa user harus menginputkan angka secara acak sebanyak 9 buah angka. Angka yang dapat diinputkan mulai angka 08. Kemudian program akan memproses pengurutan 8-puzzle dengan beberapa langkah tergantung inputan angka yang diinputkan. Setelah program 8-puzzle telah terurut program akan menampilkan langkah-langkah pengurutan 8-puzzle sampai mencapai goal state.