Dijkstra算法的python实现及最短路径问题解析

背景:最短路径问题

当我们通过网络浏览网页、电子邮件、发送qq消息时,数据会通过互联网在联网设备之间流动,抽象成如图所示,Dijkstra算法的python实现及最短路径问题解析_第1张图片
图中标注为“lnternet”的云状结构,实际上是一个由路由器连接成的网络,需要自动寻找最短路径。由于网络流量的状况会影响路径选择算法,在不同的时间,路径可能不同,因此将互联网路由器体系表示为一个带权边的图。如图所示:
Dijkstra算法的python实现及最短路径问题解析_第2张图片
解决信息在路由器网络中选择传播速度最快路径的问题,就转变为在带权重上最短路径的问题。解决该类问题的经典算法是——Dijkstra算法,

Dijkstra算法介绍及python实现

Dijkstra算法是一个迭代算法,得出从一个顶点到其余所有顶点的最短路径,很接近于广度优先搜索算法BFS的结果。
(1)具体实现上,在顶点Vertex类中的成员dist用于记录从开始顶点到本顶点的最短带权路径长度(权重之和),算法对图中的每个顶点迭代一次。
(2)顶点的访问次序由一个优先队列来控制,队列中作为优先级的是顶点的dist属性。
(3)最初,只有开始顶点dist设为0,而其他所有顶点dist设为sys.maxsize(最大整数),全部加入优先队列。随着队列中每个最低dist顶点率先出队,并计算它与邻接顶点的权重,会引起其它顶点dist的减小和修改,引起堆重排。并根据更新后的dist优先级再依次出队。
算法实现:

## 最短路径问题的Dijkstra算法
from pythonds.graphs import PriorityQueue,Graph,Vertex
def dijkstra(aGraph,start):
    pq = PriorityQueue()
    start.setDistance(0)
    pq.buildHeap([(v.getDistance(),v) for v in aGraph]) # 对所有顶点建堆,形成优先队列
    while not pq.isEmpty():
        currentVert = pq.delMin()  # 优先队列出队
        for nextVert in currentVert.getConnections():
            newDist = currentVert.getDistance() + currentVert.getWeight(nextVert)
            if newDist < nextVert.getDistance(): # 修改出队顶点所邻接顶点的dist,并逐个重排队列
                nextVert.setDistance(newDist)
                nextVert.setPred(currentVert)
                pq.decreaseKey(nextVert,newDist)

需要注意的是,**dijkstra算法只能处理大于0的权重,如果图中出现负数权重,则算法会陷入无限循环。**虽然dijkstra散发完美解决了带权图的最短路径问题,但实际上Internet的路由器中采用的是其它算法。
分析:狄式算法需要具备整个图的数据,但对于lnternet的路由器来说,显然无法获取整个互联网及其连接信息保存到本地,(internet数据量庞大,而且存在动态变化,使得保存全图缺乏现实性)互联网中路由器的选择算法常用“距离向量路由算法”更多介绍参见连接:https://blog.csdn.net/qq_41747565/article/details/84261298

算法分析

首先,将所有顶点加入优先队列并建堆,时间复杂度为O(|V|);其次,每个顶点仅出队1次,每次delMin花费O(log|V|),一共就是O(|V|log|V|);另外,每个边关联到的顶点会做一次decreaseKey操作(O(log|V|)),一共是O(|E|log|V|);上面三个加在一起,数量级就是O((|V|+|E|)log|V|)

你可能感兴趣的:(数据结构与算法-python版)