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   

Need help with my first Sudoku generator
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    Sudoku Programmers Forum Index -> Programming sudoku
View previous topic :: View next topic  
Author Message
pedrohp

Joined: 26 Aug 2008
Posts: 11
:

Items
PostPosted: Tue Aug 26, 2008 11:57 pm    Post subject: Need help with my first Sudoku generator Reply with quote

Hi there!

I'm totaly new to Sudoku and Sudoku programming. I need to program an algorithm to generate valid Sudoku boards with only one solution.

I managed to program a backtracking algorithm that generates a random solved board.

I wonder now how to determine witch Cells now i should show to the player as Givens and witch ones i should hide to keep the board with only one solution. Can anybody help-me with this?

I've uploaded my code to rapidshare, but can't post it here...
Back to top
View user's profile Send private message
Lunatic

Joined: 11 Mar 2007
Posts: 166
:
Location: Ghent - Belgium

Items
PostPosted: Wed Aug 27, 2008 10:29 am    Post subject: Reply with quote

Hi pedrohp, welcome...

You will have to randomly take away givens, step by step, and check after each step if the sudoku is still valid (one unique solution). If the sudoku became unvalid (more than one solution), you must replace the last removed given(s) and try removing another given. To keep the symetry, you better remove the givens by pairs.

Keep in mind that:
- you cannot have two empty rows in the same band or stack
- more than 4 empty boxes are not allowed
- at least 8 of the 9 numbers must be among the givens

You can insert a routine to check these restrictions before running the routine for checking the uniqueness.

Marc.
_________________
Marc
~~~<><~~~<><~~~<><~~~<><~~~
Back to top
View user's profile Send private message Send e-mail Visit poster's website
m_b_metcalf

Joined: 13 Mar 2006
Posts: 210
:
Location: Berlin

Items
PostPosted: Wed Aug 27, 2008 11:01 am    Post subject: Reply with quote

Marc is, of course, assuming that you already have a solver. Since you have a backtracking generator, you must have something pretty close. The solver has to be able to count the number of solutions that a candidate puzzle has. You can test it on the following pseudo-puzzle:
Code:

 . . 1 . . 2 . . .
 . 4 . . . . . 5 .
 6 . . . 7 . 1 . .
 . . . 6 . 3 . . 8
 . . 9 . . . 2 . .
 8 . . 2 . 1 . . .
 . . 6 . 3 . . . 9
 . 5 . . . . . 4 .
 9 . . 7 . . 8 . .  309 solutions


Once it works, you can stop the count when it reaches 2, as you need to know only whether the number of solutions is 1 or more than 1.

Hope that helps,

Mike Metcalf
Back to top
View user's profile Send private message
daj95376

Joined: 05 Feb 2006
Posts: 349
:

Items
PostPosted: Wed Aug 27, 2008 3:08 pm    Post subject: Re: Need help with my first Sudoku generator Reply with quote

pedrohp wrote:
I need to program an algorithm to generate valid Sudoku boards with only one solution.

I managed to program a backtracking algorithm that generates a random solved board.

I wonder now how to determine witch Cells now i should show to the player as Givens and witch ones i should hide to keep the board with only one solution. Can anybody help-me with this?

The second hardest part when creating a puzzle is guaranteeing a unique solution. Starting with a filled grid, as in your case, requires you to conceal cell values. Unfortunately, there isn't any rule/algorithm for this process. It's very much like the backtracking approach you used to fill the grid.

There are many references to DLX solvers in this forum. If you embed this type of solver in your puzzle generator, then you can use it to check your grid as you conceal cell values and try to turn it into a puzzle. DLX has the ability to determine exactly how many solutions remain. As Metcalf mentioned, you can stop the DLX logic after it finds two solutions. No need wasting time continuing to check when there may be thousands of solutions. Also, in my mind, it's possible to get to a position where you go straight from multiple solutions to zero solutions. DLX will tell you this as well.

Most people are accustomed to newspaper Sudoku puzzles where the clues are presented in a symmetric pattern. You may want to consider concealing clues in pairs to generate puzzles of this nature. There are several symmetric patterns, so there are different ways to select concealed pairs.

