A*算法python简单可视化实现

A*算法详解:

A*算法详解

python实现:

使用堆优化加快查找最小代价点
详细流程都写在注释里了

使用方法:

# 参数为地图高、宽、方格尺寸、起点坐标(0开始)、终点坐标(0开始)、延迟时间
demo = MiniMap(20, 30, 30, (0, 0), (29, 19), 0.05)

鼠标左键单击方格添加/删除障碍物,中键重置路径(不改变障碍物),右键开始寻路。
其中黑色为障碍物,灰色为closelist中的点,黄色为openlist中的点,橙色为结果路径

代码:

# -*- coding: utf-8 -*-
from tkinter import *
import enum
import heapq
import time
import _threadclass PointState(enum.Enum):# 障碍物BARRIER = 'black'# 未使用UNUSED = 'white'# 在open list的方格OPEN = 'gold'# 在close list的方格CLOSED = 'darkgray'# 路径PATH = 'orangered'class MiniMap:class Point:def __init__(self, x, y, f, g, father, state, rectangle):# x坐标self.x = x# y坐标self.y = y# f = g + h, h为预估代价,这里使用曼哈顿距离self.f = f# 从寻路起点到这个点的代价self.g = g# 父节点self.father = father# 当前点状态self.state = state# 当前点对应画布上的矩形self.rectangle = rectangle# 重写比较,方便堆排序def __lt__(self, other):if self.f < other.f:return Trueelse:return Falsedef __init__(self, *args):# 高self.height = args[0]# 宽self.width = args[1]# 方格尺寸self.size = args[2]# 起点self.start = args[3]# 终点self.end = args[4]# 每次绘制的延迟时间self.delay = args[5]self.root = Tk()self.root.title('navigation')self.canvas = Canvas(self.root, width=self.width * self.size + 3, height=self.height * self.size + 3)# 生成方格集合self.points = self.generatePoints()# 生成网格self.generateMesh()self.canvas.bind('<Button-1>', self.createBarrier)self.canvas.bind('<Button-2>', self.cleanMap)self.canvas.bind('<Button-3>', self.navigation)self.canvas.pack(side=TOP, expand=YES, fill=BOTH)self.root.resizable(False, False)self.root.mainloop()def generatePoints(self):"""初始化绘制用的方格集合设置每个方格的状态和对应的矩形"""points = [[self.Point(x, y, 0, 0, None, PointState.UNUSED.value,self.canvas.create_rectangle((x * self.size + 3, y * self.size + 3),((x + 1) * self.size + 3, (y + 1) * self.size + 3),fill=PointState.UNUSED.value)) for y in range(self.height)]for x in range(self.width)]return pointsdef generateMesh(self):"""绘制网格"""for i in range(self.height + 1):self.canvas.create_line((3, i * self.size + 3), (self.width * self.size + 3, i * self.size + 3))for i in range(self.width + 1):self.canvas.create_line((i * self.size + 3, 3), (i * self.size + 3, self.height * self.size + 3))def createBarrier(self, event):"""设置障碍/移除障碍通过鼠标点击位置更改对应方格的状态"""x = int((event.x + 3) / self.size)y = int((event.y + 3) / self.size)if x < self.width and y < self.height:if self.points[x][y].state == PointState.BARRIER.value:self.changeState(self.points[x][y], PointState.UNUSED.value)else:self.changeState(self.points[x][y], PointState.BARRIER.value)def cleanMap(self, event):"""清空画布"""for i in range(self.width):for j in range(self.height):# 不清空障碍物(因为太难点了),不需要此功能则去掉判断if self.points[i][j].state != PointState.BARRIER.value:self.changeState(self.points[i][j], PointState.UNUSED.value)def navigation(self, event):"""新开一个线程调用寻路函数"""_thread.start_new_thread(self.generatePath, (self.start, self.end))def changeState(self, point, state):"""修改某一point的状态"""point.state = stateself.canvas.itemconfig(point.rectangle, fill=state)def generatePath(self, start, end):"""开始寻路"""xStart = start[0]yStart = start[1]xEnd = end[0]yEnd = end[1]# 用最小堆存点,使每次取出的点都预估代价最小heap = []# 两个set用于查找,存储坐标的二元组close_list = set()open_list = set()# 将起点加入open list,每格距离设置为10,是为了使斜着走时距离设置为14,方便计算heapq.heappush(heap, self.points[xStart][yStart])open_list.add((xStart, yStart))# 寻路循环while 1:# 从open list中取出代价最小点pMin = heapq.heappop(heap)open_list.remove((pMin.x, pMin.y))# 将这个点放入close list中close_list.add((pMin.x, pMin.y))self.changeState(self.points[pMin.x][pMin.y], PointState.CLOSED.value)# 遍历八个方向for i in range(-1, 2):for j in range(-1, 2):if i == 0 and j == 0:continue# 当前要判断的点的坐标xCur = pMin.x + iyCur = pMin.y + j# 如果这个点越界则跳过if xCur >= self.width or xCur < 0 or yCur >= self.height or yCur < 0:continuepCur = self.points[xCur][yCur]# 这个点是否在pMin的非正方向(即四个角落)isCorner = i != 0 and j != 0if isCorner:# 如果将要判断的斜角方向被阻挡则跳过(如将要判断东南方向,若东方或南方被阻挡,则跳过)if self.points[xCur][pMin.y].state == PointState.BARRIER.value or \self.points[pMin.x][yCur].state == PointState.BARRIER.value:continue# 如果在close list中出现或该点为障碍物则跳过判断if (xCur, yCur) not in close_list and self.points[xCur][yCur].state != PointState.BARRIER.value:# 如果在open list中if (xCur, yCur) in open_list:# 如果通过起点到pMin再到pCur的代价比起点到pCur的代价小,则更新pCur的代价,将pMin设置为pCur的父节点if ((14 if isCorner else 10) + pMin.g) < pCur.g:# 如果在角落,则pMin到pCur的代价为14,否则为10pCur.g = pMin.g + (14 if isCorner else 10)pCur.f = pCur.g + 10 * (abs(xEnd - xCur) + abs(yEnd - yCur))pCur.father = pMin# 如果不在open list中,则代表这个点第一次被访问,直接将pMin设置为pCur的父节点else:# 如果在角落,则pMin到pCur的代价为14,否则为10pCur.g = pMin.g + (14 if isCorner else 10)pCur.f = pCur.g + 10 * (abs(xEnd - xCur) + abs(yEnd - yCur))pCur.father = pMinself.changeState(pCur, PointState.OPEN.value)# 将这个点加入open listopen_list.add((xCur, yCur))heapq.heappush(heap, pCur)# 检测是否寻路完成if (xEnd, yEnd) in open_list:pNext = self.points[xEnd][yEnd]self.changeState(pNext, PointState.PATH.value)while pNext.father:pNext = pNext.fatherself.changeState(self.points[pNext.x][pNext.y], PointState.PATH.value)break# 如果寻路不完成但open list长度为0,则没有可达路径if len(open_list) == 0:print('Unreachable!')break# 等待绘制time.sleep(self.delay)# 参数为地图高、宽、方格尺寸、起点坐标(0开始)、终点坐标(0开始)、延迟时间
demo = MiniMap(20, 30, 30, (0, 0), (29, 19), 0.05)

