IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 算法系列——A*算法 -> 正文阅读

[Python知识库]算法系列——A*算法

本系列旨在用简单的人话讲解算法,尽可能避免晦涩的定义,读者可以短时间内理解算法原理及应用细节。我在努力!

本篇文章编程语言为Python,供参考。

?A*算法

一种静态路网中求解最短路径最有效的直接搜索方法。(百度百科)

算法基本思路:创建两个数组分别记录待访问、已访问的结点,先将起始点放入待访问的数组,每次从待访问数组中选取F值最小的一个结点,然后将其上下左右四边中有效的结点放入待访问数组(有效条件:不出界、无障碍、未访问),不断重复以上操作,直到终点出现在待访问数组中(存在最短路径)或待排序数组为空(无法到达)为止。

?

?

?附全部源码:

brickList = [
    [0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0],
    [0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1],
    [0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0],
    [0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0],
    [0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0],
    [1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1],
    [0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0],
    [1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0],
    [0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1],
    [0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0],
    [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
    [0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0],
    [1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1],
    [0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    [1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0],
]

#分别求当前迷宫的宽度及高度
w_brilist = len(brickList[0])
h_brilist = len(brickList)

zongzipos = (9,4)

class Grid():
    def __init__(self, x, y, dest=None, parent=None):
        #当前点的横纵坐标
        self.x = x
        self.y = y
        #目标结点(用于计算H值)
        self.dest = dest
        #用于记录当前结点的前驱结点(输出路径用)
        self.parent = parent
        if dest is not None:
            #G值为从起始点到当前点的距离
            self.g = self.parent.g + 1 if self.parent is not None else 1
            #H值为从当前点到终点的曼哈顿距离(不考虑障碍)
            self.h = abs(dest.x - self.x) + abs(dest.y - self.y)
            #F值为从起始点经过当前点到终点的距离
            self.f = self.g + self.h
        

    def get_valid_neighbors(self, open_list, close_list):
        #从上下左右四个方向判断邻居结点是否有效
        a = [(1,0), (-1,0), (0,1), (0,-1)]
        #用于保存有效的邻居结点
        res = []
        #逐个判断四边的邻居结点是否有效
        for i in a:
            #创建并判断邻居结点是否有效,有效保存
            tmp = Grid(self.x+i[0], self.y+i[1], self.dest, self)
            if tmp.is_valid(open_list, close_list):
                res.append(tmp)

        return res

    def is_valid(self, open_list, close_list):
        #出界
        if not (0 <= self.x < w_brilist and 0 <= self.y < h_brilist):
            return False
        
        #遇障碍物
        if brickList[self.x][self.y] != 0:
            return False

        #是否已出现过
        for i in open_list + close_list:
            if self.x == i.x and self.y == i.y:
                return False

        return True

    def is_dest(self):
        #判断是否为终点结点
        return self.x == self.dest.x and self.y == self.dest.y


def a_star_algorithm(src, dest):
    #初始化待访问及已访问列表
    open_list = [src]
    close_list = []

    #每次选取F值最小的一个结点,将他所有有效邻居加入列表,直到列表为空或出现终点为止。
    while open_list != []:
        #获取f值最小节点
        open_list.sort(key=lambda x: x.f)
        now = open_list.pop(0)
        close_list.append(now)
        #向待访问列表中加入当前结点所有有效邻居结点
        open_list.extend(now.get_valid_neighbors(open_list, close_list))

        #判断终点是否出现在待访问列表
        for i in open_list:
            if i.is_dest():
                return i

    return None

def get_path(dest):
    path = []
    while dest is not None:
        path.append((dest.x,dest.y))
        dest = dest.parent

    return path[::-1]
    

dest = Grid(*zongzipos)
src = Grid(0, 0, dest, None) 

c = a_star_algorithm(src, dest)

path = get_path(c)
print(path)

成果演示视频:

(为演示清楚,用pygame做了个图像版)

?参考资料:《漫画算法:小灰的算法之旅(Python篇)》

?

后记:很有意思的一个算法,尤其是能用pygame库展示出来看效果比直接看一串坐标清楚地多。?

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-08-27 11:48:56  更:2021-08-27 11:50:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 12:10:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码