参考博客:https://blog.csdn.net/qq_32400847/article/details/51816685
C++实现代码:
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int Hash[15];
struct node
{
int f,h,g; // f(x) = h(x) + g(x)
// g(x): 到当前状态的步数
// h(x): 预估到达目标的所需代价
int x,y; //空白方格所处坐标
char map[3][3];
friend bool operator<(const node &a,const node &b)
{
if(a.f == b.f) return a.g < b.g;
return a.f > b.f;
}
};
node start;
node goal;
bool vis[500000];
int action[4][2] = {0,-1,0,1,-1,0,1,0};
int goal_x[8] = {0}, goal_y[8] = {0};
//判断是否有解
int check(node a)
{
int s[20];
int cnt=0;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
s[3*i+j] = a.map[i][j];
if(s[3*i+j] == 'x') continue;
for(int k=3*i+j-1; k >= 0; k--)
{
if(s[k] == 'x') continue;
if(s[k] > s[3*i+j]) cnt++; //记录逆序对个数
}
}
}
if(cnt%2) return 0;
return 1;
}
//康托展开
int solve(node a)
{
int s[20];
int ans = 0;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
s[3*i+j] = a.map[i][j];
int cnt = 0;
for(int k = 3*i+j-1; k >= 0; k--)
{
if(s[k] > s[3*i+j]) cnt++;
}
ans = ans + Hash[3*i+j] * cnt;
}
}
return ans;
}
//计算h值,即曼哈顿距离
int Manhattan_Distance(node a)
{
int ans = 0;
for(int i = 0; i < 3; i++)
{
for(int j = 0; j < 3; j++)
{
if(a.map[i][j] == 'x') continue;
int k = a.map[i][j]- '1';
ans += abs(goal_x[k] - i) + abs(goal_y[k] - j);
}
}
return ans;
}
//启发式搜索
int bfs()
{
int _goal = solve(goal);
memset(vis, 0, sizeof(vis));
priority_queue<node> Q;
start.g = 0;
start.h = Manhattan_Distance(start);
start.f = start.h + start.g;
if(solve(start) == _goal) return 0;
Q.push(start);
node u, v; // 前驱和后继节点
while(!Q.empty())
{
u = Q.top();
Q.pop();
int _u = solve(u);
vis[_u] = true;
for(int i = 0; i < 4; i++)
{
v = u;
v.x += action[i][0];
v.y += action[i][1];
if(v.x < 0 || v.y < 0 || v.x > 2 || v.y > 2) continue;
v.map[u.x][u.y] = u.map[v.x][v.y];
v.map[v.x][v.y] = 'x';
v.g += 1;
v.h = Manhattan_Distance(v);
v.f = v.g + v.h;
int _v = solve(v);
if(_v == _goal) return v.g;
if(vis[_v]) continue;
Q.push(v);
}
}
return -1;
}
int main()
{
Hash[0]=1;
for(int i=1;i<=9;i++) Hash[i]=Hash[i-1]*i; //阶乘
int t;
cout << "Please input the number of test data: " << endl;
cin>>t;
for(int i = 0;i < t; i++)
{
cout << "Please input Start State: " << endl;
for(int i=0;i<3;i++)
{
for(int j=0;j<3;j++)
{
char a;
cin >> a;
start.map[i][j] = a;
if(a == '0')
{
start.map[i][j] = 'x';
start.x = i;
start.y = j;
}
}
}
cout << "Please output Goal State: " << endl;
for(int i = 0; i < 3; ++i)
{
for(int j = 0; j < 3; ++j)
{
char a;
cin >> a;
goal.map[i][j] = a;
goal_x[a-'1'] = i;
goal_y[a-'1'] = j;
if(a == '0')
{
goal.map[i][j] = 'x';
goal.x = i;
goal.y = j;
}
}
}
if(check(start) != check(goal))
{
cout << "No Solution!" << endl;
}
else cout << "Steps requiread: " << bfs() << endl;
}
return 0;
}
样例输出: