方式一
from heapq import heappush, heappop
from math import sqrt # 返回 x 的平方根
def astar(start, goal, neighbors_fn, distance_fn, heuristic_fn):
"""该函数返回从起始节点到目标节点的路径。
start: 起始节点。
goal: 目标节点。
neighbors_fn: 一个函数,它接收一个节点作为参数,并返回与该节点相邻的节点列表。
distance_fn: 一个函数,它接收两个节点作为参数,并返回这两个节点之间的距离。
heuristic_fn: 一个函数,它接收两个节点作为参数,并返回从第一个节点到第二个节点的启发式距离。
"""
# 初始化起始节点
g_scores = {start: 0}
f_scores = {start: heuristic_fn(start, goal)}
open_set = [(f_scores[start], start)]
came_from = {}
# A*搜索
while open_set:
# heappop从堆 heap 中弹出并返回最小值,并保持堆不变。如果堆为空,则引发 IndexError
current = heappop(open_set)[1]
if current == goal:
path = [current]
while current in came_from:
current = came_from[current]
path.append(current)
return path[::-1]
for neighbor in neighbors_fn(current):
# neighbors_fn这是一个示例邻居函数,它接收一个节点作为参数,并返回与该节点相邻的节点列表。您可以将其替换为您自己的邻居函数
#def neighbors_fn(node):
# return [(node[0] + 1, node[1]), (node[0] - 1, node[1]), (node[0], node[1] + 1), (node[0], node[1] - 1)]
tentative_g_score = g_scores[current] + distance_fn(current, neighbor)
# distance_fn(node1, node2)
# 这是一个示例距离函数,它接收两个节点作为参数,并返回这两个节点之间的实际距离。您可以将其替换为您自己的距离函数。
#def heuristic_fn(node1, node2):
# x1, y1 = node1
# x2, y2 = node2
# return abs(x1 - x2) + abs(y1 - y2)
if neighbor not in g_scores or tentative_g_score < g_scores[neighbor]:
came_from[neighbor] = current
g_scores[neighbor] = tentative_g_score
f_scores[neighbor] = tentative_g_score + heuristic_fn(neighbor, goal)
# 将 item 插入堆 heap 中,并保持堆不变
heappush(open_set, (f_scores[neighbor], neighbor))
return None
该算法使用了堆优化来保存开放集合,并通过字典来保存每个节点的g值和f值。相比其他实现,该算法通过对g和f值的字典的使用来减少内存消耗,提高空间利用率。
函数 astar() 接收起始节点、目标节点、邻居函数、距离函数和启发式函数。它返回一条从起始节点到目标节点的路径,或者如果没有找到路径,则返回 None。
在该实现中,距离函数被视为节点之间的实际距离(例如欧几里得距离)。可以根据需要更改此函数。
方式二
另一种实现方式:
from heapq import heappush, heappop
from math import sqrt
def astar(start, goal, neighbors_fn, distance_fn, heuristic_fn):
# 初始化起始节点
g_scores = {start: 0}
f_scores = {start: heuristic_fn(start, goal)}
open_set = [(f_scores[start], start)]
closed_set = set()
# A*搜索
while open_set:
current = heappop(open_set)[1]
if current == goal:
path = [current]
while current in came_from:
current = came_from[current]
path.append(current)
return path[::-1]
closed_set.add(current)
for neighbor in neighbors_fn(current):
if neighbor in closed_set:
continue
tentative_g_score = g_scores[current] + distance_fn(current, neighbor)
if neighbor not in g_scores or tentative_g_score < g_scores[neighbor]:
g_scores[neighbor] = tentative_g_score
f_scores[neighbor] = tentative_g_score + heuristic_fn(neighbor, goal)
heappush(open_set, (f_scores[neighbor], neighbor))
return None
astar(start, goal, neighbors_fn, distance_fn, heuristic_fn)
这是A*算法的主要函数,它接收以下参数:
start: 起始节点。
goal: 目标节点。
neighbors_fn: 一个函数,它接收一个节点作为参数,并返回与该节点相邻的节点列表。
distance_fn: 一个函数,它接收两个节点作为参数,并返回这两个节点之间的距离。
heuristic_fn: 一个函数,它接收两个节点作为参数,并返回从第一个节点到第二个节点的启发式距离。
该函数返回从起始节点到目标节点的路径。
heappush(heap, item)
将 item 插入堆 heap 中,并保持堆不变。
heappop(heap)
从堆 heap 中弹出并返回最小值,并保持堆不变。如果堆为空,则引发 IndexError。
sqrt(x)
返回 x 的平方根。
neighbors_fn(node)
这是一个示例邻居函数,它接收一个节点作为参数,并返回与该节点相邻的节点列表。您可以将其替换为您自己的邻居函数。
def neighbors_fn(node):
return [(node[0] + 1, node[1]), (node[0] - 1, node[1]), (node[0], node[1] + 1), (node[0], node[1] - 1)]
distance_fn(node1, node2)
这是一个示例距离函数,它接收两个节点作为参数,并返回这两个节点之间的实际距离。您可以将其替换为您自己的距离函数。
def distance_fn(node1, node2):
x1, y1 = node1
x2, y2 = node2
return sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
heuristic_fn(node1, node2)
这是一个示例启发式函数,它接收两个节点作为参数,并返回从第一个节点到第二个节点的启发式距离。您可以将其替换为您自己的启发式函数。
def heuristic_fn(node1, node2):
x1, y1 = node1
x2, y2 = node2
return abs(x1 - x2) + abs(y1 - y2)
以上是该算法的详细实现。
```python
astar(start, goal, neighbors_fn, distance_fn, heuristic_fn)
这是A*算法的主要函数,它接收以下参数:
start: 起始节点。
goal: 目标节点。
neighbors_fn: 一个函数,它接收一个节点作为参数,并返回与该节点相邻的节点列表。
distance_fn: 一个函数,它接收两个节点作为参数,并返回这两个节点之间的距离。
heuristic_fn: 一个函数,它接收两个节点作为参数,并返回从第一个节点到第二个节点的启发式距离。
该函数返回从起始节点到目标节点的路径。
heappush(heap, item)
将 item 插入堆 heap 中,并保持堆不变。
heappop(heap)
从堆 heap 中弹出并返回最小值,并保持堆不变。如果堆为空,则引发 IndexError。
sqrt(x)
返回 x 的平方根。
neighbors_fn(node)
这是一个示例邻居函数,它接收一个节点作为参数,并返回与该节点相邻的节点列表。您可以将其替换为您自己的邻居函数。
def neighbors_fn(node):
return [(node[0] + 1, node[1]), (node[0] - 1, node[1]), (node[0], node[1] + 1), (node[0], node[1] - 1)]
distance_fn(node1, node2)
这是一个示例距离函数,它接收两个节点作为参数,并返回这两个节点之间的实际距离。您可以将其替换为您自己的距离函数。
def distance_fn(node1, node2):
x1, y1 = node1
x2, y2 = node2
return sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2)
heuristic_fn(node1, node2)
这是一个示例启发式函数,它接收两个节点作为参数,并返回从第一个节点到第二个节点的启发式距离。您可以将其替换为您自己的启发式函数。
python
Copy code
def heuristic_fn(node1, node2):
x1, y1 = node1
x2, y2 = node2
return abs(x1 - x2) + abs(y1 - y2)
以上是该算法的详细实现。