Dijkstra算法 python實現


1.Dijkstra算法的基本實現 \(O(n^2)\)

簡介:

Dijkstra算法是從一個頂點到其余各頂點的最短路徑算法,解決的是有權圖中最短路徑問題。迪傑斯特拉算法主要特點是從起始點開始,采用貪心算法的策略,每次遍歷到始點距離最近且未訪問過的頂點的鄰接節點,直到擴展到終點為止。

算法介紹推薦文章:

https://www.zhihu.com/question/20630094/answer/758191548

假設有圖G:

則G的帶權鄰接矩陣為:

matrix = [
    [99, 2, 99, 6, 99, 9, 99, 99], 
    [99, 99, 30, 1, 99, 99, 99, 99], 
    [99, 99, 99, 99, 99, 99, 99, 5], 
    [99, 99, 99, 99, 2, 99, 99, 99], 
    [99, 99, 8, 99, 99, 99, 7, 99], 
    [99, 99, 99, 99, 3, 99, 24, 99], 
    [99, 99, 99, 99, 99, 99, 99, 21], 
    [99, 99, 99, 99, 99, 99, 99, 99]]

則時間復雜度為\(O\left( n^2 \right)\)的算法如下圖(python語言):

n = len(matrix) # 計算頂點數量

# v記錄是否訪問 
# dis為起始結點到相鄰結點的距離
v = [0]*n 
dis = matrix[0].copy()

# 起始情況
v[0] = 1
dis[0] = 99

# 循環n次
for _ in range(n):
    # 找出與集合相鄰且距離起點最近的點 
    k = 0
    for j in range(n):
        if v[j] == 0 and dis[j] < dis[k]:
            k = j
	# 該點被訪問
    v[k] = 1

    # 用該點進行松弛(relax)
    for j in range(n):
        if v[j] == 0 and dis[k] + matrix[k][j] < dis[j]:
            dis[j] = dis[k] + matrix[k][j]

結果:

dis = [99, 2, 13, 3, 5, 9, 12, 18]

2.從別的地方抄的虛假的和算法導論格式一樣的堆優化實現

class Graph:
    def __init__(self):
        self.V = []
        self.w = {}

class Vertex:
    def __init__(self, x):
        self.key = x
        self.color = 'white'
        self.d = 10000
        self.pi = None
        self.adj = []

class Solution():
    def InitializeSingleSource(self, G, s):
        for v in G.V:
            v.d = 10000
            v.pi = None
        s.d = 0

    def Relax(self, u, v, w):
        if v.d > u.d + w[(u, v)]:
            v.d = u.d + w[(u, v)]
            v.pi = u

    def Dijkstra(self, G, w, s):
        self.InitializeSingleSource(G, s)
        S = set()
        Q = G.V[:]
        while Q:
            u = self.ExtractMin(Q, S)
            S.add(u)
            for v in u.adj:
                self.Relax(u, v, w)

    def ExtractMin(self, Q, S):
        Q.sort(key=lambda v: v.d)
        return Q.pop(0)



if __name__ == '__main__':
    s = Vertex('s')
    t = Vertex('t')
    y = Vertex('y')
    x = Vertex('x')
    z = Vertex('z')

    s.adj = [t, y]
    y.adj = [t, z, x]
    t.adj = [x, y]
    x.adj = [z]
    z.adj = [x, s]

    G = Graph()
    G.V = [s, t, y, x, z]
    G.w = {
        (s,t):10,
        (s,y):5,
        (t,y):2,
        (y,t):3,
        (t,x):1,
        (y,z):2,
        (x,z):4,
        (z,x):6,
        (y,x):9,
        (z,s):7
    }

    m = Solution()
    m.Dijkstra(G, G.w, s)


    for v in G.V:
        if v != s:
            print v.key, v.d, v.pi.key
        else:
            print v.key, v.d, v.pi


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM