最短路径问题

最短路径问题

最短路径是图论中一个重要的知识点,在一个有向图中,如何求出两个节点之间的最短路径?上学期学了python,然后期末做了一个旅途咨询系统,这学期刚学了图论,所以将最短路径问题整理了一下。这样一个旅途资询系统(当然旅途咨询系统不是重点)需要解决单源最短路径问题,单源最短路径问题解决后得到的是从源节点到其他节点的最短路径,用到的是Dijkstra算法,但如果是想知道一个节点到其他某一个节点的最短路径,比较好用的就是floyd算法了。

接下来我会分三个步骤讲解这两个算法,如果有理解错的地方,欢迎指正。这三个步骤是:算法思想、算法复杂度和特点以及具体实现。
有关最短路径问题的一篇文章,很多很详细

算法思想

前提:得到一个邻接矩阵,这个矩阵中的元素就是对应边的长度,或者说权重

  1. Dijkstra算法
    (1)选定一个节点V作为源节点,并用一个dist数组来记录该节点到其他节点的最短路径的距离,再用两个集合visited和T分别表示已经确定了最短路径的终点和其他节点,起初,visited中只有源节点;
    (2)在T中选择出一个到源节点路径最短的节点A,并以节点A作为中转节点,然后将A从T移到visited中,接着调整T中节点经过中转节点A到达源节点src的最短路径,调整原则是取dist[end] 与 dist[A][end]+dist[A]的最小值;
    (3)再从T中选出一个到源节点路径最短的节点B,然后将B从T移到visited中,并进行(2)中操作,依次类推直到T中没有节点为止,最后得到的是一个数组,dist[end]的值就是src到end的最短路径的距离了.。

  2. floyd(弗洛伊德)算法
    (1)从任意一条单边路径开始。所有两点之间的距离是边的权,如果两点之间没有边相连,则权为无穷大。
    (2)对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比u到v的路径更短。如果是就更新最短路径。

两种算法的算法复杂度和特点

  • 算法复杂度
    先简单说一下算法复杂度,算法复杂度分为时间复杂度和空间复杂度,时间复杂度等于所有语句的运行次数之和,通常用时间复杂度的渐进上界来衡量时间复杂度即O(f(n)),空间复杂度指在运行过程中占用了多少存储空间,主要是辅助空间,依旧是O(f(n))来衡量空间复杂度,递归栈就是需要被算入辅助空间。那么这两种算法的算法复杂度如何?
    Dijkstra算法的时间复杂度为O(n^2),空间复杂度为:O(n);
    floyd(弗洛伊德)算法的时间复杂度为O(n^3), 空间复杂度为O(n^2)
  • 算法特点:
    1、floyd(弗洛伊德)算法时间复杂度比较高,不适合计算大量数据;
    2、更为重要的是:dijkstra算法使用的前提是图中路径长度必须大于等于0;但是floyd算法则仅仅要求没有总和小于0的环路就可以了,因此floyd算法应用范围比dijkstra算法要广。;
    3、dijkstra算法返回的是一个数组,而floyd直接返回两个节点在图中的最短路径。

实现

在这里插入图片描述

  1. Dijkstra算法(使用的python,这里只有部分代码)
import sys
Max=sys.maxsize
Min=sys.maxsize
src_node=int(input("输入起始节点,节点1输入0,节点2输入1,依次类推")) #src_node=1表示源节点为节点2
dis=weight_matrix[src_node] #weight_matrix代表邻接矩阵,里面的元素是相应边的权重
src_node+=1
u=0
book = [0 for i in range(7)]
for i in range(6):
    Min=Max
    for j in range(7):
        if book[j]==0 and dis[j]<Min:
            Min=dis[j]
            u=j
    book[u]=1 #一旦一个节点做了一次中转节点就为其进行标记
    for j in range(7):
        if weight_matrix[u][j]<Max and dis[j]>dis[u]+weight_matrix[u][j]:
            dis[j]=dis[u]+weight_matrix[u][j]
for i in range(7):
    print("节点"+str(src_node)+"到达"+str(i+1)+"节点的最短路径"+str(dis[i]))
  1. floyd(弗洛伊德)算法
for a in range(7):
    for b in range(7):
        for c in range(7):
            weight_matrix[b][c]=min(weight_matrix[b][c],weight_matrix[b][a]+weight_matrix[a][c])#weight_matrix代表邻接矩阵,里面的元素是相应边的权重
weights1=weight_matrix[2][4]

print("节点3到节点5的最短路径为:",weights1)
weights2=weight_matrix[3][6]
print("节点4到节点7的最短路径为:",weights2)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值