以下代码所针对的有向加权图参照我的另一篇博客Dijkstra最短路径算法——java代码实现
import numpy as np
class Dijkstra:
def __init__(self, index, distance, flag, transfer, v, e, dis):
self.index = index # 中转点索引
self.distance = distance # 最短距离
self.flag = flag
self.transfer = transfer # 存放中转点的列表
self.v = v # 图的顶点个数
self.e = e # 图的边数
self.dis = dis # 存放所有顶点的最短距离的列表
def loadData(self, filename):
dijkstra = np.loadtxt(filename, dtype='int8')
self.v, self.e = dijkstra[0, :2] # 获取图的顶点个数和边数
adj = np.zeros((self.v, self.v)) # 通过二维数组存储图的点和边
for i in range(self.v):
for j in range(self.v):
if i == j:
adj[i, j] = 0
else:
adj[i, j] = np.inf
for i in range(1, self.e + 1):
m, n = dijkstra[i, :2]
adj[m, n] = dijkstra[i, 2]
return adj
def findMin(self, arr):
'''寻找一个顶点到其余所有顶点的最短距离'''
self.flag = False
min_value = np.inf
for i in range(self.v):
if arr[i] < min_value and arr[i] != 0:
min_value = arr[i]
self.index = i
self.flag = True
return min_value
def adjMatrix(self, adj):
d = np.array([])
t = []
for i in range(self.v):
self.transfer.append(0)
if adj[0, i] != np.inf and adj[0, i] != 0:
self.index = i
self.distance += adj[0, i]
self.transfer.append(i)
for k in range(self.v):
self.dis.append(adj[0, k])
while True:
mindis = self.findMin(adj[self.index])
if self.flag == False:
break
self.transfer.append(self.index) # 存放中转点
self.distance += mindis
for i in range(self.v):
if adj[self.index, i] != np.inf:
self.dis[i] = self.distance + adj[self.index, i]
self.dis = np.array([self.dis])
if len(d) == 0:
d = self.dis
else:
d = np.append(d, self.dis, axis=0)
t.append(self.transfer)
self.transfer = []
self.dis = []
self.distance = 0
min_index = d[:, -1].argmin()
return d[min_index, :], t[min_index]
if __name__ == "__main__":
dij = Dijkstra(0, 0, False, [], 0, 0, [])
adj = dij.loadData("dijkstra.txt")
distance, path = dij.adjMatrix(adj)
print("Minimum distance between points: ", distance)
print("The apex of the path: ", path)
Minimum distance between points: [0.0, 1.0, 8.0, 4.0, 13.0, 17.0]
The apex of the path: [0, 1, 3, 2, 4, 5]
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
g = nx.DiGraph()
g.add_nodes_from([0, 1, 2, 3, 4, 5])
g.add_weighted_edges_from([(0, 1, 1), (1, 3, 3), (3, 5, 15), (0, 2, 12), (1, 2, 9), (3, 2, 4), (3, 4, 13),
(2, 4, 5), (4, 5, 4)])
path = nx.dijkstra_path(g, source=0, target=5)
length = nx.dijkstra_path_length(g, source=0, target=5)
print("path:", path, "\tlength:", length)
fig, ax = plt.subplots()
nx.draw(g, ax=ax, with_labels=True, node_color=range(6), cmap=plt.cm.cool,
node_size=800, font_weight="bold", font_size=20)
plt.show()
path: [0, 1, 3, 2, 4, 5] length: 17