一、算法思路
1、采用广度优先搜索算法;
2、二维数组初始化无向图;
3、创建一个一维数组,初始化起点到其它所有节点的距离为无穷大,起点自己到自己的距离为0;
4、从起点开始找与起点相邻的其它节点的距离,将距离赋值到前面创建的一维数组,将此节点标记为已访问;
5、在一维数组中找一个没有访问过的节点,并且数值是最小的节点,将此节点作为起点重复第4步;
6、直至所有节点全部标记为已访问,程序执行结束;
二、代码
import sys
class Graph:
#所有节点信息
nodeAll = []
#记录节点是否已访问 0否 1是
visited = []
#指定起始点到所有其他点的距离
minDis = []
#所有的边
edge = []
#节点数量
nodeNum = 0
#路径记录
paths = []
#构造方法,初始化整个无向图
def __init__(self, nodeAll):
self.nodeAll = nodeAll
self.nodeNum = len(nodeAll)
#初始化所有节点都未访问
self.visited = [0] * self.nodeNum
#创建一个二维数据,是浅拷贝,每一维的数组都是指向同一个内容地址,会有问题
#test = [[0] * nodeNum] * nodeNum
#test[0][1] = 1
#创建一个二维数组,每次都会创建一个新的数组
self.edge = [([0] * self.nodeNum) for i in range(self.nodeNum)]
self.visited = [0] * self.nodeNum
# 初始化指定起点到其它所有节点的距离无穷大
self.minDis = [sys.maxsize] * self.nodeNum
self.paths = [''] * self.nodeNum
#添加边和权重
def addEdge(self, v1, v2, value):
self.edge[v1][v2] = value
self.edge[v2][v1] = value
#找没有访问过的节点的最小值的下标
def getMinIndex(self):
# 找到列表中没有访问过的最小值节点和下标
minV, index = sys.maxsize, -1
for i in range(self.nodeNum):
if self.visited[i] == 0 and self.minDis[i] < minV:
minV = self.minDis[i]
index = i
return index
#迪杰斯特拉
def dijkstra(self, start, end):
#标记节点被访问过
self.visited[start] = 1
for i in range(self.nodeNum):
# 如果当前节点没有被访问过,并且节点start到节点i的距离大于0
if (self.visited[i] == 0 and self.edge[start][i]>0):
#起始点到当前点的值+边的值
newDis = self.minDis[start]+self.edge[start][i]
if newDis < self.minDis[i]:
self.minDis[i] = newDis
self.paths[i] = self.paths[start] + '->' + self.nodeAll[i]
#print(start, self.minDis)
#找minDis中未被访问过的最小值节点的的下标
index = self.getMinIndex()
if index == -1:
return
self.dijkstra(index, end)
def test1():
nodes = ['A', 'B', 'C', 'D', 'E', 'F']
graph = Graph(nodes)
graph.addEdge(0, 1, 7)
graph.addEdge(0, 2, 9)
graph.addEdge(0, 3, 11)
graph.addEdge(1, 2, 8)
graph.addEdge(1, 5, 20)
graph.addEdge(2, 4, 6)
graph.addEdge(3, 4, 3)
graph.addEdge(4, 5, 1)
# 初始化无向图
print('=====初始化无向图=====')
print(graph.edge)
start, end = 0, 5
graph.minDis[start] = 0
graph.paths[start] = graph.nodeAll[start]
graph.dijkstra(start, end)
#print(graph.paths)
print('节点%s到节点%s的最短路径是:%s,距离是%s' % (graph.nodeAll[start], graph.nodeAll[end], graph.paths[end], graph.minDis[end]))
def test2():
nodes = ['V0', 'V1', 'V2', 'V3', 'V4', 'V5']
graph = Graph(nodes)
graph.addEdge(0, 1, 1)
graph.addEdge(0, 2, 4)
graph.addEdge(1, 2, 2)
graph.addEdge(1, 3, 7)
graph.addEdge(1, 4, 5)
graph.addEdge(2, 4, 1)
graph.addEdge(3, 4, 3)
graph.addEdge(3, 5, 2)
graph.addEdge(4, 5, 6)
# 初始化无向图
print('=====初始化无向图=====')
print(graph.edge)
start, end = 0, 5
graph.minDis[start] = 0
graph.paths[start] = graph.nodeAll[start]
graph.dijkstra(start, end)
print('节点%s到节点%s的最短路径是:%s,距离是%s' % (graph.nodeAll[start], graph.nodeAll[end], graph.paths[end],graph.minDis[end]))
#测试
if(__name__ == '__main__'):
test2()
参考资料: