Docstoc

Sudoku Puzzle Free

Document Sample
Sudoku Puzzle Free Powered By Docstoc
					                                                                              Anna Blasiak
                                                                        December 9, 2005
                                                                     Artificial Intelligence

                                    Sudoku Solver

Problem

The popular sudoku puzzle was invented by a retired architect, Howard Garns in 1979
(Wikipedia). Although there are many variations, a classical Sudoku puzzle is a nine by
nine board where some of the squares contain an integer between one and nine and the
rest are blank. To solve the puzzle every blank space needs to be filled so that each
integer from one to nine is in every row, column, and three by three box exactly once.
Analysis of the puzzle reveals that there are 670903752021072936960 possible
completed grids (Weisstein).

Goals

The main goal of this project is to write a program to solve a sudoku board primarily by
logic techniques that deduce the value of unknown squares, or eliminate some of the
remaining possible values. Another goal is to make an applet that illustrates the solving
process step by step to help explain how the solver works.

Overall Approach

A sudoku puzzle is a constraint satisfaction problem (CSP). The puzzle has 9x9 = 81
variables, some of which are given. The variables that are unknown start with a domain
D = {1,2,3,4,5,6,7,8,9} of possible values. There are binary constraints between all the
variables in a row, column, or box, to ensure that no value can appear in a box, row, or
column more than once. The goal is to find a solution for each variable that is legal -
does not violate any constraints. The AI technique to approach a CSP is with constraint
propagation and a backtracking search with various heuristics. However, since one of the
more interesting elements of sudoku puzzles is that most can be solved by logic alone,
before doing a backtracking search, I use logical procedures to solve the puzzle.

Board Representation

I considered two options for representing the board. Since a sudoku is a constraint
satisfaction problem, it makes sense to represent the board by its constraint graph, so each
square would be a node in a graph and it would have edges to all the squares that cannot
have the same value. With a well thought out implementation of the graph this
representation could have made eliminating conflicting values quite easy. However, I
decided to represent the sudoku grid with a two-dimensional array since it has more of a
direct connection to the image of the board. I am actually using two two-dimensional
arrays. The first is an array of integers that contains the solution so far, with zeros
representing an unknown square. The other is an array of vectors, where each vector
contains the remaining possible values for the square. When a square is solved, the
vector at the square is emptied, and the value is entered in the solution array. By using
this construction, it becomes easy to eliminate conflicting values of squares only when
the value of the square is found, and instead of doing it at every step.

Solving Methods

I implemented a number of different logic techniques to solve the puzzles in addition to
forward checking to propagate the constraints and a backtracking depth first search to
complete the sudoku puzzle if the logic cannot, especially in puzzles where there is more
than one solution.

The Recursive Solve method is outlined in pseudo code below. It uses one technique and
then checks the board again to make sure it is not done, it is solvable, and all the
conflicting values are eliminated before it uses another technique to continue solving. In
the step-by-step function of the applet, the board is shown at each call to solve.

solve {
if(done)
         exit
if ( solvable )
         if (we can back track )
                 backtrack
                 solvable = true;
else if ( update changes grid)
else if ( check rows changes grid )
else if ( check columns changes grid)
else if ( check boxes changes grid)
else
         guess
if(solvable)
         solve
}

Update checks for squares with only one remaining value, if it finds one, it clears the
vector and adds the value v to the solution array, it then does forward checking by
eliminating v from all the remaining possible values of the row, column, and box that the
square was in. When eliminating v from rows, columns, and boxes, if it removes the last
element of the vector, then there are no solutions to that square and the puzzle is
unsolvable. So if this happens the program sets a global variable “solvable” to false. The
next time solve is called, the program will backtrack if it can otherwise it will declare the
puzzle unsolvable.
Logically it would make sense to have the solve method try the easier, quicker solving
methods first, and then if those don’t eliminate values, work up to the harder ones.
However, it was more time efficient to do all the logical procedures that look at rows
together in one loop so that we only have to iterate through the rows once (likewise for
the columns and boxes).

