堆优化的A*算法-Python实现

堆优化的A*算法-Python实现

原理参考博客地址
代码借鉴地址
A*算法解决二维网格地图中的寻路问题

  • 输入:图片(白色区域代表可行,深色区域代表不行可行)
  • 输出:路径(在图中绘制)
""" 方格地图中的A*算法 (openList进行了堆优化)
A* 算法:  F = G+H
F: 总移动代价
G: 起点到当前点的移动代价  直:1, 斜:1.4
H: 当前点到终点的预估代价  曼哈顿距离
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1.把起点加入 openList中
2.While True:
    a.遍历openList,查找F值最小的节点,作为current
    b.current是终点:
        ========结束========
    c.从openList中弹出,放入closeList中
    d.对八个方位的格点:
        if 越界 or 是障碍物 or 在closeList中:
            continue
        if 不在openList中:
            设置父节点,F,G,H
            加入openList中
        else:
            if 这条路径更好:
                设置父节点,F,G
                更新openList中的对应节点
3.生成路径path
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
堆优化:
    openList:作为最小堆,按F值排序存储坐标 (不更新只增加)
    openDict:坐标:点详细信息 (既更新又增加)
    get_minfNode() 从openList中弹出坐标,去openDict中取点 (但由于不更新只增加,坐标可能冗余)
    in_openList() 判断坐标是否在openDict中即可 

"""
import math
from PIL import Image,ImageDraw 
import numpy as np
import heapq # 堆

STAT_OBSTACLE='#'
STAT_NORMAL='.'

class Node():
    """
    节点元素,parent用来在成功的时候回溯路径
    """
    def __init__(self, x, y,parent=None, g=0, h=0):
        self.parent = parent
        self.x = x
        self.y = y
        self.g = g
        self.h = h
        self.update()
    
    def update(self):
        self.f = self.g+self.h

class RoadMap():
    """ 读进一张图片,二值化成为有障碍物的二维网格化地图,并提供相关操作
    """
    def __init__(self,img_file):
        """图片变二维数组"""
        test_map = []
        img = Image.open(img_file)
#        img = img.resize((100,100))  ### resize图片尺寸
        img_gray = img.convert('L')  # 地图灰度化
        img_arr = np.array(img_gray)
        img_binary = np.where(img_arr<127,0,255)
        for x in range(img_binary.shape[0]):
            temp_row = []
            for y in range(img_binary.shape[1]):
                status = STAT_OBSTACLE if img_binary[x,y]==0 else STAT_NORMAL 
                temp_row.append(status)
            test_map.append(temp_row)
            
        self.map = test_map
        self.cols = len(self.map[0])
        self.rows = len(self.map)
        
    def is_valid_xy(self, x,y):
        if x < 0 or x >= self.rows or y < 0 or y >= self.cols:
            return False
        return True

    def 
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是实现A*算法的最短路径算法Python代码示例: ```python import heapq def astar(start, goal, graph): """A* algorithm implementation""" # Initialize the open and closed lists open_list = [] closed_list = set() # Add the start node to the open list heapq.heappush(open_list, (0, start)) # Initialize the g and h scores of the start node g_score = {start: 0} h_score = {start: heuristic(start, goal)} while open_list: # Get the node with the lowest f score _, current_node = heapq.heappop(open_list) # If the current node is the goal node, we have found the shortest path if current_node == goal: return reconstruct_path(start, goal, graph) # Add the current node to the closed list closed_list.add(current_node) # Iterate over the neighbors of the current node for neighbor, distance in graph[current_node].items(): # If the neighbor is already in the closed list, skip it if neighbor in closed_list: continue # Calculate the tentative g score of the neighbor tentative_g_score = g_score[current_node] + distance # If the neighbor is not in the open list, add it if neighbor not in [node[1] for node in open_list]: heapq.heappush(open_list, (tentative_g_score + heuristic(neighbor, goal), neighbor)) # If the neighbor is already in the open list and the tentative g score is greater, skip it elif tentative_g_score >= g_score[neighbor]: continue # Record the new g score and h score of the neighbor g_score[neighbor] = tentative_g_score h_score[neighbor] = heuristic(neighbor, goal) # If there is no path from the start node to the goal node, return None return None def reconstruct_path(start, goal, graph): """Reconstructs the shortest path from start to goal""" # Initialize the path with the goal node path = [goal] # Keep adding the previous node to the path until we reach the start node while path[-1] != start: current_node = path[-1] previous_nodes = graph[current_node] previous_node = min(previous_nodes, key=lambda node: previous_nodes[node]) path.append(previous_node) # Reverse the path and return it return list(reversed(path)) def heuristic(node, goal): """Returns the estimated distance between node and goal""" # Use the Manhattan distance as the heuristic return abs(node[0] - goal[0]) + abs(node[1] - goal[1]) # Example usage: graph = { (0, 0): {(1, 0): 1, (0, 1): 1}, (1, 0): {(0, 0): 1, (1, 1): 1}, (0, 1): {(0, 0): 1, (1, 1): 1}, (1, 1): {(1, 0): 1, (0, 1): 1, (2, 1): 1}, (2, 1): {(1, 1): 1, (2, 2): 1}, (2, 2): {(2, 1): 1} } start = (0, 0) goal = (2, 2) print(astar(start, goal, graph)) # Output: [(0, 0), (1, 0), (1, 1), (2, 1), (2, 2)] ``` 该示例代码实现了A*算法,使用了(heapq)来优化寻找最小f值的节点。在计算路径时,使用了启发式函数(heuristic),这里使用的是曼哈顿距离(Manhattan distance)。该代码可以寻找从一个起始点到一个目标点的最短路径。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值