Sudoku solver by graph coloring theory

Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
8 replies · 3K views
BRN
Messages
107
Reaction score
10
Hello everybody!

I have to implement a sudoku solver in C ++ taking advantage by graph coloring theory, where each number to insert is a color of the associated graph node. In particular I would like to use the Welsh-Powell algorithm.

I find myself in trouble starting with this project and I ask you some advice.

I should start from the adjacency matrix associated to the graph of a sudoku 9x9. To build it by hand is a really boring job. Do you know some fastest technique to do this?

Once the graph is modeled, then, how could I manage the numbers (i.e. colors) already attributed to the graph nodes? The W-P algorithm must not color these nodes, because they are already, but must consider their presence...

Do you have any idea to give me?

Thanks so much!
 
Physics news on Phys.org
So the application solves a sudoku puzzle. It doesn't generate it right?

First, I would start by searching around for examples of how others have done it.

The reason being is that your question is rather like asking how to build a car from scratch.
 
  • Like
Likes   Reactions: BRN
BRN said:
I should start from the adjacency matrix associated to the graph of a sudoku 9x9. To build it by hand is a really boring job. Do you know some fastest technique to do this?

Once the graph is modeled, then, how could I manage the numbers (i.e. colors) already attributed to the graph nodes? The W-P algorithm must not color these nodes, because they are already, but must consider their presence...
You only have to program in the adjacency matrix once. It shouldn't take more than a half-hour. It would take longer than that to devise an algorithm to construct the matrix.

When you have code for the W-P algorithm, it might be possible to describe how to initialize the problem, but until then, it is difficult.
 
  • Like
Likes   Reactions: BRN and jedishrfu
FactChecker said:
You only have to program in the adjacency matrix once. It shouldn't take more than a half-hour. It would take longer than that to devise an algorithm to construct the matrix.
I'm not so sure, that's an ## 81^2 ## matrix. Plenty of scope for human error.
BRN said:
Do you know some fastest technique to do this?
The obvious strategy is to add all row adjacencies, then all column adjacencies, then all square adjacencies. Each of these steps is a simple nest of iterators with carefully selected bounds and step size.
 
  • Like
Likes   Reactions: BRN and FactChecker
pbuk said:
I'm not so sure, that's an ## 81^2 ## matrix. Plenty of scope for human error.
Oh! I stand corrected. I made a Sudoku solver and stored the arrangement in a completely different manner. I confused it with another puzzle solver.
Yes, you should make an algorithm to generate the matrix.
 
  • Like
Likes   Reactions: BRN and pbuk
An easy way to generate new sudoku puzzles is to start with a known solution and apply sudoku allowed row col exchanges and remap the numbers.
 
  • Like
Likes   Reactions: BRN
Hi everyone and thank you for your answers.

I made steps forward and now I can generate the adjacency matrix in this way:

[CODE lang="cpp" title="Adjacency Matrix"]matrix Graph::makeAdjMatrix(int nNodes, int matOrder, int blkOrder)
{
matrix adjacencyMatrix(nNodes);
for (int i = 0; i < nNodes; i++)
{
adjacencyMatrix.resize(nNodes);
}

// Map nodes links in rows and columns
for (unsigned int i = 0; i < nNodes; i++)
{
for(unsigned int j = 0; j < nNodes; j++)
{
if(j >= (i/matOrder)*matOrder && j < (i/matOrder)*matOrder + matOrder)
adjacencyMatrix[j] = 1.;
else
if(j%matOrder == i%matOrder)
adjacencyMatrix[j] = 1.;
else
adjacencyMatrix[j] = 0;

}
}

// Map nodes links in every single block
for (unsigned int i = 0; i < nNodes; i++)
{
for(unsigned int r = 0; r < blkOrder; r++)
{
for(unsigned int k = 0; k < blkOrder; k++)
{
if((i/matOrder)%blkOrder == 0 )
for(unsigned int j = 0; j < blkOrder; j ++)
{
adjacencyMatrix[i + matOrder * r][(i/blkOrder)*blkOrder + j + matOrder * k] = 1.;
}
}
}
}

return adjacencyMatrix;
}[/CODE]

However, now, I have a problem in loading a matrix ...
This my code:

[CODE lang="cpp" title="Load Matrix"]matrix InputData::readMatrix(const std::string& nameFile)
{
std::ifstream inFile;
inFile.open(nameFile);
int row, column;
inFile >> row >> column;

matrix inputMatrix(row);

if (row == column)
{
for (int i = 0; i < row; ++i)
{
for (int j = 0; j < column; ++j)
{
inFile >> inputMatrix[j];
}
}
}
else
std::count << "Invalid dimension! Only square matrix allowed." << std::endl;

inFile.close();
return inputMatrix;
}[/CODE]

where with "matrix" I defined

[CODE lang="cpp" title="Definition Matrix"]typedef std::vector<std::vector<int>> matrix;[/CODE]

This code don't work. What's wrong?
 
Ok, maybe it's better if I open a new thread for this issue. Just to not create confusion in this.