我曾经在维基百科上得到了著名的Yen对Bellman-Ford算法的优化方法,后来我在几本教材的练习部分也发现了相同的改进(例如,在Cormen的书中,这是一个24-1问题,在Sedgewick的“算法”中是Web exercise N5)。
以下是改进内容:
Yen的第二次改进首先对所有顶点进行任意线性排序,然后将所有边的集合分为两个子集。第一个子集Ef包含所有(i,j)边,其中ij。按照v1、v2、...、v|V|的顺序访问每个顶点,在Ef中松弛该顶点的每条出边。然后按照v|V|、v|V|-1、...、v1的顺序访问每个顶点,在Eb中松弛该顶点的每条出边。算法的主循环的每次迭代(除了第一次)都会向匹配正确的最短路径距离的已松弛边的集合中添加至少两条边:一条来自Ef,一条来自Eb。这种修改将算法的主循环的最坏迭代次数从|V|-1减少到|V|/2。不幸的是,我没有找到这个上界|V|/2的证明,而且似乎我找到了一个反例。我确定我错了,但我看不出具体在哪里。
反例只是一个由1到n标记的路径图,初始顶点为1。(因此,E = {(i,i + 1)},其中i在范围从1到n-1内)。在这种情况下,正向顶点集等于E(E_f = E),而反向顶点集仅为空集。算法的每次迭代仅添加一个正确计算的距离,因此算法在n-1时间内完成,这与所提出的上界n/2相矛盾。
我做错了什么?
更新:所犯的错误非常愚蠢。我没有考虑通过顶点的迭代,认为迭代即为路径成本的即时更新。我不会删除此主题,因为有人对其进行了投票,在某些情况下,这一改进可能会引起某些人的兴趣。
以下是改进内容:
Yen的第二次改进首先对所有顶点进行任意线性排序,然后将所有边的集合分为两个子集。第一个子集Ef包含所有(i,j)边,其中ij。按照v1、v2、...、v|V|的顺序访问每个顶点,在Ef中松弛该顶点的每条出边。然后按照v|V|、v|V|-1、...、v1的顺序访问每个顶点,在Eb中松弛该顶点的每条出边。算法的主循环的每次迭代(除了第一次)都会向匹配正确的最短路径距离的已松弛边的集合中添加至少两条边:一条来自Ef,一条来自Eb。这种修改将算法的主循环的最坏迭代次数从|V|-1减少到|V|/2。不幸的是,我没有找到这个上界|V|/2的证明,而且似乎我找到了一个反例。我确定我错了,但我看不出具体在哪里。
反例只是一个由1到n标记的路径图,初始顶点为1。(因此,E = {(i,i + 1)},其中i在范围从1到n-1内)。在这种情况下,正向顶点集等于E(E_f = E),而反向顶点集仅为空集。算法的每次迭代仅添加一个正确计算的距离,因此算法在n-1时间内完成,这与所提出的上界n/2相矛盾。
我做错了什么?
更新:所犯的错误非常愚蠢。我没有考虑通过顶点的迭代,认为迭代即为路径成本的即时更新。我不会删除此主题,因为有人对其进行了投票,在某些情况下,这一改进可能会引起某些人的兴趣。