加权有向图问题2----多源最短路径问题(Floyd算法)和关键路径算法

Floyd算法

Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法。java

Floyd算法可以处理带负权重的边的有向图但不能包含负权重环。算法

算法思想:

从起始顶点开始,依次加入一个顶点,每加入一个顶点,更新一下各条最短路径长度。各条最短路径长度保存在一个二位数组中。数组

算法实现:

for (int i = 0; i < V; i++) {
    for (int v = 0; v < V; v++) {
        if (edgeTo[v][i] == null) continue;  // 优化
        for (int w = 0; w < V; w++) {
            if (distTo[v][w] > distTo[v][i] + distTo[i][w]) {
                distTo[v][w] = distTo[v][i] + distTo[i][w];
                edgeTo[v][w] = edgeTo[i][w];
            }
        }
        // 检查负循环
        if (distTo[v][v] < 0.0) {
            hasNegativeCycle = true;
            return;
        }
    }
}

关键路径算法

优先级限制下的并行任务调度:给定一组须要完成的任务和每一个任务所须要的时间,以及一组关于任务完成的前后次序的优先级限制。在知足条件的前提下应该如何在若干相同的处理器上安排任务并在最短的时间内完成任务?优化

“关键路径”算法能够在线性时间内解决此问题。这个问题与无环加权有向图的最长路径问题是等价的。spa

为了设计求关键路径的动态规划算法,如今定义三个术语设计

事件i可能最先发生的时间earliest(i): 是指从开始结点s到结点i的最长路径的长度。code

事件i容许的最迟发生时间latest(i): 是值不影响效益的条件下,事件i容许发生的最晚时间。排序

关键活动: 处于关键路径上的活动是关键活动,它必须准时启动,不然就会使任务延期。事件

算法实现:

earliest()计算方法:

  • earlist(0) = 0
  • earlist(j) = max{earlist(i) + w(i,j)}    0<j<V, i∈P(j)   注:P(j)是拓扑图中与顶点j直接相邻的前一顶点集

latest()计算方法:

  • latest(V-1) = earliest(V-1)
  • latest(i) = min{latest(j) - w(i,j)}   0<=i<V-1,j∈S(i)    注:S(i)是拓扑图中与i直接相邻的后一结点集

关键活动计算方法:

若latest(j) - earliest(i) = e.weight (e为顶点i和j之间的有权边),则边e是关键活动。对于关键路径上的每个关键结点i,都有latest(i) = ealiest(i).get

算法步骤:

  1. 确认有向图G是无环图,并进行拓扑排序;
  2. 按拓扑次序计算earliest(i), 0<=i< V-1;
  3. 按逆拓扑排序计算latest(i), 0<=i< V-1;
  4. 计算latest(j) - earliest(i),判断是否为关键活动。
相关文章
相关标签/搜索