简述回溯法

2018.1.16,我看到一道题,它的名字叫做“数独”,问题要求如下:

整个是一个9X9的大宫格,其中又被划分成9个3X3的小宫格。要求在每个小格中放入1-9中的某个数字。要求是:每行、每列、每个小宫格中数字不能重复。

我不知道它应该怎么解,但我知道我可以用回溯法去解决它。于是我打开了两年前算法设计与分析课上的PPT,试图去解决这个问题。以下则是解决这个问题时候的思考和收获:



什么是回溯法?

回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。



它能干什么?

回溯法有“通解法”之称

回溯法可以系统地搜索一个问题的所有解或任一解.

回溯法是一个既带系统性又带跳跃性的搜索算法.

回溯法是解决较为复杂枚举题的一种常用算法.



怎样去实现它?

用回溯法解问题时,应明确定义问题的解空间。问题的解空间至少应包含一个解。

确定了解空间树后,回溯法从根结点出发,以深度优先方式搜索整个解空间。

 用回溯法搜索解答树时,要采用一定策略进行“剪枝”,避免无效搜索,来提高效率。

“剪枝”策略:

  (1)用约束函数剪去不满足条件的子树;

  (2)用限界函数剪去得不到最优解的子树。

递归回溯框架

void backtrack( int t )

{    if (t>n) Output(x);

    else

          for(i=f(n,t); i<=g(n,t); ++i)

        {    x[t]=h(i);

              if(Constrain(t)&&Bound(t) )  backtrack(t+1);  }

}


解题思路:

1.初始化一个二维数组,用来存储全部9X9表格数独数据

2.初始化一个一维数组,用来存储所有空位坐标

3.对于每一个空位,填入1-9范围内的随意数,看是否可行:如果可行,把该数填入空位(numMap[x][y]=i),继续搜索下一位,直到step==stalen(当前空位已经是最后空位)时输出解;否则,说明填入该数导致无解,该数及后面填入的数应该全部废弃,numMap[x][y]=0表示全部置空,重新试填其他得数。


简述回溯法_第1张图片

trynum(x,y,i)代表是否可以在(x,y)处填入数字i,如果当前行或当前列或当前小九宫里面存在该数字,表示不可行,否则可行。


简述回溯法_第2张图片

以上过程其实是一个搜索解的过程。每一个空位都有1-9共九个数值方案,但是根据数独的规则,有些方案是明显不可行的的,我们可以通过该规则进行剪枝操作,即为if (trynum(x,y,i))

你可能感兴趣的:(简述回溯法)