A星算法代码

article/2025/10/2 20:30:06

A星算法代码python3实现

  • 前言
  • 一、A*? A星
    • 1.一个搜索算法
    • 2.结果展示
  • 二、使用环境
    • 1.python 3.x
    • 2.一些解释说明
  • 一些话


前言

产生本文的缘由

学校计科课程要求的小作业, 在csdn上看了好多, 记录一下自己的学习


以下是本篇文章正文内容

一、A*? A星

1.一个搜索算法

和深度搜索, 广度搜索类似, 能更快的找一条从起点到终点的路径.
我参考的算法文章来自 https://blog.csdn.net/hitwhylz/article/details/23089415

2.结果展示

圆圈表示地图坐标, 方块表示墙壁 , ※表示路径
在这里插入图片描述
在这里插入图片描述


二、使用环境

1.python 3.x

代码如下(示例):大家可以直接复制到一个.py文件里面直接运行即可

class Array2D:"""说明:1.构造方法需要两个参数,即二维数组的宽和高2.成员变量w和h是二维数组的宽和高3.使用:‘对象[x][y]’可以直接取到相应的值4.数组的默认值都是0"""def __init__(self, h, w):self.w = wself.h = hself.data = []self.data = [[0 for y in range(w)] for x in range(h)]def showArray2D(self):for x in range(self.h):for y in range(self.w):if self.data[x][y] == 0:print("◎", end=' ')elif self.data[x][y] == 1:print("▉",end=' ')else:print("※",end=' ')print("")def __getitem__(self, item):return self.data[item]class Point:"""表示一个点"""def __init__(self, x, y):self.x = xself.y = ydef __eq__(self, other):if self.x == other.x and self.y == other.y:return Truereturn Falsedef __str__(self):return "x:"+str(self.x)+",y:"+str(self.y)class AStar:"""AStar算法的Python3.x实现"""class Node:  # 描述AStar算法中的节点数据def __init__(self, point, endPoint, g=0):self.point = point  # 自己的坐标self.father = None  # 父节点self.g = g  # g值,g值在用到的时候会重新算self.h = (abs(endPoint.x - point.x) +abs(endPoint.y - point.y)) * 10  # 计算h值def __init__(self, map2d, startPoint, endPoint, passTag=0):"""构造AStar算法的启动条件:param map2d: Array2D类型的寻路数组:param startPoint: Point或二元组类型的寻路起点:param endPoint: Point或二元组类型的寻路终点:param passTag: int类型的可行走标记(若地图数据!=passTag即为障碍)"""# 开启表self.openList = []# 关闭表self.closeList = []# 寻路地图self.map2d = map2d# 起点终点if isinstance(startPoint, Point) and isinstance(endPoint, Point):self.startPoint = startPointself.endPoint = endPointelse:self.startPoint = Point(*startPoint)self.endPoint = Point(*endPoint)# 可行走标记self.passTag = passTag# def getMinNode(self):#     """#     获得openlist中F值最小的节点#     :return: Node#     """#     currentNode = self.openList[0]#     for node in self.openList:#         if node.g + node.h < currentNode.g + currentNode.h:#             currentNode = node#     return currentNodedef pointInCloseList(self, point):for node in self.closeList:if node.point == point:return Truereturn Falsedef pointInOpenList(self, point):for node in self.openList:if node.point == point:return nodereturn Nonedef endPointInCloseList(self):for node in self.openList:if node.point == self.endPoint:return nodereturn Nonedef searchNear(self, minF, offsetX, offsetY):"""搜索节点周围的点:param minF:F值最小的节点:param offsetX:坐标偏移量:param offsetY::return:"""# 越界检测if minF.point.x + offsetX < 0 or minF.point.x + offsetX > self.map2d.w - 1 or minF.point.y + offsetY < 0 or minF.point.y + offsetY > self.map2d.h - 1:return# 如果是障碍,就忽略if self.map2d[minF.point.x + offsetX][minF.point.y + offsetY] != self.passTag:return# 如果在关闭表中,就忽略currentPoint = Point(minF.point.x + offsetX, minF.point.y + offsetY)if self.pointInCloseList(currentPoint):return# 设置单位花费if offsetX == 0 or offsetY == 0:step = 10else:step = 14# 如果不在openList中,就把它加入openlist ,并且使得openlist的首元素为f值最小的currentNode = self.pointInOpenList(currentPoint)if not currentNode:currentNode = AStar.Node(currentPoint, self.endPoint, g=minF.g + step)currentNode.father = minFfor item in self.openList:if item.g+item.h > currentNode.g+currentNode.h:self.openList.insert(self.openList.index(item), currentNode)breakif self.openList.count(currentNode) == 0:self.openList.append(currentNode)# self.openList.append(currentNode)return# 如果在openList中,判断minF到当前点的G是否更小if minF.g + step < currentNode.g:  # 如果更小,就重新计算g值,并且改变fathercurrentNode.g = minF.g + stepcurrentNode.father = minFdef start(self):"""开始寻路:return: None或Point列表(路径)"""# 判断寻路终点是否是障碍if self.map2d[self.endPoint.x][self.endPoint.y] != self.passTag:return None# 1.将起点放入开启列表startNode = AStar.Node(self.startPoint, self.endPoint)self.openList.append(startNode)# 2.主循环逻辑while True:# 找到F值最小的点minF = self.openList[0]# 把这个点加入closeList中,并且在openList中删除它self.closeList.append(minF)self.openList.remove(minF)# 判断这个节点的周边8个节点self.searchNear(minF, 0, -1)self.searchNear(minF, 0, 1)self.searchNear(minF, -1, 0)self.searchNear(minF, 1, 0)self.searchNear(minF, -1, -1)self.searchNear(minF, 1, 1)self.searchNear(minF, -1, 1)self.searchNear(minF, 1, -1)# 判断是否终止point = self.endPointInCloseList()if point:  # 如果终点在关闭表中,就返回结果# print("关闭表中")cPoint = pointpathList = []while True:if cPoint.father:pathList.append(cPoint.point)cPoint = cPoint.fatherelse:pathList.append(self.startPoint)# print(pathList)# print(list(reversed(pathList)))# print(pathList.reverse())return list(reversed(pathList))if len(self.openList) == 0:return Noneif __name__ == '__main__':# 创建一个10*10的地图map2d = Array2D(10 , 10)# 设置障碍map2d[0][3] = 1map2d[1][3] = 1map2d[2][3] = 1map2d[3][3] = 1map2d[2][5] = 1map2d[3][5] = 1map2d[4][5] = 1map2d[5][5] = 1map2d[6][5] = 1map2d[2][7] = 1map2d[3][7] = 1map2d[4][7] = 1map2d[5][7] = 1map2d[7][7] = 1map2d[8][7] = 1map2d[9][7] = 1map2d[5][1] = 1map2d[5][2] = 1map2d[5][3] = 1map2d[5][4] = 1# 显示地图当前样子map2d.showArray2D()# 创建AStar对象,并设置起点为0,0终点为9,0aStar = AStar(map2d, Point(2,1), Point(0,9))# 开始寻路pathList = aStar.start()# 遍历路径点,在map2d上以'8'显示for point in pathList:map2d[point.x][point.y] = 8# print(point)print()print("----------------------")print()# 再次显示地图map2d.showArray2D()

2.一些解释说明

代码部分并非个人独立完成, 主体结构来自于下面的文章https://blog.csdn.net/qq_37682024/article/details/106592311

关键在于个人对其代码的修改部分, 有四个部分

一是算法实现部分, 他的代码其实没有完整实现那篇参考的算法文章,

具体在于self.openlist变量的改动, 在searchNear函数中 ,其实应该也不需要这样改,只是在算法参考文章中, 最好选择F值最小的那个要求 , 我希望能降一点时间复杂度, 直接获取self.openlist[0], 即最小F值元素. 同时删掉了getMinNode函数

以及对于当前位置周边的8个位置的探索 ,而不是仅仅局限于上下左右四个位置, 以至于无法形成斜边的路径, 也许作者是想使得路径不能有斜边吧, 可是这样那数字14的出现没有多大意义啊.
另外就是,对于算法参考的那篇文章, 墙角部分,大家可以自己去实现一下哦
在这里插入图片描述

二是对于显示的符号的改动,更加直观

三是对于行列的描述部分, 修改后 w为列 , h为行, 本来想直接修改变量名的,但是其实也无伤大雅吧.

四是对于打印的链, 我增加了打印的起点

下面是对应修改的算法代码部分

        # 如果不在openList中,就把它加入openlist ,并且使得openlist的首元素为f值最小的currentNode = self.pointInOpenList(currentPoint)if not currentNode:currentNode = AStar.Node(currentPoint, self.endPoint, g=minF.g + step)currentNode.father = minFfor item in self.openList:if item.g+item.h > currentNode.g+currentNode.h:self.openList.insert(self.openList.index(item), currentNode)breakif self.openList.count(currentNode) == 0:self.openList.append(currentNode)return
            # 判断这个节点的周边8个节点self.searchNear(minF, 0, -1)self.searchNear(minF, 0, 1)self.searchNear(minF, -1, 0)self.searchNear(minF, 1, 0)self.searchNear(minF, -1, -1)self.searchNear(minF, 1, 1)self.searchNear(minF, -1, 1)self.searchNear(minF, 1, -1)

