算法流程概述
dijkstra算法是图论中比较常见的求最短路问题的一种算法,核心思想是使用【贪心算法】,整个算法流程如下:
- 以某个起始点为出发点
- 循环其余未确定的点,将
min(当前点已知的最短路,经过某个点到达当前点的最小值)
,作为当前距离的最小值 - 选择离这个点最近的点作为出发点,循环执行第二步
图形化的解释可以参考:https://www.cnblogs.com/skywang12345/p/3711512.html
算法实现
无法通过的路径认为距离无限大,使用np.inf
代替
import numpy as np
def dijkstra_alg(matrix, start_node=0):
"""
Dijkstra算法
:param matrix: 距离矩阵
:param start_node: 起始点(从0开始算第一个点)
:return:
"""
have_used = [False] * len(matrix) # 记录已访问的点
dis_list = [np.inf] * len(matrix) # 最短路径距离数组,初始为最大值
dis_list[start_node] = 0 # 初始化,将起始节点的最短路径修改成0
for _ in range(len(matrix)):
min_value_index = None
min_value = np.inf
for index in range(len(matrix)):
# 选择未访问过 且 目测距离最短的点作为起始点
if not have_used[index] and dis_list[index] < min_value:
min_value = dis_list[index]
min_value_index = index
# 将访问节点数组对应的值修改成True,标志其已经访问过了
have_used[min_value_index] = True
for index in range(len(matrix)): # 更新距离记录
# 比较:min(当前点已知的最短路,经过某个点到达当前点的最小值)
dis_list[index] = min(dis_list[index], dis_list[min_value_index] + matrix[min_value_index][index])
return dis_list
上面便是算法的python实现,通常我们会遇到一种情况,即拿到的数据时[x,y]对应的坐标,需要自己计算距离值,然后
构造一个matrix,这里提供一个工具函数:
def reform_matrix(xy_list):
"""生成邻接矩阵模型"""
max_node = len(xy_list)
graph_matrix = np.zeros(shape=(max_node, max_node))
for _i in range(max_node):
for _j in range(max_node):
graph_matrix[_i, _j] = np.sqrt(np.sum(np.square(xy_list[_i] - xy_list[_j]))) # 计算两个坐标点的欧式距离(直线距离)
return graph_matrix
示例代码
import numpy as np
def dijkstra_alg(matrix, start_node=0):
"""
Dijkstra算法
:param matrix: 距离矩阵
:param start_node: 起始点(从0开始算第一个点)
:return:
"""
have_used = [False] * len(matrix) # 记录已访问的点
dis_list = [np.inf] * len(matrix) # 最短路径距离数组,初始为最大值
dis_list[start_node] = 0 # 初始化,将起始节点的最短路径修改成0
for _ in range(len(matrix)):
min_value_index = None
min_value = np.inf
for index in range(len(matrix)):
# 选择未访问过 且 目测距离最短的点作为起始点
if not have_used[index] and dis_list[index] < min_value:
min_value = dis_list[index]
min_value_index = index
# 将访问节点数组对应的值修改成True,标志其已经访问过了
have_used[min_value_index] = True
for index in range(len(matrix)): # 更新距离记录
# 比较:min(当前点已知的最短路,经过某个点到达当前点的最小值)
dis_list[index] = min(dis_list[index], dis_list[min_value_index] + matrix[min_value_index][index])
return dis_list
def reform_matrix(xy_list):
"""生成邻接矩阵模型"""
max_node = len(xy_list)
graph_matrix = np.zeros(shape=(max_node, max_node))
for _i in range(max_node):
for _j in range(max_node):
graph_matrix[_i, _j] = np.sqrt(np.sum(np.square(xy_list[_i] - xy_list[_j]))) # 计算两个坐标点的欧式距离(直线距离)
return graph_matrix
def main():
xy_list = np.array([[1, 4], [2, 4], [5, 5], [6, 2], [7, 6]]) # (x,y)坐标点
matrix = reform_matrix(xy_list)
start_node = 3
# matrix = np.random.randint(0, 10, size=(5, 5)) # 随机生成距离矩阵
result = dijkstra_alg(matrix, start_node=start_node)
print('起始节点到其他点距离:%s' % result)
if __name__ == '__main__':
main()