八皇后与回溯算法
Contents
八皇后问题
首先我们了解一下著名的八皇后问题
八皇后问题,一个古老而著名的问题,是回溯算法的典型案例。该问题由国际西洋棋棋手马克斯·贝瑟尔于 1848 年提出:在 8×8 格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有 76 种方案。1854 年在柏林的象棋杂志上不同的作者发表了 40 种不同的解,后来有人用图论的方法解出 92 种结果。计算机发明后,有多种计算机语言可以编程解决此问题。
八皇后的解决思路
思路一:暴力法
- 从棋盘64个方格中,选出任意8个格子摆放皇后,检查每一种可能性
- 一共有 C8/64 中可能性(大约是 4.4 * 10^9种摆法)
思路二:优化暴力法
- 显然每个皇后不可能再同一行
- 所以共有 8 ^ 8(16777216)种摆法,检查每一种摆法是否合理
回溯法
- 回溯 + 剪枝
这就引入了我们今天的主角回溯法
回溯法
回溯法 :可以理解为,通过不同的岔路口来通往目的地(找到想要的结果)
- 每一步检查都选择一条路出发,能进则进,不能进则返回上一步(回溯),换一条路试试.
- 树 / 图的深度优先搜索(DFS), 八皇后,走迷宫都是典型的回溯应用。
四皇后问题
在解决八皇后问题之前,我们先把问题规模减小,看看如何解决四皇后问题
以下为四皇后问题的推导过程
- 从第一行(1,1)开始放入皇后
- 当(1,1)放入皇后之后, 与(1,1) 同行同列同对角线的都不能再放置皇后
- 继续放第二行,(2,1)(2,2)都不能放置皇后, (2,3)可放置皇后
- 放入以后与 (2,3) 同行同列同对角线的位置不能放置皇后
- 继续放置第三方, 我们发现第三行 每一条路都已走不通. (如图一)
- 所以接下来,就是回溯
- 回溯 重新放置第二行到 (2,4)
- 继续放置 第三行(3,2)
- 再继续放置第四行,发现第四行已走不通,所以再次回溯.
- 因为 二,三行已没有其它路可走,所以回溯第一行
- 回溯 将第一行放置 (1,2)
- 继续放置第二行 (2,4)
- 放置第三行 (3,1)
- 放置第四行 (4,3)
- 截止这一步,我们走通了一种可能性
- 再继续放置 (1,3),(2,1),(3,4),(4,2)
- 到这一步,我们又走通了一种可能性
- (1,4)时,如图,依然走不通。
- 所以最终我们的答案是,有两种可能性.
整体思路:
所以 回溯算法解决八皇后问题的总体思路:
- 逐行摆放皇后
- 摆放一行后,找下一行是否有可以摆放的位置
- 如果有,则摆放,继续下一行
- 如果没有,则回溯, 换一种可能的路继续走
- 能走到最后一行,就是其中一种答案
代码如下;
|
|
LeetCode相关题目
其中51 和 面试题08.12 重复, 52和其它两道题的区别,也只在于最终输出形式,基本一样。
Author 飞熊
LastMod Jun 15