• 最短路径算法
    • Dijkstra —— 贪心算法
    • Floyd —— 动态规划

    最短路径算法

    Dijkstra —— 贪心算法

    从一个顶点到其余顶点的最短路径

    G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第1组为已求出最短路径的顶点(用S表示,初始时S只有一个源点,以后每求得一条最短路径v,...k,就将k加到集合S中,直到全部顶点都加入S)。第2组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序把第2组的顶点加入S中。

    1. 步骤:
    2. 1. 初始时,S只包含源点,即`S={v}`,顶点v到自己的距离为0U包含除v外的其他顶点,vU中顶点i的距离为边上的权。
    3. 2. U中选取一个顶点u,顶点vu的距离最小,然后把顶点u加入S中。
    4. 3. 以顶点u为新考虑的中间点,修改vU中各个点的距离。
    5. 4. 重复以上步骤知道S包含所有顶点。

    Floyd —— 动态规划

    Floyd 算法是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权(但不可存在负权回路)的最短路径问题。该算法的时间复杂度为 O(N^{3}),空间复杂度为 O(N^{2})

    D_{i,j,k} 为从 ij 的只以 (1..k) 集合中的节点为中间节点的最短路径的长度。


    D{i,j,k}=\begin{cases}
    D
    {i,j,k-1} & 最短路径不经过 k\
    D{i,k,k-1}+D{k,j,k-1} & 最短路径经过 k
    \end{cases}

    因此, D{i,j,k}=min(D{i,k,k-1}+D{k,j,k-1},D{i,j,k-1})。伪代码描述如下:

    1. // let dist be a |V| × |V| array of minimum distances initialized to ∞ (infinity)
    2. for each vertex v
    3. dist[v][v] 0
    4. for each edge (u,v)
    5. dist[u][v] w(u,v) // the weight of the edge (u,v)
    6. for k from 1 to |V|
    7. for i from 1 to |V|
    8. for j from 1 to |V|
    9. if dist[i][j] > dist[i][k] + dist[k][j]
    10. dist[i][j] dist[i][k] + dist[k][j]
    11. end if