def myDijkstra(statr:int, lst:list):
"""
:param statr: 开始的地点
:param lst: 各个城市之间的距离, 二维数组,就是用行列坐标表示图形上两点之间的距离。
:return: 到各个城市的最短距离
"""
# city 未被当作中间节点的城市列表
city = [x for x in range(len(lst)) if x != statr]
# 城市顺序
cityorder = [statr]
citylength = lst[statr] # len1 是一一维列表,里面包含着 成市 n 到各个城市的初始距离
# 用循环判断,城市n 到其他城市中最短的距离
while len(city):
idenx1 =city[0]
for i in city:
if citylength[i] < citylength[idenx1]:
idenx1 = i
# 将做过中间节点的移出city
city.remove(idenx1)
# 添加到城市最近列表
cityorder.append(idenx1)
# 更新成市 n 到各个城市之间的最短距离
for i in city:
# 当新的路线距离更进时,会更新 个城市直接的距离
if citylength[idenx1]+lst[idenx1][i] < citylength[i]:
citylength[i] = citylength[idenx1]+lst[idenx1][i]
return citylength
if __name__ == '__main__':
max = 999999 # max即表示为无法直达
graph = [
[5, max, 10, max, 30, 100],
[max, max, 5, max, max, max],
[max, 15, max, 50, max, max],
[max, max, max, max, max, 10],
[max, max, max, 20, max, 60],
[max, 15, max, max, max, max],
]
inf = 999999
mgraph = [[0, 1, 12, inf, inf, inf],
[inf, 0, 9, 3, inf, inf],
[inf, inf, 0, inf, 5, inf],
[inf, inf, 4, 0, 13, 15],
[inf, inf, inf, inf, 0, 4],
[inf, inf, inf, inf, inf, 0]]
len1 = myDijkstra(0,graph)
print(len1)
len2 = myDijkstra(0, mgraph)
print(len2)
def startwith(start: int, mgraph: list) -> list:
passed = [start]
# 初始化数组,一共有多少个城市 并为城市编号
nopass = [x for x in range(len(mgraph)) if x != start]
print('nopass',nopass)
# 到直接各个点之间的最短距离,不能直接到达的距离就是 10086
dis = mgraph[start]
print(dis)
# 执行循环,找出初始位置到各个点的最短路径
while len(nopass):
idx = nopass[0]
for i in nopass:
if dis[i] < dis[idx]:
idx = i
nopass.remove(idx)
# 还有那个的点未被访问
print("111111",nopass)
passed.append(idx)
# 最短路径的走法
print("22222",passed)
for i in nopass:
if dis[idx] + mgraph[idx][i] < dis[i]:
dis[i] = dis[idx] + mgraph[idx][i]
return dis
def dijkstra(graph, start_Node, path, cost, max):
"""
graph:二维数组,就是用行列坐标表示图形上两点之间的距离。
start_Node:起始点
path[i] 表示vi节点的前一个节点,即中转点。
cost[i] 表示V0到Vi的已知最短路径长度
mid_Node:中转点,以已求得V0到Vi的最短路径的Vi作为中转点。
NEXT_Node:尝试优化的点,以中转点为中心,检测NEXT_Node直达V0方案,和经过mid_Node中转到V0的方案哪个更优
check_Node:索引,搜索cost数组里最短路径的点,最短的点会赋值给mid_Node,作为中转点。
"""
lenth = len(graph)
v = [0] * lenth # V数组初始化为0,用于标记该点是否已取得最短路径
# 初始化 path,cost,V
for i in range(lenth):
if i == start_Node:
v[start_Node] = 1
else:
cost[i] = graph[start_Node][i] # cost获取起点至其他点的直达权重
path[i] = (start_Node if (cost[i] < max) else -1) # 前置点为起点或-1(无法直达起点)
# print v, cost, path
for i in range(1, lenth): # 遍历的数等于除去起点的点的数量
minCost = max # 初始值取最大
mid_Node = -1
for check_Node in range(lenth): # 搜索一个到起点V0最近的点,作为中转点mid_Node
if v[check_Node] == 0 and cost[check_Node] < minCost: # mid_Node点未取得最短路径,且路径权重小于最小值,则获取w,也就是先取得
minCost = cost[check_Node]
mid_Node = check_Node
if mid_Node == -1: break # 找不到权重小于max的点
# 剩下都是不可通行的节点,跳出循环
v[mid_Node] = 1 # check_Node已取得最短路径
for NEXT_Node in range(lenth):
if v[NEXT_Node] == 0 and (graph[mid_Node][NEXT_Node] + cost[mid_Node] < cost[
NEXT_Node]): # 检查所有未遍历的点NEXT_Node,检测前面获取的mid_Node对NEXT_Node的影响
cost[NEXT_Node] = graph[mid_Node][NEXT_Node] + cost[mid_Node] # 更新权值
path[NEXT_Node] = mid_Node # 更新路径
# for 更新其他节点的权值(距离)和路径
return path
最短路径 迪杰斯特拉算法
最新推荐文章于 2024-03-20 23:55:45 发布