项目要求
1)对九宫重排问题,建立图的启发式搜索求解方法;
2)用A*算法求解九宫重排问题。
3х3九宫棋盘,放置数码为1~8的8个棋子,棋盘中留有一个空格,空格周围的棋子可以移动到空格中,从而改变棋盘的布局。根据给定初始布局和目标布局,移动棋子从初始布局到达目标布局,求解移动步骤并输出。请设计算法,使用合适的搜索策略,在较少的空间和时间代价下找到最短路径。
算法与数据结构
A*算法:
A* [1] (A-Star)算法是一种静态路网中求解最短路径最有效的直接搜索方法,也是许多其他问题的常用启发式算法。注意——是最有效的直接搜索算法,之后涌现了很多预处理算法(如ALT,CH,HL等等),在线查询效率是A*算法的数千甚至上万倍。
公式表示为: f(n)=g(n)+h(n),
其中, f(n) 是从初始状态经由状态n到目标状态的代价估计,
g(n) 是在状态空间中从初始状态到状态n的实际代价,
h(n) 是从状态n到目标状态的最佳路径的估计代价。
(对于路径搜索问题,状态就是图中的节点,代价就是距离)
h(n)的选取
保证找到最短路径(最优解的)条件,关键在于估价函数f(n)的选取(或者说h(n)的选取)。
我们以d(n)表达状态n到目标状态的距离,那么h(n)的选取大致有如下三种情况:
1.如果h(n)< d(n)到目标状态的实际距离,这种情况下,搜索的点数多,搜索范围大,效率低。但能得到最优解。
2.如果h(n)=d(n),即距离估计h(n)等于最短距离,那么搜索将严格沿着最短路径进行, 此时的搜索效率是最高的。
3.如果 h(n)>d(n),搜索的点数少,搜索范围小,效率高,但不能保证得到最优解
九宫重排问题:
我们可以把每一种局面当作是一个结点。空白格可以向四个方向移动,移动后的局面是新的结点。显然,我们可以通过bfs来搜索目标局面,并且一旦搜索到就一定是最少移动次数。我们需要解决的问题有两个。
1:如何记录每一种局面。
2:如何判断当前局面是否已经出现过,即之前的搜索过程中已经搜索过了,简单点说就是判重。
问题1解决方法:
我们可以通过声明二维数组,int a[maxstate][9], a[1][9]表示第一种局面,a[2][9]表示第二种局面,这里我们为了表示方便,typedef int State[9]; State st[maxstate];这样的话,第i种局面就可以用st[i]表示。
问题2解决方法:
非常直接的方法声明数组vis[9][9][9][9][9][9][9][9][9],这样的一个九维数组,显然,这样做并不是那么合理的。这里所用的方法是哈希映射。
使用语言及运行环境
- 使用语言:Java
- 环境:JDK1.8
- 工具:IntelliJ IDEA
项目设计
分三个板块,接收系统、运算系统、显示系统