A*算法python实现

import numpy as np

from numpy.linalg import norm
from heapq import heappush,heappop
from PIL import Image
import matplotlib.pyplot as plt

def MyNorm(a, b, order):

a = np.array(a)
b = np.array(b)
return norm(a - b, order)

def ReconstructPath(OldDict, BestNode):

path = [BestNode]
while BestNode in OldDict:
    BestNode = OldDict[BestNode]
    path.append(BestNode)
return path

def astar(array, start, goal):

directions = [(0,1),(0,-1),(1,0),(-1,0),(1,1),(1,-1),(-1,1),(-1,-1)] # 8个方向

ClosedList = set()
OldDict = {}
gscore = {start:0}                 # 定义一个字典,start是key
fscore = {start:MyNorm(start, goal, 1)} # 定义f字典

OpenList = []
heappush(OpenList, (fscore[start], start))   # 将(fscore[start], start)放入最小优先级队列,按fscore[start]排序,start是真正存储元素

# while OpenList is not empty
while OpenList:  
    # 选择一个 OPEN 表没有设置的 f 值最小的节点 BESTNODE,移到 CLOSED 表
    BestNode = heappop(OpenList)[1]    

    if BestNode == goal:
        return ReconstructPath(OldDict, BestNode)

    ClosedList.add(BestNode)

    for i, j in directions:      # 对当前节点的 8 个后继节点一一进行检查
        Successor = BestNode[0] + i, BestNode[1] + j     

        ## 判断节点是否在地图范围内,并判断是否为障碍物
        if 0 <= Successor[0] < array.shape[0]:
            if 0 <= Successor[1] < array.shape[1]:                
                if array[Successor[0]][Successor[1]] == 1:   # 1为障碍物
                    continue
            else:
                # array bound y walls
                continue
        else:
            # array bound x walls
            continue

        # Ignore the Successor which is already evaluated.
        if Successor in ClosedList: 
            continue

        #  g(SUC)=g(BES)+h(BES,SUC),将两个节点间的欧氏距离作为启发函数
        tentative_gScore = gscore[BestNode] + MyNorm(BestNode, Successor, 2)

        if  Successor not in [i[1] for i in OpenList]:                # 若SUCCESSOR不在OPEN表或CLOSED表中,则将其填入 OPEN 表
            heappush(OpenList, (fscore.get(Successor, np.inf), Successor)) 
        elif tentative_gScore >= gscore.get(Successor, np.inf):   # This is not a better path.
            continue        

        # This path is the BEST until now.
        OldDict[Successor] = BestNode
        gscore[Successor] = tentative_gScore
        # 修正父节点的 g 值和 f 值,记录 g(OLD),将successor到目标点的曼哈顿距离作为启发函数
        fscore[Successor] = tentative_gScore + MyNorm(Successor, goal, 1)

return False

if name == “main”:
nmap = np.array([
[0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,1,1,1,0,1],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,0,1,1,1,1,1,1,1,1,1,1,1,1],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,1,1,1,0,1],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,0,1,1,1,1,1,1,1,1,1,1,1,1],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,1,1,1,0,1],
[0,0,0,0,0,0,0,0,0,0,0,0,0,0]])
path = astar(nmap, (0,0), (10,13)) # 设置起点和终点,测试图像尺寸为50x50

for i in range(len(path)):
    nmap[path[i]] = 88
print(nmap)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A*算法是一种启发式的搜索算法,用于在图形或网络中找到最短路径。它是基于深度优先算法和广度优先算法的一种融合算法,通过使用启发式函数来评估每个节点的优先级,以确定下一个要扩展的节点。\[2\] 在A*算法中,每个节点都有一个估计的成本,由两部分组成:从起始节点到当前节点的实际成本(g值)和从当前节点到目标节点的估计成本(h值)。通过将这两个成本相加,可以得到一个节点的总成本(f值)。算法会选择具有最低总成本的节点进行扩展,直到找到目标节点或搜索完整个图形。\[1\] A*算法的步骤包括预处理、开始搜索、继续搜索和确定实际路径。在预处理阶段,需要初始化起始节点和目标节点,并计算起始节点的f值。然后,在开始搜索阶段,将起始节点添加到一个优先队列中,并按照f值的顺序进行扩展。在继续搜索阶段,算法会选择具有最低f值的节点进行扩展,并更新其邻居节点的f值。最后,在确定实际路径阶段,可以通过回溯从目标节点到起始节点,以找到最短路径。\[3\] A*算法可以使用Python或C++等编程语言进行实现。在Python中,可以使用优先队列和适当的数据结构来实现A*算法。具体的实现细节可以参考相关的参考资料和代码示例。\[4\] #### 引用[.reference_title] - *1* *2* *3* [【路径规划】全局路径规划算法——A*算法(含python实现 | c++实现)](https://blog.csdn.net/weixin_42301220/article/details/125140910)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值