Menyelesaikan Puzzle Sudoku dengan Algoritma Brute-Force dan Runut-Balik

dokumen-dokumen yang mirip
ANTIMAGIC PUZZLE. Alwi Afiansyah Ramdan

Aplikasi Algoritma Runut Balik dalam Pembangkitan Elemen Awal Permainan Sudoku

Oleh Lukman Hariadi

Penerapan Algoritma Runut-Balik untuk Menyelesaikan Permainan Pencarian Kata

SOLUSI PERMAINAN CHEMICALS DENGAN ALGORITMA RUNUT BALIK

Perbandingan Algoritma Brute Force dan Backtracking dalam Permainan Word Search Puzzle

Penerapan Algoritma Runut-balik pada Permainan Math Maze

SOLUSI ALGORITMA BACKTRACKING DALAM PERMAINAN KSATRIA MENYEBRANG KASTIL

Penerapan Algoritma Backtrack pada Knight s Tour

Penerapan Algoritma Runut-Balik (Backtracking) pada Permainan Nurikabe

Penyelesaian Permainan 3 missionaries and 3 cannibals Dengan Algoritma Runut-Balik

Penerapan Algoritma Backtracking pada Game The Lonely Knight

Penyelesaian Game Lights Out dengan Algoritma Runut Balik

Penerapan Algoritma DFS pada Permainan Sudoku dengan Backtracking

Penerapan Algoritma Backtracking pada Knight s Tour Problem

Aplikasi Algoritma Brute Force dan Backtracking pada Permainan Slitherlink

Analisis Penerapan Algoritma Backtracking Pada Pencarian Jalan Keluar di Dalam Labirin

Pencarian Solusi Permainan Fig-Jig Menggunakan Algoritma Runut-Balik

Aplikasi Algoritma Runut-balik pada Penyelesaian Teka Teki Mengisi Angka

PENERAPAN ALGORITMA RUNUT BALIK DALAM PERMAINAN TEKA-TEKI SILANG

Pencarian Solusi Permainan Pipe Puzzle Menggunakan Algoritma Backtrack

PENERAPAN ALGORITMA BACKTRACKING PADA PERMAINAN WORD SEARCH PUZZLE

PERMAINAN KNIGHT S TOUR DENGAN ALGORITMA BACKTRACKING DAN ATURAN WARNSDORFF

ALGORITMA RUNUT-BALIK UNTUK MENGGANTIKAN ALGORITMA BRUTE FORCE DALAM PERSOALAN N-RATU

Penerapan Algoritma Backtracking untuk Menyelesaikan Permainan Hashiwokakero

Penerapan Algoritma Runut-Balik pada Magic Square

MAKALAH STRATEGI ALGORITMIK (IF 2251) ALGORITMA RUNUT BALIK DALAM GAME LABIRIN

ALGORITMA RUNUT BALIK DALAM PENYELESAIAN PERMAINAN WORD DIAGRAM

Penerapan Algoritma Runut-Balik untuk Menyelesaikan Zebra Puzzle

ALGORITMA RUNUT-BALIK (BACKTRACKING ALGORITHM) PADA MASALAH KNIGHT S TOUR

Penggabungan Algoritma Brute Force dan Backtracking dalam Travelling Thief Problem

PENERAPAN ALGORITMA RUNUT-BALIK (BACKTRACKING) DALAM PENYELESAIAN PERMAINAN SUDOKU

Implementasi Algoritma Runut Balik dalam Pengenalan Citra Wajah pada Basis Data

Pencarian Solusi Permainan Flow Free Menggunakan Brute Force dan Pruning

PENGUNAAN DUA VERSI ALGORITMA BACKTRACK DALAM MENCARI SOLUSI PERMAINAN SUDOKU

Penggunaan Algoritma Backtrack dan Aturan Warnsdorff Untuk Menyelesaikan Knight s Tour Problem

Algoritma Runut-balik (Backtracking) Bahan Kuliah IF2251 Strategi Algoritmik Oleh: Rinaldi Munir

Strategi Algoritma Penyelesaian Puzzle Hanjie

