Astar路径规划算法复现-python实现

# -*- coding: utf-8 -*-
"""
Created on Fri May 24 09:04:23 2024"""import os
import sys
import math
import heapq
import matplotlib.pyplot as plt
import time'''
传统A*算法
'''class Astar:'''AStar set the cost + heuristics as the priorityAStar将成本+启发式设置为优先级'''def __init__(self, s_start, s_goal, heuristic_type, xI, xG):self.s_start = s_startself.s_goal = s_goalself.heuristic_type = heuristic_typeself.u_set = [(-1, 0), (0, 1), (1, 0), (0, -1)]# self.obs = self.obs_map()  # 障碍物位置self.Open = []  # 优先级序列,open集合self.Closed = []  # 相邻点集合,访问visited序列self.parent = dict()  # 相邻父节点self.g = dict()  # 成本self.x_range = 51  # 设置背景大小self.y_range = 51self.xI, self.xG = xI, xGself.obs = self.obs_map()def animation(self, path_l, visited_l, name, path_color='g'):# 绘制地图基础元素obs_x = [x[0] for x in self.obs]obs_y = [x[1] for x in self.obs]plt.plot(self.xI[0], self.xI[1], "bs")  # 起点plt.plot(self.xG[0], self.xG[1], "gs")  # 终点plt.plot(obs_x, obs_y, "sk")  # 障碍物plt.title(name)plt.axis("equal")# 移除起点和终点于visited_l列表中,避免它们被标记为已访问点visited_l = [node for node in visited_l if node != self.xI and node != self.xG]# 绘制所有已访问节点for x in visited_l:plt.plot(x[0], x[1], color='gray', marker='o')# 绘制路径path_x = [point[0] for point in path_l]path_y = [point[1] for point in path_l]plt.plot(path_x, path_y, linewidth=3, color=path_color)# 显示最终图形plt.show(block=True)def obs_map(self):"""Initialize obstacles' positions:return: map of obstacles初始化障碍物位置返回:障碍物"""x = 51y = 31self.obs = set()# 绘制边界self.obs.update((i, 0) for i in range(x))self.obs.update((i, y - 1) for i in range(x))self.obs.update((0, i) for i in range(y))self.obs.update((x - 1, i) for i in range(y))# 给出障碍物坐标集1self.obs.update((i, 15) for i in range(10, 21))self.obs.update((20, i) for i in range(15))# 给出障碍物坐标集2self.obs.update((30, i) for i in range(15, 30))# 给出障碍物坐标集3self.obs.update((40, i) for i in range(16))return self.obsdef searching(self):"""A_star Searching.:return: path, visited orderAstart搜索,返回路径、访问集,"""self.parent[self.s_start] = self.s_start  # 初始化 起始父节点中只有起点。self.g[self.s_start] = 0  # 初始代价为0self.g[self.s_goal] = math.inf  # 目标节点代价为无穷大# 将元素(self.f_value(self.s_start), self.s_start)插入到Open堆中,# 并保持堆的性质(最小堆中父节点的值总是小于或等于其子节点的值))# 这行代码的意思是:计算起始节点s_start的评估值f_value(self.s_start),# 然后将这对值(f_value, self.s_start)作为一个元组插入到self.Open这个最小堆中。# 这样做的目的是在诸如A*搜索算法等需要高效管理待探索节点的场景下,# 确保每次可以从堆顶(也就是当前评估值最小的节点)取出下一个待处理的节点。# 这对于寻找最短路径、最小成本解决方案等问题非常有用。heapq.heappush(self.Open, (self.f_value(self.s_start), self.s_start))while self.Open:# heappop会取出栈顶元素并将原始数据从堆栈中删除# 在这个例子中,heappop返回的元素假设是一个包含两个元素的元组,# 但代码中只关心第二个元素(实际的数据,比如一个状态、节点或其他任何类型的数据),# 所以用_占位符丢弃了第一个元素(通常是评估值或优先级),而把第二个元素赋值给了变量s_, s_current = heapq.heappop(self.Open)  # s_current存储的是当前位置的坐标# print('栈顶元素为{0}'.format(s_current))self.Closed.append(s_current)if s_current == self.s_goal:  # 迭代停止条件,判断出栈顶元素是否为目标点,如果为目标点,则退出break# 如果不是,更新该点附近的代价值# get_neighbor为获取附近点的坐标for s_next in self.get_neighbor(s_current):new_cost = self.g[s_current] + self.cost(s_current, s_next)if s_next not in self.g:self.g[s_next] = math.infif new_cost < self.g[s_next]:self.g[s_next] = new_costself.parent[s_next] = s_current# heappush入栈时需要存储的该点的代价值的计算方式为heapq.heappush(self.Open, (self.f_value(s_next), s_next))# self.animation(self.extract_path(self.parent), self.Closed, "A*")return self.extract_path(self.parent), self.Closeddef get_neighbor(self, s_current):""":param s_current::return: 相邻点集合"""return [(s_current[0] + u[0], s_current[1] + u[1]) for u in self.u_set]def cost(self, s_current, s_next):""":param s_current 表示当前点:param s_next 表示相邻点:return 若与障碍物无冲突,则范围欧式距离成本,否则为无穷大成本计算当前点与相邻点的距离成本"""# 判断是否与障碍物冲突if self.is_collision(s_current, s_next):return math.inf# 这里返回欧式距离成本return math.hypot(s_next[0] - s_current[0], s_next[1] - s_current[1])def is_collision(self, s_current, s_next):"""check if the line segment (s_start, s_end) is collision.:param s_current: start node:param s_next: end node:return: True: is collision / False: not collision检查起终点线段与障碍物是否冲突如果线段的起点或终点之一位于障碍物集合 self.obs 内,则直接判定为碰撞,返回 True。若线段不垂直也不水平(即斜线段),则分为两种情况检查:若线段为45度线(斜率为1:1或-1),则检查线段的端点形成的矩形框内是否有障碍物。否则检查线段端点形成的另一矩形框内是否有障碍物。若上述任一矩形框内有障碍,则判定为碰撞,返回 True若无碰撞情况,则返回 False"""# obs是障碍物,如果遇到障碍物,则距离(成本)无穷大if s_current in self.obs or s_next in self.obs:return True''''''# 如果该点s_start与相邻点s_end不相同if s_current[0] != s_next[0] and s_current[1] != s_next[1]:# 如果两点横纵坐标之差相等,即线段不垂直也不水平。135度线if s_next[0] - s_current[0] == s_current[1] - s_next[1]:s1 = (min(s_current[0], s_next[0]), min(s_current[1], s_next[1]))s2 = (max(s_current[0], s_next[0]), max(s_current[1], s_next[1]))# 如果两点横纵坐标之差不相等else:s1 = (min(s_current[0], s_next[0]), max(s_current[1], s_next[1]))s2 = (max(s_current[0], s_next[0]), min(s_current[1], s_next[1]))# obs是障碍物if s1 in self.obs or s2 in self.obs:return Truereturn Falsedef f_value(self, s_currrent):"""f = g + h. (g: Cost to come, h: heuristic value):param s: current state:return: f"""return self.g[s_currrent] + self.heuristic(s_currrent)def extract_path(self, parent):path = [self.s_goal]s = self.s_goalwhile True:s = parent[s]path.append(s)if s == self.s_start:breakreturn list(path)def heuristic(self, s_current):heuristic_type = self.heuristic_type  # heuristic typegoal = self.s_goal  # goal node# 如果为manhattan,则采用曼哈顿距离,s存储的是中间点if heuristic_type == "manhattan":return abs(goal[0] - s_current[0]) + abs(goal[1] - s_current[1])# 否则就是欧几里得距离,符合勾股定理else:return math.hypot(goal[0] - s_current[0], goal[1] - s_current[1])if __name__ == '__main__':time_start = time.time()s_start = (5, 5)s_goal = (45, 26)star_m = Astar(s_start, s_goal, "ee", s_start, s_goal)path, visited = star_m.searching()star_m.animation(path, visited, "A*")  # animationtime_end = time.time()print("程序运行时间:", time_end - time_start)

