我们有一个针对通讯的有向图G = (V, E)
。每个边缘的网络具有不会失败的概率r(u, v)
(定义为边缘权重),其位于区间[0,1]中。概率是独立的,因此从一个顶点到另一个顶点,如果我们乘以所有概率,我们得到整个路径没有失败的概率。
我需要一种有效的算法来找到从一个给定顶点到另一个给定顶点的最可靠路径(即,从第一个顶点到最不可能失败的第二个顶点的路径)。我被告知log(r · s) = log r + log s
会有所帮助。
这是我到目前为止 -
DIJKSTRA-VARIANT (G, s, t)
for v in V:
val[v] ← ∞
A ← ∅
Q ← V to initialize Q with vertices in V.
val[s] ← 0
while Q is not ∅ and t is not in A
do x ← EXTRACT-MIN (Q)
A ← A ∪ {x}
for each vertex y ∈ Adj[x]
do if val[x] + p(x, y) < val[y]:
val[y] = val[x] + p(x, y)
s
是源顶点,t
是目标顶点。当然,我没有利用log
属性,因为我无法理解如何使用它。底部算法的松弛部分需要修改,val
数组将捕获结果。没有日志,它可能会存储次高概率。我应该如何修改算法以使用log
?
答案 0 :(得分:2)
目前,您的代码已
do if val[x] + p(x, y) < val[y]:
val[y] = val[x] + p(x, y)
由于此情况下的边权重代表概率,因此需要将它们相乘(而不是相加):
do if val[x] * p(x, y) > val[y]:
val[y] = val[x] * p(x, y)
我已将符号更改为>
,因为您希望概率尽可能大。
日志很有用,因为(1)log(xy) = log(x) + log(y)
(如你所说)和总和比产品更容易计算,而(2)log(x)
是x
的单调函数,所以log(x)
和x
的最大值位于同一位置。因此,您可以处理概率的对数,而不是概率本身:
do if log_val[x] + log(p(x, y)) > log_val[y]:
log_val[y] = log_val[x] + log(p(x, y))
已编辑添加(因为我没有足够的代表发表评论):您需要将val
数组初始化为0
,而不是Infinity
,因为你计算的是最大值而不是最小值。 (因为您希望最大概率不失败。)因此,在日志转换后,初始log_val
数组值应为-Infinity
。< / p>
答案 1 :(得分:1)
为了计算概率,你应该在放松阶段乘以(而不是加),这意味着改变:
do if val[x] + p(x, y) < val[y]:
val[y] = val[x] + p(x, y)
为:
do if val[x] * p(x, y) < val[y]:
val[y] = val[x] * p(x, y)
如果范围是(0,1),因为log(0)= -infinity并且log(1)= 0,则可以使用日志,这意味着对于每个x,y in (0,1]
:
{{ 1}}比:probability x < probability y
。由于我们保持相同的关系(概率之间),这种修改将提供正确的答案。
我想你可以从这里拿走它。
答案 2 :(得分:1)
我想我可能已经部分地解决了这个问题。
这是我的尝试。欢迎编辑和指示 - :
DIJKSTRA-VARIANT (G, s, t)
for v in V:
val[v] ← 0
A ← ∅
Q ← V to initialize Q with vertices in V.
val[s] ← 1
while Q is not ∅ and t is not in A
do x ← EXTRACT-MAX (Q)
A ← A ∪ {x}
for each vertex y ∈ Adj[x]
do if log(val[x]) + log(p(x, y)) > log(val[y]):
log(val[y]) = log(val[x]) + log(p(x, y))
由于我要找到尽可能高的概率值,我相信我应该使用>
。以下问题仍然存在 - :
val
数组中的初始值应该是什么?
我还需要添加其他内容吗?
编辑:我已将初始val
值更改为0.但是,log
未定义为0.我愿意接受更好的选择。此外,我将优先级队列的方法更改为EXTRACT-MAX
,因为它是需要提取的较大概率。理想情况下,这应在binary max-heap
上实现。
进一步编辑:我已经将tinybike的答案标记为已被接受,因为他们已经发布了我需要的大部分必要细节。算法应该像我在这里发布的那样。