使用python内置函数直接实现Dij算法,每次用全部已包含集中的点进行计算:
def Dij(start):
list_a = [1,2,3,4,5,6,7,8,9,10] ##所有点的集合
list_s = [start] ##最短路径已经确定的点的集合s
dist = {} ##最后的结果,存为一个dictionary,key是点的数字,value是从start出发最短的距离
dist[start] = 0
while True:
if len(list_s) == 10:
return dist
temp = {} ##临时字典,记录所有从s出发右边可以用一条边连接的点
for i in list_s:
for j in list(set(list_a)-set(list_s)):
if map[i][j] >= 0:
temp[(dist[i]+map[i][j])] = [i,j] ##记录点的临时最短距离,为s中的点的最短距离加上该边的距离
dist[temp[min(temp)][1]] = min(temp) ##挑选其中临时最短距离最小的一个点加入s,其临时最短距离就是其真实的最短距离
patch[temp[min(temp)][1]] = temp[min(temp)][0] ##记录最短路径具体经过的点
list_s.append(temp[min(temp)][1]) ##挑选其中临时最短距离最小的一个点加入s
if __name__ == '__main__':
map=[[],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
]
map[1][2] = 40
map[1][3] = 8
map[1][4] = 10
map[2][7] = 10
map[2][5] = 6
map[3][2] = 4
map[3][4] = 12
map[3][6] = 2
map[4][6] = 1
map[5][3] = 2
map[5][6] = 2
map[5][7] = 4
map[6][8] = 4
map[6][9] = 3
map[7][8] = 20
map[7][10] = 1
map[8][5] = 0
map[8][10] = 20
map[9][4] = 6
map[9][8] = 10
map[9][10] = 2
patch={}
Dij(1)
使用data_structure课中的,每次用结点进行搜索,并不断更新dist的步骤:
Python实现代码:
def Dij(start):
list_a = [1,2,3,4,5,6,7,8,9,10]
list_s = [start]
dist = [[],100,100,100,100,100,100,100,100,100,100]
dist[start] = 0 ##初始化最短距离,起点设为0,和起点有边连接的设为该边数值,其余点设为无穷大(此处为100)
for j1 in list_a:
if map[start][j1] >= 0:
dist[j1] = map[start][j1]
while True:
if len(list_s) == 10: ##终止条件
return dist
temp ={}
for j2 in list(set(list_a)-set(list_s)): ##未收录在s集合中的点中dist最小的点V
temp[dist[j2]] = j2
V = temp[min(temp)]
list_s.append(V) ##将V加入s中
for j3 in list(set(list_a)-set(list_s)): ##更新所有未收录在s集中的点的dist
if map[V][j3] >= 0:
if dist[V] + map[V][j3] < dist[j3]:
dist[j3] = dist[V] + map[V][j3]
path[j3] = V
现在考虑解决任意起点终点的最短路径问题,用floyd算法:
每次迭代计算只经过编号小于k的定点的路径
其Python的代码实现为:
def floyd():
## 初始化时没有边直接相连的点之间最短距离需要设置成无穷大,此处为100
P = map
D = map
for i1 in range(1,11):
for j1 in range(1,11):
if i1 == j1:
D[i1][j1] = 0
if map[i1][j1] == -1 :
D[i1][j1] = 100
for k in range(1,11):
for i2 in range(1,11):
for j2 in range(1,11):
if D[i2][k]+D[k][j2] < D[i2][j2]:
D[i2][j2] = D[i2][k]+D[k][j2]
return D
if __name__ == '__main__':
map=[[],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
[[],-1,-1,-1,-1,-1,-1,-1,-1,-1,-1],
]
map[1][2] = 40
map[1][3] = 8
map[1][4] = 10
map[2][7] = 10
map[2][5] = 6
map[3][2] = 4
map[3][4] = 12
map[3][6] = 2
map[4][6] = 1
map[5][3] = 2
map[5][6] = 2
map[5][7] = 4
map[6][8] = 4
map[6][9] = 3
map[7][8] = 20
map[7][10] = 1
map[8][5] = 0
map[8][10] = 20
map[9][4] = 6
map[9][8] = 10
map[9][10] = 2
result = floyd()