Sei sulla pagina 1di 28

Abstract

Abstract

Sudoko is a number-placement puzzle where the objective is to fill a

square grid of size ‘n’ with numbers between 1 to ‘n’. The numbers

must be placed so that each column, each row, and each of the sub-

grids contains all of the numbers from 1 to 9.The most common

Sudoku puzzles use a 9x9 grid. The grids are partially filled (with

hints) to ensure a solution can be reached.This project aims in using a

back tracking algorithm to solve a 9x9 sudoko puzzle.


Introduction
Introduction

Backtracking is an algorithm for finding all (or some) of the


solutions to a problem that incrementally builds candidates to the
solution(s). As soon as it determines that a candidate cannot
possibly lead to a valid solution, it abandons the candidate.

Backtracking is all about choices and consequences.


Abandoning a candidate typically results in visiting a previous
stage of the problem-solving-process. This is what it means to
“backtrack” — visit a previous stage and explore new possibilities
from thereon.

Usually, apart from the original problem and the end goal, we also
have a set of constraints that the solution must satisfy.
The simplest (read ‘dumbest’) implementations often use little to
no “logic” or “insight” to the problem. Instead, they frantically try
to find a solution by guesswork.

A backtracking algorithm can be thought of as a tree of


possibilities. In this tree, the root node is the original problem,
each node is a candidate and the leaf nodes are possible solution
candidates. We traverse the tree depth-first from root to a leaf
node to solve the problem.
The tree diagram also shows 2 groups — 
Unexplored Possible Candidates (UPC)and
Impossible Candidates(IC).UPC marks
nodes that were never explored. Some of
them could have been viable candidates,
leading to another solution. Since we never
explored them, we can never know.
Problems where multiple solutions are
acceptable won’t have this group.IC groups
are the obvious ones. It contains nodes
which have a failed candidate node as one
of their ancestor nodes. None of the nodes
in this group are candidate nodes and none
of the leaf nodes are solution nodes.
This project we will aim to create a sudoko solver, using back
tracking algorithm.

Problem:
Given a, partially filled grid of size 9x9, completely fill the grid
with number between 1 and ’n’.We achieve a solution If,
A fully filled grid has:
1. In Each row ,all numbers form 1 to 9.
2. In Each column, all numbers form 1 to 9
3. In Each sub-grid ,all numbers form 1 to 9.

Termination conditions:
Typically, backtracking algorithms have termination conditions
other than reaching goal. These help with failures in solving the
problem and special cases of the problem itself.
1. There are no empty spots left to fill and the candidate still
doesn’t qualify as a the solution.
2. There are no empty spots to begin with, i.e., the grid is
already fully filled.
Here’s how our code will “guess” at each step, all the way to the
final solution:

1. Make a list of all the empty spots.


2. Select a spot and place a number, between 1 and ‘n’, in it and
validate the candidate grid.
3. If any of the constraints fails, abandon candidate and repeat
step 2 with the next number. Otherwise, check if the goal
is reached.
4. If a solution is found, stop searching. Otherwise, repeat steps
2 to 4.
Source Code
Source Code

#include <iostream>

class Puzzle
{ public:

int data[9][9] =
{ { -1, -1, 8, -1, -1, -1, -1, -1, -1 },
{ -1, -1, 6, 9, 2, -1, -1, -1, 3 },
{ 9, -1, -1, -1, -1, 6, -1, -1, -1 },
{ 2, 6, -1, -1, -1, 7, -1, -1, -1 },
{ -1, 1, -1, 5, 9, 4, -1, 6, -1 },
{ -1, -1, -1, 6, -1, -1, -1, 1, 9 },
{ -1, -1, -1, 3, -1, -1, -1, -1, 4 },
{ 6, -1, -1, -1, 1, 8, 5, -1, -1 },
{ -1, -1, -1, -1, -1, -1, 2, -1, -1 }};

void printp(){
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
if(data[i][j]!= -1 )
std::cout<<data[i][j]<<" ";
if (data[i][j]== -1)
std::cout<<" ";
}
std::cout<<std::endl;
}
}

