A*算法详解及改进方法附核心python代码_改进a*算法_首一标准型的博客-程序员宅基地

技术标签: python  

1.前言

1.1 广度优先搜索(breadth first search)BFS

定义:是一种盲目搜索法,在各个方向上均等的探索。根据离起始节点的距离,按照从近到远的顺序对各节点进行搜索。

核心:使用队列,队列的性质就是先进先出,每次从open_list中选择最早被加入的节点将其加入close_list中,同时扩展相邻节点。

1.2 深度优先搜索(depth first search)DFS

定义:它会沿着一条路径不断往下搜索直到不能再继续为止,然后再折返,开始搜索下一条路径。让搜索的区域距离起始节点尽量的远,距离目标节点尽量的近。

核心:使用是,栈的性质就是先进后出,每次从open_list中选择最晚被加入的节点将其加入close_list中,同时扩展相邻节点,可把open_list看成一个栈,后进先出。

1.3 最佳优先搜索(best first search)称为A算法

定义:是一种启发式搜索,启发式搜索就是对状态空间中的每个节点进行一个评估,然后选出最好的位置。而在启发估价中使用到的函数我们称之为启发估价函数

广度优先搜索的改进,用启发估价函数对将要被遍历到的点进行估价,然后选择代价小的进行遍历,直到找到目标节点或者遍历完所有点,算法结束。

核心:使用优先队列,以每个节点到达终点的距离作为优先级,每次选取离目标节点最近的节点作为下一个遍历的节点。

1.4 Dijkstra算法

一种启发式搜索,是贪心算法广度优先搜索算法的改进,倾向于成本较低的路径,我们可以分配较低的成本鼓励在道路上移动,较高的成本在森林上移动,较高的成本在避免靠近敌人。

核心:使用优先队列,每次从open_list中选择 g(n) 最小的节点将其加入close_list中,同时扩展相邻节点,可把open_list看成一个优先队列,key值为 g(n),优先级最高的先出。

1.5 A*算法

一种启发式搜索,是能找到最短路径(也就是最优解)的A算法

是对dijkstra算法的修改,更优先考虑接近目标的路径。

核心:使用优先队列,每次从open_list中选择 f(n) 最小的节点将其加入close_list中,同时扩展相邻节点,可把open_list看成一个优先队列,key值为 f(n),优先级最高的先出。

核心函数:使用{\color{Green} }f(n)=g(n)+h(n)                                     (1)

f(n)是节点的估算函数,g(n)是从起始节点到n的实际成本,h(n)是从n到目标节点的估计成本,也是A*的启发函数,有三类启发函数,我们在第二章介绍。

tips:1.当在极端情况下h(n)始终为0,由g(n)决定节点的优先级,此时算法就退化为了Dijkstra算法。

       2.当h(n)>>g(n),只由h(n)产生效果,此时算法就退化为了最佳优先搜索。

2.启发函数h(n)

使用栅格法对地图进行建模,可以参考这个帖子

https://blog.csdn.net/m0_58135773/article/details/124270820?spm=1001.2014.3001.5502

设A点(x1,y1)为起始节点,点B(x2,y2)为终止节点

2.1曼哈顿距离Manhattan Distance

地图中只允许上下左右四个方向移动

计算公式:h(n)=\left | x2-x1 \right |+\left | y2-y1 \right |

此时默认两个相邻节点之间的移动代价为1。

 图1 曼哈顿距离

2.2欧几里得距离Euclidean Distance

地图中允许上下左右和斜边八个方向移动

计算公式:h(n)=\displaystyle \sqrt{(x2-x1)^{2}+(y2-y1)^{2}}

 图2 欧几里得距离

2.3对角线距离

地图中允许任意方向移动

计算公式:h(n)=(\sqrt{2}-2)(min(\left | x2-x1 \right |,\left | y2-y1 \right |))+\left | x2-x1 \right |+\left | y2-y1 \right |

 图3 对角线距离

3,流程

