单源最短路径

来源:互联网 发布:苏沉船 王晶 知乎 编辑:程序博客网 时间:2024/06/06 19:44
最优子结构——最短路径的子路径也是最短路径,动态规划和贪心算法的一个重要指标。

环路
    一条最短路径不可能包含环路
    1)    环路权重为负,如果有一条环路权重为负,则不存在最短路径
    2)    环路权重为零,如果包含该环路,则将该环路去掉即可
    3)    环路权重为正,去掉改环路可以得到更短的路径,因此不可能是最短路径

最短路径的表示
    对于每个结点v,维持一个前驱结点v.p,可能是另外一个结点或者NIL

松弛操作
    对每个结点,维持一个属性v.d,记录从源结点s到结点v的最短路径权重的上界;称v.d为s到v的最短路径估计

INITIALIZE-SINGLE-SOURCE(G, s)        //最短路径估计及前驱结点初始化
    for each vertex v 属于 G.V
        v.d = INF
        v.p = NIL
    s.d = 0
    松弛过程【针对一条边(u, v)】:先测试是否可以对s到v的最短路径进行改善,测试的方法为,将从结点s到结点u的最短路径距离加上u与v之间的边权重,并与当前的s到v的最短路径估计进行比较;如果前者更小,则进行v.d和v.p的更新
RELAX(u, v, w)
    if v.d > u.d + w(u, v)
        v.d = u.d + w(u, v)
        v.p = u


Bellman-Ford算法
    一般情况下的单源最短路径问题,边的权重可以为负值
    返回一个布尔值,以表明是否存在一个从源结点可以到达的权重为负值的环路
BELLMAN-FORD(G, w, s)
    INITIALIZE-SINGLE-SOURCE(G, s)                    //对各个结点的p和d进行初始化
    for i = 1 to |G.V| - 1                                          //每一个点,对每一条边都需要进行松弛操作
        for each edge(u, v) 属于 G.E
            RELAX(u, v, w)
    for each edge(u, v) 属于 G.E
        if v.d > u.d + w(u, v)                                    //如果不存在权重为负值的环路,则二者是相等的
            return FALSE
    return TRUE

有向无环图中的单源最短路径问题
    根据结点的拓扑顺序次序来对带权重的有向无环图G = (V, E)进行边的松弛操作,可以在O(V + E)时间内计算出从单源最短路径问题
DAG-SHORTEST-PATHS(G, w, s)
    topologically sort the vertices of G               //先对点进行拓扑排序,O(V + E)
    INITIALIZE-SINGLE-SOURCE(G, s)
    for each vertex u, taken in topologically sorted order        //按拓扑排序对结点进行一遍处理
        for each vertex v 属于 G.Adj[u]
            RELAX(u, v, w)

Dijkstra算法
    要求所有变的权重都为非负值
    维持了一组结点集合S,源结点s到这组结点的最短路径已经求出;算法重复从V-S中选择最短路径估计最小的结点u,将u加入到集合S中,然后对所有从u发出的边进行松弛
    使用一个最小优先队列Q保存结点集合S,每个结点的关键字为其d值
DIJKSTRA(G, w, s)
    INITIALIZE-SINGLE-SOURCE(G, s)
    S = 空集
    Q = G.V
    while Q 不等于 空集
        u = EXTRACT-MIN(Q)                        //第一个被提取的点即源结点
        S = S 并上 {u}
        for each vertex v 属于 G.Adj[u]
            RELAX(u, v, w)
0 0
原创粉丝点击