coursera上普林斯顿大学算法课中第四周的作业,使用A*算法解决八数码问题。

作业的具体要求如下:https://coursera.cs.princeton.edu/algs4/assignments/8puzzle/specification.php

我提交的作业(90分):https://github.com/caozixuan/AlgorithmLearning/tree/master/Exercise/8Puzzle/src

题目要求

八数码问题是一个十分经典的问题,我相信大家小时候肯定都玩过这个游戏。在这个问题中,我们需要设计一个算法,能够快速的找到通向答案的路径。把所有的标签放在应该放置的位子上(题目并不一定是九宫格)。

辅助知识

优先权队列

优先权队列的知识具体可见我的这篇博文 算法笔记:优先权队列

在本次作业中,我们利用优先权队列去储存每一个状态节点极其对应的权值。

A*搜索算法

提到搜索算法,我们首先要明白,搜索算法是干什么的?比较简单的说,搜索算法就像导航软件,是帮助我们找路的。当你站在街上茫然四顾,你就需要你的导航软件,告诉你,前面的几条路,你应该走哪一条。搜索算法也是如此,告诉你应该做什么决策,进入什么状态。

回想一下,我们之前学过哪些搜索算法,比如BFS,DFS,这两种算法告诉你基于宽度优先或者深度优先的原则进行搜索,A*算法要相对复杂一些,它是根据一个评估函数来进行决策的。在评估过程中,我们不断通过将与当前状态相邻的节点加入队列,每次取出评估函数最小的点,继续加入其相邻节点,直到找到其目标为止。下图展示了上述的过程:

下面我们来聊一聊这个评估函数。在A*算法中,这个评估函数被分成了两部分,我们目前已经付出的代价G和我们预计从当前点到目标点还要付出的代价H。已经付出的代价在这个问题中,我们可以认为G = the number of moves,走了一步G就是几,对于H,原链接中给了两种方案,一个是目前有几个数码块还不在它应该在的位置上,另一个是所有数码块与其应该在的位置的曼哈顿距离的和。

需要注意的地方

排除冗余状态

这个地方在原链接中讲的很清楚,大家可以思考一下,什么情况下会出现将相同的状态加入队列的情况。

无解的情况

这个地方困扰了我好久,资料中说到了一个定理,一个有界的状态随意交换两个数码,一定会变成无解的状态。无解的状态,随意交换两个数码,也就一定会变成有解的状态。我们要怎么根据这个定理去判断当前的状态可不可解呢?这个地方的难点是A*算法也没有给你一个范围,告诉你某个规模的问题在多少步内可以求解。后来发现其实很简单,在求解某个问题前,把这个问题变成两个问题,一个是旧问题,一个就是把旧问题中任意两个数码交换。两个问题同时求解。旧问题先得到答案,说明这个问题有解,如果新问题得到答案,就说明旧问题无解。KO!

关键代码

public Solver(Board initial){GameTreeNode root = new GameTreeNode(initial, null);GameTreeNode rootTwin = new GameTreeNode(initial.twin(),null);MinPQ<GameTreeNode> q = new MinPQ<>();MinPQ<GameTreeNode> qTwin = new MinPQ<>();q.insert(root);qTwin.insert(rootTwin);while(true){GameTreeNode curNode = q.delMin();if(curNode.board.isGoal()){canSolve = true;solveNode = curNode;break;}else{for(Board b:curNode.board.neighbors()){if (curNode.father == null || !b.equals(curNode.father.board)) {GameTreeNode node = new GameTreeNode(b, curNode);q.insert(node);}}}GameTreeNode curNodeTwin = qTwin.delMin();if(curNodeTwin.board.isGoal()){canSolve = false;solveNode = null;break;}else{for(Board b:curNodeTwin.board.neighbors()){if(curNodeTwin.father==null||!b.equals(curNodeTwin.father.board)){GameTreeNode node = new GameTreeNode(b,curNodeTwin);qTwin.insert(node);}}}}}