I. PENDAHULUAN II. DASAR TEORI. Contoh lainnya: Solusi: 0= V,1= I,2= O,3= R, 4= N,5= L,7= A,8= F,9= E.

Algoritma Backtracking Pada Logic Game : Family Crisis (Game Penyebrangan)

Penerapan Algoritma Backtracking dalam Permainan Futoshiki Puzzle

Pemanfaatan Algoritma Runut-Balik dalam Menyelesaikan Puzzle NeurOn dalam Permainan Logical Cell

Penerapan Algoritma Greedy dan Backtrackng Dalam Penyelesaian Masalah Rubik s Cube

Algoritma Runut-balik (Backtracking) Bagian 1

Penerapan Algoritma Brute-Force serta Backtracking dalam Penyelesaian Cryptarithmetic

Penerapan Algoritma Brute Force di Permainan Nonogram

Implementasi Algoritma Backtracking untuk Memecahkan Puzzle The Tile Trial pada Permainan Final Fantasy XIII-2

Penerapan Algoritma Backtracking pada Pencarian Solusi Fill-in Crossnumber

Penerapan Algoritma DFS dan BFS untuk Permainan Wordsearch Puzzle

Penerapan Algoritma Brute Force dan Backtracking pada Permainan Skycraper

Perbandingan Algoritma Brute Force dan Breadth First Search dalam Permainan Onet

Pendeteksian Deadlock dengan Algoritma Runut-balik

Algoritma Backtracking Pada Permainan Peg Solitaire

Perbandingan Algoritma Depth-First Search dan Algoritma Hunt-and-Kill dalam Pembuatan Labirin

Algoritma Runut-balik (Backtracking)

AlgoritmaBrute Force. Desain dan Analisis Algoritma (CS3024)

Implementasi Algoritma DFS pada Pewarnaan Gambar Sederhana Menggunakan Bucket tool

PENYELESAIAN TEKA-TEKI PENYUSUNAN ANGKA MENGGUNAKAN ALGORITMA RUNUT BALIK

Menyelesaikan Permainan Wordament Menggunakan Algoritma Backtracking

BAB I PENDAHULUAN. 1.1 Latar Belakang Masalah

Penyelesaian Permasalahan Nonogram dengan Algoritma Runut Balik

Penerapan Algoritma Brute Force pada Teka-teki Magic Square 3 x 3

Memecahkan Puzzle Hidato dengan Algoritma Branch and Bound

Penggunaan Algoritma Backtracking pada Permainan Mummy Maze

Penerapan Algoritma Branch & Bound dan Backtracking pada Game Flow

Penerapan Pohon dengan Algoritma Branch and Bound dalam Menyelesaikan N-Queen Problem

UNTUK PEMECAHAN MASALAH PADA PERMAINAN HASHIWOKAKERO

Penggunaan Algoritma Backtracking Untuk Menentukan Keisomorfikan Graf

Penerapan strategi BFS untuk menyelesaikan permainan Unblock Me beserta perbandingannya dengan DFS dan Branch and Bound

Algoritma Brute Force

Penggunaan Strategi Algoritma Backtracking pada Pencarian Solusi Puzzle Pentomino

Strategi Optimized Brute Force Pada Tent Puzzle Solver

Perbandingan Algoritma Greedy & Bactracking Dalam Penyelesaian Permainan 2048

PENCARIAN SOLUSI TTS ANGKA DENGAN ALGORITMA RUNUT BALIK BESERTA PENGEMBANGANNYA

Penerapan Strategi Algoritma Menyelesaikan Kompleksitas Pixel Maze secara Otomatis pada Virupizxel

Pembentukan Pohon Pencarian Solusi dalam Persoalan N-Ratu (The N-Queens Problem)

Penerapan Algoritma Backtracking pada Pewarnaan Graf

Pemanfaatan Pohon dalam Realisasi Algoritma Backtracking untuk Memecahkan N-Queens Problem

ANALISIS PENYELESAIAN PUZZLE SUDOKU DENGAN MENERAPKAN ALGORITMA BACKTRACKING ABSTRAK

Analisis Beberapa Algoritma dalam Menyelesaikan Pencarian Jalan Terpendek

