326 dijkstra算法2 #
- 节点的更新和标记
- dijkstra算法的完整实现
节点的更新和标记 #
这是dijkstra的主要部分, 更新节点直到目标节点或者所有节点更新完为止。从源节点开始,如果循环时该节点不是源节点并且到源节点的距离没更新过,则比较两者距离,
如果距离更小则更新距离和路径字典。
如果距离更小则更新距离和路径字典。
def dijkstra(from_vertex, dest_vertex):
# 首先轮流更新所有顶点获得hop_path, 再从hop_path中取得对应路径
star = int(from_vertex) - 1
des = int(dest_vertex) - 1
init_distances(star)
mark = [star] # 这个就是标记,最先标记目标点的索引
current_vertex = star # 当前所在顶点的索引
hop_path = {}
# 更新和标记所有顶点
while len(mark) <= vertices_number and current_vertex != des:
# 先计算其余顶点到当前顶点current_vertex的距离, 然后把该顶点索引标记,把到当前顶点最近的索引更新为下一个顶点
for i in range(vertices_number):
if i != current_vertex and i not in mark and \
adjacency_matrix[current_vertex][i] > 0 \
and distance[i] > adjacency_matrix[current_vertex][i]:
distance[i] = distance[current_vertex] + \
adjacency_matrix[current_vertex][i]
hop_path.update(
{i + 1: {"from": current_vertex + 1, "cost": adjacency_matrix[current_vertex][i]}})
dijkstra算法的完整实现 #
每次更新完节点后必须将路径信息更新到路径字典里,这样节点更新完后才可以找出最短路径
import sys
max = sys.maxsize
vertices_number = 6
adjacency_matrix = [
[0, 1, 10, 1, 3, 2],
[10, 0, 1, 7, 5, 1],
[1, 10, 0, 6, 1, 1],
[1, 3, 2, 0, 1, 10],
[1, 5, 2, 10, 0, 1],
[1, 2, 1, 6, 10, 0]]
start = []
dest = ["2", "5"]
distance = []
def init_distances(s: int):
# 初始化所有顶点到源的距离
global distance
distance = [max] * vertices_number
distance[s] = 0
def dijkstra(from_vertex, dest_vertex):
# 首先轮流更新所有顶点获得hop_path, 再从hop_path中取得对应路径
star = int(from_vertex) - 1
des = int(dest_vertex) - 1
init_distances(star)
mark = [star] # 这个就是标记,最先标记目标点的索引
current_vertex = star # 当前所在顶点的索引
hop_path = {}
# 更新和标记所有顶点
while len(mark) <= vertices_number and current_vertex != des:
# 先计算其余顶点到当前顶点current_vertex的距离, 然后把该顶点索引标记,把到当前顶点最近的索引更新为下一个顶点
for i in range(vertices_number):
if i != current_vertex and i not in mark and \
adjacency_matrix[current_vertex][i] > 0 \
and distance[i] > adjacency_matrix[current_vertex][i]:
distance[i] = distance[current_vertex] + \
adjacency_matrix[current_vertex][i]
hop_path.update(
{i + 1: {"from": current_vertex + 1, "cost": adjacency_matrix[current_vertex][i]}})
if current_vertex not in mark:
mark.append(current_vertex)
current_vertex = des
for i in range(vertices_number):
if i not in mark and distance[i] < distance[current_vertex]:
current_vertex = i
# 倒序找出最短路径
if len(hop_path) == 0 or int(dest_vertex) not in hop_path:
return -1, -1
else:
current_des = int(dest_vertex)
path_str = str(dest_vertex)
while(True):
current_dic = hop_path.get(current_des, None)
if(current_dic == None):
break
cost = hop_path[current_des]["cost"]
current_des = hop_path[current_des]["from"]
path_str = str(current_des) + \
" -(" + str(cost) + ")- " + path_str
print(distance)
return distance[des], path_str
cost, path = dijkstra(1, 5)
print("路径长:", cost, " 路径为: ", path)
小结 #
习题 #
- 详细描述出回溯路径的过程
- 为什么dijkstra算法不是最优解?