A*算法实现

人工智能实验一 A*算法求解 8 数码问题 通过对程序的修改、调试、完善等,实现正确输出求解八数码问题的过程,通过对实验结果的分析,如:所用时间、生成节点数、扩展结点数等的分析可知,启发性信息越强,搜索节点数越少,启发性越弱,搜索节点越多,由此可见,设计一个恰当的启发函数,对于求解一个问题是非常重要的,当然,在实验过程中发现,复杂问题,如,难以到达目标状态的八数码排列,需要耗费很长时间,经过很多步骤,生成上千节点,代价过大,所以前面的结果比较和结果截图均选用简单情况。对于一般的启发式图搜索,总是选择估价函数 f 值最小的节点作为扩展节点。 阅读详情

A*算法实现

一、 算法思想

      搜索中利用启发式信息,对当前未扩展结点根据设定的估价函数值选取离目标最近的结点进行扩展,从而缩小搜索空间,更快的得到最优解,提高效率。

二、 启发函数

1、 不在位数码个数
      启发函数h ( n )为当前结点不在位的数码个数。由于一次只能移动一个数字位,因此h ( n ) <= h * ( n ), 同时有h ( t ) = 0  而且对于结点m和n (n 是m的子结点) 有h ( m ) – h ( n ) <= 1 = Cost ( m, n )  即该启发函数满足单调限制条件,只要扩展到某个结点,就找到了从初始结点到达该结点的最优路径。

2、 每个数字位与对应目标数字位间距离和
    进一步考虑当前结点与目标结点的距离信息,令启发函数h ( n )为当前8个数字位与目标结点对应数字位距离和(不考虑中间路径), 同样满足h ( n ) <= h * ( n ), 且对于目标有 h ( t ) = 0,对于结点m和n (n 是m的子结点) 有h ( m ) – h ( n ) <= 1 = Cost ( m, n ) 满足单调限制条件。

三、 具体实现

1、 结点编码
      对于8数码问题,每个结点有8个数字和一个空格,可以将空格看成0,那么一共有9个数字,32位的int可以表示2* 109 ,可以用一个整数表示一个结点对应的信息。计算一个整数中0(即空格)的位置比较耗时间,用一个整数存储当前结点0的位置,还要存储对应的 g , h 值以及该结点由哪个结点扩展来的信息。

2、 open表的数据结构表示
      考虑对open表的操作,每次需要得到所有待扩展结点中 f 值最小的那个结点,用堆进行实现,可以达到O ( log ( heapSize ) ) 时间复杂度。

3、closed表的数据结构表示
      closed表存储已扩展的结点间的扩展关系,主要用于输出路径。考虑结点扩展的操作,设待扩展的结点为m,由它扩展生成的结点为n1, n2, … 。结点m扩展完成后被放到closed表中,放入后它在closed表中位置不发生变化,可以将n1, n2, …的前驱结点置为m在closed表中的位置,当n1, n2, ..中有结点设为n1被扩展放入closed表时,n1的前驱刚好已经存储好。下面说明closed表中任意一个结点都存储有它的前驱结点的信息,考虑closed表中任意一个结点,如果它是初始结点,它没有前驱结点,如果不是根结点,扩展该结点时它的前驱结点已经记录。从而在closed表中形成扩展关系的树状结构。因为只需要前驱结点的下标位置,可以用数组实现,每个结点记录整数表示的8数码格局和它的前驱结点的下标,输出路径时,根据前驱结点形成到达根结点的链条,递归输出即可。

4、解决结点重复扩展问题
      对于一个结点有多种方式到达该结点,这样就可能多次将它加入open表中,而启发函数满足单调限制条件,后来达到该结点的路径不再是更优的,可以不予考虑。扩展某结点时先看该结点是否已经扩展过,如果扩展过则略过。实现的可以线形遍历closed表,但效率不高时间复杂度为O ( closedSize),考虑每个结点可以用一个整数标识,用二叉平衡查找树可以得到更好的时间复杂度O ( log (closedSize) ) ,程序中用基于红黑树思想的set实现。

四、 对比程序

      为对比测试时间,实现了宽度优先方法求解8数码问题和两种启发函数的A*算法。宽度优先是一种盲目搜索方法,没有深入挖掘问题的可利用信息,或者说h ( n ) = 0。搜索扩展结点时,只是根据层数优先根据扩展结点的先后顺序选择当前要扩展的结点,搜索空间大,耗时比较长。而启发函数好坏将直接影响A*算法性能。

五、 输入输出

      程序采用文本输入输出,输入文件为astar.in,A*算法第一种启发函数输出文件为astar1.out,第二个启发函数输出为astar2.out,宽度优先算法输出为bfs.out,可以用记事本打开。
