生成A*算法求解八数码问题,使用“与目标棋局相比,位置不符的数码数目”的启发函数的C++代码

时间: 2024-03-22 07:38:43 浏览: 31
以下是使用A*算法求解八数码问题的C++代码,其中启发函数使用“与目标棋局相比,位置不符的数码数目”: ``` #include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int maxn = 1000 + 5; const int dx[4] = {-1, 0, 1, 0}; const int dy[4] = {0, 1, 0, -1}; int a[3][3], goal[3][3] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 0}}; int f[maxn], g[maxn], h[maxn], fa[maxn], vis[maxn], d[maxn]; int n = 0; struct node { int a[3][3], x, y, step; int get_h() { int ans = 0; for(int i = 0; i < 3; i++) { for(int j = 0; j < 3; j++) { if(a[i][j] == 0) continue; if(a[i][j] != goal[i][j]) ans++; } } return ans; } bool operator < (const node &rhs) const { return step + h[n] > rhs.step + h[n]; } }; node make_node(int x, int y, int step, int fa) { node tmp; tmp.x = x, tmp.y = y, tmp.step = step, tmp.a[x][y] = a[x][y], tmp.a[x ^ 1][y] = a[x ^ 1][y], tmp.a[x][y ^ 1] = a[x][y ^ 1], tmp.a[x ^ 1][y ^ 1] = a[x ^ 1][y ^ 1]; for(int i = 0; i < 3; i++) { for(int j = 0; j < 3; j++) { if(i == x && j == y) continue; if(i == x ^ 1 && j == y ^ 1) continue; if(i == x && j == y ^ 1) continue; if(i == x ^ 1 && j == y) continue; tmp.a[i][j] = a[i][j]; } } f[++n] = step + h[n], g[n] = step, fa[n] = fa; for(int i = 0; i < n - 1; i++) { if(!memcmp(&tmp, &d[i], sizeof(tmp))) { n--; return d[i]; } } return tmp; } void output(int x) { if(!x) return; output(fa[x]); printf("(%d, %d)\n", d[x].x, d[x].y); } int main() { priority_queue<node> q; node start; for(int i = 0; i < 3; i++) { for(int j = 0; j < 3; j++) { scanf("%d", &a[i][j]); if(a[i][j] == 0) { start.x = i, start.y = j; } } } start.step = 0; memcpy(start.a, a, sizeof(a)); q.push(start); memset(vis, 0, sizeof(vis)); h[0] = start.get_h(); d[0] = start; vis[start.x * 3 + start.y] = 1; while(!q.empty()) { node u = q.top(); q.pop(); if(!u.get_h()) { output(n); return 0; } for(int i = 0; i < 4; i++) { int nx = u.x + dx[i], ny = u.y + dy[i]; if(nx < 0 || nx > 2 || ny < 0 || ny > 2) continue; node v = make_node(nx, ny, u.step + 1, n); if(vis[v.x * 3 + v.y]) continue; q.push(v); vis[v.x * 3 + v.y] = 1; d[n] = v; } } return 0; } ``` 这里使用了一个 `node` 结构体来表示每个状态,其中 `a` 数组表示当前状态的棋盘布局,`x` 和 `y` 表示空格的位置,`step` 表示当前状态的步数,`get_h` 函数用来计算当前状态和目标状态之间的启发函数值。在 `make_node` 函数中,使用了双向 BFS 的思想,从当前状态向周围四个状态转移,如果当前状态已经在前面出现过,则直接返回前面的状态。在主函数中,使用了优先队列来维护状态的搜索顺序,每次取出启发函数值最小的状态进行搜索。

相关推荐

最新推荐

recommend-type

人工智能 A*算法 八数码问题 C++ 报告+代码+详细注释

使用C++语言完整的实现了A星算法解决八数码问题 内容:完整代码和详细注释; 主要函数的功能说明; 评价函数的设计; 运行测试结果
recommend-type

A* (A STAR)算法解决八数码问题

利用启发式搜索中的A*算法解决八数码问题,比传统的宽度优先等搜索算法具有更高的效率
recommend-type

A*算法解八数码问题(报告附录里有源代码),保准能运行

C++实现的A*算法解八数码问题,报告的附录里有源代码,在VC6.0的环境下开发运行的
recommend-type

Java编程实现A*算法完整代码

主要介绍了Java编程实现A*算法完整代码,简单介绍了a星算法,然后分享了完整测试代码,具有一定借鉴价值,需要的朋友可以参考下。
recommend-type

开源、易集成的人脸识别系统

这个图人脸检测服务用于检测图像中的所有人脸。人脸验证可用于:当客户向您提供身份证或驾驶执照并且您需要验证这是否是他时、当用户将他的社交网络帐户连接到您的应用程序并且您想要验证这是否是他时。它能在图像上找到对应的人脸,可以用于收集有关您的商店在不同性别中受欢迎程度的统计数据、收集有关您的活动在哪些年龄段受欢迎的统计数据、获取地标信息以了解客户的视线、收集商店中有多少顾客的统计数据、识别所有顾客是否正确佩戴口罩。
recommend-type

STC89C51 简单时钟

STC89C51 简单时钟,叫你从基础开始学习单片机,
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

MATLAB归一化方法大比拼:5种方法,哪种最适合你的数据?

![MATLAB归一化方法大比拼:5种方法,哪种最适合你的数据?](https://www.finebi.com/wp-content/uploads/2019/11/FineBI%E8%A1%8C%E4%B8%9A%E9%A9%BE%E9%A9%B6%E8%88%B1-1024x510.png) # 1. MATLAB归一化概述 归一化是一种数据预处理技术,用于将数据缩放到特定范围内,从而消除不同特征之间的尺度差异。在MATLAB中,有各种归一化方法可用于不同类型的数据和应用程序。 归一化的主要目的是: - 提高模型的训练效率和准确性,通过消除特征之间的尺度差异,使模型能够更有效地学习
recommend-type

failed to register layer: ApplyLayer exit status 1 stdout: stderr: archive/tar: invalid tar header

很抱歉听到这个问题。这个错误通常是由于Docker镜像损坏或Docker存储库中缺少所需的图层引起的。您可以尝试以下几种方法来解决这个问题: 1. 清理Docker镜像和容器:使用命令“docker system prune”清理不再使用的Docker对象。 2. 检查Docker存储库:确保您正在使用可靠的Docker存储库,并检查是否存在所有必需的图层。 3. 重新下载Docker镜像:如果您确定问题是由于损坏的Docker镜像引起的,则可以尝试重新下载Docker镜像。 4. 更新Docker版本:如果您使用的是旧版Docker,则可能会出现此问题。尝试更新到最新版本的Docke
recommend-type

Linux系统常用操作命令大全手册

附件是Linux系统常用操作命令大全手册,是 markdown格式,其中覆盖了Linux系统管理、文件操作、网络配置等多个方面,都是日常工作中非常常用的命令,欢迎大家下载学习使用!