void get_puzzle()
{ std::cout<<"enter elements in horizontal order, enter -1
for a blank:"<<std::endl;
for (int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
std::cin>>data[i][j];
}
}
}

bool check()
{
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j)
for (int k = j + 1; k < 9; ++k)
{
if (data[i][j] != -1 && data[i][j] == data[i][k])
return false;
if (data[j][i] != -1 && data[j][i] == data[k][i])
return false;
if (data[j % 3 + (i % 3) * 3][j / 3 + (i / 3) * 3] != -1 &&
data[j % 3 + (i % 3) * 3][j / 3 + (i / 3) * 3] ==
data[k % 3 + (i % 3) * 3][k / 3 + (i / 3) * 3])
return false;
}
return true;
}

bool findSolution()
{
int x = -1;
int y = -1;
int min = 10;
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j)
{
if (data[i][j] == -1)
{
int c = 0;
for (int k = 1; k <= 9; ++k)
{
data[i][j] = k;
if (check())
++c;
data[i][j] = -1;
}
if (min > c)
{
min = c;
x = i;
y = j;
}
}
}
if (x == -1)
return true;
for (int k = 1; k <= 9; ++k)
{
data[x][y] = k;
if (check())
if (findSolution())
return true;
}
data[x][y] = -1;
return false;
}

};

int main()
{
Puzzle puzzle;
using namespace std;
int a;
cout<<"welcome to sudoko puzzle solver! press 1 to see
results for default suduko puzzle. press 2 for custom
puzzle: ";
cin>>a;

switch(a)
{
case 1:
puzzle.printp();
if (puzzle.findSolution())
{
for (int i = 0; i < 9; ++i)
{
for (int j = 0; j < 9; ++j)
std::cout << puzzle.data[i][j] << " ";
std::cout << std::endl;
}
}
else
std::cout << "No solution\n";

break;

case 2:
{
puzzle.get_puzzle();
if (puzzle.findSolution())
{
for (int i = 0; i < 9; ++i)
{
for (int j = 0; j < 9; ++j)
std::cout << puzzle.data[i][j] << " ";
std::cout << std::endl;
}
}
else
std::cout << "No solution\n";
}

}
Output
Output
Limitations
Limitations:

1. Highly demanding in terms of memory and time resources


due to its brute force nature.
2. Backtracking requires recursion which can be something
worse, because CPU stack space is limited and can be
consumed quickly by recursion.
3. Highly inefficient for a large amount of data
4. Backtracking is non-deterministic unless you tracked it.
Scope of

improvement
Scope of improvement
Several studies have proposed efficient means of solving sudoko
puzzles using more complex algorithims, like
Mária Ercsey-Ravasz & Zoltán Toroczkai proposed a
mathematical deskription of solving sudoku using a concept of “k-
sats”as shown for the first time by Cook and Levin, whose detail
discussion is beyond our scope.
Result
Result

A c++ program for solving a sudoko puzzle was written using the
principles of backtracking , and the results were verified to be correct.
References
references:
1.Computer Science with C++ for Class - 12,Dhanpat Rai Publishing Co
Pvt Ltd,9th edition,ISBN13 9788177000245.
2.https://en.wikipedia.org/wiki/Conjunctive_normal_form
3.Ercsey-Ravasz, M., Toroczkai, Z. The Chaos Within Sudoku. Sci Rep 2,
725 (2012) doi:10.1038/srep00725
4.https://www.101computing.net/backtracking-algorithm-sudoku-solver/
5.https://hackernoon.com/sudoku-and-backtracking-6613d33229af
6.https://www.geeksforgeeks.org/multidimensional-arrays-c-cpp/

Potrebbero piacerti anche