Pemanfaatan Algoritma Runut-balik dalam Penentuan Golongan Suara pada Dunia Paduan Suara

ANALISIS PENERAPAN ALGORITMA RUNUT-BALIK DALAM PENCARIAN SOLUSI PERSOALAN LOMPATAN KUDA

Penyelesaian Permainan Pacman yang disederhanakan dengan Algoritma Backtracking

Penentuan Keputusan dalam Permainan Gomoku dengan Program Dinamis dan Algoritma Greedy

IMPLEMENTASI BACKTRACKING ALGORITHM UNTUK PENYELESAIAN PERMAINAN SU DOKU POLA 9X9

Penggunaan Algoritma Runut-Balik dalam Proses Resolusi Query dari Eksekusi Program dalam Bahasa Prolog

Penerapan Algoritma DFS dalam Menyelesaikan Permainan Buttons & Scissors

PENGGUNAAN ALGORITMA BACKTRACKING DALAM PENYELESAIAN PERMAINAN SUDOKU

ANALISIS PENYELESAIAN PUZZLE SUDOKU DENGAN MENERAPKAN ALGORITMA BACKTRACKING MEMANFAATKAN BAHASA PEMROGRAMAN VISUAL BASIC 6.0

PENERAPAN ALGORITMA RUNUT-BALIK DALAM PENCARIAN SOLUSI TEKA-TEKI BATTLESHIP

Penerapan Algoritma Brute Force dalam mencari Faktor Prima pada suatu Bilangan

PEMBANGKIT TEKA-TEKI SILANG DENGAN ALGORITMA BACKTRACKING SERTA APLIKASI PERMAINANNYA YANG BERBASIS WEB

Algoritma Brute Force (Bagian 1) Oleh: Rinaldi Munir

Penerapan Teori Graf untuk Menyelesaikan Teka-Teki Permainan The Knight's Tour

PENGGUNAAN ALGORITMA BRUTE FORCE DALAM PERMAINAN PERMAINAN THE LEGEND OF DRUNKEN MAN

Pembuatan Musik Tanpa Pola Dengan Menggunakan Algoritma Runut Balik

PERBANDINGAN APLIKASI ALGORITMA BRUTE-FORCE DAN KOMBINASI ALGORITMA BREADTH FIRST SEARCH DAN GREEDY DALAM PENCARIAN SOLUSI PERMAINAN TREASURE HUNT

Algoritma Brute Force pada Fluid Particle Engine

Penggunaan Algoritma DFS dan BFS pada Permainan Three Piles of Stones

Penerapan DFS dan BFS dalam Pencarian Solusi Game Japanese River IQ Test

Transkripsi:

