9

I've taken on the task of creating a sudoku solver using a genetic algorithm.

Initialization: Store the given values in each chromosome, and then randomly generate values such that each row is a valid permutation of the values 1 through 9.

Fitness: Determined by the number of "out of place" values in each row, column, and square grid, added together.

Fitness Function: Typical roulette wheel selection

Selection: Random, but weighted using the roulette wheel.

Crossover: Randomly choose various rows from two parents, which creates one child. (I've also implemented a crossover that randomly chooses 3 rows at a time from the two parents - in an effort to preserve good mini-grids). The following are two example children, one from each crossover method:

Parent 1 row 1
Parent 2 row 2
Parent 1 row 3
Parent 2 row 4
Parent 1 row 5
Parent 2 row 6
Parent 2 row 7
Parent 1 row 8
Parent 1 row 9

Parent 1 row 1
Parent 1 row 2
Parent 1 row 3
Parent 2 row 4
Parent 2 row 5
Parent 2 row 6
Parent 1 row 7
Parent 1 row 8
Parent 1 row 9

Mutation: Initially I just swapped the values at two random locations, but this actually made the algorithm much worse because it introduced duplications in rows which had been valid permutations. So I altered the mutation (which seems to perform best when the chance of mutation is in the 25% - 50% range) to randomly choose a row, and then randomize the ordering of that row (leaving the given values in their correct locations).

I also tried a mutation where it chose a random row and then chose two random (non-given) positions in the row and swapped them, but this made the performance much worse as well. (Unlike the swapping of the two random locations, I don't understand why this mutation would make the performance so much worse, yet a mutation to randomize the entire row makes the performance better)

My algorithm has yet to solve a puzzle of any difficulty. It will often times get close (in the range of only 6 to 10 conflicts), but it can never get to a solution (it's presumably finding local minima and getting stuck).

In an effort to improve the algorithm, I added the ability to replace a large portion of the population (worst performing chromosomes) with completely randomized boards, but this seems to have a minimal effect.

What are weak points in my approach? How can I improve the performance?

It seems like Sudoku might lend itself to better performance from mutation, as opposed to crossover.

Ryan
  • 3,127
  • 6
  • 32
  • 48
  • Why use a genetic algorithm for this? Genetic algorithms are usually used for NP-Complete problems, whereas solving a sudoku is much easier (and, in fact, quite an easy algorithm to write) – Jasper Nov 11 '12 at 01:41
  • I believe Soduko solvers are NP-complete problems, but we can solve small Soduko puzzles. – ajon Nov 11 '12 at 01:49
  • ajon is right. And this is more of an exercise in tackling various topics using genetic algorithms. – Ryan Nov 11 '12 at 01:51
  • @ajon: Agreed, technically they are. In a very small space, considering that sudokus that have only a single solution rarely have more than a handful of permutations that can't be seperated in less time. Of course, if you are dealing with sudokus that have more than one solution, it's a different story, but humans aren't supposed to be able to solve those either. – Jasper Nov 11 '12 at 01:57
  • @Ryan: That actually makes sense, I suppose I have been of a bit more practical mindset lately. I do see a problem with your algorithm, but I don't see a way to fix it yet. If the matter hasn't been resolved by then, I'll take a look at it tomorrow. – Jasper Nov 11 '12 at 02:01
  • Just spit-balling, but my approach might be to use an encoding of 1-9 + * where * means "wild-card" and doesn't count as either promoting or demoting fitness. (Or maybe it counts as slightly unfit, so that it eventually gets weeded out.) I think that maybe with your approach you are moving too fast into a particular area of the solution space, given the severe constraints of filling out entire mini-grids. – Larry OBrien Nov 11 '12 at 23:42
  • Sorry for not getting back to you though I said I would. I did think about the problem, I did not find any solutions to weaknesses I thought were present and at the same time I am not as sure about whether they are indeed such problems as I originally thought. I do think Larry's idea is a good one, though. – Jasper Nov 13 '12 at 00:41
  • In your mutation, you're using the rules of sudoku to check if it's a valid result? – Kostas Feb 28 '22 at 10:09

2 Answers2

8

I solved some sudoku puzzles with a GA, using this approach: http://fendrich.se/blog/2010/05/05/solving-sudoku-with-genetic-algorithms/

Sudoku has many false local minima, so it is very important to maintain population diversity. Don't converge too greedily. That is the key to many hard problems. Converge extremely slowly.

I don't like Roulette wheel selection. It is a toy that converges too quickly and is too dependent on fitness function. You can for example use tournament selection.

I agree that crossover is tricky to apply. You can view it as a sort of large mutation, that just happens to be a crossover.

Gurgeh
  • 2,130
  • 15
  • 28
0

The best strategy that I know of to solve soduko programatically is to use a Boolean satisfiability problem

ajon
  • 7,868
  • 11
  • 48
  • 86