我正在尝试使用数独生成器算法,这是我的c ++代码:
void generateSudoku(num sudoku[][N])
{ int i,j,k;
int vett[N],n,old;
//clean the sudoku matrix filling it with -1
for(i=0;i<N;i++)
for(j=0;j<N;j++)
sudoku[i][j].val=-1;
//generate the sudoku
for(i=0;i<N;){
for(j=0;j<N;){
k=0;
clean(vett,N); //fills the vector with -1
old=sudoku[i][j].val; //saves the actual value
do{
if(k<9){
do{
n=rand()%9+1;
}while(find(vett,N,n)); //generate n while it already exists in vett
vett[k++]=n;
if((!(exists(sudoku,i,j,n))) && (n!=old)){ //if it not exists on row, column and sub-matrix and it's different between the old value, it's OK
sudoku[i][j++].val=n;
if(j==N) i++;
k=10;
}
}
else{
sudoku[i][j].val=-1;
if(j>0) j--;
else if(i>0){
j=N-1;
i--;
}
k=10;
}
}while(k<=9);
}
}
}
它进入循环,我知道原因:
2 7 6 | 9 1 3 | 4 5 8
4 3 9 | 5 7 2 | * *
在这个例子中,它继续生成6-1然后1-6,其中有*,它永远不会完成。但即使我理解为什么它循环,我也不知道纠正它的最佳方法。有人能帮助我吗?
答案 0 :(得分:1)
你必须进一步回溯。第二行的最后一个单元格中没有有效条目。我不确定贪婪算法是否会作为数独生成器工作。我会尝试使用基于堆栈树的方法。
答案 1 :(得分:0)
以下可能有所帮助(未经测试):
void restore(std::vector<int>& v) {
v.clear();
for (int i = 0; i != 9; ++i) {
v.push_back(1 + i);
}
}
void generate(int (&sudoku)[9][9])
{
std::vector<int> allowedSymbols[9][9];
bool succeed = true;
for(int i = 0, j = 0; i != 9; ) {
if (succeed) {
restore(allowedSymbols[i][j]);
succeed = false;
}
while (!allowedSymbols[i][j].empty()) {
int index = rand() % allowedSymbols[i][j].size();
if (!exists(sudoku, i, j, allowedSymbols[i][j][index])) { //if it not exists on row, column and sub-matrix, it is OK
succeed = true;
break;
}
allowedSymbols[i][j].erase(allowedSymbols[i][j].begin() + index);
}
if (succeed) {
++j;
if (j == 9) {
j = 0;
++i;
}
} else {
// backtrack.
--j;
if (j == -1) {
j = 8;
--i;
}
allowedSymbols[i][j].erase(std::find(allowedSymbols[i][j].begin(),
allowedSymbols[i][j].end(),
sudoku[i][j]));
}
}
}