八数码问题算法文献综述
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
八数码问题算法
文献综述报告
摘要:随着计算机和网络的大范围普及,电脑游戏也普遍存在于人们的生活中,但是大部分的人都只是看重游戏的娱乐价值(启发思维,培养观察能力、耐心等),而不在乎其本质,比如说它有着什么样的数据结构,它的核心算法是什么等等这些问题。本文就目前一个很经典的算法问题——八数码问题来分析其核心的算法,并且借助前人得出的研究,进一步分析和设计算法。
关键词:八数码;拼图游戏;广度优先搜索;深度优先搜索;A*搜索
1引言
从古至今,“游戏”这个词对于人们来说都不陌生,从古代的斗禽,蹴鞠等到现在的一系列的电脑游戏。尤其是如今的电脑游戏,不胜其数,种类繁多,不亦乐乎,拼图游戏就是其中的一种。所谓的拼图游戏就是把一副完整的图片通过规则的或者不规则的切割后打乱成零片,玩家只需把零片拼凑回原形即可。在这个过程中,要发生无数次的状态改变,在电脑上也如此。不同的是,电脑上的拼图游戏需要一个“看不见”的存储空间来存储这一个个不同的状态。这就必须涉及到数据的存贮方式。尤其是算法,它是拼图游戏的核心,它决定了计算机怎样解决这个问题,同时还影响着这个游戏程序的存储方式。但是,并不是一个能玩的游戏都具有理想的算法和数据结构。因此,对一个游戏的算法进行分析优化并设计出一个理想的算法显得更加重要。此拼图游戏是建立在一个3*3 的方格棋盘上,把棋盘上的打散的八块图片分别用数字1-8标识,棋盘上空的那块标识为0,那么拼图游戏就可以转化成我们算法中极为极为经典的八数码问题。
2 八数码问题的研究现状
2.1 八数码问题的概念
八数码问题也称为九宫问题。在3×3的棋盘,摆有八个棋子,每个棋子上标有1至8的某一数字,不同棋子上标的数字不相同。棋盘上还有一个空格,与空格相邻的棋子可以移到空格中。要求解决的问题是:给出一个初始状态和一个目标状态,找出一种从初始转变成目标状态的移动棋子步数最少的移动步骤。所谓问题的一个状态就是棋子在棋盘上的一种摆法。棋子移动后,状态就会发生改变。解八数码问题实际上就是找出从初始状态到达目标状态所经过的一系列中间过渡状态。
2.2 八数码问题的状态空间法表示
2.2.1状态描述
八数码问题的一个状态就是八个数字在棋盘上的一种放法。每个棋子用它上面所标的数字表示,并用0表示空格,这样就可以将棋盘上棋子的一个状态存储在一个一维数组p[9]中,存储的顺序是从左上角开始,自左至右,从上到下。把
标识的八块图片抽象成一个数字序列,构成一个数组,表示其摆放的位置。例如:
假设初始状态为:⎪⎪⎪⎭⎫ ⎝⎛561407382,目标状态为:⎪⎪⎪⎭
⎫ ⎝⎛567408321 ,那么此八数码问题就
可以转换为从开始系列为[2,8,3,1,0,6,7,4,5]向目标系列为[1,2,3,8,0,4,7,6,5]转化的
问题。也可以用一个二维数组来存放。
2.3八数码问题的搜索算法
2.3.1深度优先搜索
耿国华在研究中指出了深度优先搜索(Depth_First Search ,DFS )的概念:
是指按照深度方向搜索,它类似于树的先根遍历,是树的先根遍历的推广[2]。它的算法思想中有递归算法:首先访问出发点A ,然后依次以A 的未被访问的邻
接点为出发点,深度优先搜索图,直至图中所有与A 有路径相同的顶点都被访
问。若是非连通图,那么图中一定还会有未被访问的顶点,则需要从图中另选一个还未被访问过得顶点作为起始点,重复上述搜索过程,直到图中所有顶点都被访问过为止。除了递归算法外,还用邻接表作为存储结构实现深度优先搜索,其查找邻接点的时间复杂度为O (e ),其中e 是无向图中的边数或有向图中的弧数,则深度优先搜索图的时间复杂度为O (n+e )[2]。
用深度优先搜索求解八数码问题的搜索过程:
(1) 把起始节点 S 放到未扩展节点的OPEN 表(此时OPEN 表是一个堆
栈,后进先出)中。如果此节点为一目标节点,则得到解。
(2) 如果OPEN 为一空表则无解,失败退出。
(3) 把第一个节点(记作节点 n )从 OPEN 表移到CLOSED 表。
(4) 如果节点n 的深度等于最大深度则转向第二步。
(5) 扩展节点n 产生其全部后继节点并把它们放入OPEN 表的前头。如果
没有后继节点则转向第二步。
(6) 如果后继节点中有任一个节点为目标节点,则求得一个解(反向追踪
从目标节点到起始节点的路径),成功退出;否则,转向第二步。
2.3.2广度优先搜索
广度优先搜索和深度优先搜索的基本思路相同。
与深度优先搜寻对应,耿国华还提出广度优先搜索(Breadth_First Search ,
BFS )的概念:是指按照广度方向搜索,它类似于树的层次遍历,是树的层次遍历的推广[2]。其基本的思想是:从图中某个顶点B 出发,首先访问B ;依次访问B 的各个未被访问的邻接点。最后,分别从这些邻接点(端结点)出发,依次访问它们的各个未被访问的邻接点(新的端结点)。注意,访问时应保证:如果B i 和B k 为当前的端结点,且在B i 和B k 之前被访问,则B i 的所有未被访问的邻接
点应在B k的所有未被访问的邻接点之前访问。再重复此步骤,直到所有的端结点均没有未被访问的邻接点为止。若此时还有顶点未被访问,则选一个未被访问的顶点作为起始点,重复上述过程,直到所有的顶点均被访问过为止。
深度优先搜索的过程:
1)把起始节点放到OPEN表中(如果该起始节点为一目标节点,则得到解)。
2)如果OPEN是个空表,则无解,失败退出;否则继续下一步。
3)把第一个节点(记作节点n )从OPEN表移出并把它放入CLOSED的已扩展点表中。
4)扩展节点n如果没有后继节点,则转向第2 步。
5)把n 的所有后继节点放到OPEN 表的末端并提供从这些后继节点回到n 的指针。
6)如果n的任一个后继节点是个目标节点,则找到一个解(反向追踪得到从目标节点到起始节点的路径),成功退出,否则转第3步。
2.3.3 A*搜索
吕国英研究者还提出了启发式搜索的概念:考虑问题给定的特有的性质,选用合适的规则,提高搜索的效率。[3]这正是需要探索的方向。《算法技术手册》提到的A*搜索就是一种启发式搜索,在搜索时能够利用启发式信息,智能地调整搜索策略。其实,A*搜索也是一种迭代有序的搜索,它维护一个棋面状态的开放集合。
以下是《算法技术手册》中所讲的A*搜索的具体描述:
在每次迭代时,A*搜索使用一个评价函数f*(n)评价开放集合中的所有棋面状态,选择最小的棋面状态。定义f*(n)=g*(n)+h*(n):
g*(n)估算从初始状态到状态n的最短走法序列。
h*(n)估算从状态n到目标状态的最短走法序列。
f*(n)估算从初始状态开始,经过状态n,到达目标状态的最短走法序列。
星号*表示使用了启发式信息(自从1968年开发出此算法后,这个记法就被广泛接受),因此f*(n) ,g*(n)以及h*(n)是对实际开销f(n) ,g(n)以及h(n)的估算,而这些实际开销只能在得到解后才能够知道。简而言之,就是f*(n)越低,表示状态n越接近目标状态。
f*(n)最关键的部分是启发式的计算h*(n),因为g*(n)能够在搜索的过程中,通过记录状态n的深度计算出来,如果h*(n)不能准确地区分开有继续搜索价值的状态和没有价值的状态,那么A*搜索不会表现得比上述任何盲目搜索要好。如果能准确地估算h*(n),那么使用f*(n)就能够得到一个开销最小的解。
以下是A*搜索过程[6]:
(1)把初始节点A0 放入Open 表,计算f(A0)。
(2)如果Open 表为空,则问题无解,退出。