回溯法简单应用--解数独

简单介绍

数独是当下较为流行的数学游戏之一。通常数独由9x9的格子构成,其中将9x9的格子分为9个3x3的区域,称为“宫”(通常宫与宫之间会用较粗的线来分隔)。游戏的目标则是在格子中填满1~9的数字,并且使得数字之间满足一定的约束条件。

对于标准数独,其约数条件如下:

  • 在9x9的格子下,每行,每列不得有重复的数字
  • 每个宫内不得有重复的数字

除了标准数独,还有一系列的升级版本,例如连续数独,对角线数独,窗口数独,杀手数独等等。这里暂时只讨论标准数独的回溯解法。

对于同一个数独题目,存在着有多种解,也可能只有一种解。已知信息和解的数量通常也可以来衡量一个数独题目的难易程度,通常容易的数独给出的已知信息很多,又或者可能拥有很多个解。困难的数独则是给出的已知信息少,而最终解可能只有一个。

下面是关于最简单的破解数独的算法之一 —— 回溯法。回溯法采用深度优先搜索的思想,是常用的一种算法。关于回溯法的经典例子也很多,例如找生成树,0-1背包问题,8皇后问题,走迷宫,全排列问题等等。本文要说的解数独也可以采用回溯法。

本文采用的解数独思想就是最简单的一个个格子去试探,直到试探到把格子填满,既可以检查答案,如果符合则输出。根据这个思想和回溯法的一般步骤,可以得出解数独算法的步骤,此外,这里采用递归的形式。

回溯步骤一 问题的解空间

对于一个数独,每个格子都去试探实际上是一种暴力破解的思想,对于9x9的格子,每个格子可填1~9,如果不做任何限制,问题的解空间树将会是一棵九叉树,这样的搜索空间大小是非常可怕的。

回溯步骤二 确定搜索规则

在讨论解空间后,显然应该意识到,必须确定解空间树的拓展条件来抑制解空间树的指数增长。对于数独来说,搜索规则正好就是数独填数字的规则。对于一个待填格子,选是1~9,在1~9之中,同行同列同宫都出现过的数字就不必让其子节点生成了,从该节点开始,不符合数独规则的搜索结果最终必然不是数独的解。

回溯步骤三 剪枝

搜索规则实质上就是一个剪枝函数,通过剪枝函数提前剔除不可能的解,能够有效地控制解空间树的增长,并且随着搜索的推进,解空间树的增长会越来越缓慢。想象一下当你快要将数独填满的时候,剩下的格子的选择必然是越来越少,甚至能够直接确定某格子只有一个可行的数字。

伪代码描述

backTracking(int index){
    if(index == 81){
        格子已经填满,输出结果
    }
    //x,y表示格子的坐标
    x <-- index % 9;
    y <-- index / 9;
    if(grid(x, y)的数字为题目的信息){
        backTracking(index+1);  /
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值