📅  最后修改于: 2023-12-03 14:57:28.428000             🧑  作者: Mango
当我们计算一个人从起点到达第N站的方式时,通常会使用图论中的最短路径算法。这里介绍两种最短路径算法,分别是Dijkstra算法和Floyd算法。
Dijkstra算法是一种贪心算法,通过维护一个集合S,记录已经找到最短路径的点,来逐步地寻找从起点到其余节点的最短路径。
def dijkstra(graph, start, end):
# 初始化距离和集合
distance = {node: float('inf') for node in graph}
distance[start] = 0
visited = []
while not all(node in visited for node in graph):
# 找到当前未访问节点中,距离起点最近的节点
curr_node = min((set(distance.keys()) - set(visited)), key=distance.get)
visited.append(curr_node)
# 如果已经找到终点,则直接返回距离
if curr_node == end:
return distance[end]
# 更新所有邻居节点的距离
for neighbor in graph[curr_node]:
if neighbor in visited:
continue
new_distance = distance[curr_node] + graph[curr_node][neighbor]
if new_distance < distance[neighbor]:
distance[neighbor] = new_distance
# 如果无法到达终点,则返回无穷距离
return float('inf')
这里的graph是一个字典,记录每个节点的邻居节点和对应的距离。例如,如果我们的起点是A,那么graph[A]就是一个字典,记录A的邻居节点和对应的距离。
Floyd算法通过动态规划的方式来计算最短路径,具有更好的时间复杂度。我们可以使用一个二维数组,record[i][j]表示从节点i到节点j的最短路径,动态更新record数组。
def floyd(graph, start, end):
# 初始化record数组
nodes = list(graph.keys())
record = [[float('inf') for i in range(len(nodes))] for j in range(len(nodes))]
for i in range(len(nodes)):
record[i][i] = 0
for neighbor, dist in graph[nodes[i]].items():
j = nodes.index(neighbor)
record[i][j] = dist
# 动态规划,更新record数组
for k in range(len(nodes)):
for i in range(len(nodes)):
for j in range(len(nodes)):
if record[i][j] > record[i][k] + record[k][j]:
record[i][j] = record[i][k] + record[k][j]
return record[nodes.index(start)][nodes.index(end)]
这里的graph同样是一个字典,记录每个节点的邻居节点和对应的距离。我们使用nodes列表记录图的所有节点,通过index方法获取节点在record数组中的下标。
这两种算法都可以计算起点到达终点的最短路径,对于小规模的图来说,Dijkstra算法比较适用,而对于大规模的图来说,Floyd算法更为高效。