首先我采用鄰接矩陣法來表示圖(有向圖無向圖皆可)
圖的定義如下:
class Graph: def __init__(self, arcs=[]): self.vexs = [] self.arcs = arcs def creategrapg(self): self.vexs = input().split() for i in range(len(self.vexs)): self.arcs.append([float('inf') if int(v) == 0 else int(v) for v in input().split()])
其中creategrapg用來創建圖,創建圖時,首先輸入所有頂點,以空格分隔在一行內輸入,后面為一個n*n的矩陣,n為頂點數目。
算法具體實現如下:
def ShortestPath_DIJ(self, v): #迪傑斯特拉算法 v0 = self.vexs.index(v) n = len(self.vexs) S = [False] * n S[v0] = True D = self.arcs[v0].copy() Path = [-1] * n for i in range(n): if D[i] < float('inf'): Path[i] = v0 D[v0] = 0 for i in range(1, n): min_ = float('inf') for w in range(n): if not S[w] and D[w] < min_: v_ = w min_ = D[w] S[v_] = True for w in range(n): if not S[w] and (D[v_] + self.arcs[v_][w] < D[w]): D[w] = D[v_] + self.arcs[v_][w] Path[w] = v_ print(f'從{v}到各頂點的最短路徑為:') # 算法到此其實已經結束,下面我自己寫的用來展示路徑的部分 for ind, val in enumerate(Path): if ind == v0: continue if val == -1: print(f'{self.vexs[ind]}:不可到達') continue path_ = [self.vexs[ind]] while val > 0: path_.append(self.vexs[val]) val = Path[val] # path_.append(v) print(self.vexs[ind] + ':' + '->'.join(path_[::-1]))
注:這個函數實際上是寫在Graph類里面的,為了方便敘述我才分開放了代碼。
運行代碼:
mygraph = Graph()
mygraph.creategrapg()
mygraph.ShortestPath_DIJ(mygraph.vexs[1])
輸入的圖如下圖所示。
輸入樣例為:
v0 v1 v2 v3 v4 v5 0 0 10 0 30 100 0 0 5 0 0 0 0 0 0 50 0 0 0 0 0 20 0 10 0 0 0 0 0 60 0 0 0 0 0 0
運行結果如下:
從v1到各頂點的最短路徑為: v0:不可到達 v2:v1->v2 v3:v1->v2->v3 v4:不可到達 v5:v1->v2->v3->v5