回溯数独求解器不起作用

Posted

技术标签:

【中文标题】回溯数独求解器不起作用【英文标题】:Sudoku Solver by Backtracking not working 【发布时间】:2009-10-06 03:48:20 【问题描述】:

假设一个二维数组包含一个 9x9 数独网格,我的求解函数在哪里崩溃?我正在尝试使用简单的回溯方法来解决这个问题。谢谢!

bool solve(int grid[9][9])

 int i,j,k;
 bool isSolved = false;

  if(!isSolved(grid))
   isSolved = false;

  if(isSolved)
   return isSolved;

  for(i=0; i<9; i++)
  
   for(j=0; j<9; j++)
   
    if(grid[i][j] == 0)
    
     for(k=1; k<=9; k++)
     
      if(legalMove(grid,i,j,k))
      
       grid[i][j] = k;
       isSolved = solve(grid);
       if (isSolved)
        return true;
      
      grid[i][j] = 0;
     
     isSolved = false;
    
   
  

return isSolved;

即使更改了isSolved 问题,我的解决方案似乎也陷入了无限循环。看起来我错过了一些基本案例步骤,但我不确定在哪里或为什么。我已经查看了类似的解决方案,但仍然无法确定问题所在。我只是想创建基本的求解器,不需要提高效率。感谢您的帮助!

【问题讨论】:

错误是什么?像这样暴力破解数独谜题非常疯狂——第三个内部循环中的递归调用有一些疯狂的排列。 到底是什么问题?您发布了一堆代码,并问“我的功能在哪里中断?”。请描述哪些有效,哪些无效,为什么您无法修复它,以及您希望我们做什么。 【参考方案1】:

是的,你的基本情况搞砸了。在递归函数中,基本情况应该在开始时处理。你有

bool isSolved = false;

if(!isSolved(grid))
    isSolved = false;

if(isSolved)
    return isSolved;

请注意,您的 isSolved 变量永远不能设置为 true,因此您的代码

if(isSolved)
    return isSolved;

无关紧要。

即使你解决了这个问题,它也会感觉像是一个无限循环,即使它是有限的。这是因为您的算法每次调用求解时可能总共需要检查 9*9*9 = 729 个案例。输入此函数 n 次可能需要检查多达 729^n 个案例。显然不会检查很多案例,因为它会在放置非法时找到死胡同,但是谁说可能数字的 90% 的排列导致除了一个数字以外的所有数字都合法的情况?此外,即使您要平均检查 k 个案例,其中 k 是一个小数字(k

诀窍是“尝试”将数字放置在它们很可能成为实际良好位置的地方。可能我能想到的最简单的方法是约束满足求解器,或者具有启发式(如 A*)的搜索算法。

我实际上写了一个基于约束满足求解器的数独求解器,它可以在不到一秒的时间内解决 100x100 的数独问题。

如果奇迹般地“蛮力”回溯算法在 9x9 情况下对您很有效,请尝试更高的值,您会很快看到运行时间的恶化。

我不是在抨击回溯算法,事实上我喜欢它,它一次又一次地表明,如果正确实施回溯可以与动态编程一样有效,但是,在你的情况下,你没有实现它正确。你在暴力破解它,你不妨让你的代码非递归,它会完成同样的事情。

【讨论】:

你能分享你的 100x100 求解器吗?我真的不相信你怎么能在几秒钟内解决它!【参考方案2】:

您将 isSolved 称为函数和布尔变量。 我不认为这是合法的,而且绝对不聪明。

您的函数的名称应该与您的变量不同。

【讨论】:

【参考方案3】:

似乎无论这是否合法,您都将“0”分配给方格,即“grid[i][j] = 0;”线。也许你的意思是把“else”然后“grid[i][j] = 0;” ?

【讨论】:

不这么认为,只有当solve() 的递归调用没有返回true 时,才应该进行赋值,也就是说,将那个特定的值放在那个单元格中没有得到一个解决方案。在这种情况下,您想删除该值并尝试其他方法。

以上是关于回溯数独求解器不起作用的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个“数独求解器”算法不起作用

使用 VBA 最大化的 Excel 求解器不起作用

具有回溯的数独求解器不能总是检测到多个解决方案

为啥这个数独求解器返回相同的板而不解决任何问题?

CAD2014安全系统软件锁许可管理器不起作用或未正确安装

无法回溯以使用递归 javascript 数独求解器