八数码算法研究(转载)

1.4课程设计实验环境
Microsoft Visual C++ 6.0
2问题描述及讨论
程序设计中,需要解决很多问题,除了编写程序过程中的问题,更重要的是算法设计过程中的问题。
2.1问题描述
在3x3的九宫格棋盘上,摆有8 个将牌,每个将牌都刻有1—8中的某个数码。棋盘中留有一个空格,允许其周围的某一个将牌向空格移动,这样通过移动将牌就可以不断改编将牌的布局。这种游戏求解的问题是:给定一种初始的奖牌布局或结构和一个目标布局,问如何移动将牌,实现从初始状态到目标状态的转变。而且,并不是所有初始状态到目标状态之间都存在解,如何判断解的存在与否。
2.2解存在性的讨论
首先,将8数码游戏的某一种状态按行合并,排成一行,共9个数,其中,空格用0表示。这样,8数码游戏的每一种状态都对应于一行数字。
对任意一对数字,如果前面的数字比后面的数大,则为一对逆序。对于一个序列,如果其中有奇数对逆序,则称之为逆序奇;如果其中有偶数对逆序,则称之为逆序偶。这样,对于1—n这n个数,所有的排序可以分为两类,逆序奇和逆序偶。相应的,8数码问题中的每一种状态(出去空格)也有它的奇偶性,称之为奇九宫图和偶九宫图,并有如下结论:
所有的奇九宫图之间是可达的,所有的偶九宫图之间也是可达的,但是奇九宫图和偶九宫图之间互不可达。根据此结论即可判断初始状态和目标状态之间是否可达。
2.3最优解的搜索
由初始状态到达目标状态有多种走步方法,我们的目标是选择一条所走步数最少的路径,即最优解。根据所求得的最优解走步,尽快达到目标状态。本游戏中主要用启发式搜索算法中的A* 算法来解决路径的搜索,而该算法的关键就是选取合适的启发函数。
3.核心算法
本程序的问题之一就是求最优路径,找最小的步数以尽快从初始状态到达目标状态,本设计中主要采用了A* 算法来寻找最优解。
3.1启发式搜索算法介绍
启发式搜索是利用问题拥有的启发式信息引导搜索,以达到减小搜索范围,降低问题复杂度的目的。这种利用启发信息的搜索过程称为启发式搜索。
一般情况下,启发信息过弱,产生式系统在找到一条路径之前将扩展过多的节点,即求得解路径所需搜索的工作量较大;反之,引入强的启发信息,则有可能大大降低搜索工作量,但不能保证找到最佳路径。因此,实际应用中希望最好能引入降低搜索工作量的启发信息而不牺牲找到最佳路径的保证。
在大多数实际问题中,人们感兴趣的是使路径的耗散值和求得路径所需搜索的耗散值两者的某种组合最小,更一般的情况是考虑搜索算法对求解所有可能遇见的问题,其平均的组合耗散值最小。实际上,很难给出一个计算平均组合耗散值 的方法,因此,启发能力的度量也只能根据实际经验判断,没有必要去追求严格的比较结果。
启发式搜索过程中,要对OPEN表进行排序,这就需要有一种方法来计算得拓展节点有希望通过目标节点的不同程度,我们总是希望能找到最有可能同通向目标节点的待拓展节点优先拓展。一种最常用的方法是定义一个评价函数对各个节点进行计算,其目的就是用来估算出“有希望”的节点,如何定义一个评价函数呢?通常可以参考的原则有:一个节点处在最佳路径下的概率:求出任意一个节点与目标节点集之间的距离度量或差异度量:根据格局(博弈问题)或状态的特点来打分,即根据问题的启发信息,从概率角度、差异角度或计分方法给出计算评价函数的方法。
3.2 A*算法
在介绍A* 算法之前,先介绍A算法。
同宽度优先搜索和深度优先搜索,OPEN表用来存储待扩展的节点,CLOSED表登录已扩展节点。利用评价函数 来排列OPEN表节点顺序的图搜索算法称为A算法。其中, 表示已经搜索的深度或者说耗散值, 表示所估计的与目标节点的距离,即启发函数, 是评价函数。A算法的搜索过程见图3.1。 
 


 图3.1 A算法流程图


如果设从节点n到目标节点的最短距离是h*(n),且使用的估价函数满足:h(n)<=h*(n),那么,此时的A算法称之为A*算法。
3.3 算法设计
本程序中使用A*算法来解决路径的搜索,下面来选取启发函数:
设评价函数为 , ,其中, 代表节点的深度,取 表示讨论单位耗散的情况。
分别取 和 ,其中, 为不在位的将牌个数; 为每个将牌与其目标位置之间距离的综合;则有, <= <= 。
本程序中采用 ,对于 ,仍不能估计出交换相邻两个将牌位置难易程度的影响,因此,再引入 分量。 是对节点n中将牌排列顺序的计分值,对非中心位置的将牌,顺着某一方向检查,若某一将牌后面跟的后继者和目标状态相应的将牌顺序不一致时,则将该将牌估分值取为2,一致时取0,对中心位置有将牌时估分取2,无将牌时估分取0;所有非中心位置每个将牌估分总和加上中心位置的将牌估分值定义为 。取 。
4 游戏过程的实现
作为游戏,除了程序运行流畅,有很好的健壮性,还应该有很好的界面,很好的交互性。
4.1程序功能介绍
1)可以分别输入初始状态和目标状态。设计三个Picture控件,以分别显示初始状态、目标状态以及在执行过程中显示搜索过程
2)用户可以选择进行游戏的方式:“人工”或者“机器”
3)选择“人工”,则用户通过点击“上”、“下”、“左”、“右”按钮,人工地移动空白块,以达到目标状态;选择“机器”,则计算机自己搜索最优路径,计算目标状态是否可达,以及计算达到目标状态所需的最少步数
4)若选择了“机器”,搜索到最优解后,点击“自动演示”按钮,就可以自动演示走步过程
4)用户可以设置搜索深度
6)程序中有状态提示以提示用户当前状态
7)当界面应为一些原因显示内容消失时,可以点击“恢复显示”,恢复显示
4.2界面设计
如图4.1为游戏初始界面:


 
图4.1 初始界面


通过点击输入“初始状态”和“输入目标”状态,输入初始态和目标态,其中,0表示空格,如图4.2


 
图4.2 输入状态


选择“人工”,则人手动通过点击“上”、“下”、“左”、“右”按钮走步,如图4.3


 
图4.3


选择“机器”,则应该先搜索最优解,搜索最优解时用到A*算法,状态提示中会显示搜索结果,如图4.4


 
图4.4搜索最优解


得到最优解后,点击“显示走步过程”,每点击一次,走一步,点击“自动演示”,程序自动演示走步过程,如图4.5
 
图4.5
用户还可以设置搜索深度,如图4.6
 
图4.6
5 总结
通过这次课程设计,复习了C++的相关知识以及VC6.0的使用,熟练掌握了C++中类的使用及用MFC设计界面的技术,同时也学到了很多新的知识,如启发式搜索算法等。此外,也锻炼了综合运用以前所学的知识、解决问题以及搭档合作的能力,还提高查阅资料、写作等的能力。
本次课程设计中能力提高的同时,也让我认识到自己的不足之处。可以指导我今后的学习,逐步去完善学习方式,改掉自己的不足。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值