A*——AcWing 179. 八数码

A*

定义

A* 算法是一种在图形或地图中寻找最短路径的启发式搜索算法。它通过综合考虑起始节点到当前节点的实际代价和当前节点到目标节点的预估代价,来决定下一步的搜索方向。

运用情况

  • 路径规划:如在地图导航中为车辆、行人规划最优路线。
  • 游戏开发:例如在策略游戏中为角色寻找到达目标的最短路径。
  • 机器人导航:帮助机器人在复杂环境中找到高效的移动路径。

注意事项

  • 启发函数的设计:启发函数的准确性对算法的效率和结果质量有很大影响。如果启发函数过于乐观或悲观,可能导致算法找不到最优解或效率低下。
  • 内存使用:在处理大规模的地图或图形时,A* 算法可能需要大量的内存来存储已访问和待访问的节点信息。
  • 优化策略:需要根据具体问题选择合适的优化策略,如双向搜索、限制搜索区域等。

解题思路

  1. 初始化:将起始节点放入开放列表,设置其代价。
  2. 循环:
    • 从开放列表中选择代价最小的节点作为当前节点。
    • 将当前节点移出开放列表,放入关闭列表。
    • 对当前节点的相邻节点进行处理:
      • 如果相邻节点在关闭列表中,忽略。
      • 如果不在开放列表中,计算其代价并放入开放列表。
      • 如果在开放列表中,更新其代价,如果新代价更小则更新其父节点。
  3. 直到目标节点被放入关闭列表,或者开放列表为空(未找到路径)。

例如,在地图导航中,起始节点是你的当前位置,目标节点是你的目的地。每个节点代表地图上的一个位置,节点之间的连接表示可能的路径。通过不断评估每个可能的下一步路径的代价,A* 算法能够快速找到从起始点到目标点的最短路径。

A 算法的优缺点*:

优点:

  1. 高效性:通常能够在合理的时间内找到较优的解,特别是在地图规模不是特别巨大的情况下。
  2. 最优性保证:在启发函数估计准确的前提下,能够找到最优解。
  3. 灵活性:可以应用于各种不同类型的图和问题领域,只要能够定义合适的代价函数和启发函数。
  4. 易于理解和实现:其基本思想相对直观,实现起来并不复杂。

例如,在城市交通导航中,A* 算法能够快速为司机规划出一条相对较短且高效的行驶路线,节省时间和燃油。

缺点:

  1. 启发函数的依赖:启发函数的质量对算法性能影响极大,如果启发函数设计不好,可能导致算法效率低下或找不到最优解。
  2. 内存消耗:在处理大规模的问题时,可能需要大量的内存来存储节点信息和搜索过程中的数据。
  3. 计算开销:计算每个节点的代价和启发值需要一定的计算资源。
  4. 对复杂环境的适应性有限:在某些极端复杂或动态变化的环境中,可能表现不佳。

比如,在一个实时变化的物流配送网络中,由于路况等因素不断变化,A* 算法可能难以快速适应并重新规划最优路径。

常用的路径规划算法

Dijkstra 算法
这是一种用于求解图中单个源点到其他所有顶点的最短路径的算法。它会遍历所有可能的路径,逐步更新节点的最短距离,直到找到所有节点的最短路径。优点是能保证找到最短路径,缺点是计算量较大,效率相对较低。

例如,在物流配送中心规划送货路线时,如果只关注从配送中心到各个目的地的最短距离,Dijkstra 算法就可以适用。

Floyd-Warshall 算法
用于计算图中所有顶点对之间的最短路径。通过动态规划的思想,逐步更新任意两点之间的最短距离。该算法的优点是可以一次性得到所有点对之间的最短路径,缺点是时间和空间复杂度较高。

比如,在分析多个城市之间的最优交通连接时,Floyd-Warshall 算法可以提供全面的路径信息。

蚁群算法
模拟蚂蚁在寻找食物过程中的行为来寻找最优路径。蚂蚁会根据路径上的信息素浓度选择路径,同时在经过的路径上留下信息素,使得后续的蚂蚁更倾向于选择较优的路径。优点是具有较强的全局搜索能力和自适应性,缺点是计算时间可能较长,参数设置较复杂。

在大规模的网络路由规划中,蚁群算法可以发现复杂网络中的优质路径。

粒子群优化算法
通过模拟鸟群觅食的行为来寻找最优解。粒子在解空间中移动,根据自身和群体的历史最优位置来更新自己的位置。优点是实现简单,收敛速度较快,缺点是容易陷入局部最优。

例如,在无人机的自主飞行路径规划中,可以使用粒子群优化算法来找到合适的路线。

遗传算法
基于生物进化的思想,通过选择、交叉和变异等操作来优化解。优点是能够处理复杂的优化问题,具有较好的全局搜索能力,缺点是计算量较大,编码和解码过程可能较复杂。

比如,在机器人在复杂环境中的路径规划问题中,遗传算法可以发挥作用。

AcWing 179. 八数码

题目描述

AcWing 179. 八数码 - AcWing

运行代码

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <unordered_map>
using namespace std;
typedef pair<int, string> PIS;
int f(string state)
{int res = 0;for(int i = 0; i < state.size(); i ++ )if(state[i] != 'x'){int t = state[i] - '1';res += abs(i / 3 - t / 3) + abs(i % 3 - t % 3);}return res;
}
string bfs(string start)
{int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};char op[4] = {'u', 'r', 'd', 'l'};string end = "12345678x";unordered_map<string, int> dist;unordered_map<string, pair<string, char>> prev;priority_queue<PIS, vector<PIS>, greater<PIS>> heap;heap.push({f(start), start});dist[start] = 0;while(heap.size()){auto t = heap.top();heap.pop();string state = t.second;if(state == end) break;int step = dist[state];int x, y;for(int i = 0; i < state.size(); i ++ )if(state[i] == 'x'){x = i / 3, y = i % 3;break;}string scource = state;for(int i = 0; i < 4; i ++ ){int a = x + dx[i], b = y + dy[i];if(a >= 0 && a <= 2 && b >= 0 && b <= 2){swap(state[x * 3 + y], state[a * 3 + b]);if(!dist.count(state) || dist[state] > step + 1){dist[state] = step + 1;prev[state] = {scource, op[i]};heap.push({dist[state] + f(state), state});}swap(state[x * 3 + y], state[a * 3 + b]);}}}string res;while(end != start){res += prev[end].second;end = prev[end].first;}reverse(res.begin(), res.end());return res;
}
int main()
{string g, c, seq;while(cin >> c){g += c;if(c != "x") seq += c;}int res = 0;for(int i = 0; i < seq.size(); i ++ )for(int j = i + 1; j < seq.size(); j ++ )if(seq[i] > seq[j]) res ++ ;if(res & 1) puts("unsolvable");else cout << bfs(g) << endl;return 0;
}

代码思路

  1. f 函数用于计算一个状态与目标状态的曼哈顿距离估计值,作为启发函数。
  2. bfs 函数实现了广度优先搜索来求解八数码问题的最优路径。
    • 定义了移动方向和对应的操作字符。
    • 使用优先队列进行搜索,根据当前状态的步数和启发函数值进行排序。
    • 通过遍历四个方向,尝试交换空白格与相邻位置的数字,更新状态和相关信息。
    • 最终通过回溯得到从起始状态到目标状态的路径。
  3. main 函数用于读取输入的八数码状态,判断是否可解,并调用 bfs 函数求解。

改进思路

  1. 数据结构优化:考虑使用更高效的数据结构来存储已访问的状态,例如布隆过滤器或者哈希表的优化实现,以提高查找速度。
  2. 启发函数改进:进一步优化启发函数,使其更准确地估计到目标状态的距离,可能会提高搜索效率。
  3. 剪枝策略:分析问题的特性,添加更多有效的剪枝条件,避免不必要的搜索。
  4. 并行化:如果计算资源允许,可以考虑对搜索过程进行并行化处理,加快搜索速度。
  5. 代码可读性和可维护性:添加更多的注释来解释关键代码段的作用和逻辑。将一些复杂的逻辑提取为独立的函数,以提高代码的可读性和可维护性。

其它代码

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <unordered_map>
using namespace std;
typedef pair<int, string> PIS;
int f(string state) {int res = 0;for (int i = 0; i < state.size(); i++)if (state[i]!= 'x') {int t = state[i] - '1';res += abs(i / 3 - t / 3) + abs(i % 3 - t % 3);}return res;
}
string bfs(string start) {int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};char op[4] = {'u', 'r', 'd', 'l'};string end = "12345678x";unordered_map<string, int> dist;unordered_map<string, pair<string, char>> prev;priority_queue<PIS, vector<PIS>, greater<PIS>> heap;heap.push({f(start), start});dist[start] = 0;while (heap.size()) {auto t = heap.top();heap.pop();string state = t.second;if (state == end) break;int step = dist[state];int x, y;for (int i = 0; i < state.size(); i++)if (state[i] == 'x') {x = i / 3, y = i % 3;break;}string scource = state;for (int i = 0; i < 4; i++) {int a = x + dx[i], b = y + dy[i];if (a >= 0 && a <= 2 && b >= 0 && b <= 2) {swap(state[x * 3 + y], state[a * 3 + b]);if (!dist.count(state) || dist[state] > step + 1) {dist[state] = step + 1;prev[state] = {scource, op[i]};heap.push({dist[state] + f(state), state});}swap(state[x * 3 + y], state[a * 3 + b]);}}}string res;while (end!= start) {res += prev[end].second;end = prev[end].first;}reverse(res.begin(), res.end());return res;
}int main() {string g, c, seq;while (cin >> c) {g += c;if (c!= "x") seq += c;}int res = 0;for (int i = 0; i < seq.size(); i++)for (int j = i + 1; j < seq.size(); j++)if (seq[i] > seq[j]) res++;if (res & 1) puts("unsolvable");else cout << bfs(g) << endl;return 0;
}

代码思路

  • f 函数用于计算当前状态与目标状态的曼哈顿距离估计值。
  • bfs 函数通过广度优先搜索和优先队列来找到从初始状态到目标状态的最优路径。
    • 定义了移动方向和对应的操作字符。
    • 维护了已访问状态的距离和前驱信息。
    • 通过交换 x 与相邻位置的数字来探索新状态。
  • main 函数读取输入的初始状态,判断其是否可解,然后调用 bfs 函数求解并输出结果。

改进思路

  • 可以考虑使用位运算来表示状态,减少存储空间和计算量。
  • 对于启发函数,可以进一步研究更精确的估计方式。
  • 对搜索过程中的一些边界情况和异常处理进行更完善的考虑。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/39505.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学会python——用python制作一个登录和注册窗口(python实例十八)

目录 1.认识Python 2.环境与工具 2.1 python环境 2.2 Visual Studio Code编译 3.登录和注册窗口 3.1 代码构思 3.2 代码实例 3.3 运行结果 4.总结 1.认识Python Python 是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读…

免杀笔记 ---> PE

本来是想先把Shellcode Loader给更新了的&#xff0c;但是涉及到一些PE相关的知识&#xff0c;所以就先把PE给更了&#xff0c;后面再把Shellcode Loader 给补上。 声明&#xff1a;本文章内容来自于B站小甲鱼 1.PE的结构 首先我们要讲一个PE文件&#xff0c;就得知道它的结构…

SPI四种模式--极性与相位

SPI的四种模式&#xff1a;相位和极性 极性 定义时钟空闲状态&#xff1a; CPOL0&#xff1a;时钟线在空闲状态为低电平 CPOL1&#xff1a;时钟线在空闲状态为高电平 这个设置决定了设备不进行通信时时钟线的状态。 兼容性&#xff1a; 不同的SPI设备可能需要不同的时钟极性…

【Linux开发实战指南】基于TCP、进程数据结构与SQL数据库:构建在线云词典系统(含注册、登录、查询、历史记录管理功能及源码分享)

目录 项目演示&#xff1a; 1. 主界面 技术讲解&#xff1a; TCP连接 进程的并发 链表 SQLite3 IO对文件的读写 功能实现 实现逻辑 我遇到的问题&#xff1a; 服务器端代码思路解析 必要条件 步骤详解 客户端代码思路解析 步骤详解 服务器源码如下&#xff1a;…

windows电脑如何运行python的定时任务

这里需要使用&#xff1a;windows系统设置-控制面板里的计划任务 1.打开计划任务之后&#xff0c;选择&#xff1a;创建基本任务 2.填写名称&#xff0c;这里根据自己具体的项目需求填写&#xff0c;然后点击下一步。 3.选择每日&#xff0c;再点击下一步 4.设置时间&…

科普文:linux I/O原理、监控、和调优思路

Linux 文件系统 磁盘和文件系统的关系&#xff1a; 磁盘为系统提供了最基本的持久化存储。 文件系统则在磁盘的基础上&#xff0c;提供了一个用来管理文件的树状结构。 文件系统工作原理 索引节点和目录项 文件系统&#xff0c;本身是对存储设备上的文件&#xff0c;进行…

多维度多场景文档门户,鸿翼ECM文档云打造文档管理新范式

​在现代企业运营中&#xff0c;内容协作的效率直接影响到组织的整体表现和竞争力。传统的文档管理系统都是通过目录结构的方式进行文件管理&#xff0c;在实际业务中无法满足用户多视角、多维度、多场景的文档业务需求。因此&#xff0c;搭建结合文档体系的业务门户是许多企业…

策略模式入门:基本概念与应用

目录 策略模式策略模式结构策略模式应用场景策略模式优缺点练手题目题目描述输入描述输出描述题解 策略模式 策略模式&#xff0c;又称政策模式&#xff0c;是一种行为型设计模式&#xff0c;它能让你定义一系列算法&#xff0c;并将每种算法分别放入独立的类中&#xff0c;以…

数字研发·驱动变革 | 2024达索系统装备行业数字化研发专题研讨会成功举办

2024年6月28日&#xff0c;由百世慧举办的“数字研发驱动变革|2024达索系统装备行业数字化研发专题研讨会”在达索系统&#xff08;重庆&#xff09;智能制造创新中心成功举办。 随着全球制造业向着智能化、数字化转型&#xff0c;我国工业装备行业也面临着转型升级的压力和机遇…

Gym cuda error: invalid resource handle

gym模拟的时候&#xff0c; 出现问题&#xff1a; sim和gym的定义如下&#xff1a; from isaacgym import gymapi,gymtorch import math,random# 1. Simulation Setup gym gymapi.acquire_gym()# get default set of parameters sim_params gymapi.SimParams() sim_params.u…

企业多存储方式如何兼顾安全统一管理、便捷流畅访问的双向需求?

数据和文件存储是企业最基础的需求&#xff0c;常见的存储方式有磁盘存储、NAS存储、SAN存储、云存储、分布式存储、闪存存储等&#xff1b;随着企业规模的扩大、业务结构的复杂化&#xff0c;企业内部可能会同时出现多种存储方式、多个存储设备并行使用的情况。 这样的使用场景…

【启明智显技术分享】Model3C芯片电阻屏RTP配置、调试与测试指南

一、背景 本指南将详细介绍启明智显的Model3C芯片电阻屏RTP配置、调试与测试指南。无论您是电子爱好者、开发者还是工程师&#xff0c;这份指南都能助您快速上手并充分利用这款触摸屏的各项功能。 二、芯片介绍 Model3C是一款基于RISC-V的高性能、国产自主、工业级高清显示与…

面试篇-系统设计题总结

这里记录一些有趣的系统设计类的题目&#xff0c;一般大家比较喜欢出的设计类面试题目会和高可用系统相关比如秒杀和抢红包等。欢迎大家在评论中评论自己遇到的题目&#xff0c;本篇文章会持续更新。 1、设计一个抢红包系统 抢红包系统其实也是秒杀类中的一个场景&#xff0…

类的动态加载-双亲委派模型

java反射基础 Java 基础 - 反射机制详解 | Java 全栈知识体系 (pdai.tech) 类的动态加载 参考链接&#xff1a;类的动态加载 构造是和实例化也就是对象相关的。 静态代码块是在初始化的时候就调用的 Class.forName();就会调用静态代码块 forName&#xff0c;加载类时默认…

你们叫AI,我们叫DI

大家好&#xff0c;才是真的好。 最近Notes/Domino产品在做哪些更新&#xff0c;想必大家都很好奇。 从2022年年末到现在&#xff0c;快两年了&#xff0c;任何一个有追求的大企业或巨头&#xff0c;应该都在追求实现一件事情&#xff1a;AI人工智能。 从小道消息来看&#…

【高级篇】分区与分片:MySQL的高级数据管理技术(十三)

引言 在上一章,我们探讨了MySQL的主从复制与高可用性,这是构建健壮数据库架构的基石。现在,让我们深入到更高级的主题——分区与分片,这些技术对于处理大规模数据集和提升数据库性能至关重要。我们将详细介绍表分区的概念、类型及分片技术的应用,为下一章讨论MySQL集群与…

解决Vue3中路由页面跳转出现白屏,刷新页面之后展示正常的问题

遇到这个问题&#xff0c;首先需要检查根组件标签最外层是否包含了个最大的div盒子来包裹内容。如下图所示&#xff1a; 我的项目就是因为没有将两块内容放到一个大盒子里面&#xff0c;所以才会出现白屏的问题。然后我去查了相关的资料&#xff0c;了解到这个问题是Vue组件渲染…

TSINGSEE智能分析网关V4人员区域徘徊AI检测:算法原理介绍及技术应用场景

一、引言 在现代社会&#xff0c;随着科技的不断发展&#xff0c;视频监控系统已广泛应用于各个领域&#xff0c;如公共安全、商业管理、交通监控等。其中&#xff0c;区域徘徊检测算法作为一种重要的视频分析技术&#xff0c;能够有效地识别出特定区域内人员的徘徊行为&#…

Spring Cloud Alibaba - Sentinel 分布式系统流量哨兵

目录 概述特征基本概念 安装Sentinel微服务引入Sentinel案例流控规则&#xff08;流量控制&#xff09;流控模式-直接流控模式-关联流控模式-链路流控效果-快速失败流控效果-预热WarmUp流控效果-排队等候 流控规则&#xff08;并发线程数控制&#xff09;熔断规则&#xff08;熔…

Django 安装 Zinnia 后出现故障

在Django中安装和配置Zinnia时遇到故障可能有多种原因&#xff0c;通常包括版本兼容性、依赖关系或配置问题。这里提供一些常见的解决方法和调试步骤&#xff0c;帮助大家解决问题。 首先&#xff0c;确保您安装的Zinnia版本与Django版本兼容。查看Zinnia的官方文档或GitHub页…