Dijkstra算法与python实现

算法流程概述

dijkstra算法是图论中比较常见的求最短路问题的一种算法,核心思想是使用【贪心算法】,整个算法流程如下:

  1. 以某个起始点为出发点
  2. 循环其余未确定的点,将min(当前点已知的最短路,经过某个点到达当前点的最小值),作为当前距离的最小值
  3. 选择离这个点最近的点作为出发点,循环执行第二步

图形化的解释可以参考: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()

你可能感兴趣的:(python,算法,python)