📅  最后修改于: 2023-12-03 15:05:44.213000             🧑  作者: Mango
Uniform-Cost Search(一致代价搜索)是一种用于解决加权图最短路径问题的算法,又被称为大图的 Dijkstra 算法。与 Dijkstra 算法相似,Uniform-Cost Search 也使用了优先队列来管理遍历过的节点,但是它以代价更小的路径优先遍历节点,而不是以最短距离优先遍历节点。Uniform-Cost Search 的优点在于可以处理图中存在负边权的情况。
初始状态为起点,把起点加入到优先队列中,代价为零。
对于队列中的每个节点,选择队列中代价最小的节点进行遍历,同时更新从起点到该节点的最优代价和路径。
将遍历到的节点放入遍历过的集合中,标记为已经遍历过。
对于遍历到的节点,扩展它的相邻节点,如果相邻节点不在已经遍历的集合中,就把它加入到优先队列中。
对于已经遍历过的节点,更新它的代价和路径,如果更新后的代价更小,就重新放入优先队列中。
重复步骤 2-5,直到从起点到终点的最短路径被找到,或者队列为空为止。
下面是 Uniform-Cost Search 的实现代码:
import heapq
def uniform_cost_search(graph, start, goal):
"""
graph 是一个邻接表,表示图的结构和边权
start 是起点,goal 是终点
返回从起点到终点的最短路径和代价
"""
# 用一个字典记录遍历过的节点和从起点到该节点的最小代价和路径
explored = {start: (None, 0)}
# 初始化优先队列,将起点放入队列中
queue = [(0, start)]
while queue:
# 取出队列中代价最小的节点进行遍历
cost, node = heapq.heappop(queue)
# 如果遍历到终点,返回从起点到终点的最小代价和路径
if node == goal:
path = []
while node is not None:
path.append(node)
node = explored[node][0]
path.reverse()
return path, explored[goal][1]
# 遍历从当前节点能够到达的所有节点
for neighbor, weight in graph[node].items():
# 计算到达相邻节点的代价
new_cost = explored[node][1] + weight
# 如果相邻节点还没有被遍历过或者新的代价更小,就把它加入到优先队列中进行遍历
if neighbor not in explored or new_cost < explored[neighbor][1]:
explored[neighbor] = (node, new_cost)
heapq.heappush(queue, (new_cost, neighbor))
# 如果从起点无法到达终点,返回 None
return None, float('inf')
Uniform-Cost Search 的时间复杂度取决于图的大小和边的数量,最坏情况下是 $O(b^{1 + \lfloor C^/\epsilon \rfloor})$,其中 $b$ 是分支因子,$C^$ 是从起点到终点的最短距离,$\epsilon$ 是任意正数。因此 Uniform-Cost Search 不适用于大规模的图。