迪杰斯特拉算法

171 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

迪杰斯特拉算法

迪杰斯特拉(Dijkstra)算法是典型最短路径算法,它用于计算一个顶点到其他顶点的最短路径。它的主要特点是:以起始点为中心向外层层扩展(广度优先搜索思想), 直到扩展到终点

把图的顶点集合划分为两个集合 S 和 V-S。第一个集合 S 表示距源点最短距离已经确定的顶点集,即一个顶点如果属于集合 S 则说明从源点 s 到该顶点的最短路径已知。其余的顶点放在另一个集合 V-S 中。初始时,集合 S 只包含源点,即 S = { s },这时只有源点到自己的最短距离是已知的。设 v 是 V 中的某个顶点,把从源点 s 到顶点 v 且中间只经过集合 S 中顶点的路径称为从源点到 v 的特殊路径,并用数组 D 来记录当前所找到的从源点 s 到每个顶点的最短特殊路径长度。从尚未确定最短路径长度的集合 V-S 中取出一个最短特殊路径长度最小的顶点 u,将 u 加入集合 S,同时修改数组 D 中由 s 可达的最短路径长度。

def myDijkstra(statr:int , lst:list):
    """
    :param statr:  开始的地点
    :param lst:  各个城市之间的距离,  二维数组,就是用行列坐标表示图形上两点之间的距离。
    :return:  到各个城市的最短距离
    """
    # city 未被当作中间节点的城市列表
    city = [x for x in range(len(lst)) if x != statr]
    # 城市顺序
    cityorder = [statr]
    citylength = lst[statr]    # len1 是一一维列表,里面包含着 成市 n 到各个城市的初始距离
    # 用循环判断,城市n 到其他城市中最短的距离
    while len(city):
        idenx1 =city[0]
        for i in city:
            if citylength[i] < citylength[idenx1]:
                idenx1 = i
        # 将做过中间节点的移出city
        city.remove(idenx1)
        # 添加到城市最近列表
        cityorder.append(idenx1)
        # 更新成市 n 到各个城市之间的最短距离
        for i in city:
            # 当新的路线距离更进时,会更新 个城市直接的距离
            if citylength[idenx1]+lst[idenx1][i] < citylength[i]:
                citylength[i] = citylength[idenx1]+lst[idenx1][i]
    return citylength


if __name__ == '__main__':
    max = 999999  # max即表示为无法直达

    graph = [
        [5, max, 10, max, 30, 100],
        [max, max, 5, max, max, max],
        [max, 15, max, 50, max, max],
        [max, max, max, max, max, 10],
        [max, max, max, 20, max, 60],
        [max, 15, max, max, max, max],
    ]
    inf = 999999
    mgraph = [[0, 1, 12, inf, inf, inf],
              [inf, 0, 9, 3, inf, inf],
              [inf, inf, 0, inf, 5, inf],
              [inf, inf, 4, 0, 13, 15],
              [inf, inf, inf, inf, 0, 4],
              [inf, inf, inf, inf, inf, 0]]

    len1 = myDijkstra(0,graph)
    print(len1)
    len2 = myDijkstra(0, mgraph)
    print(len2)