首页 > 编程语言 >A* 算法

A* 算法

时间:2024-02-08 21:11:25浏览次数:23  
标签:终点 Dijkstra 距离 算法 搜索 rightarrow

先来想想这么一个题目:

在方格图中,有 \(M\) 个障碍,不能通过这些障碍。给定起点坐标和终点坐标,求出最短路。

1. 贪心最优搜索和 Dijkstra 算法

  1. 贪心最优搜索

贪心最优搜索的流程是:从起点出发,在它的邻居结点上选择离终点最近的点。但是这样往往不能取得最优解。其思想为只看终点,不管起点

  1. Dijkstra 算法

Dijkstra 的流程是:从起点出发,在它的邻居结点上选择里起点最近的点。但是这样搜索是盲目的。其思想为只看起点,不管终点

2. A* 算法的原理

A* 算法结合了这两个算法,即既看起点,也看终点。它比 Dijkstra 快,因为它不像 Dijkstra 一样盲目。它比贪心最优搜索更准确,因为它可以找到最短路。

那么如何结合呢?

设起点为 \(s\),终点为 \(t\)。当走到点 \(i\) 的时候,可以把 \(s \rightarrow t\) 的路径分为 \(s \rightarrow i \rightarrow t\)。

  1. \(s \rightarrow i\) 的距离,可以在扩散搜索的时候记录。

  2. \(i \rightarrow t\) 的距离,用贪心最优搜索来预测下一个结点。

以上思路可以用估价函数具体操作。即:

\(f(i)=g(i)+h(i)\)。

其中 \(f(i)\) 是对 \(i\) 的评估,\(g(i)\) 是记录的距离,\(h(i)\) 是到终点的曼哈顿距离。

每次根据最小的 \(f(i)\) 选择下一个点,可以使用优先队列选择最小的点。这样当 \(i=t\) 时,\(f(i)\) 即为最短路。

3 种算法的对比

这张图可以直观地解释出来。

其中黑色格子是障碍,数字是估价,有数字的格子是该算法搜索到的格子。

Dijkstra 算法搜索的结点最多,A* 算法居中,贪心最优搜索最少。

Dijkstra 算法和 A* 算法取得了最短路。

在这个图中,A* 算法会先访问所有估价为 \(10\) 的格子,接着访问 \(12,14\),然后到达终点。

h 函数的设计

对于平面问题,一般有以下 \(3\) 种方法:

  1. 曼哈顿距离,即 \(h(i)=\lvert x_1-x_2 \rvert+\lvert y_1-y_2 \rvert\)。应用于向 \(4\) 个方向移动的题目。

  2. 对角线距离,即 \(h(i)=\max(\lvert x_1-x_2 \rvert,\lvert y_1-y_2 \rvert)\)。应用于向 \(8\) 个方向移动的题目。

  3. 欧式距离,即 \(h(i)=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}\)。应用于可以任意方式移动的题目。

对于非平面问题,根据题目灵活处理。

应遵循以下三条规则:

  1. \(g\) 和 \(h\) 应采用同样的计算方法。例如 \(g\) 是曼哈顿距离,\(h\) 也应是曼哈顿距离。

  2. 根据应用情况正确选择 \(h\)。如题目要就计算曼哈顿距离,就不能选择欧氏距离。

  3. \(h\) 应该优于实际存在的所有路径。这是最重要的一条规则。如果不这样,程序可能会选择另一条非最优的路径,会造成错误。

A* 算法例题

例题 POJ-2449/洛谷-P2901

这道题可以用 A* 算法解决。

我们每搜到一个一个点时,就将它与它的距离加入优先队列,并用它去扩展更多的点。优先队列中弹出的节点顺序就是距离的顺序。当终点 \(t\) 第 \(K\) 次从优先队列弹出,就是第 \(K\) 短路径。

接下来考虑估价函数。\(g(i)\) 表示 \(s \rightarrow i\) 的距离,可以在扩展的时候计算。\(h(i)\) 表示 \(i \rightarrow t\) 的距离,可以用 Dijkstra 算法求出,建一个反图,然后对 \(t\) 跑 Dijkstra。于是这个题就可以做了。

这样时间复杂度为 \(\mathcal{O}(NK \log N)\)。

下面给出 POJ-2449 的代码。

代码

标签:终点,Dijkstra,距离,算法,搜索,rightarrow
From: https://www.cnblogs.com/lrxmg139/p/18012131