在这里插入图片描述

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

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

相关文章

Kafka集成flume

1.flume作为生产者集成Kafka kafka作为flume的sink&#xff0c;扮演消费者角色 1.1 flume配置文件 vim $kafka/jobs/flume-kafka.conf # agent a1.sources r1 a1.sinks k1 a1.channels c1 c2# Describe/configure the source a1.sources.r1.type TAILDIR #记录最后监控文件…

基于python-CNN深度学习的水瓶是否装满水识别-含数据集+pyqt界面

代码下载地址&#xff1a; https://download.csdn.net/download/qq_34904125/89374853 本代码是基于python pytorch环境安装的。 下载本代码后&#xff0c;有个requirement.txt文本&#xff0c;里面介绍了如何安装环境&#xff0c;环境需要自行配置。 或可直接参考下面博文…

绘唐2.5一键追爆款2.5免费版

免费分享给您 小说推文工具是一种用于在社交媒体上宣传和推广小说的工具。它可以帮助作者将小说的内容和相关信息以推文的形式快速发布在各种社交媒体平台上&#xff0c;吸引读者的注意力并增加小说的曝光度。 以下是一些小说推文工具可能具备的功能&#xff1a; 1. 编辑和排…

【linux】进程控制——进程创建,进程退出,进程等待

