Dijkstra算法指定任意两点距离(邻接矩阵法)
“最短路算法”编程项目,指定两个结点,计算最短距离并输出该路径
>题目分析:
1.选择Python语言进行算法编程模拟。
Python语言更加简洁易懂,且用列表的表示自由度更大,内置函数丰富
2.可随机输入任意图表,并指定任意两点,从而计算距离
通过构建含有n个结点的邻接矩阵来表示图标(对称矩阵表示无向图),x代表无穷大。
3.最短路径的表示方法
使用父辈结点的存储指向,最终不断回溯进行模拟。
4.函数的参数以及执行
定义dijkstra算法函数,需引入参数有三个:图的邻接矩阵matrix,所寻找路径的起始点begin,所寻找路径的终点end,通过利用多个列表参数作为其属性:
parent[i]:结点的父辈结点
collected[i] : 表示节点是否已被收录(bool类型,是则为True,不是则为False)
distTo[i] : 表示结点距离起始点begin的最短距离,每轮执行算法时需不断更新
path[end] : 最终begin结点距离end结点的最短路径(经过的结点组)
查阅内容:
1.Dijkstra算法中路径的表示方法
经过分析,可向每一个节点添加属性parent,类似指针作用,指向使其距离起始点路径长短缩小的头结点,不断进行循环回溯(起始节点的父辈结点为空(用-1表示)),最终联系成为两点间最短路径
2.Dijkstra算法中邻接矩阵以及邻接表的表示方法
可以使用邻接矩阵来表征一个图(有向图或无向图),其中的表示结点间的距离,反之亦然。其中,若初始时为直接相连,则定义为∞,其行列数相等,均等于图中结点总数。
邻接表则类似于树的结构,每一个结点中存在一个类似于属性的成员,由其保存或指向与其邻接的结点,并含有该边的权值,其中含有顺序分配和链式分配。
综合来说,无向图更适合于使用邻接矩阵法从而避免数据的冗杂。故该编程项目使用邻接矩阵法进行表示。
程序实现:
若某结点的最短路径中途不需要更新时,无法正确输出路径,最终使用parent父辈结点之间连线进行解决。
执行结果:
如图所示作为邻接矩阵的无向图的最短路径:
任意指定两点间距离,执行结果如下(例):
begin = 5, end = 1时:path: [5, 4, 1] distance: 4
begin = 0, end = 5时:path: [0, 1, 4, 5] distance: 7
Python具体代码:
x = float('inf') #定义无穷大
def dijkstra(mat,begin,end):
n = len(mat)
parent = [] #用于记录每个结点的父辈结点
collected = [] #用于记录是否经过该结点
distTo = mat[begin] #用于记录该点到begin结点路径长度,初始值存储所有点到起始点距离
path = [] #用于记录路径
for i in range(0,n): #初始化工作
if i == begin:
collected.append(True) #所有结点均未被收集
else:
collected.append(False)
parent.append(-1) #均不存在父辈结点
while True:
if collected[end]==True:
break
min_n = x
for i in range(0,n):
if collected[i]==False:
if distTo[i] < min_n: #代表头结点
min_n = distTo[i]
v = i
collected[v] = True
for i in range (0,n):
if (collected[i]==False) and (distTo[v] + mat[v][i] < distTo[i]): #更新最短距离
parent[i] = v
distTo[i] = distTo[v] + mat[v][i]
e = end
while e != -1: #利用parent-v继承关系,循环回溯更新path并输出
path.append(e)
e = parent[e]
path.append(begin)
path.reverse()
print("path: ",path)
print("distance: ",distTo[end])
matrix = [ #邻接矩阵
[0,3,2,x,x,x],
[3,0,2,1,2,x],
[2,2,0,3,x,x],
[x,1,3,0,4,6],
[x,2,x,4,0,2],
[x,x,x,6,2,0]]
dijkstra(mat = matrix,begin = 0,end = 5)
#可以改为令用户自行输入邻接表
后记:
该程序实现输出一个最短路径,程序也可改为令用户自行输入邻接表