接上一篇博客
本文和上一篇博客相关代码下载地址:http://download.csdn.net/detail/realmagician/6748915
生成可解的智能拼图后(具体方法参见:
http://blog.csdn.net/realmagician/article/details/17395035
)就要想办法找到自动解决的办法。
对于3*3的拼图游戏,有9!种排列方式,其中有一半是可解的。
首先可以暴力搜索,采用dfs的策略,每次大概需要10W次移动,这是不可接受的。。
再就是用A*算法的思想解决。A*算法类似BFS,都是用一个数据结构保存可能的路径,在BFS中用队列,A*中用openList(可以用堆实现)。然后从数据结构中选一个当前代价(拼图中就是移动次数)最少的节点继续搜索。在设置一个数据结构表示已访问过的状态。
BFS只考虑了从起点到当前搜索点的代价。而A*算法是基于估计的,即当前代价由起点到当前搜索点的代价与当前搜索点到目标点的估计代价之和表示,用公式可以表示为:f(n)=C(n)+G(n)。
估计代价是A*的关键之处。我的想法是计算当前状态和目标状态的差异,设当前状态可以用矩阵A[3][3]表示,目标状态可以用矩阵B[3][3]表示。找到A[ai][aj]在B中的对应点B[bi][bj],那么这两个点的距离可以用欧式距离表示dis = sqrt((ai-bi)^2+(aj-bj)^2)。那么估计代价就是两个矩阵中所有点的距离之和G(n) = SUM(dis)。
具体编码的时候用一个双向链表表示openList,但是pre指针不是指向前一个节点,而是指向上一个状态的节点。
class ptstate{
public:
int currentCost;//当前实际代价
int guessCost;//当前实际代价估计代价
int state;
ptstate( int _currentCost=0,int _guessCost=0,int _state=0):currentCost(_currentCost),guessCost(_guessCost),state(_state){};
ptstate(ptstate &_ptstate){
currentCost = _ptstate.currentCost;
guessCost = _ptstate.guessC