A*算法完美解决八数码问题
C++的八数码的原代码
-----------------------------------------------------*/
#include <iostream>
#include <ctime>
#include <vector>
using namespace std;
const int ROW = 3;
const int COL = 3;
const int MAXDISTANCE = 10000;
const int MAXNUM = 10000;
typedef struct _Node{
int digit[ROW][COL];
int dist; // distance between one state and the destination
int dep; // the depth of node
// So the comment function = dist + dep.
int index; // point to the location of parent
} Node;
Node src, dest;
vector<Node> node_v; // store the nodes
bool isEmptyOfOPEN() {
for (int i = 0; i < node_v.size(); i++) {
if (node_v[i].dist != MAXNUM)
return false;
}
return true;
}
bool isEqual(int index, int digit[][COL]) {
for (int i = 0; i < ROW; i++)
for (int j = 0; j < COL; j++) {
if (node_v[index].digit[i][j] != digit[i][j])
return false;
}
return true;
}
ostream& operator<<(ostream& os, Node& node) {
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++)
os << node.digit[i][j] << ' ';
os << endl;
}
return os;
}
void PrintSteps(int index, vector<Node>& rstep_v) {
rstep_v.push_back(node_v[index]);
index = node_v[index].index;
while (index != 0) {
rstep_v.push_back(node_v[index]);
index = node_v[index].index;
}
for (int i = rstep_v.size() - 1; i >= 0; i--)
cout << "Step " << rstep_v.size() - i
<< endl << rstep_v[i] << endl;
}
void Swap(int& a, int& b) {
int t;
t = a;
a = b;
b = t;
}
void Assign(Node& node, int index) {
for (int i = 0; i < ROW; i++)
for (int j = 0; j < COL; j++)
node.digit[i][j] = node_v[index].digit[i][j];
}
int GetMinNode() {
int dist = MAXNUM;
int loc; // the location of minimize node
for (int i = 0; i < node_v.size(); i++) {
if (node_v[i].dist == MAXNUM)
continue;
else if ((node_v[i].dist + node_v[i].dep) < dist) {
loc = i;
dist = node_v[i].dist + node_v[i].dep;
}
}
return loc;
}
bool isExpandable(Node& node) {
for (int i = 0; i < node_v.size(); i++) {
if (isEqual(i, node.digit))
return false;
}
return true;
}
int Distance(Node& node, int digit[][COL]) {
int distance = 0;
bool flag = false;
for(int i = 0; i < ROW; i++)
for (int j = 0; j < COL; j++)
for (int k = 0; k < ROW; k++) {
for (int l = 0; l < COL; l++) {
if (node.digit[i][j] == digit[k][l]) {
distance += abs(i - k) + abs(j - l);
flag = true;
break;
}
else
flag = false;
}
if (flag)
break;
}
return distance;
}
int MinDistance(int a, int b) {
return (a < b ? a : b);
}
void ProcessNode(int index) {
int x, y;
bool flag;
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COL; j++) {
if (node_v[index].digit[i][j] == 0) {
x =i; y = j;
flag = true;
break;
}
else flag = false;
}
if(flag)
break;
}
Node node_up;
Assign(node_up, index);
int dist_up = MAXDISTANCE;
if (x > 0) {
Swap(node_up.digit[x][y], node_up.digit[x - 1][y]);
if (isExpandable(node_up)) {
dist_up = Distance(node_up, dest.digit);
node_up.index = index;
node_up.dist = dist_up;
node_up.dep = node_v[index].dep + 1;
node_v.push_back(node_up);
}
}
Node node_down;
Assign(node_down, index);
int dist_down = MAXDISTANCE;
if (x < 2) {
Swap(node_down.digit[x][y], node_down.digit[x + 1][y]);
if (isExpandable(node_down)) {
dist_down = Distance(node_down, dest.digit);
node_down.index = index;
node_down.dist = dist_down;
node_down.dep = node_v[index].dep + 1;
node_v.push_back(node_down);
}
}
Node node_left;
Assign(node_left, index);
int dist_left = MAXDISTANCE;
if (y > 0) {
Swap(node_left.digit[x][y], node_left.digit[x][y - 1]);
if (isExpandable(node_left)) {
dist_left = Distance(node_left, dest.digit);
node_left.index = index;
node_left.dist = dist_left;
node_left.dep = node_v[index].dep + 1;
node_v.push_back(node_left);
}
}
Node node_right;
Assign(node_right, index);
int dist_right = MAXDISTANCE;
if (y < 2) {
Swap(node_right.digit[x][y], node_right.digit[x][y + 1]);
if (isExpandable(node_right)) {
dist_right = Distance(node_right, dest.digit);
node_right.index = index;
node_right.dist = dist_right;
node_right.dep = node_v[index].dep + 1;
node_v.push_back(node_right);
}
}
node_v[index].dist = MAXNUM;
}
int main() {
int number;
cout << "Input source:" << endl;
for (int i = 0; i < ROW; i++)
for (int j = 0; j < COL; j++) {
cin >> number;
src.digit[i][j] = number;
}
src.index = 0;
src.dep = 1;
cout << "Input destination:" << endl;
for (int m = 0; m < ROW; m++)
for (int n = 0; n < COL; n++) {
cin >> number;
dest.digit[m][n] = number;
}
node_v.push_back(src);
cout << "Search..." << endl;
clock_t start = clock();
while (1) {
if (isEmptyOfOPEN()) {
cout << "Cann't solve this statement!" << endl;
return -1;
}
else {
int loc; // the location of the minimize node
loc = GetMinNode();
if(isEqual(loc, dest.digit)) {
vector<Node> rstep_v;
cout << "Source:" << endl;
cout << src << endl;
PrintSteps(loc, rstep_v);
cout << "Successful!" << endl;
cout << "Using " << (clock() - start) / CLOCKS_PER_SEC
<< " seconds." << endl;
break;
}
else
ProcessNode(loc);
}
}
return 0;
}
//程序完美运行
相关推荐
Python实现A*算法求解八数码问题:从状态表示到启发式搜索实战
状态空间搜索是人工智能和算法领域的核心概念,它通过系统性地探索所有可能状态来寻找问题的最优解。其基本原理是构建状态图,并应用搜索算法遍历该图。在众多搜索算法中,A*算法因其结合了实际代价与启发式估计而具有重要技术价值,能高效地在庞大状态空间中寻找最优路径,广泛应用于路径规划、游戏AI和机器人导航。本文以经典的八数码问题为应用场景,深入探讨如何使用Python实现A*算法,涵盖状态的可哈希化表示、曼哈顿距离启发函数设计以及开放集与关闭集的高效管理,并针对算法初学者和开发者提供了完整的代码实现与性能优化技巧。
八数码问题求解器:手把手教你用Python实现A*算法(含启发函数调优技巧)
本文详细介绍了如何使用Python实现A*算法解决八数码问题,包括启发函数的设计与调优技巧。通过对比曼哈顿距离和不在位数启发函数的性能,帮助开发者掌握算法优化的核心思想,提升搜索效率。文章还提供了完整的代码实现和工程实践建议,适合算法学习者和Python开发者。
A*搜索算法实战:从原理到代码,手把手解决八数码难题
本文详细介绍了A*搜索算法在解决八数码难题中的应用,从算法原理到代码实现,手把手教你如何设计评估函数、管理Open表和Close表,并追踪移动路径。通过实战案例展示如何用A*算法高效解决初始状态为724506831的八数码问题,并分享性能优化技巧,帮助读者深入理解启发式搜索算法的核心思想与实践方法。
从八数码到A*算法:启发式搜索的实战演练与性能优化
本文深入探讨了从八数码问题到A*算法的启发式搜索实战演练与性能优化。通过经典八数码问题展示了A*算法如何利用曼哈顿距离等启发式函数大幅提升搜索效率,并详细介绍了工程优化技巧,如状态表示优化和并行化探索。文章还涵盖了A*算法在现实场景中的变体应用及常见调试陷阱,为开发者提供了全面的性能调优指南。
从游戏设计视角看八数码问题:如何用搜索算法打造智能解谜引擎
本文从游戏设计视角探讨八数码问题的智能解法,结合搜索算法如宽度优先搜索和深度优先搜索,打造高效解谜引擎。通过状态空间设计、搜索策略优化及启发式提示系统,提升游戏体验与难度曲线控制,为开发者提供实战指南。


Windows SDK/API
