数独的生成和破解算法分析


  最近在捉摸数独的破解方法,自己本不是搞软件的,而是电子的。所以虽然写出来了一个,但是方法很笨拙。 在网上查好时,发现了有一种算法的思维与众不同,既简单又高效,不像其他算法一样递归的太深。

     我对作者的代码分析了下,并且给出了点注释。 原网址是:http://blog.pfan.cn/rickone/22806.html

     

     作者的核心思想是她/他说的:

核心算法:深度优先搜索(其它形式的搜索也可以)

数据结构:如果用递归的形式写深搜,定义在函数dfs里的所有变量都可以看成是这里的数据结构,因为它们自动地被系统压入栈内,所以,省了,你唯一要做的就是一个二维数组,存放当前数独的状态。

当然有了这些,偶还不敢动手做,如果你做过马遍历的程序,大概会有点怕,那才8x8,这里是9x9,不来点‘启发式’谁敢动手写程序,有可能一个数独来几千几万个解,一个解要搜80层上下(估计),懂得树这个数据结构的人就会明白,80层是什么概念,1-9有9个数字,就是9叉树,至少是9^80量级的代价,什么?计算机反正算得快?也不行,再快的计算机遇到指数复杂度的程序也得变回傻子!谢天谢地,棋局尺寸是固定不变的,我们需要做的就是,剪枝。

偶的启发式思想来源于偶想数独的思路,数独之所以难是因为可行情况太多,把这种不确定性降低就会使它变得简单。某个格子上可以填的数字的个数就称为它的不确定度吧,首先,如果一开始空格比较少,那空格上的不确定度就小,数独也就相对容易,同时,随着填上去数字增多,剩余空格上的不确定度也会降低,如果某个格子上的不确定度降到1,那这个格子可以先确定下来,如果降到了0,哦,非常遗憾,在前面的填数中一定是填错了,剪枝也发生在这里,你不得不回退。

详细地说,如果把每个空格做为分枝,那要优先选择哪个分枝进行搜索呢?对每个空格计算它的权值,也就是它的不确定度,然后从中选出最小的一个进行搜索,同时放弃其它空格在这一层上的搜索!也就是说对剩余的空格交给子层处理。这样在某一个结点上的处理就包括两步:1,选择最佳空格,2,遍历这个空格的所有可行值,填入空格,递归。

   生成数独的主要代码是: 

 


  对于破解数独代码:


  作者后面还给出了改进的算法,就不加以介绍了。
posted @ 2011-11-06 22:18  计算机技术  阅读(2881)  评论(0)    收藏  举报