7、迪杰斯特拉算法

迪杰斯特拉算法

1、狄克斯特拉算法
步骤:

(1) 找出最便宜的节点,即可在最短时间内前往的节点。

(2) 对于该节点的邻居,检查是否有前往它们的更短路径,如果有,就更新其开销。

(3) 重复这个过程,直到对图中的每个节点都这样做了。

(4) 计算最终路径。 

要计算非加权图中的最短路径,可使用广度优先搜索。要计算加权图中的最短路径,可使用狄克斯特拉算法。 

狄克斯特拉算法只适用于有向无环图directed acyclicgraphDAG)。 如果有负权边,就不能使用狄克斯特拉算法因为负权边会导致这种算法不管用。 

 

2、代码示例

from prettytable import PrettyTable

# 模拟地杰斯特拉求解最短路径
def seachShortestPath(G,startPoint,inf):
    # 初始距离表,都先置为无穷大
    distanceGraph = dict((i,inf) for i in G.keys())
    # 起点
    currentPoint = startPoint
    distanceGraph[startPoint] = 0
    # 记录访问的点
    visitedPoint = []
    # 记录每次遍历后的当前最短路径
    currentPathTable = dict((i,[]) for i in G.keys())
    # 起点指向自己
    currentPathTable[currentPoint] = str(currentPoint)

    while len(visitedPoint) < len(G):
        visitedPoint.append(currentPoint)
        # 遍历当前点的所有邻近点(默认遍历keys)
        for item in G[currentPoint]:
            # 如果当前点到邻近点的距离小于初始距离表的距离,更新此距离到初始距离表中
            if distanceGraph[currentPoint] + G[currentPoint][item] < distanceGraph[item]:
                distanceGraph[item] = distanceGraph[currentPoint] + G[currentPoint][item]
                # 连接路径
                currentPathTable[item] = "-".join((str(currentPathTable[currentPoint]),str(item)))

        tempDistance = inf
        # 求经过一次计算后,当前距离表的最短路径,并选取当前最短路径的点下次为起始点
        for item in distanceGraph.keys():
            # 已访问的点直接continue
            if item in visitedPoint:continue
            if distanceGraph[item] < tempDistance:
                tempDistance = distanceGraph[item]
                currentPoint = item

    return distanceGraph,currentPathTable



if __name__ == '__main__':
    G = {
        1:{1:0,2:1,3:12},
        2: {2: 0, 3: 9, 4: 3},
        3: {3: 0, 5: 5},
        4: {3: 4, 4: 0, 5: 13, 6: 15},
        5: {5: 0, 6: 4},
        6: {6: 0}
    }
    Infinity = float("inf")
    distanceGraph,currentPathGraph = seachShortestPath(G,1,Infinity)

    table = PrettyTable()
    print("\033[34;1m模拟地杰斯特拉算法求单源最短路径\033[0m")
    # table.= ["\033[34;1m模拟地杰斯特拉算法求单源最短路径\033[0m"]
    table.field_names = ["\033[1m顶点","路径","长度\033[0m"]
    for point,path,distance in zip(list(currentPathGraph.keys()),list(currentPathGraph.values()),list(distanceGraph.values())):
        table.add_row([point,path,distance])
    print(table)

3、小结

广度优先搜索用于在非加权图中查找最短路径。
狄克斯特拉算法用于在加权图中查找最短路径。
仅当权重为正时狄克斯特拉算法才管用。
如果图中包含负权边,可采用Floyd算法。

4、应用场景

 求单源最短距离

posted @ 2020-11-04 10:20  Dammond  阅读(414)  评论(0)    收藏  举报