【问题标题】:Number of shortest paths in weighted graph加权图中的最短路径数
【发布时间】:2015-05-24 13:02:06
【问题描述】:

这是一个问题: 给定一个有向图 G=(V,E),源顶点 s $epsilon V,我们知道 G 中的所有环都是正权重(>0)。在运行 Bellman-Ford 之后,我们也得到了图表,这意味着对于 V 中的每个 v,我们都知道 d[v](从 s 到 v 的最短路径)和 pi[v](v 的前任)

描述一个算法来找到V中所有v的从s到v的最短路径数。该算法必须在O(V+E)中运行

*我们无法编辑算法上的 Bellman-Ford 运行

这就是我的想法: 我们运行一个修改后的 DFS,

算法(G,s):

1.DFS-Visit(G,s)
2. return count[v] foreach v in V

DFS-访问(G,u):

1.foreach v in Adj[u]
   2.if d[v] == d[u] + w(u,v) && (u,v) is not a backedge
      3.count[v] = count[v] + 1
      4.DFS-visit(G,v)

*算法似乎会陷入无限循环,也许我可以忽略后端? (因为最短路径总是很简单)

*这不是重复的 How to find the number of different shortest paths between two vertices, in directed graph and with linear-time?

在那个问题中,图在这里是未加权的(边) 你认为这是正确的吗? 谢谢

【问题讨论】:

  • 在那个问题中,图表未加权@AmiTavory
  • 抱歉,可能错过了。
  • 由于时间复杂度限制,我们不能使用 Bellman-Ford?!因为否则,我们也可以使用 Bellman-Ford 找到最短路径的数量。

标签: algorithm graph


【解决方案1】:

if d[v] == d[u] + w(u,v) && (u,v) is not a backedge

条件d[v]==d[u]+w(u,v) 在这里是最重要的。如果保证这永远不是一个后边,而且,它保证你永远不会回到你所在的顶点。

确实,假设您回到了您曾经所在的顶点。然后你有

d[v1]==d[v0]+w(v0,v1)
d[v2]==d[v1]+w(v1,v2)
...
d[v0]==d[vn]+w(vn,v0)

总结一下,我们发现

w(v0,v1)+w(v1,v2)+...+w(vn,v0)==0

这是一个零权重循环,但我们被告知没有这样的循环。

所以这个算法永远不会陷入死循环;此外,如果你只留下满足d[v]==d[u]+w(u,v) 的边(即使图没有被定向),结果图将是无环的。

因此,您可以运行在无环图中找到多种方式的标准算法。事实上这是你已经写的(你的DFS),请注意

count[v] = count[v] + 1

应该是

count[v] = count[v] + count[u]

【讨论】:

  • 我如何确定保持满足条件的边会给我一个无环图?感谢您的回答
  • @Bilal27(我吐了,因为我只是略过这个)答案可能是如果其中有循环,我们可以删除它们以获得更短的路径,因为你说只有正权循环存在.
  • @Bilal27,证明和我文章开头的证明完全一样。
【解决方案2】:

以问题中描述的方式修改的 DFS(使用已接受答案的更正)允许多次访问节点,并可能导致指数时间算法(有关发生这种情况的图的一般结构,请参见下面的反例)。

如果我们像经典 DFS 一样访问每个节点一次,算法并不总是正确计算最短路径的数量。

反例

7 个节点,8 条边,所有权重均为 1

1 -> 2
1 -> 5
2 -> 3
5 -> 3
3 -> 4
3 -> 6
4 -> 7
6 -> 7

一般结构看起来像这样

  2   4
 / \ / \
1   3   7
 \ / \ /
  5   6

从节点 1 开始运行 Bellman-Ford 后:

d[1] = 0
d[2] = d[5] = 1
d[3] = 2
d[4] = d[6] = 3
d[7] = 4

从节点 1 到节点 7 有 4 种不同的最短路径:

1 2 3 4 7
1 2 3 6 7
1 5 3 4 7
1 5 3 6 7

但是应用 DFS 我们得到:

count[1] = 1
Visiting node 1: count[2] = 1
Visiting node 2: count[3] = 1
Visiting node 3: count[4] = 1
Visiting node 4: count[7] = 1
Visiting node 7: no outgoing arcs
Returning to node 4: no more neighbors
Returning to node 3: count[6] = 1
Visiting node 6: count[7] = 2
Node 7 already visited, so we skip it
Returning to node 6: no more neighbors
Returning to node 3: no more neighbors
Returning to node 2: no more neighbors
Returning to node 1: count[5] = 1
Visiting node 5: count[3] = 2

如果不允许多次访问节点,这就是算法结束的地方,所以 count[7] 将保持为 2,这是不正确的(正确的应该是 4)。如果我们允许多次访问一个节点,运行时间将是 2^n 的数量级。

正确的算法

正如 Petr 的回答所示,最短路径的边形成有向无环图 (DAG)。我们需要对这个 DAG 的节点进行拓扑排序,并按照拓扑顺序对节点应用计数算法。运行时间为O(n + m):拓扑排序遍历图一次,计数算法遍历一次图。

反例演示的正确算法

One possible topological order: 1 2 5 3 4 6 7
Visiting nodes in this order:
count[1] = 1
Visiting 1: count[2] = 1, count[5] = 1
Visiting 2: count[3] = 1
Visiting 5: count[3] = 2
Visiting 3: count[4] = 2, count[6] = 2
Visiting 4: count[7] = 2
Visiting 6: count[7] = 4

【讨论】:

    猜你喜欢
    • 2016-06-25
    • 2014-06-26
    • 1970-01-01
    • 1970-01-01
    • 2014-12-04
    • 1970-01-01
    • 2017-08-10
    • 1970-01-01
    • 2022-01-22
    相关资源
    最近更新 更多