Finally, none of the above addresses the difficulty level of the resulting puzzle. Be aware that over 95% of all Sudoku puzzles can be solved easily. If you plan to generate puzzles of varying difficulty, then you have a much bigger headache ahead!!!
Back to top
View user's profile Send private message
m_b_metcalf

Joined: 13 Mar 2006
Posts: 210
:
Location: Berlin

Items
PostPosted: Wed Aug 27, 2008 4:40 pm    Post subject: Re: Need help with my first Sudoku generator Reply with quote

daj95376 wrote:
Also, in my mind, it's possible to get to a position where you go straight from multiple solutions to zero solutions.

Surely, if you're generating from a solution grid, there must always be at least one solution?
Quote:

Finally, none of the above addresses the difficulty level of the resulting puzzle. Be aware that over 95% of all Sudoku puzzles can be solved easily. If you plan to generate puzzles of varying difficulty, then you have a much bigger headache ahead!!!

Yes, it's called the Patterns Game!

Regards,

Mike Metcalf
Back to top
View user's profile Send private message
pedrohp

Joined: 26 Aug 2008
Posts: 11
:

Items
PostPosted: Wed Aug 27, 2008 7:00 pm    Post subject: Reply with quote

Hi there,

Thank you all who replied! i really appreciate!

I could guess that i'm gonna need a solver, but i really don't have one already, and in fact, i don't get the slightest idea on how to code a solver... Specially because the solver for this task has to determine how many possible solutions there are.