一些话

很感谢csdn的一些大佬们, 希望大家能创作更多的文章
真没想到下面的链接才是真正的作者, 我真的是服了, 真的是指针的指针了

似乎不找最小F值的元素, 仅仅只是把self.openlist全部遍历(类似广度搜索),也可以找到一条路径, 但是不是短路径就请读者去探索吧

感谢原作者,谢谢啦

狡猾的皮球
https://blog.csdn.net/qq_39687901/article/details/80753433


http://chatgpt.dhexx.cn/article/2cPKadj3.shtml

相关文章

A星算法(基于matlab)

概述 基于上一篇文章提到的DFS算法和BFS算法 A星算法属于图这种数据结构的搜索算法&#xff0c;对比于树的遍历搜索&#xff0c;需要考虑到的问题是&#xff1a;同一个节点的重复访问&#xff0c;所以需要对于已经访问过的节点进行标记。 曼哈顿距离&#xff1a; 在几何度量空…

【A星算法】--第四篇(A星算法)

本篇主要介绍A星算法的过程&#xff1a; * 把起始节点加进openList * while openList 不为空 { * 当前节点 openList 中成本最低的节点 * if&#xff08;当前节点 目标节点&#xff09;{ * 路径完成 …

A星算法详解(个人认为最详细,最通俗易懂的一个版本)

A* 寻路算法 原文地址&#xff1a; http://www.gamedev.net/reference/articles/article2003.asp 概述 虽然掌握了 A* 算法的人认为它容易&#xff0c;但是对于初学者来说&#xff0c; A* 算法还是很复杂的。 搜索区域(The Search Area) 我们假设某人要从 A 点移动到 B 点&…

A星算法理解

A星算法理解 1.选择A星算法的原因 为了进行路径规划算法是不可回避的&#xff1a;启发式搜索算法是比较常规的一类算法就是在状态空间中的搜索对每一个搜索的位置进行评估&#xff0c;得到最好的位置&#xff0c;再从这个位置进行搜索直到目标。这样可以省略大量无谓的搜索路…

A星(A*, A Star)算法详解

MulinB按&#xff1a;经典的智能寻路算法&#xff0c;一个老外写的很透彻很清晰&#xff0c;很容易让人理解神秘的A*算法。以下是一个中文翻译版。 A*寻路初探 GameDev.net 作者&#xff1a; Patrick Lester 译者&#xff1a;Panic 2005年3月18日 译者序&#xff1a;很久以前就…

A星算法

A星算法 1.简述 A星算法就是试图在地图中找到一条最短路径&#xff0c;但不保证一定存在。 任务 小猫去找青蛙玩&#xff08;好TM弱智啊~&#xff09;条件 黑色方块无法通行&#xff0c;每走一个格子小猫消耗的体力都为1。 2.如果说你是小猫&#xff0c;你会怎么走&#xf…

A星算法说明

A*算法说明 文章目录 前言原理说明如何构造 h ( n ) h(n) h(n)一、欧氏距离二、曼哈顿距离三、其他 关于 g ( n ) g(n) g(n)路况设置如何实现 完整的流程搜索过程图示允许斜走&#xff0c;使用优先队列禁止斜走&#xff0c;使用优先队列允许斜走&#xff0c;使用普通队列禁止斜…

A星算法优化(一)启发函数

基于Python语言对A星算法进行优化&#xff1a;(视频中会拿python与matlab作对比) 源码地址&#xff1a;https://github.com/Grizi-ju/ros_program/blob/main/path_planning/Astar.py B站详解视频&#xff1a;https://www.bilibili.com/video/BV1FL4y1M7PM?spm_id_from333.999…

猴子都能看懂的A星算法原理

文章目录 A星算法基本原理什么是寻路算法算法的思路 算法实现脚本1————cconst.cs脚本2————AStar.cs Unity演示演示样例一演示样例二演示样例三演示样例四 俗话说&#xff0c;好记性不如烂笔头&#xff0c;对于有了解过寻路算法的同学&#xff0c;对于A星算法应该不陌生…

A星寻路算法详解(C++实现 完整代码+图片演示 )

