Dijkstra算法

Dijkstra算法

Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,即计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。注意该算法要求图中不存在负权边。

算法描述

在无向图 G=(V,E) 中,要求v0到其余各顶点的最短距离,这里将图中的顶点在计算过程中分为已确定最短路径的顶点集合(T),和目前并不确定最短路径的顶点集合(U)。在当前已经确定的最短路径集合中向外扩展,依次把U中距离v0最短的顶点并入T,并且每次在并入新顶点时更新以新顶点最为中介点,v0到其余各点的距离。如此,遍历至最后一点可找出V0到各顶点的最短距离。

基本执行分三步

<1>找出当前V0到各顶点的最短距离,并记录这条边的终点,和长度。

<2>将<1>中终点并入T(代码中s集合对应点标记为1)。
<3>以新并入的点作为中介点,更新此时V0到各顶点的最短距离。重复上述步骤直至到最后一点,即可得V0到图中所有顶点的最短距离。

举个简单的例子:计算下图中顶点1到图中任一点的最短距离。


源代码(python):

if __name__ == '__main__':
    maxInt = 999999
    v0 = 1
    data = [[0, 1, 2, 3, 4, 5, 6],  # 数集下表对应点集下标,第零行和第零列为行列序号
            [1, 0, 7, 9, 0, 0, 14],
            [2, 7, 0, 10, 15, 0, 0],
            [3, 9, 10, 0, 11, 0, 2],
            [4, 0, 15, 11, 0, 6, 0],
            [5, 0, 0, 0, 6, 0, 9],
            [6, 14, 0, 2, 0, 9, 0]]

    dis = [0, 0]                # 记录定点到图中各点的最短距离
    s = [0, 1, 0, 0, 0, 0, 0]   # 标志点分集,0表示在U集合,1表示在T集合
    for i in range(2, 7):
        if data[v0][i] == 0:
            dis.append(maxInt)
        else:
            dis.append(data[v0][i])

    for m in range(1, 7):       # 查找U集合中每一点到V0最短距离
        mindis = maxInt
        u = v0
        for k in range(1, 7):
            if not s[k] and dis[k] < mindis:
                mindis = dis[k]
                u = k
        s[u] = 1                    # 记录当前能并入T中最短距离的点
        for j in range(1, 7):       # 以新并入的点为中间点更新最短距离集合
            if not s[j] and data[u][j] and (dis[u] + data[u][j]) < dis[j]:
                dis[j] = dis[u] + data[u][j]
    print(dis)

运行结果:


负权值不适用

如下图所示的情况:


原来是这样的,本来全为正值的时候,只要每次保证都是加入的最短路径,那么直至最后一定能保证计算结果为最短的。然,不幸的是中间出现了负权值,导致从一开始加入的最短路径的做法并不一定是最优的,而现在的算法却只有按照并入的点往上加,而无法退回去重新算一下原来计算出的结果。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值