A*算法使用集合open_list表示待遍历的节点,使用集合close_list表示已经遍历过的节点。

完整的A*算法描述如下:


初始化open_list和close_list

将起点A加入open_list中,并设置优先级为0

如果open_list不是空的,从中选取优先级最高的节点n:

      如果节点n为终点,则:

              从终点B逐步追踪父节点,一直到达起点A

              返回找到的结果路径,算法结束

      如果节点n不是终点,则:

              将节点n从open_list中删除,加入close_list

              遍历节点n所有的邻近节点:

                       如果邻近节点m在close_list中,则跳过,选取下一个邻近节点

                      如果邻近节点m不在close_list中,则:

                             设置节点m的父节点为n

                             计算节点m的优先级

                             将节点m加入open_list中


4,核心代码

def astar(workMap):
    startx,starty = workMap.startx,workMap.starty
    endx,endy = workMap.endx,workMap.endy
    startNode = Node(startx, starty, 0, 0, None)
    openList = []
    # 待遍历的节点
    closeList = []
    # 已经遍历过的节点
    closeList.append(startNode)
    # 将起点startNode加入closelist()中,并将优先级设置为0(因为我们已知初始节点不是终点)
    currNode = startNode
    # 当前节点为初始节点
    while((endx,endy) != (currNode.x,currNode.y)):
        # 当前节点不是终点
        workList = currNode.getNeighbor(workMap.data,endx,endy)
        # work list 为当前节点的八个临近节点
        for i in workList:
            if (i not in closeList):
                if(i.hasNode(openList)):
                    i.changeG(openList)
                else:
                    openList.append(i)
        openList.sort(key=getKeyforSort)# 关键步骤,对open list排序
        currNode = openList.pop(0) # 选择优先级最高的为当前节点
        closeList.append(currNode) # 将当前节点传入close list中
    result = []  # 创建一个名为result的空列表
    while(currNode.father!=None):
        # 当前节点的父节点不是空的时候
        result.append((currNode.x,currNode.y))
        # 将当前节点的 x, y 坐标传入 result 列表中
        currNode = currNode.father
    result.append((currNode.x,currNode.y))
    return result

5,改进方法

1.启发函数:

启发函数的公式是:

f(p) = g(p) + w(p) * h(p)

w(p)是权重系数,权重系数的改进即动态加权方法

优点:速度变快 缺点:搜索结果不是最优路径


2.搜索邻域:

基于8邻域搜索改进,16近邻搜索矩阵

优点:对启发函数的遍历范围更大,速度变快,结果更平滑


3.搜索策略

双向A*搜索

JPS策略:JPS算法对子节点进行扩展跳跃,提高路径规划效率

指数函数加权


4.路径平滑处理

贝塞尔曲线、B样条曲线,三次均匀B样条插值函数

Floyd算法:对所规划路径进行平滑优化

5.OPEN表

采用最小堆替换数组作为OPEN表的存储结构


时间仓促,笔者水平有限,如有疏漏请各位不啬赐教!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_58135773/article/details/124141784

智能推荐

C、C++、Java三种语言语法对比(一)_崚峰的博客-程序员宅基地

C语言是我接触的第一门课程,当时根本就不知道计算机的世界有多大,计算机行业的体系架构是怎样的,就好像站在一座摩天大楼的门口,只知道这栋大厦非常宏伟,但不知其内部构造,而C语言正是我看到的那座门。 之后我没有学习C++,而是学习的Java,虽然很多人说学完Java就没必要学C++,直到我本科毕业我依然认为这是对的,但是在我接触C++之后,我才发现并不完全对,准确来说只有一点点对,就是对面向对象的理解

不要再封装各种工具类了,这个神级框架值得收藏!_全栈开发者社区的博客-程序员宅基地

点击上方[全栈开发者社区]→右上角[...]→[设为星标]Hutool 谐音 “糊涂”,寓意追求 “万事都作糊涂观,无所谓失,无所谓得” 的境界。Hutool 是一个 Java 工具包...

