空间复杂度较低的 Python A*算法实现

方式一

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)
以上是该算法的详细实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值