输入格式为一个测试用例由两个中间由一空行隔开的8数码格局组成,输出为对应测试用例的走法路径及相关统计信息,程序假定输入数据符合要求,未做检查。

六、 测试结果

      测试用例最后一个需要30步才能得到结果,数据规模较大,宽度优先算法和第一种启发函数A*算法需要几秒才能运行得出结果,第二种算法非常快即得到结果。以下数据为VC++6.0编译得到的结果,VC++6.0对标准C++中STL支持不好,利用g++进行编译可以极大的缩短时间(经测试所有测试用例均在1秒内得出正确结果)。

宽度优先算法:

输入数据编号

步数

扩展结点数

生成结点数

搜索用时(毫秒)

1

5

36

65

15

2

18

23486

34961

1141

3

1

2

7

0

4

30

181413

181440

6235

A*算法1,利用第一个启发函数:

输入数据编号

【规划】A*算法以及c++实现 A*算法 A*算法的核心在于估价函数的设计上,如下式所示: 其中 称为耗散函数,表示从起始节点 到节点 n 的实际代价; 称为启发函数,表示节点 到目标节点 的估计代价; 表示从起始节点经由节点 到目标节点的估计代价。 同Dijkstra算法类似,A*算法也维持一个Open表。Open表中节点的优先级是依据 的大小排列的, 值越小,被搜索到的优先级越高。为保证能搜索到最... 阅读详情

相关推荐

Python A*算法的简单实现

总起 A*算法常用于游戏的寻路中,用于求解静态路网中的最短路径,是最有效的直接搜索方法。 这次正好花了几天时间学习了一下Python,便拿这个算法做了一下练习。这篇文章也会对其思路做一个简单介绍。 文章中的源码可以在 GitHub - anguangzhihen/PythonTest 中的AStarTest.py找到。 算法思路 A*算法实际是由广度优先遍历和Dijkstra算法演变而来的: 1.广度优先遍历主要是通过从起点依次遍历周围的点而寻找最优的路径; 2.Dijkstra基

暗光之痕的博客 1万+

C#实现A*算法

理解A*寻路算法具体过程 这两天研究了下 A* 寻路算法, 主要学习了这篇文章, 但这篇翻译得不是很好, 我花了很久才看明白文章中的各种指代. 特写此篇博客用来总结, 并写了寻路算法的代码, 觉得有用的同学可以看看. 另外因为图片制作起来比较麻烦, 所以我用的是原文里的图片. 当然寻路算法不止 A* 这一种, 还有递归, 非递归, 广度优先, 深度优先, 使用堆栈等等, 有兴趣的可以研究研究...

believe_s的博客 1万+

A*算法 C++实现

以前觉得看不懂的A*算法最近心血来潮突然想搞一下,结果看了一遍原理写完之后,发现好像也就那么回事。 参考文章:https://www.cnblogs.com/21207-iHome/p/6048969.html 总之先上算法流程: 1. 把起点加入open list。 2. 重复如下过程:   a. 遍历open list,查找F值最小的节点,把它作为当前要处理的节点,然后移到cl...

qq_38105943的博客 2367

python寻路算法:A* 算法实现

python寻路算法:A* 算法实现A* 算法简介关键代码介绍保存基本信息的地图类搜索到的节点类算法主函数介绍代码的初始化完整代码 A* 算法简介 A* 算法需要维护两个数据结构:OPEN 集和 CLOSED 集。OPEN 集包含所有已搜索到的待检测节点。初始状态,OPEN集仅包含一个元素:开始节点。CLOSED集包含已检测的节点。初始状态,CLOSED集为空。每个节点还包含一个指向父节点的指针,...

marble_xu的博客 1万+

【算法】用C++实现A*算法

A*(A-Star)算法是一种广泛应用于路径规划和图搜索问题中的启发式搜索算法。它结合了Dijkstra算法的广度优先搜索和贪心最佳优先搜索的优点,通过引入启发式函数来估计从当前节点到目标节点的成本,从而有效地减少搜索空间。A*算法的核心思想是使用一个评估函数 `f(n) = g(n) + h(n)` 来选择下一个要扩展的节点。其中,`g(n)` 表示从起点到当前节点的实际代价,`h(n)` 是从当前节点到目标节点的估计代价(启发式函数),而 `f(n)` 则是总代价,表示从起点经过当前节点到达目标节点的估

一个被知识诅咒的人 2022

算法 | A*算法实现最优路径规划

启发式探索是利用问题拥有的启发信息来引导搜索,达到减少探索范围、降低问题复杂度的目的。A*寻路算法是启发式探索的一个典型实践,在寻路搜索的过程中,给每个节点绑定了一个估计值(即启发式),在对节点的遍历过程中采取估计值优先原则,估计值更优的节点会被优先遍历。...

