Sudoku Programmers Forum Index

 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister   ProfileProfile   Log inLog in          Games  Calendar

Log in to check your private messagesLog in to check your private messages   

What's the fastest approach to solving Sudokus?

 
Post new topic   Reply to topic    Sudoku Programmers Forum Index -> Programming sudoku
View previous topic :: View next topic  
Author Message
UmberGryphon

Joined: 05 Oct 2005
Posts: 8
:

Items
PostPosted: Wed Oct 05, 2005 10:13 pm    Post subject: What's the fastest approach to solving Sudokus? Reply with quote

I've been playing around with writing Sudoku-solving programs, since it seemed like an interesting problem. I started out with a fairly straightforward brute-force searcher, which worked (although slowly). I then started Googling for better basic methods, found this forum, and decided that I liked dodo's basic approach, as seen here. It isn't that far removed from brute-force, but it seemed much more efficient and easy-to-optimize than what I'd been doing.

I've done lots of optimizations, including a 9-by-9 array that does nothing but give an index into the boxes[] bitsets given x and y coordinates (because apparently (x/3)*3+y%3 isn't as cheap as you'd think), a 512-element array that does nothing but tell you how many bits are set in a given number, and reordering the rows so that the easiest row in the easiest 3-row block gets priority when cells tie for number of candidates (which isn't much help in top1011, but helps a lot in top95).

After all that, I can solve top1011 in 0.178 seconds and top95 in 0.488 seconds on a 3 GHz P4 (using Cygwin gcc -O9). But other people get better times on slower computers. Is there a faster fundamental approach? Am I missing some important optimization? Does cygwin-gcc suck? I'm confused.