文章目录 三种寻路算法 A星寻路算法A星寻路算法思想A星寻路准备A星寻路过程&#xff08;图例&#xff09;A星寻路代码&#xff08;完整&#xff09; 三种寻路算法 深度寻路算法&#xff1a;不一定能找到最佳路径&#xff0c;但是寻路快速&#xff0c;只能走直线。广度寻路算法…

A星(A*、A Star)路径规划算法详解(附MATLAB代码)

首先看看运行效果&#xff0c;分别有三种模式&#xff0c;代码运行前需要通过鼠标点击设置起点和终点。 第一种模式直接输出最短路径 第二种模式输出最短路径的生成过程 第三种模式输出最短路径的生成过程和详细探索的过程 代码获取 gitee链接&#xff1a;https://gitee.c…

什么是脏读?不可重复读?幻读?如何解决?

什么是脏读&#xff1f;不可重复读&#xff1f;幻读&#xff1f;如何解决&#xff1f; 朋友最近面试美团&#xff0c;被面试官问到数据库的幻读问题&#xff0c;自己正好最近复习到这&#xff0c;做个笔记整理一下数据库的三大特征以及隔离级别。 一.先来回顾一下什么是事务&…

MySQL理论:脏读、不可重复读、幻读

&#x1f3c6;今日学习目标&#xff1a; &#x1f340;MySQL理论&#xff1a;脏读、不可重复读、幻读 ✅创作者&#xff1a;林在闪闪发光 ⏰预计时间&#xff1a;30分钟 &#x1f389;个人主页&#xff1a;林在闪闪发光的个人主页 &#x1f341;林在闪闪发光的个人社区&#xf…

数据库事务隔离级别(脏读、幻读、不可重复读)

一、脏读、幻读和不可重复读 一、脏读、不可重复读、幻读 1、脏读&#xff1a;脏读就是指当一个事务正在访问数据&#xff0c;并且对数据进行了修改&#xff0c;而这种修改还没有提交到数据库中&#xff0c;这时&#xff0c;另外一个事务也访问这个数据&#xff0c;然后使用了…

快速理解脏读,不可重复读,幻读

介绍 要聊事务&#xff0c;不可避免的要提到数据库事务的四大特性&#xff1a;ACID atomicconsistenceisolationdurability 先放一个表格&#xff0c;看看4个隔离级别会出现的各种问题&#xff0c;网上的解释一大堆。看完后还是一脸懵逼&#xff0c;感觉懂了&#xff0c;又好…

MySQL之脏写、脏读、不可重复读、幻读

脏写和脏读都是在多个事务同时修改或读取同一行数据的情况下产生的问题。比如现在有事务1和事务2同时对一行数据进行修改&#xff0c;事务1将值改成1&#xff0c;而事务2将值改成了2&#xff0c;这时的值应该是2&#xff0c;但是就在这时&#xff0c;事务1发生了回滚&#xff0…

数据库必备知识:脏读和幻读的定义及应对策略

随着数据库应用的广泛使用&#xff0c;数据库并发性和一致性的问题成为了引起重视的问题之一。其中&#xff0c;脏读&#xff08;Dirty Read&#xff09;和幻读&#xff08;Phantom Read&#xff09;是常见的并发访问问题&#xff0c;本文将对脏读、幻读进行详细介绍&#xff0…

Seata AT模式怎样防止脏写和脏读

前言 Seata AT 模式是一种非侵入式的分布式事务解决方案&#xff0c;Seata 在内部做了对数据库操作的代理层&#xff0c;我们使用 Seata AT 模式时&#xff0c;实际上用的是 Seata 自带的数据源代理 DataSourceProxy&#xff0c;Seata 在这层代理中加入了很多逻辑&#xff0c;…

mysql 脏数据是什么_什么是脏读?

什么是脏读&#xff1f; 脏读又称无效数据的读出&#xff0c;是指在数据库访问中&#xff0c;事务T1将某一值修改&#xff0c;然后事务T2读取该值&#xff0c;此后T1因为某种原因撤销对该值的修改&#xff0c;这就导致了T2所读取到的数据是无效的&#xff0c;值得注意的是&…

[Database] 脏读、幻读这些都是什么?事务隔离级别又是什么?MySQL数据库的事务隔离级别都有哪些?

文章目录 前言事务隔离级别三种数据不一致问题1. 脏读2. 不可重复读3. 幻读不可重复读 vs 幻读 四种事务隔离级别1. READ UNCOMMITTED2. READ COMMITTED3. REPEATABLE READ4. SERIALIZABLE 不同事务隔离级别会面临的问题不同隔离事务级别的使用率排名 实战查看事务隔离级别更改…