Check Rows, check columns, and check boxes all implement three distinct logical
solving methods, that I have named Single Value, Box/Column/Row Pairs/Triples, and
Two Square Pair. Following is an explanation of each of these solving techniques in
terms of rows. The case for columns and boxes is analogous.

Single Value
The simplest of the three techniques, Single Value searches the grid of vectors by row
and looks for a value that appears only once in all the remaining values in the row. If a
single value v is found in square s it must be the case that s takes on value v so that v will
appear in the row.

In the sudoku grid section below, the highlighted squares show an example of a single
value in a row. In the top row, a two appears only in the highlighted square, and
likewise, in the bottom row, a five appears only in the highlighted square.




The algorithm identifies the single value, and in the next step, the squares have been
assigned the two and five respectively.
Row Pairs/Triples
Row Pairs/Triples looks for two or three occurrences of a value in a row where all the
occurrences appear in the same box. (Note: when the boxes are searched the occurrences
must appear in the same column and/or row, so we look for both Column Pairs and Row
Pairs.) If a value v is found only in the remaining values of squares in box b and row r,
we can deduce that v must occur in row r of box b, since otherwise r would not have a
square take on value v. Therefore, v can be eliminated from all the remaining possible
values in the rest of box b.

In the section of the sudoku grid below, we see that a search of the pink row finds that the
value eight (in the bright pink squares) occurs only in the right box. Since eight must
therefore be in either of the two bright pink squares to get an eight on the bottom row,
eight can be eliminated from all the other squares in the right box.




The two yellow highlighted squares in the right box have eights and thus in the next step
they are removed.




Two Square Pair
Finally, the last technique searches for two values that appear twice in a row and also are
both in the same two squares. If this is found, the squares must take on those values, so
any other values in those squares can be eliminated.

Below, a search of the pink row reveals that five and six both appear only twice in the
row, and they both appear in the same two squares, which are bright pink.
So, it must be the case that the five is in one of the bright pink squares and the six is in
the other. Thus, the nine and four can be eliminated from those squares as possible
values.




Backtracking search
If there are unsolved squares and none of the above methods can help eliminate any
values, the program guesses a value for the square with the minimum remaining values.
The solving then continues with the logic functions, and then if the puzzle becomes
unsolvable, it backtracks to undo the last guess and then makes a new guess.

Results

The sudoku solver is a success. It has no limitations on the puzzles it can solve (or
determine unsolvable) because it uses a backtracking search with a finite state space. In
addition, the solver is quite fast. For a puzzles ranked level “very hard” on a sudoku
website, the highest average time to solve the puzzle was 6 ms. In addition, the applet is
a excellent demonstration of how to solve sudoku puzzles. It clearly illustrates the
solving techniques for constraint satisfaction problems by displaying the remaining
possible values for each variable and how the constraints are enforced.

Currently the project is mostly a learning tool, but it could be interesting to expand the
project to do some time comparisons between the solver with and without using logic
techniques. I did a limited time comparison and it revealed that the logic techniques
don’t make any significant time difference for easier puzzles, and sometimes slow it
down a little bit. However, for the puzzle that took 6 ms on average, without the logic
techniques it took about 3 times as long. To do a more interesting time comparison it
would require writing a sudoku puzzle generator, so it could be tested on thousands of
puzzles. With a puzzle generator, another interesting question we could answer is the
longest amount of time it takes to solve a puzzle.


References

Stuart, Andrew. “Sudoku Solver.” <http://www.scanraid.com/Sudoku.htm>.
"Sudoku." Wikipedia, The Free Encyclopedia.
      <http://en.wikipedia.org/w/index.php?title=Sudoku&oldid=30761372>.

Weisstein, Eric W. et al. "Sudoku." From MathWorld--A Wolfram Web Resource.
      <http://mathworld.wolfram.com/Sudoku.html>.