bellman-ford的实现与实现

j1dl9f46  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(187)

最近我看到这个问题贝尔曼福特和一些事实如下:
我们知道bellman-ford算法检查每一步中的所有边,对于每一条边,如果d(v)>d(u)+w(u,v)保持不变 d(v) 正在更新。 w(u,v) 是边缘的重量 (u, v) 以及 d(u) 顶点的最佳寻径长度 u . 如果有任何一步 no update for any vertexes ,算法 terminate .
用于从顶点查找所有最短路径 s 在图g中 n 顶点此算法在 k < n 迭代。
以下事实是正确的。
所有最短路径中的边数 s 最多是 k-1 在这本书中,我们有3个实现(一些优化)的bford。我的问题是,如果我们同时有松弛,应该使用哪种算法,通过使用它,上述事实应该是正确的?总的来说,上述事实是否属实?


zsbz8rwp

zsbz8rwp1#

最后的算法, BellmanFordFinal(s) 是上述3种算法的优化版本。
优化1:
在这本书中,著名的杰夫·埃里克森教授解释说,贝尔曼提出的原始算法是如何通过去除算法中最后3行的缩进来优化的。
因为最外层的迭代考虑每个边 u->v 只有一次,它们被处理的顺序并不重要。
优化2:
指数 i-1 已更改为 i 在最后两行中,这使算法能够更快地正确计算值(最短路径)。
优化3:
由于二维dp数组是不需要的,所以它被转换为一维。
因此,使用最后一个算法, BellmanFordFinal(s) .
事实上我们需要运行最外层的循环 N-1 时间总是真实的,与任何实现无关,因为从源到目标的最长最短路径是 N-1 对于线性图,其中n是图中的节点数。
回答你对 k-1 从s开始的所有最短路径的边数最多为k-1
以上语句取决于算法的实现。
如果添加if条件以在没有任何边进一步松弛时打断最外层的循环,则此语句为false。
否则就是真的。
请看我在上发现的以下实现https://cp-algorithms.com/graph/bellman_ford.html:

void solve()
{
    vector<int> d (n, INF);
    d[v] = 0;
    for (;;)
    {
        bool any = false;

        for (int j=0; j<m; ++j)
            if (d[e[j].a] < INF)
                if (d[e[j].b] > d[e[j].a] + e[j].cost)
                {
                    d[e[j].b] = d[e[j].a] + e[j].cost;
                    any = true;
                }

        if (!any) break;
    }
    // display d, for example, on the screen
}

变量 any 用于检查在任何迭代中是否进行了任何松弛。如果不这样做,打破循环。
因此,循环可能在k=2且最长路径中的边数为3之前终止。现在,3<=2-1,不正确。

相关问题