不断学习,不断进步,提高自己 6630

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

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

Matlab 2023b 科研党必备:MOSEK 10.1.25 安装与配置全记录(附License过期解决方案)

本文详细介绍了在Matlab 2023b中安装与配置MOSEK 10.1.25的全过程,特别针对科研用户提供学术许可申请、证书文件部署及环境集成的实用指南。文章还包含常见问题解决方案和性能调优建议,帮助用户高效完成优化计算任务。

weixin_30598225的博客 171

告别手册!S32K3XX的eMIOS实战:从GPT定时到PWM输出,一个通道搞定电机控制

本文深入探讨了NXP S32K3XX系列MCU的eMIOS模块在电机控制中的高效应用。通过单通道实现PWM生成、输入捕获和定时中断三大功能,展示了如何简化BLDC电机控制硬件设计。文章结合RTD库与寄存器级编程,提供动态模式切换和性能优化方案,显著降低CPU负载。

weixin_42522374的博客 147

遥感大模型之Prithvi的关键技术解读

Prithvi系列模型开创了遥感领域基础模型新范式,通过海量多源时空数据(HLS和SAR)与Vision Transformer架构的深度融合,采用掩码自编码器进行自监督预训练,实现了强大的地球观测表征能力。该技术体系突破传统方法在全局建模、多模态融合和时空分析上的局限,仅需少量标注数据即可在土地分类、灾害监测等任务上取得优异表现。从初代3亿参数到Prithvi-EO-2.0的10亿参数升级,展现了模型可扩展性,为构建地球数字孪生智能基座奠定基础。

panshengwu的博客 866

基于FPGA进位链的TDC高精度延时链设计与实现

本文详细介绍了基于FPGA进位链的高精度TDC延时链设计与实现方法。通过利用FPGA的CARRY4硬件资源,构建了理论分辨率达13.25ps/级的延时链,并提供了Verilog代码实现、物理布局约束技巧以及温度补偿策略。文章还涵盖了标定方法、数据转换处理和系统验证方案,为激光测距、高能物理等需要精确时间测量的应用提供了实用解决方案。

weixin_28731223的博客 488

SAP FI 提示没有为会计年度0 定义版本2025 GP626

SAP 错误 GP626 是一个常见的系统消息,通常表示某个会计年度的版本(如版本 0)未被定义或未激活。:在执行某些事务(如创建采购订单、过账凭证或维护成本中心)时,系统会检查相关版本是否已定义。的“Settings for Each Fiscal Year”界面中,选择一个已激活的会计年度。的“Settings for Each Fiscal Year”界面中,找到未激活的会计年度。:在控制范围(Controlling Area)中,未为指定的会计年度定义版本 0。如果没有,添加或复制现有年度的设置。

GAVIN 2490

CDD数据库文件制作(二)——服务配置(0x27)

主要根据诊断调查表,针对0x27服务在CDD中的每一步配置给出详细介绍 1.会话切换配置 1.1.根据诊断调查表进行信息提取 1.2.子功能添加 1.2.1.Level1安全等级1创建 1.2.2.Level3安全等级3创建 1.2.3.安全等级名字查看与修改 1.3.会话切换信息提取(应用程序下) 1.4.会话转换配置(应用程序下) 1.5.会话切换信息提取(引导程序下) 1.6.会话转换配置(引导程序下) 2.安全等级配置信息提取 2.1.安全访问配置(level1) 2.2.安全访问配置(level2

LOVE135149的博客 2930

Android Framework WMS面试题及参考答案

什么是 WindowManagerService(WMS)?它的作用是什么? WindowManagerService(WMS)是 Android 系统中非常重要的一个系统服务。它运行在系统进程(system_server 进程)中。 从本质上来说,WMS 是 Android 窗口管理系统的核心。它负责管理系统中的所有窗口,包括应用程序窗口、系统窗口(如状态栏、导航栏)等。 它的主要作用有很多。首先是窗口的创建和销毁。当一个应用请求创建一个窗口时,WMS 会协调各个模块完成窗口的创建工

大模型大数据攻城狮的专栏 2164

基于深度学习的异常检测实战:从自编码器到GAN

本文通过一个完整的实战案例,展示了如何使用自编码器和GAN进行异常检测。我们详细介绍了数据准备、模型定义、训练和评估的步骤,并提供了可运行的代码。希望本文能为读者在实际项目中应用异常检测技术提供实用的指导和启发。

Programming Talk 242

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

上一篇: 汇编结构体数组寻址
下一篇: Linux下创建静态、动态库
fifan
博客等级 码龄22年 2粉丝 8原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值