A*算法python可视化实现相关推荐

  1. 我用 Python 3分钟实现9种经典排序算法的可视化

    导读:最近在某网站上看到一个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感. 不知道作者是怎么做的,但是突然很想自己实现一遍,而且用python实现特别快,花了一天的时间,完成了这个项目. ...

  2. 快速修改数组的某个值_我用Python,3分钟快速实现,9种经典排序算法的可视化...

    最近在某网站上看到一个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感. ▼ 6分钟演示15种排序算法 https://v.qq.com/x/page/t0396emm8oy.html 不知 ...

  3. 3分钟快速实现:9种经典排序算法的可视化

    作者 | 爱笑的眼睛 来源 | 恋习Python(ID:sldata2017) 最近在某网站上看到一个视频,是关于排序算法的可视化的,看着挺有意思的,也特别喜感. ▼ 6分钟演示15种排序算法 不知道 ...

  4. 2021-03-15 数据挖掘算法—K-Means算法 Python版本

    数据挖掘算法-K-Means算法 Python版本 简介 又叫K-均值算法,是非监督学习中的聚类算法. 基本思想 k-means算法比较简单.在k-means算法中,用cluster来表示簇:容易证明 ...

  5. 最优化算法python实现篇(4)——无约束多维极值(梯度下降法)

    最优化算法python实现篇(4)--无约束多维极值(梯度下降法) 摘要 算法简介 注意事项 算法适用性 python实现 实例运行结果 算法过程可视化 摘要 本文介绍了多维无约束极值优化算法中的梯度 ...

  6. Python可视化:Seaborn(二)

    本文由 保一雄@科赛网 数据分析师 原创. Seaborn是一个很棒的可视化库,尤其是当数据维度很大时,它可以让我们用最少的代码去绘制一些描述性统计的图,便于找寻各维度变量之间的特征. 继上篇Pyth ...

  7. 探索性数据分析,这8个流行的 Python可视化工具就够了

    来源 / 机器之心  作者 / Aaron Frederick 参与 / 李诗萌.王淑婷 Matplotlib.Seaborn 和 Pandas ggplot(2) Bokeh Plotly Pyga ...

  8. 决策算法python_GitHub - nxety/MachineLearning_Python: 机器学习算法python实现

    机器学习算法Python实现 目录 1.代价函数 其中: 下面就是要求出theta,使代价最小,即代表我们拟合出来的方程距离真实值最近 共有m条数据,其中代表我们要拟合出来的方程到真实值距离的平方,平 ...

  9. 数据结构与算法 python版 之 递归三定律

    #数据结构与算法 python版 之 谢尔宾斯基三角形 , 树叉 1.为了向阿西莫夫的"机器人三定律"直径,递归算法也总结出"三定律" 1递归算法必须有一个基本 ...