个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 祝福语&#xff1a;愿你拥抱自由的风 相关文章 【Linux】进程地址空间-CSDN博客 【linux】详解linux基本指令-CSDN博客 目录 进程控制概述 创建子进程 fork函数 父子进程执行流 原理刨析 常见用法 出错原因 进程退出 概…

MyBatis-Plus学习总结

一.快速入门 (一)简介 MyBatis-Plus (opens new window)&#xff08;简称 MP&#xff09;是一个 MyBatis (opens new window) 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 (二)快速入门 1.准备数据库脚本 2.准备bo…

六、Docker Swarm、Docker Stack和Portainer的使用

六、Docker swarm和Docker stack的使用 系列文章目录1.Docker swarm1.简介2.docker swarm常用命令3.docker node常用命令4.docker service常用命令5.实战案例6.参考文章 2.Docker stack1.简介3.Docker stack常用命令4.实战案例5.常见问题及调错方式1.查看报错信息并尝试解决&am…

SpringBootWeb 篇-深入了解 Redis 五种类型命令与如何在 Java 中操作 Redis

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Redis 概述 1.1 Redis 下载与安装 2.0 Redis 数据类型 3.0 Redis 常见五种类型的命令 3.1 字符串操作命令 3.2 哈希操作命令 3.3 列表操作命令 3.4 集合操作命令 …

7-43 排列问题

排列问题 分数 10 全屏浏览 切换布局 作者 雷丽兰 单位 宜春学院 全排列问题 输出自然数1至n中n个数字的全排列&#xff08;1≤n≤9&#xff09;&#xff0c;要求所产生的任一数字序列中不允许出现重复的数字。 输入格式: 一个自然数 输出格式: 由1到n中n个数字组成的…

Tessy学习系列(三):单元测试——官方例程isValueInRange

一、工程创建 &#xff08;1&#xff09;新建工程 注意&#xff1a;工程名称以及路劲不能包含空格和中文 &#xff08;2&#xff09;新建测试集与单元测试模块 新建测试集 新建单元测试模块 设置测试模块为单元测试模块并选择GNU GCC编译器如果需要其他的编译器&#xff0c;…

关于选择,关于处事

一个人选择应该选择的是勇敢&#xff0c;选择不应该选择的是无奈。放弃&#xff0c;不该放弃的是懦夫&#xff0c;不放弃应该放弃的是睿智。所以&#xff0c;碰到事的时候要先静&#xff0c;先不管什么事&#xff0c;先静下来&#xff0c;先淡定&#xff0c;先从容。在生活里要…