Menyelesaikan Puzzle Sudoku dengan Algoritma Brute-Force dan Runut-Balik Ahmad Naufal Hakim 13517055 Program Studi Teknik Informatika Sekolah Teknik Elektro dan Informatika Institut Teknologi Bandung, Jl. Ganesha 10 Bandung 40132, Indonesia ahmadnaufalhakim@gmail.com Abstrak Sudoku adalah permainan teka-teki dengan tujuan menyusun angka dari satu sampai sembilan pada grid yang terdiri atas 9x9 kotak. Aturan dari permainan ini adalah penyusunan angka-angka pada board tidak boleh ada yang sama dalam setiap baris, kolom, dan 3x3 kotak yang berada di dalam grid. Pada awal permainan, sudah terdapat beberapa angka yang berguna sebagai clue bagi pemain agar bisa mengisi kotak-kotak selanjutnya. Tingkat kesulitan permainan ini ditentukan oleh banyaknya clue yang ada pada awal permainan. Semakin sedikit clue yang tersedia, maka Sudoku akan semakin susah untuk diselesaikan. Pada makalah ini, akan dibahas terkait cara menyelesaikan Sudoku dengan menggunakan algoritma Backtracking, serta waktu penyelesaian yang dibutuhkan untuk menyelesaikan Sudoku. Kata kunci Sudoku, Brute-force, DFS, Backtracking. I. PENDAHULUAN Sudoku adalah sebuah permainan teka-teki yang terdiri atas sebuah grid yang berisi 81 kotak yang tersusun dalam 9 baris dan 9 kolom. Pada grid Sudoku itu sendiri, terdapat subgrid yang berukuran 3x3. Dalam permainan Sudoku, pemain diminta untuk mengisi setiap kotak di dalamnya dengan satu angka, yaitu angka 1 sampai 9, sehingga pada setiap kotak memiliki angka yang unik untuk masing-masing baris, kolom, dan subgrid pada board. Tingkat kesulitan permainan Sudoku diukur dari banyaknya clue yang terdapat pada grid pada awal permainan. Semakin sedikit clue yang ada pada grid, maka Sudoku akan semakin susah untuk diselesaikan. Permainan Sudoku diciptakan pada tahun 1970-an oleh Howard Garns. Permainan ini dipopulerkan oleh majalah yang diterbitkan di Jepang pada tahun 1984. Kemudian pada tahun 1997, sudah banyak puzzle Sudoku yang ditemukan pada toko buku Jepang. Beberapa tahun kemudian, Wayne Gould, seorang pensiunan hakim dari Hong Kong yang berasal dari Selandia Baru mengembangkan permainan Sudoku menjadi program komputer. Permainan ini sangat populer di Jepang dan meluas hingga ke seluruh dunia. Menyelesaikan Sudoku adalah salah satu contoh dari masalah NP- Complete yang ada. Artinya belum ada algoritma yang mampu menyelesaikan permasalahan tersebut dengan waktu yang konsisten. Secara keseluruhan, ada sebanyak 6.670.903.752.021.072.936.960 kemungkinan grid Sudoku berukuran 9x9 yang dapat dibuat. Apabila menggunakan pendekatan dengan algoritma brute-force saja tentu tidak efisien, karena algoritma brute-force akan mengenumerasi segala kemungkinan grid yang ada dan mengecek seluruh kemungkinan grid tersebut, sehingga algoritma tersebut tidak mangkus karena akan memakan waktu yang sangat banyak. Meskipun begitu, untuk menyelesaikan Sudoku bisa menggunakan implementasi algoritma runut-balik, dan disertai bantuan algoritma brute-force.