最新文章

  1. 10.QT事件机制源码时序分析(中)
  2. 记录安装mysql5.7.24遇到的坑
  3. Android之玩转MPAndroidChart让(折线图、柱形图、饼状图、散列图、雷达图)优雅的舞动
  4. Windows高级编程学习笔记(二)
  5. Alexa市场占有率分析:Compute、CDN、DNS
  6. ios基础篇(十二)——UINavgationController的使用(三)ToolBar
  7. Android 开发笔记“context和getApplicationContext”
  8. Gephi教程【1】安装
  9. opencv-python:17_图像经典边缘检测算子(边缘检测、图像梯度、Roberts算子、Prewitt算子、Sobel 算子、Laplacian 算子、Canny算子、算子优缺点对比)
  10. 华为网络设备调试命令(日常总结)
  11. c#mvc模式进行crud_实用的微服务开发模式:CRUD与。 CQRS
  12. Python实现分卷压缩
  13. 世界多国尝试弃用美元 滥用霸权、转嫁危机恐将自食其果
  14. windows 无法在此计算机上完成安装,重装系统后显示无法完成安装|Windows无法在此计算机安装...
  15. 我推荐阅读的微信公众号-IT类
  16. FME转换DWG到KML或KMZ
  17. sqlzoo第七关More JOIN operations
  18. 年薪 30W 和 60W,数据分析师的两道坎
  19. ffmpeg-avi转mp4命令
  20. 事务操作(事务概念)

热门文章

  1. 目前市场上用于个人计算机的硬盘尺寸是,2016年计算机组装与维修高考题
  2. Java基础总结大全(面试必看)
  3. Listener监听器快速入门
  4. Android入门之addWindow
  5. argument type mismatch 参数类型不匹配
  6. Bypass安全狗之SQL注入
  7. 读者调研 | 行上行下小书屋邀你填问卷啦
  8. 使用驱动器之前需要将其格式化
  9. 心中的感慨,当前的社会太现实了
  10. 阿里国际站的评论可以删除吗?要如何运营?