【线性代数】向量空间,子空间,向量空间的基和维数

向量空间 设V为n维向量的集合&#xff0c;如果V非空&#xff0c;且集合V对于向量的加法以及数乘两种运算封闭&#xff0c;那么就称集合V为向量空间 x&#xff0c;y是n维列向量。 x 向量组等价说明可以互相线性表示 向量组等价则生成的向量空间是一样的 子空间 例题18是三位向…

Docker Swarm持久化

Docker Swarm持久化 1 简介 Docker Swarm持久化有bind、volume和NFS三种方式&#xff0c;bind和volume两种方式适合挂载单个宿主机&#xff0c;不适合集群&#xff1b;NFS适合集群服务&#xff0c;但需要安装NFS系统。 注意&#xff1a;Docker Swarm需要先安装集群。 由Doc…

python-数字黑洞

[题目描述] 给定一个三位数&#xff0c;要求各位不能相同。例如&#xff0c;352是符合要求的&#xff0c;112是不符合要求的。将这个三位数的三个数字重新排列&#xff0c;得到的最大的数&#xff0c;减去得到的最小的数&#xff0c;形成一个新的三位数。对这个新的三位数可以重…

【数据结构】【版本1.0】【线性时代】——顺序表

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、顺序表的概念1.1 最基础的数据结构&#xff1a;数组1.2 数组与顺序表的区别 二、静态顺序表三、动态…

error while loading shared libraries 找不到动态库问题如何解决

在使用 c 或 c 开发应用时&#xff0c;在启动程序时&#xff0c;有时会遇到这个错误&#xff0c;找不到动态库。这个时候&#xff0c;我们使用 ldd 来查看&#xff0c;发现可执行文件依赖的动态库显示为 not found。 1 实验代码 使用如下 3 个文件做实验。 hello.h 中声明了函…

【Vue】修改数量

文章目录 底部总价展示完整代码 注意&#xff1a;前端 vuex 数据&#xff0c;后端数据库数据都要 注册点击事件 页面中dispatch action 提供action函数 提供mutation处理函数 底部总价展示 提供getters 动态渲染 完整代码 main.js import Vue from vue import App from…

Linux:基础开发工具

文章目录 Linux 软件包管理器 yum什么是软件包关于rzsz查看软件包安装软件卸载软件安装扩展源 Linux 编辑器 vimvim的基本概念正常/普通/命令模式(Normal mode)插入模式(Insert mode)底行模式(last line mode) vim的基本操作[命令模式]切换至[插入模式][插入模式]切换至[命令模…

【CW32F030CxTx StartKit开发板】开发资料

本来是参加21ic的评测活动&#xff0c;不知道为什么评测文章一直被提示有不良内容&#xff0c;所以只好先在此记录一下相关的资料。 此次测试的是CW32F030CxTxStartKit 评估板。该开发板为用户提供一种经济且灵活的方式使用 CW32F030CxTx 芯片构建系统原型&#xff0c;可进行性…

激活乡村振兴新动能:推动农村产业融合发展,打造具有地方特色的美丽乡村,实现乡村全面振兴

目录 一、推动农村产业融合发展 1、农业产业链条的延伸 2、农业与旅游业的结合 二、挖掘地方特色&#xff0c;打造美丽乡村 1、保护和传承乡村文化 2、发展特色农业 三、加强基础设施建设&#xff0c;提升乡村品质 1、改善农村交通条件 2、提升农村水利设施 四、促进…

吴恩达2022机器学习专项课程C2W2:2.23 选修_反向传播算法的工作原理(什么是导数图计算大型神经网络)

目录 引言一.导数的计算1.epsilon与导数的关系2.其它导数符号形式3.导数小结 二.小型神经网络的计算图1.什么是计算图&#xff08;前向传播过程&#xff09;2.反向传播计算过程3.验证反向传播的计算结果4.为什么用反向传播计算导数&#xff1f; 三.扩大神经网络的计算图1.计算反…