算法笔记:使用A*算法解决八数码问题相关推荐

  1. A*算法解决八数码问题 Java语言实现

    A*算法解决八数码问题 Java语言实现 参考文章: (1)A*算法解决八数码问题 Java语言实现 (2)https://www.cnblogs.com/beilin/p/5981483.html ...

  2. 题目2:隐式图的搜索问题(A*算法解决八数码)

    数据结构课程实践系列 题目1:学生成绩档案管理系统(实验准备) 题目2:隐式图的搜索问题(A*算法解决八数码) 题目3:文本文件单词的检索与计数(实验准备) 文章目录 数据结构课程实践系列 题目1:学 ...

  3. Nilsson's sequence score算法解决八数码问题解释

    解决了最近一个人工智能关于解决八数码难题的作业. 图可能看不清,除了黑块外其他位置是英文字母ABCDEFGH A*:f(n)=g(n)+h(n) 其中f为总花费,g为已知花费(深度),h为估计花费 关 ...

  4. Python利用A*算法解决八数码问题

    资源下载地址:https://download.csdn.net/download/sheziqiong/86790565 资源下载地址:https://download.csdn.net/downl ...

  5. Astar、A星算法解决八数码问题--python实现

    一.问题描述 数码问题又称9宫问题,与游戏"华容道"类似.意在给定的3*3棋格的8个格子内分别放一个符号,符号之间互不相同,余下的一格为空格.并且通常把8个符号在棋格上的排列顺序称 ...

  6. python---A*搜索算法解决八数码问题

    A*解决八数码问题 问题内容 算法流程 相关设置 具体程序 运行结果 遇到的问题 完结 问题内容 [八数码问题] 在一个3×3的九宫中有1-8这8个数字以及一个空格随机摆放在其中的格子里.将该九宫格调 ...

  7. 宽度优先搜索算法解决八数码问题

    宽度优先搜索算法解决八数码问题 原理 1.宽度优先搜索是指在一个搜索树中,搜索以同层邻近节点依次扩展节点.这种搜索是逐层进行的,在对下一层的任一节点进行搜索之前,必须搜索完本层的所有节点. 宽度优先搜 ...

  8. 算法笔记之hoorspool算法

    算法笔记之hoorspool算法 从右往左进行字符扫描,如果所有匹配成功,则找到了匹配的字串,如果遇到不匹配的时候,就需要将模式右移动,这个时候考虑的是文本与模式最后一个字符对齐的文本字符C 当字符不 ...

  9. 深度优先搜索解决八数码难题

    八数码问题 以前用java写的通过深度优先瘦素解决八数码难题. 对于八数码难题来说,可以把9宫格看成一个[3][3]的二维数组,将空格位置看成0,将0可以移动的方向看成树的枝丫,分为上下左右4个方向. ...

  10. A*算法解决八数码问题 人工智能原理实验报告 启发式搜索 python

    目录 一.实验主要步骤 ①.设计界面输入规则 ②.判断是否有解 ③.求解 二.实验结果展示 三.附录 完整实验程序代码: 一.实验主要步骤 ①.设计界面输入规则 有且仅有9位数字代表数码和空格,从左到 ...

最新文章

  1. lzma打包exe_Web 项目打包EXE
  2. 数据库存在即更新的高并发处理 - 转
  3. 【oracle】oracle jdbc驱动与c3p0的一个兼容问题
  4. Jirasearch 2.0狗粮:使用Lucene查找我们的Jira问题
  5. strlen和sizeof的长度区别
  6. 2019有的图纸打印出来看不清楚_CAD制图初学入门:CAD打印实用技巧
  7. 神舟笔记本触摸板驱动_关闭笔记本触摸板的四种方法
  8. 【MyBatis源码解析】MyBatis一二级缓存
  9. 评委打分安卓端与服务管理端的前期准备及操作关键点说明
  10. win11配置jdk1.8环境变量
  11. 一种基于区块链的物联网架构设计
  12. ucfirst() 把字符串中的首字符转换为大写
  13. Hive虚拟内存溢出报错:2.9GB of 2.1GB virtual memory used. Killing container.解决办法
  14. 零基础学前端系列教程 | 和前端谈恋爱的第005天——约会账单
  15. matlab fisher z变换,关于GCA统计
  16. Unity3d Mesh、Texture、UI 压缩降低内存
  17. Arnold Denoise流程
  18. 《数据结构》C语言版 链表的基本操作实现
  19. 华为支付切换到某国家后支付报错60003
  20. tp管理界面找不到服务器,我的TP-LINK路由器无法登陆管理界面

热门文章

  1. vue音乐播放器笔记
  2. java判断闰年条件
  3. 家里wifi网速越来越慢_家里网速变得很慢怎么排查原因
  4. win10下安装Elasticsearch和kibana教程
  5. 黄海广:那些年做的学术公益——你不是一个人在战斗
  6. 拳皇FANS们不得不看的动画
  7. 基于pygame的小游戏开发
  8. 今天属于李志-梵高先生
  9. 金三银四跳槽季,教你这几招提高面试成功率
  10. (转)鲶鱼理论、鲶鱼效应