基于启发式搜索算法A星解决八数码问题
用A星算法解决八数码问题

A*算法解决八数码问题1 问题描述什么是八数码问题八数码游戏包括一个3×3的棋盘,棋盘上摆放着8个数字的棋子,留下一个空位。
与空位相邻的棋子可以滑动到空位中。
游戏的目的是要达到一个特定的目标状态。
标注的形式化如下:问题的搜索形式描述状态:状态描述了8个棋子和空位在棋盘的9个方格上的分布。
初始状态:任何状态都可以被指定为初始状态。
操作符:用来产生4个行动(上下左右移动)。
目标测试:用来检测状态是否能匹配上图的目标布局。
路径费用函数:每一步的费用为1,因此整个路径的费用是路径中的步数。
现在任意给定一个初始状态,要求找到一种搜索策略,用尽可能少的步数得到上图的目标状态。
解决方案介绍算法思想(估价函数是搜索特性的一种数学表示,是指从问题树根节点到达目标节点所要耗费的全部代价的一种估算,记为f(n)。
估价函数通常由两部分组成,其数学表达式为f(n)=g(n)+h(n)其中f(n) 是节点n从初始点到目标点的估价函数,g(n) 是在状态空间中从初始节点到n 节点的实际代价,h(n)是从n到目标节点最佳路径的估计代价。
保证找到最短路径(最优解)的条件,关键在于估价函数h(n)的选取。
估价值h(n)<= n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索范围大,效率低。
但能得到最优解。
如果估价值>实际值, 搜索的点数少,搜索范围小,效率高,但不能保证得到最优解。
搜索中利用启发式信息,对当前未扩展结点根据设定的估价函数值选取离目标最近的结点进行扩展,从而缩小搜索空间,更快的得到最优解,提高效率。
启发函数进一步考虑当前结点与目标结点的距离信息,令启发函数h ( n )为当前8个数字位与目标结点对应数字位距离和(不考虑中间路径),且对于目标状态有 h ( t ) = 0,对于结点m和n (n 是m的子结点)有h ( m ) – h ( n ) <= 1 = Cost ( m, n ) 满足单调限制条件。
A星算法求八数码问题实验报告

A星算法求八数码问题实验报告人工智能实验报告实验名称:八数码问题姓名:xx学号:2012210xxxx计算机学院2014年1月14日一.实验目的掌握A*的思想,启发式搜索,来求解在代价最小的情况下将九宫格从一个状态转为另状态的路径。
二.实验内容给定九宫格的初始状态,要求在有限步的操作内,使其转化为目标状态,且所得到的解是代价最小解(2 8 31 6 47 0 52 8 31 6 47 0 5三、A*算法思想:1、思想:A*算法是一种静态路网中求解最短路最有效的直接搜索方法。
估价值与实际值越接近,估价函数取得就越好2、原理:估价函数公式表示为: f(n)=g(n)+h(n),其中 f(n) 是从初始点经由节点n到目标点的估价函数,g(n) 是在状态空间中从初始节点到n节点的实际代价,h(n) 是从n到目标节点最佳路径的估计代价。
保证找到最短路径(最优解的)条件,关键在于估价函数h(n)的选取:估价值h(n)<= n到目标节点的距离实际值,这种情况下,搜索的点数多,搜索范围大,效率低。
但能得到最优解。
并且如果h(n)=d(n),即距离估计h(n)等于最短距离,那么搜索将严格沿着最短路径进行此时的搜索效率是最高的。
如果估价值>实际值,搜索的点数少,搜索范围小,效率高,但不能保证得到最优解。
四、算法流程:Heuristic_Search(启发式搜索)While是从未拓展表中删N为目是,输出路径否,生成n的所有子状态Case:此子状Case:此子状Case:此子状计算该子状记录比已有记录比已有返回五、关键技术:1、使用了CreateChild()函数,求得了任意未拓展九宫格的扩展结点,便于拓展子空间,搜索所有情况。
关键代码:bool CreateChild(NOExtend ns[],NOExtend ne){int i,j,k=0;for(i=0;i<3;i++){for(j=0;j<3;j++){if(ne.cur_sudoku.num[i][j]==0){ //寻找九宫格空缺所在的坐标if(i-1>=0){ //将空格向上移动CopySudoku(ns[k].cur_sudoku,ne.cur_sudo ku);//先把未改变的九宫格复制给九宫格数组的某一元素ns[k].cur_sudoku.num[i][j]=ne.cur_sudoku.num[i-1][j];//然后仅改变此二维九宫格的两项值即可ns[k].cur_sudoku.num[i-1][j]=0;ns[k].dx=1;k++;}if(j+1<=2){ //将空格向右移动CopySudoku(ns[k].cur_sudoku,ne.cur_sudo ku);ns[k].cur_sudoku.num[i][j]=ns[k].cur_su doku.num[i][j+1];ns[k].cur_sudoku.num[i][j+1]=0;ns[k].dx=1;k++;}if(i+1<=2){ //将空格向下移动CopySudoku(ns[k].cur_sudoku,ne.cur_sudo ku);ns[k].cur_sudoku.num[i][j]=ns[k].cur_su doku.num[i+1][j];ns[k].cur_sudoku.num[i+1][j]=0;ns[k].dx=1;k++;}if(j-1>=0){ //将空格向左移动CopySudoku(ns[k].cur_sudoku,ne.cur_sudo ku);ns[k].cur_sudoku.num[i][j]=ns[k].cur_su doku.num[i][j-1];ns[k].cur_sudoku.num[i][j-1]=0;ns[k].dx=1;k++;}return 1;}}}return 0;2、用启发式搜索函数寻找求解路径,运用了A*算法的思想,能够更快的求解出最优解。
启发式搜索 八数码问题

启发式搜索1. 介绍八数码问题也称为九宫问题。
在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。
棋盘上还有一个空格(以数字0来表示),与空格相邻的棋子可以移到空格中。
要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。
所谓问题的一个状态就是棋子在棋盘上的一种摆法。
解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态。
2. 使用启发式搜索算法求解8数码问题。
1) A ,A 星算法采用估价函数()()()()w n f n d n p n ⎧⎪=+⎨⎪⎩, 其中:()d n 是搜索树中结点n 的深度;()w n 为结点n 的数据库中错放的棋子个数;()p n 为结点n 的数据库中每个棋子与其目标位置之间的距离总和。
2)宽度搜索采用f(i)为i 的深度,深度搜索采用f(i)为i 的深度的倒数。
3. 算法流程① 把起始节点S 放到OPEN 表中,并计算节点S 的)(S f ;② 如果OPEN 是空表,则失败退出,无解;③ 从OPEN 表中选择一个f 值最小的节点i 。
如果有几个节点值相同,当其中有一个 为目标节点时,则选择此目标节点;否则就选择其中任一个节点作为节点i ;④ 把节点i 从 OPEN 表中移出,并把它放入 CLOSED 的已扩展节点表中;⑤ 如果i 是个目标节点,则成功退出,求得一个解;⑥ 扩展节点i ,生成其全部后继节点。
对于i 的每一个后继节点j :计算)(j f ;如果j 既不在OPEN 表中,又不在CLOCED 表中,则用估价函数f 把 它添入OPEN 表中。
从j 加一指向其父节点i 的指针,以便一旦找到目标节点时记住一个解答路径;如果j 已在OPEN 表或CLOSED 表中,则比较刚刚对j 计算过的f 和前面计算过的该节点在表中的f 值。
如果新的f 较小,则(I)以此新值取代旧值。
a星算法求解八数码问题python

a星算法求解八数码问题python一、介绍八数码问题是一种经典的智力游戏,也是人工智能领域中的经典问题之一。
在这个问题中,有一个3×3的棋盘,上面摆着1至8这8个数字和一个空格,初始状态和目标状态都已知。
要求通过移动数字,将初始状态变换成目标状态。
其中空格可以和相邻的数字交换位置。
为了解决这个问题,我们可以使用A*算法。
本文将详细介绍如何用Python实现A*算法来求解八数码问题。
二、A*算法简介A*算法是一种启发式搜索算法,常用于寻找最短路径或最优解等问题。
它基于Dijkstra算法,并加入了启发式函数来加速搜索过程。
在A*算法中,每个节点都有两个估价值:g值和h值。
g值表示从起点到该节点的实际代价,h值表示从该节点到目标节点的估计代价。
启发式函数f(n) = g(n) + h(n) 表示从起点到目标节点的估计总代价。
A*算法采用优先队列来保存待扩展的节点,并按照f(n)值从小到大排序。
每次取出队头元素进行扩展,并将扩展出来的新节点按照f(n)值插入队列中。
当扩展出目标节点时,算法结束。
三、八数码问题的状态表示在八数码问题中,每个状态都可以表示为一个3×3的矩阵。
我们可以用一个一维数组来表示这个矩阵,其中0表示空格。
例如,初始状态可以表示为[2, 8, 3, 1, 6, 4, 7, 0, 5],目标状态可以表示为[1, 2, 3, 8, 0, 4, 7, 6, 5]。
四、A*算法求解八数码问题的步骤1.将初始状态加入优先队列中,并设置g值和h值为0。
2.从队头取出一个节点进行扩展。
如果该节点是目标节点,则搜索结束;否则,将扩展出来的新节点加入优先队列中。
3.对于每个新节点,计算g值和h值,并更新f(n)值。
如果该节点已经在优先队列中,则更新其估价值;否则,将其加入优先队列中。
4.重复第2步至第3步直到搜索结束。
五、Python实现以下是用Python实现A*算法求解八数码问题的代码:```import heapqimport copy# 目标状态goal_state = [1,2,3,8,0,4,7,6,5]# 启发式函数:曼哈顿距离def h(state):distance = 0for i in range(9):if state[i] == 0:continuerow = i // 3col = i % 3goal_row = (state[i]-1) // 3goal_col = (state[i]-1) % 3distance += abs(row - goal_row) + abs(col - goal_col)return distance# A*算法def A_star(start_state):# 初始化优先队列和已访问集合queue = []visited = set()# 将初始状态加入优先队列中,并设置g值和h值为0heapq.heappush(queue, (h(start_state), start_state, 0))while queue:# 取出队头元素进行扩展f, state, g = heapq.heappop(queue)# 如果该节点是目标节点,则搜索结束;否则,将扩展出来的新节点加入优先队列中。
启发式搜索A星算法的八数码实现报告

1. 请简述人工智能概念于何时何地由何人第一次正式提出?答:1956年夏,在美国的达特茅斯(Dartmouth )学院,由McCarthy (斯坦福大学,MIT )、Minsky (哈佛大学数学和神经学家)、Lochester (IBM 公司)、Shannon (贝尔实验室)四人共同发起,邀请IBM 公司的Moore 、Samuel ,MIT 的Selfridge 、Solomonff ,还有Simon 、Newell 等人参加学术讨论班,在一起共同学习和探讨用机器模拟智能的各种问题,在会上,经McCarthy 提议,决定使用“人工智能”一词来概括这个研究方向。
这次具有历史意义的会议标志着人工智能这个学科的正式诞生。
2.当前人工智能有哪些学派?简述它们在人工智能理论上有何不同之处?a.符号主义: 起源于数理逻辑 基于逻辑推理 认知是符号的处理过程,推理是问题求解过程(核心是知识表示) 无法表示不确知事物和常识问题 Nilssonb.连接主义: 起源于仿生学 基于神经网络 思维是神经元的连接活动而不是符号运算过程(学习算法和网络结构) 用大量非线性并行处理器模拟大脑 Newellc.行为主义: 起源于控制论 基于”感知-行动” 直接利用机器对环境发出作用后环境对作用者的响应为原型(有限状态机,不表示不推理) 能应付复杂环境 MIT Brooks 3.八数码问题初始状态定义估价函数: f(x) = d(x) + h(x),其中:d(x)表示节点x 的深度,h(x)表示节点x 的棋局与目标节点棋局距离的度数。
(1) 使用以上估价函数进行全局择优搜索,列出头三步搜索中的OPEN 表和CLOSED 表全局择优搜索过程如下:(1) 把初始节点S0放入OPEN 表,f(S0)。
(2) 如果OPEN 表为空,则问题无解,退出。
(3) 把OPEN 表的第一个节点(记为节点n)取出放入CLOSED 表。
(4) 考察节点n 是否为目标节点。
八数码问题C语言A星算法详细实验报告含代码【范本模板】

一、实验内容和要求八数码问题:在3×3的方格棋盘上,摆放着1到8这八个数码,有1个方格是空的,其初始状态如图1所示,要求对空格执行空格左移、空格右移、空格上移和空格下移这四个操作使得棋盘从初始状态到目标状态。
例如:图1 八数码问题示意图请任选一种盲目搜索算法(广度优先搜索或深度优先搜索)或任选一种启发式搜索方法(全局择优搜索,加权状态图搜索,A 算法或A*算法)编程求解八数码问题(初始状态任选)。
选择一个初始状态,画出搜索树,填写相应的OPEN 表和CLOSED表,给出解路径,对实验结果进行分析总结,得出结论。
二、实验目的1. 熟悉人工智能系统中的问题求解过程;2. 熟悉状态空间的盲目搜索和启发式搜索算法的应用;3. 熟悉对八数码问题的建模、求解及编程语言的应用。
三、实验算法A*算法是一种常用的启发式搜索算法.在A*算法中,一个结点位置的好坏用估价函数来对它进行评估.A*算法的估价函数可表示为:f'(n)= g’(n)+ h’(n)这里,f'(n)是估价函数,g'(n)是起点到终点的最短路径值(也称为最小耗费或最小代价),h’(n)是n到目标的最短路经的启发值。
由于这个f’(n)其实是无法预先知道的,所以实际上使用的是下面的估价函数:f(n) = g(n) + h(n)其中g(n)是从初始结点到节点n的实际代价,h(n)是从结点n到目标结点的最佳路径的估计代价。
在这里主要是h(n)体现了搜索的启发信息,因为g(n)是已知的。
用f(n)作为f’(n)的近似,也就是用g(n)代替g'(n),h(n)代替h'(n)。
这样必须满足两个条件:(1)g(n)〉=g’(n)(大多数情况下都是满足的,可以不用考虑),且f必须保持单调递增。
(2)h必须小于等于实际的从当前节点到达目标节点的最小耗费h(n)<=h'(n).第二点特别的重要。
可以证明应用这样的估价函数是可以找到最短路径的。
基于A星算法的8数码问题求解方案设计(1)

基于A星算法的8数码问题求解⽅案设计(1)⼀、问题描述8数码问题⼜称9宫问题,与游戏“华容道”类似。
意在给定的33棋格的8个格⼦内分别放⼀个符号,符号之间互不相同,余下的⼀格为空格。
并且通常把8个符号在棋格上的排列顺序称作8数码的状态。
开始时,规则给定⼀个初始状态和⼀个⽬标状态,并要求被试者对棋格内的符号经过若⼲次移动由初始状态达到⽬标状态,这个过程中只有空格附近的符号可以朝空格的⽅向移动,且每次只能移动⼀个符号。
为⽅便编程和表⽰,本⽂中8个格⼦内的符号分别取1—8的8个数字表⽰,空格⽤0表⽰。
并给定8数码的初始状态和⽬标状态分别如图1、2所⽰。
图1 初始状态图2 ⽬标状态则要求以图1为初始状态,通过交换0和0的上、下、左、右四个⽅位的数字(每次只能和其中⼀个交换),达到图2所⽰⽬标状态。
⼆、实验⽬的熟悉和掌握启发式搜索的定义、估价函数和算法过程,并利⽤A*算法求解N数码难题,理解求解流程和搜索顺序。
三、实验任务1)实现类似于如图所⽰N数码难题演⽰程序。
2)⽤你所熟悉的程序语⾔实现,可以B/S实现,也可以C/S实现四、算法设计根据任务要求,本⽂采⽤A*搜索算法。
但要在计算机上通过编程解决该问题,还应当解决该问题在计算机上表⽰的⽅式,并设计合适的启发函数,以提⾼搜索效率。
①状态的表⽰在A*算法中,需要⽤到open表和closed表,特别是在open表中,待扩展节点间有很严格的扩展顺序。
因此在表⽰当前状态的变量中,必须要有能指向下⼀个扩展节点的指针,以完成对open表中元素的索引。
从这⼀点上看,open表中的元素相互间即构成了⼀个线性表,因此初步选定使⽤结构体表⽰问题的状态。
如图3所⽰,表⽰问题的结构体包括表⽰当前节点状态的DATA和指向open 表中下⼀个待扩展节点的指针NEXT。
图3 结构体现在进⼀步考虑DATA中包括的内容:如图1、2所⽰,8数码问题的提出是以⼀个33数表表⽰的,因此本⽂中采⽤⼀个33的⼆维数组s[3][3]表⽰当前状态的具体信息。
八数码 人工智能实验报告

八数码人工智能实验报告八数码人工智能实验报告引言:八数码是一种经典的数学问题,也是人工智能领域中常用的实验题目之一。
本次实验旨在通过使用搜索算法解决八数码问题,探讨人工智能在解决复杂问题上的应用。
一、问题描述:八数码问题是一种数字排列游戏,使用一个3x3的方格,其中8个方格上各有一个数字,剩下一个方格为空白。
通过移动数字方格,最终将数字按照从小到大的顺序排列,空白方格位于最后一个位置。
例如,初始状态为:1 2 38 47 6 5目标状态为:1 2 34 5 67 8二、算法选择:本次实验采用了A*搜索算法来解决八数码问题。
A*算法是一种启发式搜索算法,通过估计每个搜索节点到达目标状态的代价来进行搜索。
它综合了广度优先搜索和最佳优先搜索的优点,能够高效地找到最优解。
三、实验过程:1. 状态表示:在实验中,我们使用一个3x3的二维数组来表示八数码的状态。
数组中的每个元素代表一个方格的数字,空白方格用0表示。
2. 启发函数:为了评估每个搜索节点到达目标状态的代价,我们需要定义一个启发函数。
本实验中,我们选择了曼哈顿距离作为启发函数。
曼哈顿距离是指每个数字方格与其目标位置之间的水平和垂直距离之和。
3. A*算法:A*算法的核心思想是维护一个优先队列,根据每个搜索节点的估价函数值进行排序。
具体步骤如下:- 将初始状态加入优先队列,并设置初始估价函数值为0。
- 从优先队列中取出估价函数值最小的节点,进行扩展。
- 对于每个扩展节点,计算其估价函数值,并将其加入优先队列。
- 重复上述步骤,直到找到目标状态或者队列为空。
四、实验结果:经过实验,我们发现A*算法能够高效地解决八数码问题。
对于初始状态为随机排列的八数码,A*算法能够在较短的时间内找到最优解。
实验结果表明,A*算法在解决八数码问题上具有较好的性能。
五、实验总结:本次实验通过使用A*搜索算法解决八数码问题,展示了人工智能在解决复杂问题上的应用。
A*算法通过合理的启发函数和优先队列的维护,能够高效地找到最优解。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int statue[size][size]; //记录当前节点的状态 struct Node * Tparent; //用来构成搜索树,该树由搜索图的反向指针构成 struct Node * opennext; //用来构成 open 表,该指针指向该节点在 open 表中的下一个 节点 struct Node * closenext; //用来构成 open 表,该指针指向该节点在 close 表中的下一个 节点 struct Node * brothernext; //构成兄弟链表,该指针指向该节点在兄弟链表中的下一个节 点 int f; //记录当前节点的 f 函数值 int g; //记录当前节点的 g 函数的值 int h; //记录当前节点的 h 函数的值 };
5
get_bestroute (bestNode); return; }
2.2.7 生成 bestNode 所指节点的后继节点
定义一个后继节点链表,表头为 head_b,将 bestNode 所指节点的不是前驱节点的后继 节点,链接到后继及诶单链表中。getchild 函数可以实现这个功能。
//产生 bestNode 的一切后继节点。。 head head_b; //定义 bestNode 的后继节点表 head_b.next=NULL; getchild (&head_b,bestNode); //产生 bestNode 的子节点,将不是 bestNode 的父节点的
while (head_b.next!=NULL) { Node *tmp=getbrother (&head_b); //从后继节点表中取出一个节点记为 tmp,并从
6
后继节点表中删除该节点
Node * atposion; //如果在 open 表中或在 close 表中,则返回 true,并将 atposion 指 向该节点
子节点放入后继节点表中
2.2.8 对后继节点链表中的节点分类处理
利用 getbrother 函数从后继节点链表中取得一个节点,并将该节点从后继节点中移除。 对该节点依照条件,作下面的处理: 利用 atopen 函数判断该节点是否在 open 表中,如果在,则比较该节点与 open 表中状态相 同的节点到搜索树根的距离,即g(������������)的值,如果前者小于后者,则更新搜索树,并用前者替 换掉后者。
利用 atclose 函数判断该节点时候在 close 表中,如果在,则比较该节点与 close 表中状 态相同的节点到搜索树根的距离,即g(������������)的值,如果前者小于后者,则更新搜索树,以及用 前者替换掉后者。
如果上面的两种条件都不满足,即该节点之前在搜索图中没有出现过,则将该节点连接 到搜索树中,并用 move_to_open 函数将该节点连接到 open 表尾部。
} else if (bool at2=atclose(&head_c,tmp,&atposion)) {
if ((atposion->g) > (tmp->g)) { atposion->Tparent=tmp->Tparent; atposion->f=tmp->f; atposion->g=tmp->g; atposion->h=tmp->h;
} } else {
tmp->Tparent=bestNode; move_to_open(&head_o,tmp); continue; } }
2.2.9 转到 2.2.4 ቤተ መጻሕፍቲ ባይዱ续执行。
3 结果分析
3.1 程序运行情况示例
实 验 在 DEVC++ 平 台 上 进 行 , 采 用 C++ 语 言 实 现 算 法 。 实 验 的 完 整 代 码 可 参 见 文 件
定义表头类型,用来定义表头变量。例如,定义一个变量 head_o 来作为 open 表的表头,指 向 open 表的第一个节点。
//定义表头结构 struct head {
struct Node * next; };
3
2.2.2 定义启发式函数
试验中选择的启发式函数是: ������������(������������) = ������������(������������) + ℎ(������������)
2.2.6 判断 bestNode 所指节点是不是属于目标状态
使用 ifequal 函数判断 bestNode 是不是属于目标状态。如果属于,就成功找到目标状态, 利用 get_bestroute 函数输出最佳路径并退出。
if (bool equal=ifequal (bestNode,Sg)) { cout <<"找到目标状态!"<<endl; cout <<"请按任意键,输出最佳路径..."<<endl; system("pause");
人工智能实验报告
基于启发式搜索算法 A*问题求解方法实验
姓名:王鑫
学号:12349021
日期:2016.1.3
摘要
本篇报告的所介绍的内容是使用 A*算法解决八数码问题。包括介绍 A*算法的流程,如 何使用 A*算法来解决八数码问题,本文依照 A*算法的流程,详细的介绍了 A*算法的每一步 的实现方法。最后输入数据对 A*算法的性能作出评估,通过与 BFS 算法的对比,总结了 A* 算法的优势体现在哪里,并且反思了 A*算法存在的不足。
2.2 A*算法解决八数码问题的步骤
2.2.1 定义节点类型
在 A*算法中我们会用到一张 open 表,一张 close 表,一棵搜索树,以及以个搜索图。 这些数据结构中都是由节点彼此链接构成的。所以我们定义如下的节点结类型:
2
其包含一个二维数组 statue 来记录当前节点的状态; 包含多个指针,这些指针的作用是把同一个节点链接在不同的数据结构中。例如,指针 Tparent 的作用是把该节点链接到搜索树中。在该节点被接入搜索树中时对 Tparent 赋值,使 得 Tparent 指向该节点在树中的前驱节点,如果该节点尚未被接入搜索树,则 Tparent 的值 为空。 同理,如果该节点在 open 表中,则 opennext 指向该节点在 open 表中的下一个节点。 其余指针类似也是类似的道理。
1
属于盲搜索算法的广度优先算法不同的是,A*算法从 open 表中选取的是启发式函数值最优 的节点来生成后继节点。所以 A*算法可以大大减少搜索无关节点的数目,从而提高搜索效 率。
2 实验过程
2.1 A*算法的流程
(1)定义两个表,一个是 open 表,用来存放已经生成,并且已用启发式函数做过估计或评 价,但尚未产生他们的后继节点的那些节点。另一个是 close 表,用来存放,已经生成,并 且已经用启发式函数做过估计且已经产生后继节点的那些节点。 (2)初始化两张表,将所有初始状态存放进 open 表中,将 close 表清空。 (3)如果 open 表为空,失败退出 (4)在 open 表中取出启发式函数������������(������������)值最小的节点 n,把 n 放入 close 表中。 (5)如果n ∈ ������������������������(目标状态),则成功退出,此时解为 Tree 上从 n 到������������0(初始状态)的路径。 (6)产生 n 的一切后继,将后继中不是 n 的前驱点的一切点构成集合 M,将装入 G 作为 n 的后继,这就除掉了既是 n 的前驱又是 n 的后继的节点,就避免了回路,节点之间有偏序关 系存在。 (7)对 M 中的任意一个元素 P,分别作两类处理: a.若P ∉ G,即 P 不在 open 表中,也不在 close 表中,则 P 根据一定原则加入到 open 表中, 同时加入搜索图 G 中,对 P 进行估计放入 Tree 中。 b.若P ∈ G,则决定是否更改 Tree 中 P 到 n 的指针。 (8)转第(3)步。
4
head_c.next=NULL; Troot.next=S0;
2.2.4 判断 open 表是否为空
如果 open 表为空,则搜索失败,退出。 if (head_o.next==NULL) {
cout <<"查找失败!"<<endl; return; }
2.2.5 在 open 表中取出最优节点
1 导言
本次试验我准备使用 A*算法解决八数码问题。 八数码问题也称为九宫问题,是在 3×3 的棋盘,摆有八个棋子,每个棋子上标有 1 至 8 的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格,与空格相邻的棋子可以 移到空格中。要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变 成目标状态的移动棋子步数最少的移动步骤。 所谓问题的一个状态就是棋子在棋盘上的一种摆法。棋子移动后,状态就会发生改变。 解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态。 八数码问题一般使用搜索法来解。广度优先搜索是解决八数码问题常用的一种方法,但 是使用广度优先搜索有很大的缺陷,虽然广度优先搜索法在有解的情形总能保证搜索到最短 路经,也就是移动最少步数的路径,但广度优先搜索法的最大问题在于搜索的结点数量太多。 因为在广度优先搜索法中,每一个可能扩展出的结点都是搜索的对象。随着结点在搜索树上 的深度增大,搜索的结点数会很快增长,并以指数形式扩张,从而所需的存储空间和搜索花 费的时间也会成倍增长。 所以本次实验我选用 A*算法来解决八数码问题,A*算法是一种启发式的搜索算法,与
int fvalue; //计算 h(n); int hvalue=0; for (int i=0; i<size; ++i) {