II. DASAR TEORI 2.1 Algoritma Brute-Force Algoritma brute-force adalah sebuah pendekatan yang lempang ( straightforward ) untuk memecahkan suatu masalah, biasanya didasarkan pada suatu pernyataan masalah ( problem statement ) dan definisi konsep yang dilibatkan. Algoritma brute-force memecahkan masalah dengan sangat sederhana, langsung dan dengan cara yang jelas ( obvious way ). Algoritma brute-force umumnya tidak cerdas dan tidak mangkus, karena membutuhkan jumlah langkah yang besar dalam penyelesaiannya, terutama bila masalah yang dipecahkan berukuran besar. Kadang-kadang algoritma brute-force disebut juga algoritma naif ( naive algorithm ). Algoritma brute-force seringkali merupakan pilihan yang kurang disukai karena ketidakmangkusannya, tetapi dengan mencari pola-pola yang mendasar, keteraturan, atau trik-trik khusus, biasanya akan membantu kita menemukan algoritma yang lebih cerdas dan lebih mangkus. Untuk masalah yang ukurannya kecil, kesederhanaan brute-force biasanya lebih diperhitungkan daripada kemangkusannya. Algoritma brute-force lebih sering digunakan sebagai basis bila membandingkan beberapa alternatif algoritma yang mangkus. Misalnya pada perhitungan a n, dengan algoritma brute-force mudah diperlihatkan bahwa kompleksitas waktunya adalah O (n). Bila perhitungan tersebut diselesaikan dengan metode Divide and Conquer, maka kompleksitas waktunya jauh lebih baik daripada brute-force, yaitu O (log n). Meskipun brute-force bukan merupakan teknik pemecahan masalah yang mangkus, namun teknik brute-force dapat diterapkan pada sebagian besar masalah. Agak sukar menunjukkan masalah yang tidak dapat dipecahkan dengan teknik brute-force. Bahkan ada masalah yang hanya dapat dipecahkan secara brute-force. Beberapa pekerjaan mendasar di dalam komputer dilakukan secara brute-force, seperti menghitung jumlah dari n buah bilangan, mencari elemen terbesar di dalam tabel, dan sebagainya. Selain itu, algoritma brute-force seringkali lebih mudah diimplementasikan daripada algoritma yang lebih canggih, dan karena kesederhanaannya, kadang-kadang algoritma brute-force dapat lebih mangkus (ditinjau dari segi implementasi). 2.2 Algoritma Runut-balik Algoritma runut-balik (backtracking) adalah algoritma yang berbasis pada DFS untuk mencari solusi persoalan secara lebih mangkus. Runut-balik, yang merupakan perbaikan dari algoritma brute-force, secara sistematis mencari solusi persoalan di antara semua kemungkinan solusi yang ada. Dengan metode ini, kita tidak perlu memeriksa semua kemungkinan solusi yang ada. Hanya pencarian yang mengarah ke solusi saja yang selalu dipertimbangkan. Akibatnya, waktu pencarian dapat dihemat. Runut-balik lebih alami dinyatakan secara rekursif. Kadang-kadang disebutkan pula bahwa runut-balik merupakan bentuk tipikal dari algoritma rekursif. Istilah runut-balik pertama kali diperkenalkan oleh D.H. Lehmer pada tahun 1950. Selanjutnya, R.J. Walker, Golomb, dan Baumert menyajikan uraian umum tentang runut-balik dan penerapannya pada berbagai persoalan. Saat ini algoritma runut-balik banyak diterapkan untuk program games (seperti menemukan jalan keluar dalam labirin, catur, tic-tac-toe, dll) dan permasalahan pada bidang artificial intelligence ). 2.2.1 Properti Umum Algoritma Runut-balik a. Solusi persoalan Solusi dinyatakan dalam bentuk vektor dengan tupel X = (x 1, x 2,, x n ), x i S i. Mungkin saja S 1 = S 2 =... = S n. Contoh: S i = {0,1}, x i = 0 atau x i = 1

b. Fungsi pembangkit nilai x k Fungsi pembangkit dinyatakan sebagai T(k) di mana T(k) membangkitkan nilai untuk x k yang merupakan komponen vektor solusi. c. Fungsi pembatas Dinyatakan dalam predikat B(x 1, x 2,, x k ). B bernilai benar jika (x 1, x 2,, x k ) mengarah ke solusi. Jika benar, maka pembangkitan nilai untuk x k+1 dilanjutkan, tetapi jika tidak, maka (x 1, x 2,, x k ) dibuang. 2.2.2 Prinsip Pencarian Solusi dengan Algoritma Runut-balik ekspan tersebut akan dibunuh sehingga menjadi simpul mati. f. Fungsi yang digunakan untuk membunuh simpul ekspan menerapkan fungsi pembatas. Simpul yang mati tidak akan pernah diperluas lagi. 2.2.3 Skema Umum Algoritma Runut-balik Untuk menyelesaikan Sudoku, ada dua cara dalam menyatakan algoritma runut-balik, yaitu secara rekursif dan iteratif. Pada makalah ini akan dibahas cara menyelesaikan Sudoku dengan menggunakan algoritma runut-balik secara rekursif, karena algoritma runut-balik lebih alami dinyatakan dalam bentuk rekursi. Berikut adalah skema umum dari algoritma tersebut: function solve( input g : Node) Algoritma: if (mencapai solusi) then return True else for semua node yang belum dicoba kunjungi node if (solve(g)) then return True else backtrack endif endfor return False endif Gambar 1. Ilustrasi algoritma runut-balik (sumber: dreamincode.net) a. Solusi dicari dengan membentuk lintasan dari akar ke daun. Aturan pembentukan yang dipakai mengikuti aturan depth-first order (DFS). b. Simpul-simpul yang sudah dilahirkan dinamakan simpul hidup. c. Simpul-simpul yang sedang diperluas dinamakan simpul ekspan. d. Tiap kali simpul ekspan diperluas, lintasan yang dibangun olehnya bertambah panjang. e. Jika lintasan yang sedang dibentuk tidak mengarah ke solusi, maka simpul III. PENGGUNAAN ALGORITMA RUNUT BALIK UNTUK MENYELESAIKAN SUDOKU Untuk bisa mengaplikasikan algoritma runut-balik, pertama kita perlu membuat sebuah struktur data untuk merepresentasikan sebuah grid Sudoku. Pada makalah ini, penulis menggunakan bahasa pemrograman Python dan memanfaatkan array untuk merepresentasikan sebuah grid Sudoku. Nilai angka pada kotak-kotak dalam grid akan dibaca melalui file eksternal. Berikut ini adalah contoh implementasinya:

def readfile(grid, fileinp): with open(fileinp+".txt",'r') as f: for line in f : line = line.rstrip() row = [] for value in line : if (value=='.'): row.append(0) row.append((int)(value)) grid.append(row) Selanjutnya, dibuat implementasi aturan yang berlaku pada permainan Sudoku, yaitu angka yang ada pada setiap kotak harus unik pada setiap baris, kolom, dan subgrid. Berikut adalah contoh implementasinya: def isinrow(grid, row, n): for j in range(len(grid)): if (grid[row][j]==n): def isincol(grid,col,n): for i in range(len(grid)): if (grid[i][col]==n): def isinsubgrid(grid, row, col, n): for i in [0,1,2]: for j in [0,1,2]: if(grid[((int)(row/3))*3+i] [((int)(col/3))*3+j]==n): def issafe(grid, row, col, n): return not isinsubgrid(grid, row, col, n) and not isinrow(grid, row, n) and not isincol(grid, col, n) Lalu, untuk membuat implementasi dari algoritma runut-balik, perlu dibuat suatu fungsi yang mengecek apakah semua kotak dalam grid Sudoku sudah terisi semuanya, serta sebuah fungsi yang akan mencari kotak pertama yang akan di- assign pertama kali pada saat pemanggilan algoritma runut-balik. Berikut ini adalah contoh implementasinya: def isgridfull(grid): if (isunassigned(grid,i,j)): def searchfirstunassignedcell(grid, cell): if (isunassigned(grid,i,j)): cell[0] = i cell[1] = j Pada makalah ini, penulis menyelesaikan permasalahan Sudoku dengan menggunakan pendekatan menggunakan algoritma runut-balik secara rekursif, sehingga program akan memanggil fungsi tersebut sehingga semua kotak dalam grid Sudoku terisi seluruhnya. Berikut ini adalah pseudocode dari algoritma runut-balik yang akan digunakan: function solvegrid( input g : grid) {Mengisi grid Sudoku dengan cara backtracking, yaitu mengisi seluruh kotak dalam grid Sudoku dengan semua kemungkinan yang memenuhi aturan permainan Sudoku} Algoritma: if ( grid penuh) then return True else for angka 1 sampai 9 yang memenuhi aturan Sudoku do isicell(angka) if (solvegrid(g)) then return True else hapusisicell(angka) endif endfor endif Dengan memanfaatkan fungsi dan prosedur pembantu yang telah didefinisikan di atas, maka algoritma runut-balik sudah bisa

diimplementasikan. Berikut ini adalah contoh implementasinya: def solvesudokubacktrack(grid): if (isgridfull(grid)): startcell = [0,0] searchfirstunassignedcell(grid, startcell) row = startcell[0] col = startcell[1] for val in range(1,10): if (issafe(grid, row, col, val)): grid[row][col] = val if (solvesudokuwithbacktrack (grid)): grid[row][col] = 0 Gambar 2. Puzzle Sudoku New York Times Medium (sumber:www.nytimes.com/crosswords/game/sudoku/medi um) Proses algoritma runut-balik dimulai dengan mengecek apakah grid sudah penuh atau belum. Jika grid sudah penuh, maka proses backtracking selesai. Jika tidak, maka program akan mencari kotak pertama yang belum diisi sebuah angka, lalu mengisi semua kemungkinan angka yang bisa diisi pada kotak tersebut. Kemudian program secara rekursif akan memanggil kembali fungsi tersebut. Algoritma akan terus berjalan hingga seluruh kotak pada grid terisi penuh. Jika terdapat kotak yang tidak bisa diisi oleh angka berapapun, maka program akan melakukan backtrack dengan cara menghapus isi dari kotak yang sebelumnya sudah terisi. Gambar 3. Grid Sudoku New York Times Medium (sumber: pribadi) Berikut ini adalah contoh puzzle Sudoku yang ada di website https://www.nytimes.com/crosswords/game/sud oku/medium beserta program yang digunakan untuk menyelesaikan puzzle tersebut: Gambar 4. Solusi Sudoku New York Times Medium (sumber: pribadi)

