国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

圖論(四)------非負權有向圖的單源最短路徑問題,Dijkstra算法

2019-11-14 17:43:09
字體:
供稿:網(wǎng)友

Dijkstra算法解決了有向圖G=(V,E)上帶權的單源最短路徑問題,但要求所有邊的權值非負。

Dijkstra算法是貪婪算法的一個很好的例子。設置一頂點集合S,從源點s到集合中的頂點的最終最短路徑的權值均已確定。算法反復選擇具有最短路徑估計的頂點u,并將u加入到S中,對u

的所有出邊進行松弛。如果可以經(jīng)過u來改進到頂點v的最短路徑的話,就對頂點v的估計值進行更新。

如上圖,u為源點,頂點全加入到優(yōu)先隊列中

,隊列中最小值為u(值為0),u出隊列,對u的出邊進行松弛(x、v、w),隊列最小值為x。

將x出列加入S,將x的出邊松弛(v、y、w),其中w的值需要更新(4<5),隊列最小值為v。

將v出列,加入到S中,將v的出邊松弛(w),因x已在S中,故不做松弛。隊列中的最小值為y。

將y出列,y加入到S,松弛y的出邊(w、z),更新w的值(3<4),隊列最小值為w。

將w出列,加入到S中,松弛w的出邊(z),隊列最小值為z。

將z出列,加入到S中。將z的出邊松弛(無),此時隊列為空,算法結束。

Dijkstra算法的運行時間依賴于最小優(yōu)先隊列的具體實現(xiàn)。如果簡單的運用數(shù)組實現(xiàn)求最小值,運行時間為O(V2+E)=O(V2)。

如果圖比較稀疏,E=o(V2/lgV),如果用二叉最小堆實現(xiàn),則為O((V+E)lgV)。

如果用斐波那契堆實現(xiàn),可以提升到O(VlgV+E)。

import sysclass Vertex(object):    def __init__(self,key):        self.id=key        self.adj={}    def addNeighbor(self,nbr,weight=0):        self.adj[nbr]=weight    def getNeighbors(self):        return self.adj.keys()    def getId(self):        return self.id    def getWeight(self,key):        return self.adj[key]class Graph(object):    def __init__(self):        self.vertexlist={}        self.size=0    def addVertex(self,key):        vertex=Vertex(key)        self.vertexlist[key]=vertex        self.size+=1        return vertex    def getVertex(self,key):        return self.vertexlist.get(key)    def __contains__(self,key):        if key in self.vertexlist:            return True        else:            return False    def addEdge(self,f,t,weight=0):        if f not in self.vertexlist:            self.addVertex(f)        if t not in self.vertexlist:            self.addVertex(t)        self.vertexlist[f].addNeighbor(self.vertexlist[t],weight)    def getVertices(self):        return self.vertexlist.keys()    def __iter__(self):        return iter(self.vertexlist.values())def Dijkstra(G,s):    path={}    vertexlist=[]    for v in G:        vertexlist.append(v)        path[v]=sys.maxsize    path[s]=0    queue=PRiorityQueue(path)    queue.buildHeap(vertexlist)    while queue.size>0:        vertex=queue.delMin()        for v in vertex.getNeighbors():            newpath=path[vertex]+vertex.getWeight(v)            if newpath<path[v]:                path[v]=newpath                queue.perUp(v)    return path       class PriorityQueue(object):    def __init__(self,path):        self.path=path        self.queue=[]        self.size=0    def buildHeap(self,alist):        self.queue=alist        self.size=len(alist)        for i in xrange(self.size/2-1,0,-1):            self._perDown(i)    def delMin(self):        self.queue[0],self.queue[-1]=self.queue[-1],self.queue[0]        minvertex=self.queue.pop()        self.size-=1        self._perDown(0)        return minvertex        def perUp(self,v):        i=self.queue.index(v)        self._perUp(i)    def _perUp(self,i):        if i>0:            if self.path[self.queue[i]]<=self.path[self.queue[(i-1)/2]]:                self.queue[i],self.queue[(i-1)/2]=self.queue[(i-1)/2],self.queue[i]                self._perUp((i-1)/2)    def _perDown(self,i):        left=2*i+1        right=2*i+2        little=i        if left<=self.size-1 and self.path[self.queue[left]]<=self.path[self.queue[i]]:            little=left        if right<=self.size-1 and self.path[self.queue[right]]<=self.path[self.queue[little]]:            little=right        if little!=i:            self.queue[i],self.queue[little]=self.queue[little],self.queue[i]            self._perDown(little)       if __name__=='__main__':    g= Graph()    g.addEdge('u','x',1)    g.addEdge('u','v',2)    g.addEdge('u','w',5)    g.addEdge('x','v',2)    g.addEdge('x','y',1)    g.addEdge('x','w',3)    g.addEdge('v','w',3)    g.addEdge('y','w',1)    g.addEdge('y','z',1)    g.addEdge('w','z',5)    u=g.getVertex('u')    path=Dijkstra(g,u)    for v in path:        print v.id,path[v]

  


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 新源县| 平顺县| 湖南省| 施甸县| 普定县| 孟州市| 安图县| 江华| 横峰县| 河北区| 鄱阳县| 桂林市| 晴隆县| 怀远县| 蛟河市| 南涧| 冷水江市| 华坪县| 巩义市| 昔阳县| 沾益县| 垣曲县| 青铜峡市| 翁源县| 永安市| 芦山县| 富顺县| 绥棱县| 新乡市| 郁南县| 个旧市| 黑水县| 益阳市| 公安县| 东乡县| 内丘县| 娄烦县| 常州市| 桐城市| 巴林左旗| 五家渠市|