UmberGryphon
(who suspects there's a faster algorithm)
Back to top
View user's profile Send private message
xyzzy

Joined: 24 Aug 2005
Posts: 80
:

Items
PostPosted: Thu Oct 06, 2005 2:17 am    Post subject: Reply with quote

Keep track of more data and do less recalculating.

As far as I've found, I've written the fastest soduko solver yet, and I used gcc. But not cygwin, bleh, Linux only.
Back to top
View user's profile Send private message Visit poster's website
dukuso

Joined: 14 Jul 2005
Posts: 424
:
Location: germany

Items
PostPosted: Thu Oct 06, 2005 8:57 am    Post subject: Reply with quote

maybe you should include some more lookahead using
some of the known "technics".
http://www.setbb.com/phpbb/viewtopic.php?t=178&mforum=sudoku


Quote:

and reordering the rows so that the easiest row in the easiest 3-row block gets priority when cells tie for number of candidates (which isn't much help in top1011, but helps a lot in top95).


I'm interested in this. What's the "easiest row", "easiest 3-row-block" ?
Back to top
View user's profile Send private message Send e-mail Visit poster's website
UmberGryphon

Joined: 05 Oct 2005
Posts: 8
:

Items
PostPosted: Thu Oct 06, 2005 4:00 pm    Post subject: Reply with quote

dukuso wrote:
I'm interested in this. What's the "easiest row", "easiest 3-row-block" ?


I saw several people mention that sudokus that their programs find difficult become easy if they're just flipped upside-down or whatnot. So the first thing my solver does is calculate how many possible candidates every cell has (putting 1 in for the starting value cells), and then multiply the values for all the cells in a row together to determine how many combinations or "combos" that row has. And then for the 3-row blocks (since you can't shuffle rows between blocks because you'd mess up the 3x3 blocks), I multiply the 3 "combos" values together to get my "blockcombos" values.

Then, because my algorithm is biased towards cells at the top of the sudoku grid when it's deciding which cell to recurse into next, I move the 3-row blocks that have the lowest "blockcombos" values towards the top of the grid, and within each 3-row block, I move the rows that have the lowest "combos" value towards the top. If I'm printing out solutions, my solution-printing routine has to remember to print the rows in the order they're supposed to be in, not the order they are in, but that's not too hard.

The theory is that this way, by attacking the rows with fewer possibilities first, the algorithm will discover that it's on the wrong path faster than it would if it was working on rows with more possibilities, and so I'll have to do less bouncing around to find the right path.

My time for top95 goes from 0.574 seconds to 0.488 seconds with this optimization. It's pretty much a wash on top1011, though.

UmberGryphon
(who thought about doing the same thing for columns, but "swapcolumns()" turned out to be too expensive timewise)
Back to top
View user's profile Send private message
dukuso

Joined: 14 Jul 2005
Posts: 424
:
Location: germany

Items
PostPosted: Fri Oct 07, 2005 6:23 am    Post subject: Reply with quote

your 20% gain on top95 is not so much, but maybe the
effect is stronger for larger sudokus, 16*16,25*25,..

let me compare it with these :


----------------------------------------


Dotu/delVal/Cebrian : ("dom-lessO")
select the variable with the minimum domain size
and then select the value which occurs the fewest times in the domains
of the variables of the rows and columns [and blocks] of the selected variable


Regin/Gomes : ("dom-maxB-lessO")
when two variables have the same size of domain we select the one for
which the number of instantiated variables of the row and of the
column [and of the block] is maximum.


UmberGryphon :
when two variables have the same size of domain we select the one for
which the product of the domainsizes of the variables in
the same row/column/block/chute is minimum
(I'm not sure about the exact preferrence row/col/block/chute here)



variable : cell
domian of a variable : candidates for that cell
value : smbol or digit which goes into a sudoku-cell
instantiated variable : filled cell,clue,only one candidate


----------------------------------------
Back to top
View user's profile Send private message Send e-mail Visit poster's website
UmberGryphon

Joined: 05 Oct 2005
Posts: 8
:

Items
PostPosted: Fri Oct 07, 2005 4:25 pm    Post subject: Reply with quote

dukuso wrote:
let me compare it with these....


The core of my solver algorithm is mind-bogglingly dumb. It doesn't even find hidden singles. The advantage of the row-reordering optimization is that I can do it up-front without spending cycles every loop.

The whole reason I started this thread is that I can't seem to optimize my current approach any further, and I wanted someone to point me to a better algorithmic approach that will let me get faster. I don't want source code or anything... after all, I'm doing this to learn. I just want xyzzy or one of his peers to point me in the right direction. Is Knuth's "dancing links" a fast algorithm? Or is the fastest approach a really smart algorithm that knows how to find hidden quads? Or what?

UmberGryphon
(who has no interest in doing inline assembly)
Back to top
View user's profile Send private message
xyzzy

Joined: 24 Aug 2005
Posts: 80
:

Items
PostPosted: Fri Oct 07, 2005 9:42 pm    Post subject: Reply with quote

Dancing links are fast, but I didn't use dancing links and am faster. For 9x9 sudoku complex logic is slower, I've yet to make anything more than singles show an overall speed improvement. I'm close with subsets though. For 16x16, using subsets (all forms) does offer a speed improvement. When you preform a depth first search, it's very important to have a good heuristic to choose which branch to take first. Think about the operations you will perform, and create your data structures so that these operations can be preformed quickly. And of course think about ways to use lookup tables to avoid multiplication, division, and looping.
Back to top
View user's profile Send private message Visit poster's website
Ruud
Site Admin
Joined: 17 Sep 2005
Posts: 708
:
Location: Netherlands

Items
PostPosted: Fri Oct 07, 2005 10:53 pm    Post subject: Reply with quote

You could do the easy pickings (singles, box-row, subsets) first and then hand it to a backtracking solver like dancing links. With an integrated data model, the "logic" code can disable DLX rows on the fly. That would save initialization time for the DLX solver.

Ruud
(who also refuses to do inline assembly)
Back to top
View user's profile Send private message Visit poster's website
UmberGryphon

Joined: 05 Oct 2005
Posts: 8
:

Items
PostPosted: Tue Oct 11, 2005 5:21 pm    Post subject: Reply with quote

Ruud wrote:
You could do the easy pickings (singles, box-row, subsets) first and then hand it to a backtracking solver...


Just by finding hidden singles before reordering the rows and doing my optimized brute-force search, top1011 is 5% faster and top95 is 45%(!) faster. Very Happy I'm not sure I could find subsets fast enough to be a win, and because of the way I use bitset ANDs to determine my possible values in the brute-force search, box-row/column isn't really doable for me.

UmberGryphon
(who is mostly content with his speed now)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Sudoku Programmers Forum Index -> Programming sudoku All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Sudoku Programmers topic RSS feed 


Powered by phpBB © 2001, 2005 phpBB Group

Igloo Theme Version 1.0 :: Created By: Andrew Charron