回溯法之N皇后问题(C语言)

合集下载

N皇后问题回溯算法探讨

N皇后问题回溯算法探讨
一 一
i 1 : :
变换, 而且有以下结论 :
wi (> ){ * he i 0 / 安置第 i l 行上的皇后 * ( / ※※)
A i++; lJ
定理 1 设 x A 1A 2 .A N ∈SN , =B 1B 2 . B N ∈S = [] []. [ ] ( )y [] []. [ ] ・ -
摘要 : 文在分析 N皇后 问题解的结构的基础 上, 化 了利用回溯 法求解 N皇后 问题 的算法的循环 结束 条件 , 本 优 借助 于矩 阵改进 了互不攻 击的条件 检测方法 。 避免 了求解复杂的逻辑表 述式, 大大地减少 了比较次数, 使得 算法的运行效率更高。
关 键 词 : 皇后 问题 ; 不 攻 击 的布 局 ; N元 互 回溯 算 法
维普资讯 http://www.cqvip.com
6 4
第6 期
N . O6
宜宾学院学报
J r l f inU i r t on Yb n e i u a 0 i v sy
Jn . 0 ue2 6 O
N皇后 问题 回溯 算法探讨
张 万 军
( 宜宾卫生学校 , 四川 宜 宾 64 0 ) 4O0
这便是 N皇后问题的数学模型, 通过解上述复合不等式便可求出 N 皇后问题的所有解, 解该问题的回溯算法见算法一。 算法一: N皇后问题的回溯算法 求解

N皇后问题 回溯法

N皇后问题 回溯法

N皇后问题
在一个n*n的国际象棋棋盘上放置n个皇后,使得它们中任意2个之间都 不互相“攻击”,即任意2个皇后不可在同行、同列、同斜线上。 输出N,⑴求N皇后问题的一种放法;
⑵求N皇后问题的所有放法
分析: N=4时,右图是一组解
要素一: 解空间
一般想法:利用二维数组,用[i,j]确定一个皇后位置!
优化:利用约束条件,只需一维数组即可! x:array[1..n] of integer; x[i]:i表示第i行皇后 x[i]表示第i行上皇后放第几列
注意:同一个问题可以有多种表示,有些表示方法更简单, 所需表示的状态空间更小(存储量少,搜索方法简单)。
n=3时的0-1背包问题用完全二叉树表示的解空间
生成问题状态的基本方法
► ► ► ►
► ►
扩展结点:一个正在产生儿子的结点称为扩展结点 活结点:一个自身已生成但其儿子还没有全部生成的节点称 做活结点 死结点:一个所有儿子已经产生的结点称做死结点 深度优先的问题状态生成法:如果对一个扩展结点R,一旦 产生了它的一个儿子C,就把C当做新的扩展结点。在完成 对子树C(以C为根的子树)的穷尽搜索之后,将R重新变成 扩展结点,继续生成R的下一个儿子(如果存在) 宽度优先的问题状态生成法:在一个扩展结点变成死结点 之前,它一直是扩展结点 回溯法:为了避免生成那些不可能产生最佳解的问题状态, 要不断地利用限界函数(bounding function)来处死那些实 际上不可能产生所需解的活结点,以减少问题的计算量。 具有限界函数的深度优先生成法称为回溯法

基本算法4-回溯法-N皇后问题

基本算法4-回溯法-N皇后问题

1
x1=1 2
x2= 2 3 kill
1
1 2
回溯到结点2生成结点8, 路径变为(1, 3), 则结点8成为E-结点, 它生成结点9和结点11都会被杀死(即它的儿子表示不可能导 x1=1 致答案的棋盘格局), 所以结点8也被杀死, 应回溯.
1
1
1
2
2
3
x2= 2 x2= 3 3 kill 8 x3=2 9 kill x3=4 11 kill
61 2
64
3
16
3
20
4
22
1
25
4 1 27 1
30
4 1
38 41
9 11
4
43 46 48 52 54
57 59
62
2
3
15
2
17
4
21
3
23
4
26
3
1
4
2
39
4
42
1
44
2
1
2
3
3
58
1
60
2
63
1
65
5
10 12
28 31
33 37
47 49
53 55
参考程序段
Procedure try(I:Integer) ; Var j:integer; Begin for j:=1 to N do IF 在J位置安排皇后不冲突,满足条件 then begin 确定A(I)=J,同时确定以后的约束条件 IF 不是最后一个皇后 THEN 递归调用 try(i+1) ELSE 打印结果; 如果I+1出了问题,应在此时回溯。上面的A(I)=J释放, 由于递归时,自动记录了定位时的J值,所以在前面的J值后继续探索。 End; End;

N皇后问题

N皇后问题

湖南城市学院

数学与计算科学学院

算法设计与分析

课程设计

题目: N皇后问题

班级学号: 0909301-40 姓名:夏丽云

时间:2012年6月20日指导老师:赵专政

目录

一.问题描述 (3)

二.伪代码: (3)

三.代码实现 (4)

四.实验结果 (4)

五.存在的问题 (5)

六.算法改进 (5)

七.算法改进二 (8)

八、课程总结 (8)

九、参考文献 (9)

常规N皇后解决问题过程

一.问题描述

运用回溯法解题通常包含以下三个步骤:

(1)针对所给问题,定义问题的解空间;

(2)确定易于搜索的解空间结构;

(3)以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索;

通过上述的基本思路,我们可以将问题描述为:X(j)表示一个解的空间,j表示行数,里面的值表示可以放置在的列数,抽象约束条件得到能放置一个皇后的约束条件

(1)X(i)!=X(k);(2)abs(X(i)-X(k))!=abs(i-k)。应用回溯法,当可以放置皇后时就继续到下一行,不行的话就返回到第一行,重新检验要放的列数,如此反复,直到将所有解解出。也就是对于N×N的棋盘,选择出N个符合i!=r∧j!=s∧|i-r|!=|j-s|∨(i+r)!=(j+s)的点的排列总数。

二.伪代码:

判断点是否符合要求:

place(k, X)

I=1

While i

If x[i]==x[k] or abs(x[i]-x[k])==abs(i-k) then

Return false

I=i+1

Return true

求问题的所有解:

Nqueens(n, X)

Sum=0 , X[1]=0 , k=1

回溯法解八皇后问题

回溯法解八皇后问题
///
Resove the ways of n queens
///////////////////////////////////////////////////////////////////////
/*/
void nqueens( int n )
{ int k = 1;
gx[1] = 0;
while ( k > 0 )
fprintf(fp,"the sum of the ways of queens:%d\n", sum);
printf("the sum of the ways of queens:%d\n", sum);
fclose(fp);
return 1;
}
/*/////////////////////////////////////////////////////////////////////
{ gx[k] = gx[k] + 1;
while ( ( gx[k] <= n ) && ( !place(k) ) )
gx[k] = gx[k] + 1;
if ( gx[k] <= n )
if ( Biblioteka Baidu == n ) print(gx);
else {k = k + 1; gx[k] = 0;}

n皇后 实验报告

n皇后 实验报告

n皇后实验报告

n皇后实验报告

引言:

n皇后问题是一个经典的数学问题,其目标是在一个n×n的棋盘上放置n个皇后,使得它们互不攻击。本实验旨在通过编程实现n皇后问题的解法,并对不

同的算法进行性能分析。

实验方法:

本实验采用Python语言编写程序,实现了两种常见的解法:回溯法和遗传算法。回溯法是一种穷举搜索的方法,通过不断尝试每一种可能的放置方式,直到找

到满足条件的解;而遗传算法则是通过模拟生物进化的过程,利用选择、交叉

和变异等操作逐步优化解的质量。

实验结果:

在实验中,我们分别测试了回溯法和遗传算法在不同规模的n皇后问题上的性

能表现。以下是实验结果的总结:

1. 回溯法:

- 对于规模较小的问题(n<10),回溯法可以在短时间内找到所有解,并输出

结果。

- 随着问题规模的增大,回溯法的搜索时间呈指数级增长。当n=15时,搜索

时间已经超过10秒。

- 回溯法在解决大规模问题时,遇到了组合爆炸的问题,无法在合理的时间内得出结果。

2. 遗传算法:

- 遗传算法对于规模较小的问题表现不如回溯法,因为其需要较长的时间来找到一个较优解。

- 随着问题规模的增大,遗传算法的性能逐渐超过回溯法。当n=20时,遗传算法能够在合理的时间内找到一个较优解。

- 遗传算法在解决大规模问题时,相比回溯法有明显的优势,因为其搜索时间增长较慢。

实验讨论:

通过对实验结果的分析,我们可以得出以下结论:

- 回溯法适用于规模较小的n皇后问题,但在大规模问题上的性能不佳。

- 遗传算法在大规模问题上表现较好,但对于规模较小的问题需要更长的时间来找到较优解。

人工智能--N皇后问题回溯法爬山算法的实现及性能分析

人工智能--N皇后问题回溯法爬山算法的实现及性能分析

N皇后问题爬山法和回溯法的实现及性能

分析

云南大学信息学院

专业:计算机软件与理论

目录

一、N皇后问题 (3)

1.问题描述 (3)

2.数据结构 (3)

二、爬山算法 (3)

1.爬山算法一般介绍 (3)

2. 爬山算法的伪代码 (4)

3. 算法评价 (4)

三、回溯法 (4)

1.回溯法一般介绍 (4)

2. 回溯法的伪代码 (4)

3. 算法评价 (5)

四、算法实现及性能比较 (5)

五、两种算法性能分析 (6)

六、结论 (7)

七、参考文献 (7)

附录 (8)

一、N皇后问题

1.问题描述

(1)n皇后问题:在n*n格的国际象棋上摆放n个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,(2)分别用回溯法(递归)、爬山法和GA算法求解n皇后问题。要求:输入n,并用运行时间比较几种算法在相同规模的问题时的求解效率。列表给出结果。

2.数据结构

1、逻辑结构:用到线性结构包括数组等。

2、存储结构(物理结构):顺序存储结构。

二、爬山算法

1.爬山算法一般介绍

爬山法是指从当前的节点开始,和周围的邻居节点的值进行比较。如果当前节点是最大的,那么返回当前节点,作为最大值(既山峰最高点);反之就用最高的邻居节点来,替换当前节点,从而实现向山峰的高处攀爬的目的。如此循环直到达到最高点。

每次都选择是与目标结点启发函数值最小的那个结点,经过迂回前进,最终达到解决问题的总目标。如果我们把目标函数的几何图形看成一个山峰,那么点的直接移动就像人在爬山,选择方向,逐步向山顶移动。爬山法需要建立一个描述数据库变化的单极值函数,且使极值对应目标状态;选取使函数值增长最大的那条规则作用于数据库;重复上步,直到没有规则使函数值继续增长。

概率算法-n皇后的LV算法

概率算法-n皇后的LV算法

概率算法-n皇后的LV算法

概率算法结束了,要交作业了,其中⼀个题⽬是⽤LV算法解n皇后问题,并且给出当皇后数为12-20时,对于的随机放置皇后数(stepVegas)值。

不想全部从头写,打算找⼀个⽤回溯法求解n皇后的正确代码(因为lv算法⾥⾯有⽤到回溯部分),如果找到了,只需修改部分就可以⽤了。

虽然有个⼩错误,但是其它都对,算法写的很精炼。有了回溯法,修改就⽅便了。

回溯法是采⽤了穷举遍历的思想,优点是可以⼀次性找到所有解,缺点是算法性能较差。

由于n皇后的解是离散分布的,导致了在遍历搜索的过程中,很多都是做“⽆⽤功”。

这个时候LV算法就有了⽤武之地,先随机放置stepVegas个皇后(在前stepVegas⾏),剩下的n-stepVegas⾏调⽤回溯算法就⾏了。

由于遍历搜索的范围缩⼩,算法所需时间减少,响应的返回的解也只是部分解。但是可以通过多次执⾏返回更多的解。

这⾥还有⼀个问题就是stepVegas的值取多少最好,stepVegas过⼩,遍历搜索范围缩⼩不明显,算法时间过长,返回的解多。

stepVegas过⼤,遍历搜索范围⼩,但是随机放置stepVegas个满⾜要求的皇后同样需要花费⼤量时间。

事实上stepVegas的个数与n皇后解的分布情况有关。

举个例⼦,对于8后⽽⾔⼀共有92个解:

简要统计

第1⾏皇后放第1列的解有4个。

第1⾏皇后放第2列的解有8个。

.....

分析前两个皇后

第1⾏皇后放第1列,第2⾏皇后必须放5,6,7才有解。7解最多。

第1⾏皇后放第2列,第2⾏皇后必须放4,5,6,7,8才有解。

回溯法求N皇后问题

回溯法求N皇后问题

Tree-回溯法求N皇后问题

#include

#include

#define N 4 //N皇后

typedef int Chessboard[N + 1][N + 1]; //第0号位置不用

bool check(Chessboard cb, int i, int j) { //看棋盘cb是否满足合法布局

int h, k;

int m = i + j, n = i - j;

for(h=1; h

if(cb[h][j] == 1 && h != i) return false; //检查第j列

if(m-h<=N && cb[h][m-h] == 1 && h != i) return false; //检查斜的,m-h<=N是为了保证不越界

if(h-n<=N && cb[h][h-n] == 1 && h != i) return false; //检查斜的,h-n<=N是为了保证不越界

}

for(k=1; k

return true;

}

void printfChessboard(Chessboard cb) {//打印棋盘

int i, j;

for(i=1; i<=N; i++) {

for(j=1; j<=N; j++) printf("%d ", cb[i][j]);

printf("\n");

}

printf("\n");

}

/*进入本函数时,在n*n棋盘前n-1行已放置了互不攻击的i-1个棋子。现从第i行起继续为后续棋子选择合适位置。当i>n时,求得一个合法的布局,输入之。*/

void trial(int i, Chessboard &cb) {

【题1】n皇后问题

【题1】n皇后问题

【题1】n皇后问题

一个n×n(1≤n≤100)的国际象棋棋盘上放置n个皇后,使其不能相互攻击,即任何两个皇后都不能处在棋盘的同一行、同一列、同一条斜线上,试问共有多少种摆法?

输入:

n输出:

所有分案。每个分案为n+1行,格式:

方案序号

以下n行。其中第i行(1≤i≤n)行为棋盘i行中皇后的列位置。

在分析算法思路之前,先让我们介绍几个常用的概念:

1、状态(state)

状态是指问题求解过程中每一步的状况。在n皇后问题中,皇后所在的行位置i(1≤i≤n)即为其时皇后问题的状态。显然,对问题状态的描述,应与待解决问题的自然特性相似,而且应尽量做到占用空间少,又易于用算符对状态进行运算。

2、算符(operater)

算符是把问题从一种状态变换到另一种状态的方法代号。算符通常采用合适的数据来表示,设为局部变量。n皇后的一种摆法对应

1..n排列方案(a

1,…,a

n)。排列中的每个元素a

i对应i行上皇后的列位置(1≤i≤n)。由此想到,在n皇后问题中,采用当前行的列位置i(1≤i≤n)作为算符是再合适不过了。

由于每行仅放一个皇后,因此行攻击的问题自然不存在了,但在试放当前行的一个皇后时,不是所有列位置都适用。例如(l,i)位置放一个皇后,若与前

1..l-1行中的j行皇后产生对角线攻击(|j-l|=|a

j-i|)或者列攻击(i≠a

j),那么算符i显然是不适用的,应当舍去。因此,不产生对角线攻击和列攻击是n皇后问题的约束条件,即排列(排列a

1,…,a

i,…,a

j,…,a

n)必须满足条件(|j-i|≠|a

j-a

著名算法matlab编程 贪心算法 背包问题 递归算法 Hanoi塔问题 回溯算法 n皇后问题

著名算法matlab编程    贪心算法 背包问题    递归算法 Hanoi塔问题     回溯算法 n皇后问题

20/22
function search() global SCHEME_MATRIX N CURROW for i=1:N%在当前行逐列搜索 if checkchess(CURROW,i) %满足放置条件 SCHEME_MATRIX(end,CURROW)=i;%在当前行放入皇后 if(CURROW<N) CURROW=CURROW+1;search;%进入下一行搜索 else %已在最后一行放入皇后,添加新的方案行 SCHEME_MATRIX=[SCHEME_MATRIX;SCHEME_MATRIX(end,:)]; break; end end end CURROW=CURROW-1;%回溯到上一行, 继续搜索
>> [s,v,t]=backpack(110,[1 10 20 40 45 22 30 55],[10 20 30 50 55 32 40 60]) s= 1 1 1 0 0 1 1 0 v = 132 t = 83
4/22
递 归 算 法 Hanoi塔问题
传说在贝拿勒斯的圣庙里,有块黄铜板,上面竖着3根宝石 柱,这些宝石柱,径不及小指,长仅半臂。大梵天王(印度教 的一位主神)在创造世界的时候,在其中一根柱上放置了64片 中心有插孔的金片。这些金片的大小不一样,大的在下面, 小的在上面,从下而上叠成塔形,这就是所谓的梵天宝塔。 大梵天王立下法则:金片从一柱移到另一柱时,每次只能移 动一片,且移动过程中,小金片永远在大金片上面,绝不允 许颠倒。 大梵天王预言:当金片从它创造世界时的宝石柱移到另一宝 石柱上时,世界末日就要来临,一声霹雳会将梵塔、庙宇和 众生都消灭干净。

算法设计与分析实验报告

算法设计与分析实验报告

算法设计与分析报告

学生姓名

学号

专业班级

指导教师

完成时间

目录

一、课程内容 (3)

二、算法分析 (3)

1、分治法 (3)

(1)分治法核心思想 (3)

(2)MaxMin算法分析 (3)

2、动态规划 (4)

(1)动态规划核心思想 (4)

(2)矩阵连乘算法分析 (5)

3、贪心法 (5)

(1)贪心法核心思想 (5)

(2)背包问题算法分析 (6)

(3)装载问题算法分析 (7)

4、回溯法 (7)

(1)回溯法核心思想 (7)

(2)N皇后问题非递归算法分析 (7)

(3)N皇后问题递归算法分析 (8)

三、例子说明 (9)

1、MaxMin问题 (9)

2、矩阵连乘 (10)

3、背包问题 (10)

4、最优装载 (10)

5、N皇后问题(非递归) (11)

6、N皇后问题(递归) (11)

四、心得体会 (12)

五、算法对应的例子代码 (12)

1、求最大值最小值 (12)

2、矩阵连乘问题 (13)

3、背包问题 (15)

4、装载问题 (17)

5、N皇后问题(非递归) (19)

6、N皇后问题(递归) (20)

一、课程内容

1、分治法,求最大值最小值,maxmin算法;

2、动态规划,矩阵连乘,求最少连乘次数;

3、贪心法,1)背包问题,2)装载问题;

4、回溯法,N皇后问题的循环结构算法和递归结构算法。

二、算法分析

1、分治法

(1)分治法核心思想

当要求解一个输入规模为n,且n的取值相当大的问题时,直接求解往往是非常困难的。如果问题可以将n个输入分成k个不同子集合,得到k个不同的可独立求解的子问题,其中1

那末,这类问题可以用分治法求解。

n皇后 实验报告

n皇后 实验报告

n皇后实验报告

n皇后实验报告

引言:

n皇后问题是一个经典的数学问题,旨在找到在一个n×n的棋盘上放置n个皇后,使得它们互不攻击。这个问题涉及到了组合数学、图论和计算机算法等多个领域,具有一定的难度和挑战性。本实验旨在通过不同的算法和策略来解决n皇后问题,并对它们的效率和性能进行评估。

实验一:暴力法

暴力法是最简单直接的解决方法之一。它通过穷举法遍历所有可能的皇后放置方式,并检查是否满足条件。具体步骤如下:

1. 生成一个空的n×n棋盘。

2. 从第一行开始,依次尝试将皇后放置在每个格子上。

3. 如果当前格子可以放置皇后,则继续下一行;否则,回溯到上一行,重新选择一个可行的格子。

4. 当所有行都放置了皇后时,找到了一个解,记录下来。

5. 继续尝试下一个可能的放置方式,直到遍历完所有情况。

实验结果显示,暴力法在小规模问题上表现良好,但在n较大时,其时间复杂度呈指数级增长,运行时间非常长。

实验二:回溯法

回溯法是一种优化的解决方法,它通过剪枝操作来减少不必要的搜索。具体步骤如下:

1. 生成一个空的n×n棋盘。

2. 从第一行开始,依次尝试将皇后放置在每个格子上。

3. 如果当前格子可以放置皇后,则继续下一行;否则,回溯到上一行,重新选择一个可行的格子。

4. 当所有行都放置了皇后时,找到了一个解,记录下来。

5. 在每次尝试放置皇后时,通过检查当前格子所在的行、列和对角线上是否已经有皇后,来判断是否满足条件。

6. 在每次回溯时,可以通过剪枝操作来减少搜索的空间。

实验结果显示,回溯法相较于暴力法有了一定的提升,但在n较大时,仍然存在一定的时间复杂度问题。

AI--回溯法解决四皇后问题

AI--回溯法解决四皇后问题

AI--回溯法解决四皇后问题

AI -- 回溯法解决四皇后问题

回溯法四皇后C语⾔

问题描述

在 4*4 的棋盘上⽆冲突的摆放 4 个皇后,⽆冲突是指⼀个皇后所在位置的⽔平、竖直以及斜线上不能出现其他的皇后,其他的 n 皇后问题以此类推

解决⽅法

按⾏来摆放棋⼦,下⼀⾏的摆放满⾜于与上⼀⾏的棋⼦没有冲突,否则就返回上⼀步⾛其他的路线,这就是所谓的回溯法详细说明

1. 在第⼀⾏有四种可能,选择第⼀个位置放上皇后

2. 第⼆⾏原本可以有四种可能摆放,但是第⼀第⼆个已经和第⼀⾏的皇后冲突了,因此只剩下第三第四个格⼦了,先选择

第三个格⼦

3. 接下来是第三⾏,根据规则可以看出,第三⾏已经没有位置放了,因为都跟第⼀第⼆⾏的皇后冲突,此时返回到第⼆⾏

第四个

4. 继续来到第三⾏,发现只有第⼆个满⾜条件

5. 然后发现第四⾏已经不能放了,只能继续返回,返回到第⼀⾏,开始下⼀种可能

6. 按照 1-5 的步骤,可以找到下⾯的其中⼀种解法

总⽽⾔之,回溯法就是开始⼀路到底,碰到南墙了就返回⾛另外⼀条路,有点像穷举法那样⾛遍所有的路算法实现

构建⼆维数组,增加规则,利⽤递归实现回溯效果

# include <stdio.h>

# define N 4 // 可以调整

int count=0;

// 判断 Q[i][j] 是否存在冲突

int isCorrect(int i, int j, int (*Q)[N]) {

int s,t;

// 判断⾏

for(s=i,t=0; t<N; t++)

if(Q[s][t]==1 && t!=j)

n皇后的实验报告

n皇后的实验报告

09级计算机科学与技术2班

组长:郭惠芝40912091

小组成员:席菲菲40912098

闫卫红40912099

王铝红40912103

回溯法----------n皇后问题

王铝红,郭惠芝,席菲菲,闫卫红

(陕西师范大学计算机科学学院陕西西安710062)

摘要:文章中对“八皇后问题”进行了分析,给出了一种回溯算法解决“八皇后问题”

并用

C++语言实现,从而上升为对“n皇后问题”的解决。

关键字:回溯法,八皇后问题,算法,实现

Eight Queens Puzzle

Abstract: Article in the “Eight Queens Puzzle” issues were analyzed and given an iteration method to solve “Eight Queen Puzzle” and use C ++ language implementation.

Keywords:Iteration method , Eight Queens Puzzle, Algorithm, Implementation

中心内容:

1、问题描述

八皇后问题,是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论

比较特殊的是,皇后6x6棋盘的解比5 x 5少,其余解的数目随着皇后数目增加。但似乎无数学表达式可以描述。

C语言实现全排列和回溯法总结

C语言实现全排列和回溯法总结

C语⾔实现全排列和回溯法总结⼀、递归实现全排列

1 #include"cstdio"

2int A[50];

3void print_permutation(int n,int *A,int cur){

4if(cur==n){

5for(int i=0;i<n;i++)

6 printf("%d",A[i]);

7 printf("\n");

8 }

9else for(int j=1;j<n+1;j++){

10int ok=1;

11for(int k=0;k<cur;k++)

12if(A[k]==j)

13 ok=0;

14if(ok){

15 A[cur]=j;

16 print_permutation(n,A,cur+1);

17 }

18 }

19 }

20int main(){

21int n;

22 scanf("%d",&n);

23 print_permutation(n,A,0);

24return0;

25 }

View Code

⼆、解答树

1 #include <string.h>

2 #include <iostream>

3

4using namespace std;

5const int N = 99999999; //输⼊排序的个数的最⼤值

6int record[N]; //记录每次排序的序列

7int visited[N]; //标记节点是否被访问过

8int n; //输⼊节点的数⽬

9int totalSize = 0;

10void DFS(int start){

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

//回溯法之N皇后问题当N>10,就有点抽了~~

/*结果前total行每行均为一种放法,表示第i行摆放皇后的列位置,第total+1行,输出total*/

#include

#include

int n,stack[100]; //存当前路径

int total; //路径数

void make(int l) //递归搜索以stack[l]为初结点的所有路径

{

int i,j; //子结点个数

if (l==n+1)

{

total=total+1; //路径数+1

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

printf("%-3d",stack[i]); //输出第i行皇后的列位置stack[i] printf("\n");

exit; //回溯(若试题仅要求一条路径,则exit改为halt即可)}

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

{

stack[l]=i; //算符i作用于生成stack[l-1]产生子状态stack[l];

if (!att(l,i)) make(l+1);

} //再无算符可用,回溯

}

int att(int l,int i)

{

int k;

for (k=1;k

if (abs(l-k)==abs(stack[k]-i)||i==stack[k]) return 1;

return 0;

}

int main()

{

printf("N=");

scanf("%d",&n);

total=0; //路径数初始化为0

make(1); //从结点1出发,递归搜索所有的路径

printf("%d\n",total);

system("pause");

return 0;

}

由回溯法的算法流程可以看出,除非边界条件设置不当而导致死循环外,回溯法一般是不会产生内存溢出的。但是,回溯法亦有其致命的弱点——时间效率

比数学解析法低。为了改善其时效,我们可以从下述几个方面考虑优化:

1、递归时对尚待搜索的信息进行预处理,减少搜索量;

2、尽可能减少分支(解答树的次数);

3、增加约束条件,使其在保证出解的前提下尽可能“苛刻”;

4、在约束条件中设置限定搜索层次的槛值。

相关文档
最新文档