回溯算法与八皇后问题N皇后问题Word版

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

回溯算法与八皇后问题(N皇后问题)

1 问题描述

八皇后问题是数据结构与算法这一门课中经典的一个问题。下面再来看一下这个问题的描述。八皇后问题说的是在8*8国际象棋棋盘上,要求在每一行放置一个皇后,且能做到在竖方向,斜方向都没有冲突。更通用的描述就是有没有可能在一张N*N的棋盘上安全地放N个皇后?

2 回溯算法

回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。

在现实中,有很多问题往往需要我们把其所有可能穷举出来,然后从中找出满足某种要求的可能或最优的情况,从而得到整个问题的解。回溯算法就是解决这种问题的“通用算法”,有“万能算法”之称。N皇后问题在N增大时就是这样一个解空间很大的问题,所以比较适合用这种方法求解。这也是N皇后问题的传统解法,很经典。

下面是算法的高级伪码描述,这里用一个N*N的矩阵来存储棋盘:

1) 算法开始, 清空棋盘,当前行设为第一行,当前列设为第一列

2) 在当前行,当前列的位置上判断是否满足条件(即保证经过这一点的行,列与斜线上都没

有两个皇后),若不满足,跳到第4步

3) 在当前位置上满足条件的情形:

在当前位置放一个皇后,若当前行是最后一行,记录一个解;

若当前行不是最后一行,当前行设为下一行, 当前列设为当前行的第一个待测位置;

若当前行是最后一行,当前列不是最后一列,当前列设为下一列;

若当前行是最后一行,当前列是最后一列,回溯,即清空当前行及以下各行的棋盘,然后,当前行设为上一行,当前列设为当前行的下一个待测位置;

以上返回到第2步

4) 在当前位置上不满足条件的情形:

若当前列不是最后一列,当前列设为下一列,返回到第2步;

若当前列是最后一列了,回溯,即,若当前行已经是第一行了,算法退出,否则,清空当前行及以下各行的棋盘,然后,当前行设为上一行,当前列设为当前行的下一个待测位置,返回到第2步;

算法的基本原理是上面这个样子,但不同的是用的数据结构不同,检查某个位置是否满足条件的方法也不同。为了提高效率,有各种优化策略,如多线程,多分配内存表示棋盘等。

为了便于将上述算法编程实现,将它用另一种形式重写:

Queen()

Loop:

if check_pos(curr_row, curr_col) == 1 then

put_a_queen(curr_row, curr_col);

if curr_row == N then

record_a_solution();

end if;

if curr_row != N then

curr_row = curr_row + 1;

curr_col = 1;

else

if curr_col != N then

curr_col = curr_col + 1;

else

backtrack();

end if;

end if;

else

if curr_col != N then

curr_col = curr_col +1;

else

backtrack();

end if;

end if;

end Queen;

3 实现

3.1 数据结构

这里,用一个N个元素的一维数组来表示。数组的下标表示棋盘的行,数组的元素表示该行皇后所在的列。这个结构自然就消除了列冲突,因为每一行只有一个皇后。还有利用它解决行冲突,也很简单,只要比较各个元素就行了,看有没有相等的元素。斜线冲突也简单,因为同一斜线上的在一直线上,该直线的斜率为+1(左下至右上)或-1(左上至右下),所以,左下至右上的冲突检测方法为看式子是否成立(row –curr_row)/(col –curr_col) = 1,也就是(row - col) = (curr_row –curr_col),相同,则有冲突。同理,左上至右下看式子(row + col) = (curr_row +curr_col)。

这里,也是看下标与其对应元素的和与差是不是与要检测位置的相应结果相同,如果有一个相同,就有冲突。

数据结构一确定,冲突检测方法就有了,关键的部分的算法就完成了。

3.2 代码

/*************************************************************** File: NQueen.c

Descripton: N皇后问题求解之回溯版

Author: liuqh, Hunan University

Date: 2007.5.22, Tues.

Version: 1.0

**************************************************************/

#include

#include

#include

#include

#include

#define SOLS(n) (int)(pow(2.0, (double)(n)))

#define DEBUG

/*************************

全局变量定义

**************************/

int N = -1; /*棋盘的大小*/

char *p_board = NULL; /*指向棋盘,这里是用一个长度为N 的一维数组表示的*/

char *buf = NULL; /* 输出缓冲 */

int buf_index = -1;

相关文档
最新文档