IMPLEMENTASI ALGORITMA A STAR (A*) PADA GAME PUZZLE-8
Diajukan Untuk Memenuhi Tugas Mata Kuliah Kecerdasan Buatan
Mochammad Mahessa Lazuardy Dede Juniawan S.
10111454 10112664
AI - 5
PROGRAM STUDI TEKNIK INFORMATIKA FAKULTAS TEKNIK DAN ILMU KOMPUTER UNIVERSITAS KOMPUTER INDONESIA 2015
KATA PENGANTAR
Puji syukur penyusun panjatkan ke hadirat Allah SWT, karena berkat rahmat-Nya kami bisa menyelesaikan makalah yang berjudul “Implementasi Algoritma A Star (A*) pada Game Puzzle-8” Puzzle- 8”.. Kami mengucapkan terima kasih kepada semua pihak yang telah membantu sehingga makalah ini dapat diselesaikan tepat pada waktunya. Makalah ini masih jauh dari sempurna, oleh karena itu, kritik dan saran yang bersifat membangun sangat kami harapkan demi sempurnanya makalah ini. Semoga makalah ini memberikan informasi dan bermanfaat untuk pengembangan wawasan dan peningkatan peningkatan ilmu pengetahuan bagi kita.
Bandung, November 2015
Penyusun
DAFTAR ISI
KATA PENGANTAR ......................................................................................................... i DAFTAR ISI ........................................................................................................................ i BAB I .................................................................................................................................. ii PENDAHULUAN .............................................................................................................. ii 1.1
Latar Belakang..................................................................................................... ii
1.2
Rumusan Masalah .............................................................................................. iii
1.3
Tujuan Penulisan ................................................................................................ iii
BAB II ................................................................................................................................. 1 PENGENALAN SISTEM .................................................................................................. 1 2.1
Representasi Data Masukan ............................................................................... 2
2.2
Mekanisme Sistem .............................................................................................. 3
2.3
Representasi Ouput Sistem................................................................................. 4
BAB III ............................................................................................................................... 5 ANALISIS DAN IMPLEMENTASI SISTEM ................................................................... 5 3.1
Analisis ................................................................................................................ 5
3.2
Implementasi ...................................................................................................... 6
BAB IV ............................................................................................................................. 17 PENUTUP ........................................................................................................................ 17 4.1.
Simpulan ........................................................................................................... 17
4.2.
Saran ................................................................................................................. 17
DAFTAR PUSTAKA ....................................................................................................... 18 LAMPIRAN ...................................................................................................................... 19
i
BAB I
PENDAHULUAN 1.1 Latar Belakang
Puzzle-8 adalah representasi permainan teka-teki yang dapat diselesaikan dengan mengurutkan atau menyusun komponen-komponen pembentuknya sesuai dengan kondisi yang berurut. Komponen pada Puzzle-8 adalah berupa kotak-kotak bernomor yang dapat diacak sedemikian hingga menjadi suatu pola random yang dapat dicari jalan penyelesaiannya .
Sesuai namanya,
Puzzle-8 terdiri atas 8 kotak dan 1 tempat kosong yang dapat digerakkan dengan aturan tertentu. Aturan pergerakannya hanya berupa empat arah pergerakan, yaitu atas, bawah, kanan, dan kiri. Pada Puzzle-8, batasannya adalah ukuran 3×3. Sehingga, 8 kotak yang dimiliki hanya dapat bergerak dalam lingkup ukuran tersebut. Aplikasi permainan merupakan salah satu implementasi dari ilmu di bidang komputer. Inti dari sebuah aplikasi permainan adalah mengembangkan kemampuan otak untuk mengatur strategi, kecepatan, dan ketepatan dalam mencapai tujuan akhir. Salah satu contoh permainan adalah puzzle. Puzzle terdiri dari beberapa jenis, ada yang menggunakan angka, huruf, dan gambar. Dalam permainan puzzle, pemain diharapkan dapat mencapai tujuan akhir untuk membentuk sebuah puzzle menjadi sebuah gambar atau pola yang benar dengan waktu yang cepat. Algoritma A Star adalah algoritma pencarian graf yang menemukan jalur dari status awal ke status akhir. Algoritma ini menggunakan fungsi heuristic (biasanya didenotasikan dengan A*) untuk menentukan urutan dimana pencarian
dilakukan
dengan
mengunjungi
node
dalam
pohon.
merepresentasikan biaya jalan yang paling efisien sampai ke tujuan. Fungsi heuristic yang digunakan Algoritma A Star untuk memecahkan kasus bervariasi tergantung dari kasus yang akan dihadapi, misal untuk memecahkan kasus pencarian jalur terpendek dari satu ke kota lain menggunakan fungsi ii
heuristic distance plus cost sedang untuk memecahkan kasus Puzzle-8, maka digunakan fungsi heuristic city block distance atau sering juga disebut dengan istilah manhattan distance. Dalam program Puzzle-8 ini, Initial state di tentukan secara acak, dan dengan Final state yang sudah ditentukan. Untuk memenangkan permainan, pemain harus mencapai Final state yang sudah ditentukan sebelumnya, selain itu program juga akan memberikan solusi yang tepat dan cepat untuk menyelesaikan Puzzle-8 jika pemain menginginkannya. 1.2 Rumusan Masalah
Menganalisis, memodelkan, serta mengimplementasikan algoritma A Star sebagai problem solving pada kasus game Puzzle-8. 1.3 Tujuan Penulisan
Mengetahui cara memodelkan dan mengimplementasikan algoritma A Star pada kasus puzzle.
iii
BAB II
PENGENALAN SISTEM
Algoritma A Star merupakan salah satu algoritma yang menggunakan fungsi biaya. Algoritma A Star memeriksa kelayakan biaya yang diperlukan untuk mencapai suatu simpul dari sebuah simpul lain. Dalam kasus puzzle 8 ini, algoritma A Star membandingkan 2 posisi puzzle yaitu posisi puzzleawal (state awal) dengan posisi puzzle yang terurut dengan benar (state akhir). Berikut ini adalah algoritma A Star secara umum.
1
2.1 Representasi Data Masukan Pada kasus puzzle ini diperlukan data masukkan berupa array 2 dimensi
(matriks) yang telah diinisialisasi. private int[][] tileMatrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; Kemudian bilangan yang ada pada matriks tersebut aka diacak posisinya menggunakan
method
random
yang
telah
disediakan
oleh
bahasa
pemrograman java. Selain itu, diperlukan juga konstanta berupa array 2 dimensi yang berfungsi membandingkan kesesuaian posisi array yang telah diacak. private int[][] FinalState = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
2
Selain data masukan tersebut, Algoritma A* menggunakan dua senarai yaitu OPEN dan CLOSED. OPEN adalah senarai (list) yang digunakan untuk menyimpan simpul-simpul yang pernah dibangkitkan dan nilai heuristiknya telah dihitung tetapi belum terpilih sebagai simpul terbaik (smallest node) biasa juga disebut dengan istilah best node, dengan kata lain OPEN berisi simpul-simpul masih memiliki peluang untuk terpilih sebagai simpul terbaik, sedangkan CLOSED adalah senarai untuk menyimpan simpul-simpul yang sudah pernah dibangkitkan dan sudah pernah terpilih sebagai simpul terbaik. Artinya, CLOSED berisi simpul-simpul yang tidak mungkin terpilih sebagai simpul terbaik (peluang untuk terpilih sudah tertutup). 2.2 Mekanisme Sistem Berikut ini adalah gambaran sederhana mengenai arsitektur sistem yang
dibuat. Dimana link list, list node, dan node merupakan struktur data yang dibutuhkan oleh algoritma A Star. Kemudian di algoritma A Star difungsikan untuk menentukan langkah yang diambil dalam permainan ini (problem solving).
Berikut ini adalah mekanisme sistem yang dibuat secara umum yang disajikan dalam bentuk flowchart.
3
2.3 Representasi Ouput Sistem Output yang dihasilkan oleh system berupa array dua dimensi yang telah
tersusun yaitu {{ 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }.
4
BAB III
ANALISIS DAN IMPLEMENTASI SISTEM 3.1 Analisis Algoritma A Star merupakan salah satu algoritma yang menggunakan
fungsi biaya (cost). Algoritma A Star memeriksa kelayakan biaya yang diperlukan untuk mencapai suatu simpul dari sebuah simpul lain. Dalam kasus Puzzle-8 ini, algoritma A Star membandingkan 2 posisi puzzle yaitu posisi puzzle awal (state awal) dengan posisi puzzle yang terurut dengan benar (state akhir). Rumus yang digunakan oleh algoritma A Star yaitu: f(n) = g(n) + h(n) dengan: g(n) = Jumlah pergerakan untuk mencapai final state h(n) = Jumlah total gerakan vertikal dan horizontal yang diperlukan setiap kotak pada state-n untuk mencapai final state. Contoh penentuan heuristic: 1
2
3
4
5
6
7
B
8
Nilai heuristic susunan diatas yaitu h(n)= 2 karena kotak-8 dan kotak kotak-B (blank) membutuhkan satu kali pergerakan untuk mencapai final state. Berikut ini adalah ilustrasi penyelesaian game Puzzle-8 menggunakan algoritma A*.
5
3.2 Implementasi
Inisialisasi variabel yang berkaitan
public class Node { // deklarasi 9 kotak ke dalam node // state private int[][] state = new int[3][3]; private int h; // deklarasi fungsi heuristic Manhattan private int g; private int id;
6
private int parentID; private int emptyX; private int emptyY; public Node() { g = -1; id = -1; parentID = -1; }
// instansiasi node baru. public Node( int g, int[][] state, int id, int parentID) { this.g = g; setState(state); this.id = id; this.parentID = parentID;
} // mengcopy semua variabel fungsi public void copyAll(Node n) { setState(n.getState()); h = n.getH(); g = n.getG(); id = n.id; parentID = n.getParentID(); emptyX = n.getEmptyX(); emptyY = n.getEmptyY(); } public int[][] getState() { return state; } public void setState( int[][] state) { for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) this.state[i][j] = state[i][j]; calculateXY(); calculateH(); }
// menghitung xy public void calculateXY() { for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) if (state[i][j] == 9) { emptyX = i; emptyY = j; break; } } public int getID() {
7
return id;
} public int getParentID() { return parentID; } public int getG() { return g; } public int getH() { return h; } public int getEmptyX() { return emptyX; } public int getEmptyY() { return emptyY; } public int getF() { return g + h; }
// menghitung h public void calculateH() { int tempH = 0; int FinalStateX = 0, FinalStateY = 0; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { switch (state[i][j]) { case 1: FinalStateX = 0; FinalStateY = 0; break; case 2: FinalStateX = 0; FinalStateY = 1; break; case 3: FinalStateX = 0; FinalStateY = 2; break; case 4: FinalStateX = 1; FinalStateY = 0; break; case 5: FinalStateX = 1; FinalStateY = 1; break; 6: case FinalStateX = 1;
8
FinalStateY = 2; break; case 7: FinalStateX = 2; FinalStateY = 0; break; case 8: FinalStateX = 2; FinalStateY = 1; break; 9: case FinalStateX = 2; FinalStateY = 2; break; } tempH += Math. abs(FinalStateX - i) + Math.abs(FinalStateY - j); } this.h = tempH;
} } public class ListNode {
// node private Node node; // node berikutnya public ListNode nextNode; // node sebelumnya public ListNode previousNode ; // list node baru public ListNode() { node = new Node(); } // list node baru public ListNode(Node node) { this(node, null, null); } // list node baru public ListNode(Node node, ListNode previous, ListNode next) { this.node = node; previousNode = previous; nextNode = next;
} public Node getNode() { return node; } public ListNode getNext() {
9
return nextNode;
} public ListNode getPrevious() { return previousNode ; }
}
public class LinkList {
// node pertama private ListNode firstNode; // node terakhir private ListNode lastNode; public LinkList() { firstNode = lastNode = null; } public void insertAtBack(Node node) { if (isEmpty()) firstNode = lastNode = new ListNode(node); else { ListNode newNode = new ListNode(node); lastNode.nextNode = newNode; newNode.previousNode = lastNode; lastNode = newNode; } } public void insertAtFront(Node node) { if (isEmpty()) firstNode = lastNode = new ListNode(node); else { ListNode newNode = new ListNode(node); newNode.nextNode = firstNode; firstNode.previousNode = newNode; firstNode = newNode; } } public Node getSmallestNode() {
Node minimumNode = firstNode.getNode(); ListNode current = firstNode.getNext(); while (current != null) { if (current.getNode().getF() < minimumNode.getF()) minimumNode = current.getNode(); current = current.getNext(); } return minimumNode;
} public void removeNode(Node node) {
10
if (isEmpty()) return; else if (isSameState(node, firstNode.getNode()) && firstNode == lastNode) { firstNode = lastNode = null; return; } else if (isSameState(node, firstNode.getNode())) { firstNode = firstNode.getNext(); firstNode.previousNode = null; return; } else if (isSameState(node, lastNode.getNode())) { lastNode = lastNode.getPrevious(); lastNode.nextNode = null; } else { ListNode current = firstNode; while (current.getNext() != null) { if (isSameState(current.getNext().getNode(), node)) { current.nextNode.nextNode.previousNode = current; current.nextNode = current.getNext().getNext(); return; // break } else current = current.nextNode; } } }
// cek apakah kosong public boolean isEmpty() { return firstNode == null; } // cek apakah isi public boolean alreadyExists(Node node) { if (!isEmpty()) { ListNode current = firstNode; while (current != null) { if (isSameState(current.getNode(), node)) return true; else current = current.getNext(); } return false; } return false; } // cek apakah state sama public boolean isSameState(Node A, Node B) { int[][] stateA = A.getState(); int[][] stateB = B.getState();
11
for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) if (stateA[i][j] != stateB[i][j]) return false; return true;
} public ListNode getLastNode() { return lastNode; } public ListNode getFirstNode() { return firstNode; }
// set list yang kosong public void setEmptyList() { firstNode = lastNode = null; } }
Skema pengkodean
public void solvepuzzle() { System.gc(); openList.setEmptyList(); finalState.setEmptyList(); closeList.setEmptyList(); idCount = 0; startNode = new Node(0, tileMatrix, idCount, -1);
openList.insertAtBack(startNode); while (!openList.isEmpty()) { smallestNode = openList.getSmallestNode(); // Final state muncul if (isSameState(smallestNode.getState(), FinalState)) { closeList.insertAtBack(smallestNode); break; } else { // Final state not reached yet and needs further search{ openList.removeNode(smallestNode); closeList.insertAtBack(smallestNode);
// case 0 if (smallestNode.getEmptyX() == 0 && smallestNode.getEmptyY() == 0) { branchNode = blankRight(smallestNode); checkBranchNodeInLists(); branchNode = blankDown(smallestNode); checkBranchNodeInLists();
12
} // case 1 else if (smallestNode.getEmptyX() == 0 && smallestNode.getEmptyY() == 1) { branchNode = blankLeft(smallestNode); checkBranchNodeInLists(); branchNode = blankDown(smallestNode); checkBranchNodeInLists(); branchNode = blankRight(smallestNode); checkBranchNodeInLists(); } // case 2 else if (smallestNode.getEmptyX() == 0 && smallestNode.getEmptyY() == 2) { branchNode = blankLeft(smallestNode); checkBranchNodeInLists(); branchNode = blankDown(smallestNode); checkBranchNodeInLists(); } // case 3 else if (smallestNode.getEmptyX() == 1 && smallestNode.getEmptyY() == 0) { branchNode = blankUp(smallestNode); checkBranchNodeInLists(); branchNode = blankRight(smallestNode); checkBranchNodeInLists(); branchNode = blankDown(smallestNode); checkBranchNodeInLists(); } // case 4 else if (smallestNode.getEmptyX() == 1 && smallestNode.getEmptyY() == 1) { branchNode = blankUp(smallestNode); checkBranchNodeInLists(); branchNode = blankRight(smallestNode); checkBranchNodeInLists(); branchNode = blankDown(smallestNode); checkBranchNodeInLists(); branchNode = blankLeft(smallestNode); checkBranchNodeInLists(); } // case 5 else if (smallestNode.getEmptyX() == 1 && smallestNode.getEmptyY() == 2) { branchNode = blankUp(smallestNode); checkBranchNodeInLists(); branchNode = blankLeft(smallestNode); checkBranchNodeInLists(); branchNode = blankDown(smallestNode);
13
checkBranchNodeInLists(); } // case 6 else if (smallestNode.getEmptyX() == 2 && smallestNode.getEmptyY() == 0) { branchNode = blankUp(smallestNode); checkBranchNodeInLists(); branchNode = blankRight(smallestNode); checkBranchNodeInLists(); } // case 7 else if (smallestNode.getEmptyX() == 2 && smallestNode.getEmptyY() == 1) { branchNode = blankLeft(smallestNode); checkBranchNodeInLists(); branchNode = blankUp(smallestNode); checkBranchNodeInLists(); branchNode = blankRight(smallestNode); checkBranchNodeInLists(); } // case 8 else if (smallestNode.getEmptyX() == 2 && smallestNode.getEmptyY() == 2) { branchNode = blankUp(smallestNode); checkBranchNodeInLists(); branchNode = blankLeft(smallestNode); checkBranchNodeInLists(); } } } backTrackNodes(); currentListNode = finalState.getFirstNode(); timer1.start(); resetTilesMatrix(); }
Meghitung nilai h(n)
public void calculateH() { int tempH = 0; int FinalStateX = 0, FinalStateY = 0; for (int i = 0; i < 3; i++) for (int j = 0; j < 3; j++) { switch (state[i][j]) { case 1: FinalStateX = 0; FinalStateY = 0; break; case 2:
14
FinalStateX = 0; FinalStateY = 1; break; case 3: FinalStateX = 0; FinalStateY = 2; break; case 4: FinalStateX = 1; FinalStateY = 0; break; case 5: FinalStateX = 1; FinalStateY = 1; break; case 6: FinalStateX = 1; FinalStateY = 2; break; case 7: FinalStateX = 2; FinalStateY = 0; break; case 8: FinalStateX = 2; FinalStateY = 1; break; case 9: FinalStateX = 2; FinalStateY = 2; break; } tempH += Math. abs(FinalStateX - i) + Math.abs(FinalStateY - j); } this.h = tempH;
}
Mendapatkan nilai g(n)
public Node(int g, int[][] state, int id, int parentID) { this.g = g; setState(state); this.id = id; this.parentID = parentID;
}
15
Menghitung nilai f(n) public int getF() { return g + h;
}
16
BAB IV
PENUTUP 4.1.Simpulan
Algoritma A Star menghasilkan output yang baik karena algoritma tersebut pada game puzzle ini khusunya, memilih langkah perpindahan state berdasarkan cost sehingga pertimbangannya cukup baik. Dalam kondisi state yang
acak
dan
rumit
serta
memiliki
banyak
kemungkinan
solusi
memungkinkan algoritma A* cocok untuk mencari solusi yang terbaik. Setiap pergerakan yang dilakukan pada kotak statusnya akan disimpan pada suatu list.List ini akan digunakan untuk melakukan pengecekan apakah kita sudah pernah membangun status tersebut atau belum agar kita tidak menggerakkan kotak yang sama berkali-kali ke status yang sama. Dengan menerapkan strategi ini, selain menemukan solusi, algoritma ini juga bisa menemukan langkah terpendek untuk mencapai solusi tersebut. 4.2.Saran
Beberapa
saran
yang
dapat
diberikan
untuk
membantu
dalam
pengembangan aplikasi ini lebih lanjut yaitu game dapat disajikan dalam bentuk gambar. Selain itu, apabila makalah ini dijadika referensi penerapan A Star dalam kasus lain, diperlukan analisis dan perancangan ulang karena akan berbeda parameter cost -nya.
17
DAFTAR PUSTAKA
[1] Wennyi, Jayner . “Artificial Intelligence - A Star “. 8 November 2015. http://www.slideshare.net/jaylovejesusnwannabemusician/artificialintelligence-a-star [2] Bendi, K. Jawa “.Penerapan Algoritma A* Pada Aplikasi Puzzle”. 8 November 2015. https://www.academia.edu/5795061/Penerapan_Algoritma_A_Pada_Aplikasi _Puzzle [3] Taufiq, Andik. “8-Puzzle Problem (Bagian 2)”. 10 November 2015. https://andiktaufiq.wordpress.com/2010/05/02/8-puzzle-problem-bagian-2/ [4] Handayani Ritongga, Fitri. “Variasi Algoritma A*”. 8 November 2015. http://fitrihandayani.blog.upi.edu/variasi-algoritma-a/
18
LAMPIRAN
1. Screenshoot antar muka
2. Screenshoot proses
3. Screenshoot hasil
19