algorithm - 找到最可靠的路径 - Dijkstra 算法
问题描述
给定一个有向图 G = (V, E),其中每条边 (u, v) ∈ E 都有一个关联值 r(u, v),它是 0 ≤ r(u, v) 范围内的实数) ≤ 1,表示从顶点 u 到顶点 v 的通信通道的可靠性。我们将 r(u, v) 解释为从 u 到顶点的通道不会失败的概率,并且我们假设这些概率是独立的。给出一个有效的算法来找到两个给定顶点之间最可靠的路径。
a
/ \
b<--c a directed to c; c directed to b; b directed to a
假设这是图 G = (V, E); 顶点a是根,边之一是a到c。a = u & c = v 所以边是 (u, v)。我想使用 Dijkstra 的算法来解决这个问题,但不知道如何。
a
\
b<--c path c: a -> c & b: a -> c -> b
有人可以以最简单的方式解释最可靠的路径吗?
这个问题来自Introduction to Algorithms, 3rd edition, chp 24.3
提前致谢!
解决方案
我们将 r(u, v) 解释为从 u 到的通道不会失败的概率,并且我们假设这些概率是独立的。
由此您可以推断出给定路径不会失败的概率等于构成路径r(u,v)
的所有边的乘积(u,v)
。
您想最大化该产品。
这就像最短路径问题,你肯定知道一个算法,除了你试图最大化一个乘积而不是最小化一个总和。
从乘积到求和有一个很酷的工具:它是对数。对数是一个递增函数,因此最大化一个乘积与最大化该乘积的对数相同。但是对数还有一个很酷的特性,即乘积的对数等于对数之和:
log(a * b * c * d * ...) = log(a) + log(b) + log(c) + log(d) + ...
因此最大化可靠性r(u,v)
的乘积与最大化对数可靠性的总和相同log(r(u,v))
。
由于可靠性是边的概率,它们的值介于 0(不包括)和 1(包括)之间。您可以排除 0,因为如果一条边的可靠性为 0,您可以从图中删除该边。因为0 < r(u,v) <= 1
,所以它log(r(u,v))
是负数或 0。
所以你试图最大化负值的总和。这与最小化相反值的总和完全相同。
因此:应用你的最短路径算法,使用-log(r(u,v))
边缘的长度。
推荐阅读
- java - 如何从资产文件夹共享 htm 文本文件?
- c# - 未填充身份自定义属性(保存到数据库作品)
- vb.net - 如何为每一行分配不同的图像?
- excel - VBA - 带上下括号的控制图
- database - SQLite 使用 lag() 函数打印历史记录
- html - 浮动柱
- machine-learning - 如何将粒子群优化应用于 keras 中的神经网络模型
- assembly - 在概念层面上,是否有可能在汇编/编译代码层面实现分布式计算?
- nginx - URL 查询参数中的 Nginx 范围请求
- django - Django REST Framework SerializerMethodField 与 Django 模型方法