吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2955|回复: 7
收起左侧

[Python 原创] 【A*/A star】启发式路径搜索算法

[复制链接]
Lthero 发表于 2021-4-27 21:10
本帖最后由 Lthero 于 2021-5-31 18:38 编辑

A*教程
视频:https://www.bilibili.com/video/BV1bv411y79P?from=search&seid=1736083035601105399
图文:https://www.redblobgames.com/pathfinding/a-star/introduction.html

redblob有代码,我在此基础上修改了一些内容,并做了可视化
核心代码
[Python] 纯文本查看 复制代码
'''A star算法部分
[url=https://www.bilibili.com/video/BV1bv411y79P?from=search&seid=1736083035601105399]https://www.bilibili.com/video/BV1bv411y79P?from=search&seid=1736083035601105399[/url]
[url=https://www.redblobgames.com/pathfinding/a-star/introduction.html]https://www.redblobgames.com/pathfinding/a-star/introduction.html[/url]
'''
# 每个结点的附近四个结点
def neighbors(the_one):
    return [[the_one[0], the_one[1] - 1], [the_one[0] + 1, the_one[1]], [the_one[0], the_one[1] + 1],
            [the_one[0] - 1, the_one[1]]]

# 当前代价
def weight(first, second):
    return 1

# 预估代价,采用欧式距离
def heuristic(first, second):
    x_dis = abs(first[0] - second[0])
    y_dis = abs(first[1] - second[1])
    return math.sqrt(pow(x_dis, 2) + pow(y_dis, 2))

# 主代码
def A_star(the_map):
    # 迷宫长度宽度
    len_row = len(the_map)
    len_col = len(the_map[0])
    # 起点
    start = [man_x[0], man_y[0]]
    # 出口
    target = [door_x[0], door_y[0]]
    # 等待遍历的点,左边是当前的总代价=当前(距离起点)代价+预估代价
    frontier = [(0, start)]
    # 记录当前结点的来向结点
    came_from = {}
    # 记录已经走过的结点,用字典存,key是结点的(x,y)降维后的一个数字,如下面,value是当前代价
    # start[0] * 3.141 + start[1] * 2.727 只是个标识,数字随便乘的,当作cost_so_far的key
    cost_so_far = {}
    came_from[start[0] * 3.141 + start[1] * 2.727] = None
    cost_so_far[start[0] * 3.141 + start[1] * 2.727] = 0
    # 等待遍历的点不为空
    while len(frontier) != 0:
        # 弹出总代价最小的结点
        ww = frontier.pop(0)
        current = ww[1]
        # 当前结点就是出口,退出
        if current[0] == target[0] and current[1] == target[1]:
            break
        # 遍历当前结点的上下左右的邻居结点
        for next_one in neighbors(current):
            # 下面都是对这个邻居结点操作
            # 邻居结点没超过地图范围 && 邻居结点还在障碍物中
            if 0 <= next_one[0] <= len_col and 0 <= next_one[1] <= len_row and next_one not in barriers:
                # 计算 到达邻居结点的当前代价
                new_cost = cost_so_far[current[0] * 3.141 + current[1] * 2.727] + weight(current, next_one)
                # 如果邻居结点不在已经走过的集合中 或者 走邻居结点的代价小于走当前结点的代价
                if next_one[0] * 3.141 + next_one[1] * 2.727 not in cost_so_far.keys() or new_cost < cost_so_far[
                    current[0] * 3.141 + current[1] * 2.727]:
                    # 记录到邻居结点的当前代价是new_cost
                    cost_so_far[next_one[0] * 3.141 + next_one[1] * 2.727] = new_cost
                    # 计算 邻居结点的总代价
                    priority = new_cost + heuristic(target, next_one)
                    # 如果下一个结点是终点,res_flag设置1,提前退出
                    if next_one[0] == target[0] and next_one[1] == target[1]:
                        came_from[target[0] * 3.141 + target[1] * 2.727] = current
                        res_flag[0] = 1
                    else:
                        #不是终点,把这个邻居结点放在frontier中
                        came_from[next_one[0] * 3.141 + next_one[1] * 2.727] = current
                        frontier.append((priority, next_one))
                    #重新排序,确保总代价最小的结点在第一个
                    frontier.sort(key=lambda x: x[0])
        if res_flag[0] == 1:
            break
    #输出路径
    p = target
    path.append([target[0], target[1]])
    while came_from[p[0] * 3.141 + p[1] * 2.727] != start:
        path.append([came_from[p[0] * 3.141 + p[1] * 2.727][0], came_from[p[0] * 3.141 + p[1] * 2.727][1]])
        p = came_from[p[0] * 3.141 + p[1] * 2.727]
    path.append([start[0], start[1]])
    came_from.clear()
    cost_so_far.clear()

一般迷宫
QQ截图20210427212019.jpg

特殊情况
QQ截图20210427210421.jpg
这种情况,用迪克斯特拉算法,程序运行很慢,我等了5分钟没出结果。
但A*算法只用了不到1秒。

迷宫A star 算法plus.zip

3.68 KB, 下载次数: 13, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 5吾爱币 +16 热心值 +4 收起 理由
苏紫方璇 + 10 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
_小白 + 1 用心讨论,共获提升!
涛之雨 + 4 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
lendone + 1 + 1 谢谢@Thanks!
renpeng009 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

sam喵喵 发表于 2021-4-27 21:42
这个迷宫也太特殊了吧
 楼主| Lthero 发表于 2021-4-27 22:11
sam喵喵 发表于 2021-4-27 21:42
这个迷宫也太特殊了吧

普通的迷宫当然有解,这种情况下迪克算法或者深度优先时间复杂度就太高了,突显下A*的特点吧
lendone 发表于 2021-4-27 22:28
duanshifeng1994 发表于 2021-6-12 14:39
大佬 资源里没有close.png
 楼主| Lthero 发表于 2021-6-12 15:45
duanshifeng1994 发表于 2021-6-12 14:39
大佬 资源里没有close.png

我是随便找的图,表示障碍的。你可以替换下
Joysaic 发表于 2022-11-26 16:10
马一下 可能会用到
angang20 发表于 2022-11-27 13:57
redblobgames不错~~
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 02:44

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表