相关文章

  • 分块与莫队算法
    1.分块分块的思想分块是把一个长度为\(N\)的数列分为\(\sqrt{N}\)个块,每个块的长度为\(\sqrt{N}\)。这样在区间操作的时候,对于每个涉及到的块,如果涉及到半个块,就直接操作;如果涉及到整个块,就整体操作。下面通过例题来了解一下分块。例1洛谷-P3372这道题可以用分块来做......
  • 2024牛客寒假算法基础集训营1
    D.数组成鸡题解观察到\(abs(M)\leq1e9\),容易知道如果绝对值不为\(1\)的数的个数大于\(30\)个的话,显然溢出,不会在答案的范围内再仔细分析性质,如果整个数组中数的种类超过了\(20\)种,那么除了\(0\)之外,最坏的结果就是\(-10,-9...-1,1,2,...10\)这样的情况,他们......
  • 2024牛客寒假算法基础集训营1 补题
    2024牛客寒假算法基础集训营1补题A.DFS搜索模拟题意:给你一个字符串\(S\),求出\(S\)中是否存在子序列“DFS“和"dfs"。思路:直接模拟即可参考代码:#include<bits/stdc++.h>usingnamespacestd;#definefffirst#definesssecond#defineebemplace_back#define......
  • 差分约束算法
    一、题目描述P5960【模板】差分约束二、题目简析差分约束问题的典型特征是一组不等式。只要画出约束图,这类问题都可以准换为最短路径问题。注意:约束图是有向图。2.1约束图的顶点约束图的顶点(\(V\))=一个未知数对应一个顶点(\(v_1,v_2,...,v_n\))+一个额外的顶点(\(v_0\)......
  • 2024牛客寒假算法基础集训营3
    2024牛客寒假算法基础集训营3A.智乃与瞩目狸猫、幸运水母、月宫龙虾思路:就是一个简单的字符串#include<bits/stdc++.h>usingnamespacestd;voidsolve(){stringa,b;cin>>a>>b;if(a[0]==b[0]||a[0]-'A'+'a'==b[0]||b[0]-'A'+'a'==......
  • 代码随想录算法训练营第十五天| 层序遍历 10 226.翻转二叉树 101.对称二叉树 2
    层序遍历  102.二叉树的层序遍历-力扣(LeetCode)思路:结合了昨天学到的标记法,每当一层遍历完,向队列中添加一个NULL标记。遍历到NULL节点表示该层遍历完了,将结果存入结果集中。/***Definitionforabinarytreenode.*structTreeNode{*intval;*TreeNo......
  • 【教3妹学编程-算法题】3028. 边界上的蚂蚁
    3妹:2哥,今天春节回的去吗?最火春运遭遇最强暴雪:冻雨像刨冰2哥:听说湖北的高速、高铁都已经停了。3妹:是啊,如果是雪还好办,可以除雪,冻雨就比较难办了。2哥:哎,好多人都滞留的高铁站了,没法回家了3妹:也有好多人滞留在高速上面,急的像热锅上的蚂蚁,惨。2哥:3妹,要不别回去了吧,我们就地过......
  • TCP拥塞控制算法初步介绍
    TCP拥塞控制算法初步介绍写得较为浅显,若有错误的地方还请指正.一、TCP拥塞控制:让发送方自己感知网络的拥塞程度并限制其能向链接发送流量的速率.限制方法:设置LastByteSent-LastByteAcked<=min{cwnd,rwnd}即已发送而未被确认的流量小于等于两个窗口长其中,cwnd......
  • SSL证书使用了弱Hash算法漏洞修复
    首先确认端口号,如果为3389端口,那就是远程桌面服务中的算法有弱Hash算法。在Windows中打开计算机配置-管理模板-Windows组件-网络-SSL配置设置查看配置中是否存在包含MD2、MD3、MD4、MD5、SHA-1等算法,如果有就删掉。将配置算法粘贴到一个文本文件中修改时注意官方的修改方......
  • 【国产化】禁止使用不安全的密码算法:DES、RC2,RSA(1024位及以下),MD5,SHA1
    一、引言随着互联网的普及和技术的发展,网络安全问题日益严重。密码算法作为网络安全的基石,其安全性直接关系到用户数据的安全。一些不安全的密码算法不断被曝光,给用户带来了极大的安全隐患。二、不安全的密码算法1.DESDES(DataEncryptionStandard)是一种对称加密算法,自1977年......