题目描述
简单介绍一下八数码问题:
在一个3×3的九宫格上,填有1~8八个数字,空余一个位置,例如下图:
1 2 3
4 5 6
7 8
在上图中,由于右下角位置是空的,你可以移动数字,比如可以将数字6
下移一位:
1 2 3 1 2 3
4 5 6 → 4 5
7 8 7 8 6
或者将数字 8 右移一位:
1 2 3 1 2 3
4 5 6 → 4 5 6
7 8 7 8
1~8按顺序排列的情况称为“初始状态”(如最上方图)“八数码问题”即是
求解对于任意的布局,将其移动至“初始状态”的方法。
给定一个的九宫格布局,请输出将它移动至初始状态的移动方法的步骤。
输入
输入包含多组数据,处理至文件结束。每组数据占一行,包含8个数字
和表示空位的‘x’,各项以空格分隔,表示给定的九宫格布局。
例如,对于九宫格
1 2 3
4 6
7 5 8
输入应为:1 2 3 x 4 6 7 5 8
注意,输入的数字之间可能有(不止一个?)空格。
输出
对于每组输入数据,输出一行,即移动的步骤。向上、下、左、右移动
分别用字母u、d、l、r表示;如果给定的布局无法移动至“初始 状态”,
请输出unsolvable。 如果有效的移动步骤有多种,输出任意即可。
首先先介绍一下A*算法
A*算法是 BFS 的一种改进。
定义起点 \(s\) ,终点 \(t\) 。
从起点(初始状态)开始的距离函数 \(g(x)\) 。
到终点(最终状态)的距离函数 \(h(x), h*(x)\) 。
定义每个点的估价函数 \(f(x)=g(x)+h(x)\) 。
A*算法每次从 优先队列 中取出一个 \(f\) 最小的,然后更新相邻的状态。
如果 \(h\leq h*\) ,则 A*算法能找到最优解。
上述条件下,如果 \(h\) 满足三角形不等式,则 A*算法不会将重复结点加入队列 。
其实…… \(h=0\) 时就是 DFS 算法, \(h=0\) 并且边权为 \(1\) 时就是 BFS 。
对于八数码问题(A*经典题)
\(h\) 函数可以定义为,不在应该在的位置的数字个数。
容易发现 \(h\) 满足以上两个性质,此题可以使用 A*算法求解。
代码实现:
/*
A* BFS
1)首先根据逆序对来判断是否有解
2)用状态的曼哈顿距离来作为估价函数
3)BFS {
1、预处理,需要存储步数和上一步状态
2、定义优先队列来进行搜索
3、根据答案倒推出答案
}
*/
/*---------------------------------*/
#include
//IDA*
参考:
八码数-IDA*算法https://blog.csdn.net/weixin_43769146/article/details/103102622
八码数有解条件推广https://blog.csdn.net/tiaotiaoyly/article/details/2008233#commentBox
曼哈頓距離wiki讲解https://zh.wikipedia.org/wiki/%E6%9B%BC%E5%93%88%E9%A0%93%E8%B7%9D%E9%9B%A2
八数码的八个境界 https://www.cnblogs.com/goodness/archive/2010/05/04/1727141.htmlEight HDU - 1043