数据结构课程设计 回溯法解决8皇后n皇后问题

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

数据结构课程设计

学院:信息科学技术学院专业:电子信息工程(1)姓名:谢后乐

学号:20101601310015

N皇后问题

N皇后问题:

在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上。

回溯法简介:

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

我们发现,对于许多问题,所给定的约束集D具有完备性,即i元祖(x1,x2,…,xi)满足D中仅涉及到x1,x2,…,xi的所有约束意味着j(j<=i)元组(x1,x2,…)一定也满足D中仅涉及到x1,x2,…,的所有约束,i=1,2,…,n。换句话说,只要存在0≤j≤n-1,使得(x1,x2,…,)违反D中仅涉及到x1,x2,…,的约束之一,则以(x1,x2,…,)为前缀的任何n元组(x1,x2,…,j+1,…,)一定也违反D中仅涉及到x1,x2,…,xi的一个约束,n≥i≥j。因此,对于约束集D具有完备性的问题P,一旦检测断定某个j元组(x1,x2,…)违反D中仅涉及x1,x2,…,的一个约束,就可以肯定,以(x1,x2,…)为前缀的任何n元组(x1,x2,…,)都不会是问题P的解,因而就不必去搜索它们、检测它们。回溯法正是针对这类问题,利用这类问题的上述性质而提出来的比枚举法效率更高的算法。

空间树

回溯法首先将问题P的n元组的状态空间E表示成一棵高为n的带权有序树T,把在E中求问题P的所有解转化为在T中搜索问题P的所有解。树T类似于检索树,它可以这样构造:设Si中的元素可排成xi(1) ,xi(2) ,...,xi(mi-1) ,|Si| =mi,i=1,2,...,n。从根开始,让T的第I层的每一个结点都有mi个儿子。这mi个儿子到它们的双亲的边,按从左到右的次序,分别带权xi+1(1) ,xi+1(2) ,...,xi+1(mi) ,i=0,1,2,...,n-1。照这种构造方式,E 中的一个n元组(x1,x2,...)对应于T中的一个叶子节点,T的根到这个叶子结点的路径上依次的n条边的权分别为x1,x2,...,,反之亦然。另外,对于任意的0≤i≤n-1,E中n元组(x1,x2,...)的一个前缀I元组(x1,x2, (xi)

对应于T中的一个非叶子节点,T的根到这个非叶子结点的路径上依次的I条边的权分别为x1,x2,…,xi,反之亦然。特别,E中的任意一个n元组的空前缀(),对应于T的根。因而,在E中寻找问题P的一个解等价于在T中搜索一个叶子节点,要求从T的根到该叶子结点的路径上依次的n条边相应带的n

个权x1,x2,…满足约束集D的全部约束。在T中搜索所要求的叶子节点,很自然的一种方式是从根出发,按深度优先的逐步深入,即依次搜索满足约束条件的前缀1元组(x1i)、前缀2元组(x1,x2)、…,前缀I元组(x1,x2,…,xi),…,直到i=n为止。在回溯法中,上述引入的树被称为问题P的状态空间树;树T上任意一个结点被称为问题P的状态结点;树T上的任意一个叶子节点被称为问题P的一个解状态结点;树T上满足约束集D的全部约束的任意一个叶子结点被称为问题P的一个回答状态结点,它对应于问题P的一个解

解题思路:

要解决N皇后问题,其实就是要解决好怎么放置这n个皇后,每一个皇后与前面的所有皇后不能在同一行、同一列、同一对角线,在这里我们可以以行优先,就是说皇后的行号按顺序递增,只考虑第i个皇后放置在第i行的哪一列,所以在放置第i个皇后的时候,可以从第1列判断起,如果可以放置在第1个位置,则跳到下一行放置下一个皇后。如果不能,则跳到下一列...直到最后一列,如果最后一列也不能放置,则说明此时放置方法出错,则回到上一个皇后向之前放置的下一列重新放置。此即是回溯法的精髓所在。当第n个皇后放置成功后,即得到一个可行解,此时再回到上一个皇后重新放置寻找下一个可行解...如此后,即可找出一个n皇后问题的所有可行解。

在解决n皇后之前,我们不妨先来看看一个比较简单的例子,也就是8皇后问题,8皇后也就是n皇后问题中的一种特殊情况,我们只要把8皇后问题解决了,n 皇后问题自然也迎刃而解。根据上面解题思路我们写出8皇后的源程序。

#include

#include

#include

#define a 8

int icount=0;

int x;

int site[100];

void queen(int n);

void out();

int panduan(int n);

void main()

{

queen(0);

}

void queen(int n)

{

int i;

if(n==a)

{

out();

return;

}

for(i=1;i<=a;i++)

{

site[n]=i;

if(panduan(n))

queen(n+1);

}

}

int panduan(int n)

{

int i;

for(i=0;i

{

if(site[i]==site[n])

return 0;

if(abs(site[i]-site[n])==(n-i)) return 0;

}

return 1;

}

void out()

{

int i;

printf("no.%-5d",++icount); for(i=0;i

{

printf("%d",site[i]);

}

printf("/n");

}

相关文档
最新文档