我正在使用一个使用递归回溯算法的解算器制作数独游戏程序,并使用单解决方案数独生成器作为我正在进行的在线CS类的项目。 然而,当与生成器一起使用时,求解器似乎经常陷入无限循环(我使用求解器来检查每一步是否有解决方案),并且我无法弄清楚我的求解函数有什么问题。
我花了很多时间试图找出导致它不按预期行事的原因,但此时我感到困惑。
我不希望任何人提供使用的确切代码,我也不想。但是,如果有人能给我一些关于这个功能有什么问题的指针,我将非常感激。 这是我的代码:
bool solve(int cell)
{
// if reached the end, return true
if (cell == 81)
return true;
// if is a given number, go to next cell
if (givnums[0][cell] == true)
{ // pass in the return value of next cell to previous cell
if (solve(cell + 1) == false)
return false;
else
return true;
}
// find a valid number to insert
for (int i = 1; i <= 9; i++)
{
// if is an invalid move, continue
if (rows[cell / 9][i - 1] == true || cols[cell % 9][i - 1] == true || minigrids[((cell / 9) / 3) * 3 + (cell % 9) / 3][i - 1] == true)
continue;
// else place the number, update all grids and go to next cell
else
{
s_grid[0][cell] = i;
s_rows[cell / 9][i - 1] = true;
s_cols[cell % 9][i - 1] = true;
s_minigrids[((cell / 9) / 3) * 3 + (cell % 9) / 3][i - 1] = true;
// go to next cell
if (solve(cell + 1) == false)
{
// if next cell returns false, undo last step
s_grid[0][cell] = 0;
s_rows[cell / 9][i - 1] = false;
s_cols[cell % 9][i - 1] = false;
s_minigrids[((cell / 9) / 3) * 3 + (cell % 9) / 3][i - 1] = false;
}
// else return true
else
return true;
}
}
// no valid number, return false
return false;
}
该函数在找到解决方案时应返回true,如果没有则返回false。数组s_cols,s_rows和s_minigrids用于跟踪有效移动,而givnums用于跟踪不应触及的数字。
编辑:
所以,如果有人关心的话,还有一点点更新 - 我最新修订的程序(我在这里发布的代码)的逻辑很好。造成这个错误的原因在于这一行:
if (rows[cell / 9][i - 1] == true || cols[cell % 9][i - 1] == true || minigrids[((cell / 9) / 3) * 3 + (cell % 9) / 3][i - 1] == true)
我应该使用s_grid,s_rows等,它们是当前网格状态的副本,可以使用solve()。我错过了那种愚蠢的感觉,但现在一切都很完美!对于强力方法来说它也非常快。生成随机有效sodoku网格只需1-2秒,我在随机空闲单元格中插入一个随机数,并在每一步使用求解器检查是否有解决方案,否则返回一步。