Floyd-Warshall算法与Dijkstra算法的区别

Floyd-Warshall算法

For (k = 0; k < len(G.nodes); k++)
    For (i = 0; i < len(G.nodes); i++)
        For (j = 0; j < len(G.nodes); j++)
            if (matrix[i][j] < matrix[i][k] + matrix[k][j])
                matrix[i][j] = matrix[i][k] + matrix[k][j]

以上是一个比较简单的Warshall算法,通过不断寻找中间结点k来完成松弛操作。该算法主要用于寻找图(包括有向图,无向图,正权图,负权图,针对不同图需要对算法作少许修改)的最短路径和环路,时间复杂度约为 O ( n 3 ) O(n^3) O(n3),空间复杂度为 O ( n 2 ) O(n^2) O(n2)

Dijkstra算法

def Dijkstra(fa):
    inf, v, d = inf, [], [0] + [inf] * len(list(fa.nodes))
    for i in range(len(list(fa.nodes))):
        x, m = inf, inf
        for y in range(len(list(fa.nodes))):
            if (y not in v and d[y] < m):
                m = d[y]
                x = y
        v.append(x)
        for y in range(len(list(fa.nodes))):
            if (fa.has_edge(x, y) and d[x] + fa[x][y]['w'] < d[y]):
                d[y] = d[x] + fa[x][y]['w']
                #p[y] = x 记录前一状态方便递归打印
    return d

以上是用两层循环写的Dijkstra算法,该算法的主要思想是通过递归地计算下一节点和出发点的距离完成松弛操作。该算法主要用于寻找除负权图外其他图的最短路径。本算法中没有应用递归算法,转而运用两层For替代,第1层For循环实际上便是递归深度,第2层负责寻找上一阶段中的已计算结点,该结点的子结点需要满足未被记录这一条件。时间复杂度为 O ( n 2 ) O(n^2) O(n2),空间复杂度为 O ( n 2 ) O(n^2) O(n2)

综上可知,Warshall算法可处理图的范围比Dijkstra算法更广泛,然而算法复杂度也比Dijkstra算法更大。

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