1、什么是最短路径
这里讨论的是带权有向图和带权无向图,在这类图中一个顶点到其他顶点可能有路径,可能没有路径,也可能有多条不同的路径,怎样找到一条最好的路径呢,这就是本节要讨论的最短路径问题。
定义:
在图中:
看完了,还是有点晕还是来看例子吧。
时间复杂度:O(Elog(v))
我们以一个例子来看看dijkstra的具体实现:
下面将介绍最短路径树的矩阵生成方式:
matrix=[[0,5,11,5,0,0,0],
[5,0,0,3,9,0,7],
[11,0,0,7,0,6,0],
[5,3,7,0,0,0,20],
[0,9,0,0,0,0,7],
[0,0,6,0,0,0,8],
[0,7,0,20,7,8,0]]
n=len(matrix[0]) #顶点数
record=[False for i in range(n)]
dict1={} #利用字典充当一个队列,每次从中选择当前的最短路径,字典每次记录
#所有的最短路径树,并从中弹出最短路径
dict2={} #记录最短路径树各个边对应的路径顺序
for i in range(n):
dict1[i]=None
dict2[i]=[]
#初始化顶点
i=0
dict1[i]=0
dict2[i].append([0,0])
record_arr=[]
while True:
print('dict1:',dict1)
print('dict2:',dict2)
if sum(record)==n:
break
list1=sorted(dict1.items(),key=lambda x:x[0],reverse=True)
edge=list1.pop()
dict1=dict(list1)
start=edge[0]
w1=edge[1]
record[start]=True
dict2[start]=edge
i=start
arr1=[]
for j in range(n):
if matrix[i][j]!=0 and record[j]==False:
arr1.append([i,j,matrix[i][j]])
#用最短边去更新dict1
for edge in arr1:
start,end,w=edge[0],edge[1],edge[2]
if record[end]==False:
if dict1[end]==None:
dict1[end]=w+w1
else:
dict1[end]=min(dict1[end],w1+w)
dict1: {0: 0, 1: None, 2: None, 3: None, 4: None, 5: None, 6: None}
dict2: {0: [[0, 0]], 1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
dict1: {6: None, 5: None, 4: None, 3: 5, 2: 11, 1: 5}
dict2: {0: (0, 0), 1: [], 2: [], 3: [], 4: [], 5: [], 6: []}
dict1: {6: 12, 5: None, 4: 14, 3: 5, 2: 11}
dict2: {0: (0, 0), 1: (1, 5), 2: [], 3: [], 4: [], 5: [], 6: []}
dict1: {6: 12, 5: 17, 4: 14, 3: 5}
dict2: {0: (0, 0), 1: (1, 5), 2: (2, 11), 3: [], 4: [], 5: [], 6: []}
dict1: {6: 12, 5: 17, 4: 14}
dict2: {0: (0, 0), 1: (1, 5), 2: (2, 11), 3: (3, 5), 4: [], 5: [], 6: []}
dict1: {6: 12, 5: 17}
dict2: {0: (0, 0), 1: (1, 5), 2: (2, 11), 3: (3, 5), 4: (4, 14), 5: [], 6: []}
dict1: {6: 12}
dict2: {0: (0, 0), 1: (1, 5), 2: (2, 11), 3: (3, 5), 4: (4, 14), 5: (5, 17), 6: []}
dict1: {}
dict2: {0: (0, 0), 1: (1, 5), 2: (2, 11), 3: (3, 5), 4: (4, 14), 5: (5, 17), 6: (6, 12)}
dict1为一个优先队列不断更新与弹出当前最短路径
dict2为最短记录树的记录