【问题标题】:Bellman Ford Implementation and simultaneously relaxation贝尔曼福特实施和同时放松
【发布时间】:2021-03-17 20:37:21
【问题描述】:

最近看到Bellman Ford and Some Facts这个问题如下:

我们知道 bellman-ford 算法会检查每一步中的所有边,并且对于每条边,如果 d(v)>d(u)+w(u,v) 成立则 @ 987654329@ 正在更新。 w(u,v) 是边 (u, v) 的权重,d(u) 是顶点 u 的最佳查找路径的长度。如果在任何一步有no update for any vertexes,算法terminate

为了找到从图 G 中的顶点 sn 顶点的所有最短路径,此算法在 k < n 迭代后终止。

以下事实是正确的。

s 开始的所有最短路径中的边数最多为k-1

在这个Book 中,我们有 3 个 BFord 的实现(一些优化)。我的问题是,如果我们有 同时放松应该使用其中的哪种算法,并且通过使用它,上述事实应该是正确的?还是一般情况下上述事实是正确的?

【问题讨论】:

  • 为什么你有java和c++标签。我们不赞成在这里发送垃圾邮件。

标签: java c++ algorithm data-structures graph


【解决方案1】:

最终算法BellmanFordFinal(s) 是上述所有 3 种算法的优化版本。

优化 1:

在书中,传奇的 Jeff Erickson 教授解释了 Bellman 提出的原始算法是如何通过去除算法中最后 3 行的缩进来优化的。

因为最外层迭代只考虑每条边 u->v 一次,所以它们的处理顺序无关紧要。

优化 2:

最后 2 行中的索引 i-1 已更改为 i,这使算法能够在正确计算值(最短路径)的情况下更快地工作。

优化 3:

2 维 DP 数组被转换为 1 维,因为它是不必要的。

因此,使用最终算法,标题为BellmanFordFinal(s)

我们需要在最外层循环运行N-1 次这一事实始终是正确的并且独立于任何实现,因为从源到目标的最长最短路径将是N-1线性图,其中 N 是图中的节点数。

回答您对k-1的担忧

从 s 出发的所有最短路径中的边数最多为 k-1

上述语句取决于您的算法的实现。

如果您添加一个 if 条件以在没有任何边进一步松弛时中断最外层循环,则此语句为假。

否则为真。

看看我在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

【讨论】:

  • 完美。 a--> b-->--c ,为第一次迭代后的每个节点获取值。在这种情况下,算法在 k=2 次迭代后停止,因为第二次迭代没有改变任何东西。最长最短路径中的边数为 3 且 3
  • 如果它解决了您的疑问,请接受答案。
  • 我提供了反例,说明从 s 开始的所有最短路径中的边数最多为 k-1。请检查一下。
  • 对于,a->b->c,边数为2。另外,2小于等于N-1 = 3-1 = 2。
  • 4 个顶点呢?
猜你喜欢
  • 1970-01-01
  • 2018-05-16
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-16
相关资源
最近更新 更多