八数码问题的A算法解决方案及判定方法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
八数码问题的A*算法解决方案及判定方法
设计说明:1。数据结构和表示:
程序用1、2、3、4分别表示将右、上、左、下的数字块移动到空格之中。采用典型的树+链表结构,每种局面产生一个BoardState类。出于避免走法顺序列表被过多复制的考虑,在树结构中保存局面的继承关系。每种新的局面产生后,引用估值函数产生f的值,再根据大小将其插入链表之中,以便实现“优先展开f 值小的节点”。Solve()函数在成功解决问题之后保存一个走法序列供输出并返回零,而失败则返回失败处的节点层数。(具体的判断方法见后文)
2。A*
A*算法的核心是f=g+h,而由于每个BoardState对象保存了层数信息,所以g就是m_nDepth。关于关键的h,本程序采用的是“曼哈顿距离”,即每个不在目标位置上的数字块到目标位置的最少步数之总和(空位0不计)。由于任何一步中该距离只可能减少1,所以该h值作为当前局面到目标局面的不超过任何可能值的估计是非常好的。该值大于由不在目标位置上的块个数值(记为h'),而又满足h函数的基本条件,所以其性能远优于h'。程序的输出结果中包含展开的节点总数。将Evaluate()改为m_nDepth+h',则可以看出展开的节点总数大于应用h时的情况。
3。终止情况的判断
这是一个很棘手的问题。最开始的程序中没有考虑终止情况,所以对于难度较大或者根本无解的问题其计算规模经过20步以上的指数增长将变得无法承受。翻阅资料并自行设计一些通过随机反向走法产生的可解局面(甚至包括20步以上的可解局面)研究知,A*由于其苛刻的展开节点的条件,将使每层平均的展开数大大降低,且层数越大则平均每层接点展开数b*越低,一般情况下,超过5层即有b*<1.4,在20层以上b*< 1.2。这些可以帮助我们粗略判定一些难解问题甚至无解问题。实验了几个难解局面(在没有终止判定的情况下这几种局面在我的P4机器上运行了30分钟也没有产生结果)后发现,其b*在层数n=7或8时即超过了1.4,而且随着层数而增长。本程序中为保险起见,仅在大于10层且b*>1.4时进行无解判定。实验表明,这种方法对随机生成的有解局面不造成任何影响,而一些公认的“难解”局面被判定为无解
4。有待进一步讨论的问题
终止情况的判断在随机生成了几千个可解局面时完全正常工作,但能否证明b*过大的初始局面就一定无解呢?或者有没有可能这当中某些局面计算规模十分巨大但是可以证明有解呢?这些都需要数学的严格证明。十分欢迎各位高人指点,也欢迎朋友们探讨。