IV. PENGGUNAAN ALGORITMA RUNUT BALIK DENGAN BANTUAN BRUTE-FORCE Algoritma runut-balik bisa digunakan untuk menyelesaikan seluruh kemungkinan puzzle Sudoku yang ada, namun ada kalanya kasus di mana puzzle Sudoku yang hendak diselesaikan membutuhkan banyak proses backtracking, dikarenakan sedikitnya clue yang ada di awal permainan. Hal ini bisa membuat algoritma runut-balik menjadi tidak terlalu efisien. Biasanya dalam menyelesaikan puzzle Sudoku, pemain pasti akan mengisi kotak-kotak pada grid Sudoku yang memiliki solusi angka yang sudah pasti hanya bisa diisi pada kotak tersebut, atau mengisikan solusi angka pada kotak yang hanya bisa diisi pada baris, kolom, atau subgrid yang bersesuaian dengan kotak tersebut. Maka dari itu, agar implementasi algoritma runut-balik bisa lebih mangkus dan efisien, akan diimplementasikan empat buah fungsi baru dengan algoritma brute-force yang bisa mengimplementasikan strategi di atas. Berikut ini adalah contoh implementasinya: def solveobviouscell(grid,arraycell): values = [1,2,3,4,5,6,7,8,9] candidatesolution = [] for val in values: if (isunassigned(grid,i,j and issafe(grid,i,j,val)): candidatesolution.append (val) if(len(candidatesolution)==1): grid[i][j] = candidatesolution[0] arraycell.append((i,j)) arraycell = list(set(arraycell)) def solveobviousrow(grid,arraycell): values = [1,2,3,4,5,6,7,8,9] for val in values: candidatesolution = {val:[]} if (isunassigned(grid,i,j) and issafe(grid,i,j,val)): candidatesolution[val].append((i,j)) if (len(candidatesolution[val]) ==1): grid[candidatesolution[val] [0][0]][candidateSolution[val] [0][1]] = val arraycell.append( (candidatesolution[val] [0][0],candidateSolution[val] [0][1])) arraycell = list(set(arraycell)) def solveobviouscol(grid,arraycell): values = [1,2,3,4,5,6,7,8,9] for val in values: candidatesolution = {val:[]} if (isunassigned(grid,i,j) and issafe(grid,i,j,val)): candidatesolution[val].append((i,j)) if (len(candidatesolution[val]) ==1): grid[candidatesolution[val] [0][0]][candidateSolution[val] [0][1]] = val

arraycell.append( (candidatesolution[val] [0][0],candidateSolution[val] [0][1])) arraycell = list(set(arraycell)) def solveobvioussubgrid(grid, arraycell): values = [1,2,3,4,5,6,7,8,9] for isubgrid in [0,1,2]: for jsubgrid in [0,1,2]: for val in values: candidatesolution = {val:[]} for offsetrow in [0,1,2]: for offsetcol in [0,1,2]: if (isunassigned(grid, (isubgrid*3+offsetrow), (jsubgrid*3+offsetcol)) and issafe(grid, (isubgrid*3+offsetrow), (jsubgrid*3+offsetcol), val)): candidatesolution[val].append((isubgrid*3 +offsetrow,jsubgrid*3 +offsetcol)) if (len(candidatesolution [val])==1): grid[candidatesolution [val][0][0]] [candidatesolution [val][0][1]] = val arraycell.append( (candidatesolution[val] [0][0],candidateSolution [val][0][1])) arraycell = list(set (arraycell)) dibuat sebelumnya, sehingga setiap kali fungsi dipanggil, keempat fungsi tersebut akan dipanggil terlebih dahulu untuk menyelesaikan kotak-kotak yang mudah untuk diselesaikan sebelum menyelesaikan grid Sudoku keseluruhan dengan algoritma runut-balik yang murni. Namun, jika di tengah proses menyelesaikan grid Sudoku dengan algoritma runut-balik diperlukan untuk melakukan backtracking, maka kotak-kotak yang sebelumnya telah di- assign oleh fungsi dengan algoritma brute-force harus dihapus nilainya. Sehingga, harus dibuat suatu fungsi sederhana yang menghapus nilai dari semua kotak yang telah diisi oleh empat fungsi algoritma brute-force tersebut untuk proses backtracking. Berikut ini adalah contoh implementasinya: def unsolveobvious(grid,arraycell): for cell in arraycell: grid[cell[0]][cell[1]] = 0 Sehingga algoritma runut-balik yang didapatkan adalah sebagai berikut: def solvesudokuimprovedbacktrack (grid): obvcells = [] solveobvioussubgrid(grid,obvcells) solveobviousrow(grid,obvcells) solveobviouscol(grid,obvcells) solveobviouscell(grid,obvcells) if (isgridfull(grid)): startcell = [0,0] searchfirstunassignedcell(grid, startcell) row = startcell[0] col = startcell[1] Keempat algoritma tersebut akan dijalankan di dalam algoritma runut-balik yang sudah

for val in range(1,10): if (issafe(grid, row, col, val)): grid[row][col] = val if (solvesudokuimproved Backtrack(grid)): grid[row][col] = 0 unsolveobvious(grid,obvcells) Selanjutnya, penulis akan membandingkan kedua algoritma utama yang telah dijabarkan di atas, di mana algoritma pertama adalah algoritma runut-balik murni, dan algoritma kedua adalah algoritma runut-balik + brute-force. Untuk membandingkan kedua algoritma tersebut, penulis menguji kedua algoritma dengan 5 buah puzzle Sudoku dengan tingkat kesulitan di atas Hard yang hanya memiliki 21 clue di awal permainan. Waktu eksekusi kedua algoritma untuk masing-masing puzzle yang tercatat adalah sebagai berikut: No. Waktu eksekusi algoritma 1 (s) 1. 3.150596 0.023975 2. 6.336058 0.028924 Waktu eksekusi algoritma 2 (s) algoritma pertama (runut-balik murni) untuk menyelesaikan puzzle Sudoku adalah 8.497206 detik. Sedangkan rata-rata waktu yang dibutuhkan algoritma kedua (runut-balik + brute-force ) adalah 0.037707 detik. V. KESIMPULAN Hal ini menunjukkan bahwa algoritma runut-balik bisa diimplementasikan bersama dengan algoritma brute-force untuk menyelesaikan puzzle Sudoku 225 kali lebih cepat bila dibandingkan dengan algoritma runut-balik yang murni. VI. DAFTAR PUSTAKA [1] Munir, Rinaldi, Diktat Kuliah IF2211 Strategi Algoritma. Program Studi Teknik Informatika ITB, 2015. [2] https://www.kristanix.com/sudokuepic/sudoku-solving -techniques.php Diakses pada 26 April 2019 [3] https://www.minimumsudoku.com/ Diakses pada 26 April 2019 [4] https://www.codeproject.com/articles/865143/a-sudokuprogram-with-some-advanced-features Diakses pada 26 April 2019 PERNYATAAN Dengan ini saya menyatakan bahwa makalah yang saya tulis ini adalah tulisan saya sendiri, bukan saduran, atau terjemahan dari makalah orang lain, dan bukan plagiasi. Bandung, 26 April 2019 3. 12.011887 0.086748 4. 15.133148 0.028922 5. 5.854344 0.019967 Tabel 1. Perbandingan kecepatan algoritma pertama terhadap algoritma kedua (sumber: pribadi) Ahmad Naufal Hakim 13517055 Berdasarkan percobaan yang telah dilakukan, didapatkan hasil sesuai dengan tabel di atas. Rata-rata waktu yang dibutuhkan