另类万圣节:十三种令程序员们夜不能寐的恐怖噩梦_公众号-老炮说Java的博客-程序员宅基地

21套精品Java架构师高并发高性能高可用分布式集群电商缓存性能调优设计项目教程39阶段精品云计算大数据项目实战视频教程互联网技术(java框架、分布式、集群)干货视频大全200本经典编...

C++实现四则运算表达式的计算_(4444+5555)/123454321_陈小白233的博客-程序员宅基地

输入为一个整数四则运算表达式,可以有括号。程序实现:判断括号是否合法将表达式转换为后缀表达式计算出表达式的结果(这里使用自己实现的栈类辅助操作)代码如下:#include <iostream>#include <string>#include <vector>using namespace std;/*----------------..._(4444+5555)/123454321

老外的两个4-20ma光耦隔离输出电路_4-20ma隔离电路-程序员宅基地

图在二楼…楼下还有光隔离输入第一个。用一个普通四光耦的线性部分Optically Isolated 4- To 20-mA Current-Loop Transmitter Is Accurate, InexpensiveSep 25, 2008 W. Stephen Woodward | Electronic Designhttps://www.amobbs.com/forum.php?..._4-20ma隔离电路

JAVA开发RSS订阅器_java开发者必知的 rss订阅_灬点点的博客-程序员宅基地

一、首先介绍什么RSS、ROME。RSS:RSS订阅是站点用来和其他站点之间共享内容的一种简易方式,即Really Simple Syndication(简易信息聚合)。RSS以其方便快捷的工作方式,为广大网编带了工作效率的跨越,但是也助长了信息高速重复。ROME:Rome是为RSS聚合而开发的一个框架,让你可以快速的开发基于java的RSS阅读。二、使用Springboo..._java开发者必知的 rss订阅

随便推点

policy and pbr/distibution__enforcer.enforce_dingdingwolf的博客-程序员宅基地

关于policy:前面说keystone的时候,keystone的作用是认证/授权,这里policy我理解成鉴权,功能有很大的交叠部分,也可以认为属于一类,不过侧重点不一样,即使认证通过,还得通过鉴权再次细分。无论是nova还是neutron等模块,/etc/xxx下基本都有policy.json的文件,内容风格近似,在nova中,我们可以看到nova.policy.enfor__enforcer.enforce

eclipse>>GitHub管理项目出现异常The current branch is not configured for pull No value for key branch解决方法_PsEmperor的博客-程序员宅基地

1,进入Window-->preferences-->Team-->Git-->Configuration2,选择 Repository Settings3,点击Add Entry ~Key: branch.master.merge Value: refs/heads/master ~Key: branch.master.remote Value: or

金蝶K3供应链期初数据录入案例教程2_金蝶k3物料首次录入_杨杨杨杨杨呢的博客-程序员宅基地

期初库存启用时仓库物料的结存情况的记录,设置初始数据分仓库、仓位录入。不同的物料录入信息不同,比如,采用实际成本法计价的物料不录入成本差异信息,而采用计划成本法的物料则需要录入成本差异信息。对于年初、本年累计收入、本年累计发出、期初等共四组数据(包括数量、金额、差异),每组都不是必录内容。 用户录入数据保存时,系统会自动按公式检验是否平衡,如不平衡会给予提示,并在修改前不予保存。期初库存数据可以自动传递到总账系统,将业务初始数据自动转化为财务初始数据。期初库存手工录入案例erplabs整_金蝶k3物料首次录入

oozie_中文乱码解决方式_oozie spark 中文乱码_TURBODW的博客-程序员宅基地

一. 平台背景: hue上oozie调度hql执行二. 问题描述 : 如果hql里硬编码 中文插入数据到hive里会乱码, 具体表现是在hue上直接写sql不会乱码, 但是放到Oozie上调度运行写入会乱码三. 演示如下:当sql中含有如下写法( 部分sql )case open_account_type when 1 then ..._oozie spark 中文乱码

推荐文章

热门文章

相关标签