In fact, i was trying to avoid programming a solver, because if i have a solve, i could simply try to generate a new valid board from the solver approach... so i wasted my time coding this solved board generator... : (

Also, i had a talk to my professor who gave-me this task and he told me that i should build a Graph from the board and the use my generated grid to color the Graph. After colored, i should search inside this graph for the smallest connected structure. This should get me to the (theoricaly) hardest possible board.

I managed to create the Graph matrix, but i think that searching this structure shall be very hard to code, so i'll try what you guys proposed here first...

Sorry for my bad english, i'm not a native english speaker...
Back to top
View user's profile Send private message
daj95376

Joined: 05 Feb 2006
Posts: 349
:

Items
PostPosted: Thu Aug 28, 2008 6:50 pm    Post subject: Reply with quote

I hesitate to offer an alternate approach because I consider it a terrible option. That said ...

You can write a backtracking -- i.e., brute force -- routine that takes the puzzle and starts from cell [r1c1] and systematically assigns a candidate as it moves from cell-to-cell until it finally reaches cell [r9c9].

Now, use the same routine but have it backtrack from cell [r9c9] to [r1c1]. If the solution is the same as the first, then the puzzle has one solution (In my opinion).

Important: the routine must assign candidate values in the same order -- no matter which direction it is traveling Exclamation
Back to top
View user's profile Send private message
pedrohp

Joined: 26 Aug 2008
Posts: 11
:

Items
PostPosted: Thu Aug 28, 2008 11:38 pm    Post subject: Reply with quote

daj95376 wrote:

You can write a backtracking -- i.e., brute force -- routine that takes the puzzle and starts from cell [r1c1] and systematically assigns a candidate as it moves from cell-to-cell until it finally reaches cell [r9c9].

Now, use the same routine but have it backtrack from cell [r9c9] to [r1c1]. If the solution is the same as the first, then the puzzle has one solution (In my opinion).

Important: the routine must assign candidate values in the same order -- no matter which direction it is traveling Exclamation


I think that this implementation you suggested will just find the first solution avaliable in forward and backward. There might be other solutions... Please, correct-me if i'm wrong!

Or else, it seems that i got to implement the DLX. Does anybody know a easier way for me to find out if a board has more then one solution?
Back to top
View user's profile Send private message
m_b_metcalf

Joined: 13 Mar 2006
Posts: 210
:
Location: Berlin

Items
PostPosted: Fri Aug 29, 2008 6:10 am    Post subject: Reply with quote

pedrohp wrote:
Does anybody know a easier way for me to find out if a board has more then one solution?


The easist way is to write a backtracking solver. It doesn't necessarily have to be DLX. Since you claim to have a backtacking generator, you would seem to have the basics already in place. You can worry about efficiency later.

I know of no way to prove, without counting, that a candidate puzzle has multiple solutions, other than by finding one solution, determining all the unavoidable sets that it contains, and showing that at least one is not covered. You may not want to get into that.

Regards,

Mike Metcalf
Back to top
View user's profile Send private message
Lunatic

Joined: 11 Mar 2007
Posts: 166
:
Location: Ghent - Belgium

Items
PostPosted: Fri Aug 29, 2008 11:15 am    Post subject: Reply with quote

pedrohp wrote:
Does anybody know a easier way for me to find out if a board has more then one solution?


You can take a look at the brute force backtracking solver code written in Visual Basic, wich is an easy language to understand, and use it as a guide for your own solver. See topic: Dancing Links and Visual Basic
The code in that topic is a substitute for Dancing Links without using pointers, and is based upon the 4 line brute force solver (see topic: four line sudoku solver ) where rwaddilove wrote:

Quote:
Sudoku puzzles can be solved with just 4 lines of code. Here's it is:

1 sp(cell(ptr))=(sp(cell(ptr)) + 1) mod 10
2 if sp(cell(ptr))=0 then ptr=ptr+1:goto 1
3 if countnum(cell(ptr))=3 then ptr=ptr-1
4 if ptr>-1 then goto 1

Of course, it needs a bit of explanation. This is a brute force method, but it is so short and simple that it is very fast. You need to create two arrays and a pointer like this:

sp(80) is the sudoku puzzle - 9 x 9 grid, 81 cells, numbered 0-80
cell(80) is a list of blank cells - when you read in the puzzle, store the blank cell numbers here
ptr=points to the last blank cell in the list

One other thing you need is a countnum() function. This counts how many times a number appears. It should appear once in a row, once in a column and once in a block, hence the if countnum()=3 then...

That's it. You want to see some real code? Here it is in Visual Basic - I dislike goto so the structured version is a little longer:
Code:

While ptr > -1
  sp(cell(ptr)) = (sp(cell(ptr)) + 1) Mod 10
  If sp(cell(ptr)) = 0 Then
    ptr = ptr + 1
  Else
    If CountNum(cell(ptr)) = 3 Then ptr = ptr - 1
  End If
Wend

That's the main program loop that solves the puzzle in sp() - just print out the array afterwards to see the solution. The CountNum() function just counts the occurances like this:
Code:

Function CountNum(ByVal n As Integer) As Integer
Dim i, j, k, r, c As Integer

k = 0   'count

'check the row and column
r = n \ 9   'row 0-8
c = n Mod 9   'column 0-8
For i = 0 To 8
  If sp(r * 9 + i) = sp(n) Then k = k + 1   'row
  If sp(c + i * 9) = sp(n) Then k = k + 1   'column
Next

'check the block
c = 3 * (c \ 3)   'left column of block 0/3/6
r = 3 * (r \ 3)    'top row of block 0/3/6
For i = 0 To 2
  For j = c To c + 2
    If sp((r + i) * 9 + j) = sp(n) Then k = k + 1
  Next
Next
CountNum = k

End Function

This function could be made faster by checking the row and exiting if there's more than one, then checking the column and exiting if more than one, then checking the block. It would save some checking. However, it seems fast enough as it is. VB isn't particularly quick, but simple puzzles are solved instantaneously and the hard ones only take 5 or 10 seconds.






Marc.
_________________
Marc
~~~<><~~~<><~~~<><~~~<><~~~
Back to top
View user's profile Send private message Send e-mail Visit poster's website
daj95376

Joined: 05 Feb 2006
Posts: 349
:

Items
PostPosted: Fri Aug 29, 2008 2:54 pm    Post subject: Reply with quote

pedrohp wrote:
I think that this implementation you suggested will just find the first solution avaliable in forward and backward. There might be other solutions... Please, correct-me if i'm wrong!

Think of it this way. Create a sorted list of all possible solutions to a puzzle. The forward search will find the first entry in the list. The backward search will find the last entry in the list. Unless the puzzle has only one solution, the first entry and the last entry will be different.

My earlier note is still critical!
Back to top
View user's profile Send private message
daj95376

Joined: 05 Feb 2006
Posts: 349
:

Items
PostPosted: Fri Aug 29, 2008 3:04 pm    Post subject: Re: Need help with my first Sudoku generator Reply with quote

m_b_metcalf wrote:
daj95376 wrote:
Also, in my mind, it's possible to get to a position where you go straight from multiple solutions to zero solutions.

Surely, if you're generating from a solution grid, there must always be at least one solution?

If you start with a filled grid and conceal pairs of cells to generate a symmetric puzzle, Then I've never seen a proof that you are guaranteed to reduce it to where it goes from multiple solutions to a single solution. In particular, is there a multiple solution 18? If so, then I rest my case.
Back to top
View user's profile Send private message
m_b_metcalf

Joined: 13 Mar 2006
Posts: 210
:
Location: Berlin

Items
PostPosted: Fri Aug 29, 2008 4:07 pm    Post subject: Re: Need help with my first Sudoku generator Reply with quote

daj95376 wrote:
m_b_metcalf wrote:
daj95376 wrote:
Also, in my mind, it's possible to get to a position where you go straight from multiple solutions to zero solutions.

Surely, if you're generating from a solution grid, there must always be at least one solution?

If you start with a filled grid and conceal pairs of cells to generate a symmetric puzzle, Then I've never seen a proof that you are guaranteed to reduce it to where it goes from multiple solutions to a single solution. In particular, is there a multiple solution 18? If so, then I rest my case.

Right, but that's not what you said in your first statement. Most grids with concealed pairs will have multiple solutions, some combination of concealment may yield one, none can have zero.

I don't understand what you mean by 'multiple solution 18'. Take any minimal 19-clue puzzle and remove any clue and you have an 18-clue pseudo-puzzle with multiple solutions. Are we talking at cross-purposes?

Regards,

Mike Metcalf
Back to top
View user's profile Send private message
daj95376

Joined: 05 Feb 2006
Posts: 349
:

Items
PostPosted: Fri Aug 29, 2008 4:51 pm    Post subject: Re: Need help with my first Sudoku generator Reply with quote

m_b_metcalf wrote:
Are we talking at cross-purposes?

Yes, and I'm the one who missed the boat. I'm sorry for the mix-up Embarassed

Danny
Back to top
View user's profile Send private message
pedrohp

Joined: 26 Aug 2008
Posts: 11
:

Items
PostPosted: Sat Aug 30, 2008 5:33 pm    Post subject: Reply with quote

daj95376 wrote:
Think of it this way. Create a sorted list of all possible solutions to a puzzle. The forward search will find the first entry in the list. The backward search will find the last entry in the list. Unless the puzzle has only one solution, the first entry and the last entry will be different.

My earlier note is still critical!


Ok, i took another look on your last note and this worries me:

daj95376 wrote:
Important: the routine must assign candidate values in the same order -- no matter which direction it is traveling


My generator uses random candidates. Take a look where the arrow poins:


Code:
bool populateCell(int * SudokuBoard, int index){
     int i;
     int RandValues[9]={1,2,3,4,5,6,7,8,9};
     
     //End condition for the recurssion
     if(index == 81){
          return true;
     }
     
     //Shuffles the Candidates
     ShuffleArray(RandValues,9);
     
     //This is a loop to test the values
     for(i=0;i<9;i++){
          SudokuBoard[index]=RandValues[i];  <----------------------------
          if(ValidateBoard(SudokuBoard,index)){
                              if(populateCell(SudokuBoard,index+1)){
                                 return true;
                              }
          }
     }
     SudokuBoard[index]=0;
     return false;
}


My idea for the solver is:

1- Read the board
2- Calculate the Candidate Values for each blank cell
3- Use each cell candidate's array as the RandValues (without the shuffle) int the above shown algorithm to solve the board.

will this be enought?
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
Goto page 1, 2, 3  Next
Page 1 of 3

 
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