如何在加权图中找到最长的路径?
Posted
技术标签:
【中文标题】如何在加权图中找到最长的路径?【英文标题】:How do I find the longest path in a weighted graph? 【发布时间】:2022-01-19 05:29:21 【问题描述】:如果给我一个包含货币兑换率的数据结构:
与交换价值的货币关系列表。 (印度卢比 - 美元)
那我怎样才能找到从货币1到货币2的最佳汇率呢?
我的思考过程: 方法一:
如果我获取交换值列表并将其转换为图形 - 邻接表和权重列表(因为这似乎是加权图问题),我可以使用 DFS 查找所有可能的路径,然后保留跟踪生成最高汇率的路径(因此我将乘以路径中的每个转化率并将其存储。每当路径生成更好的转化率时,我会更新此变量,因此我有最大值)
请评论此算法的正确性。我的想法正确吗?这会产生正确的结果吗?
我马上看到的一个问题是,这是非常低效的,因为它需要指数级的时间。
方法 2:我可以直接否定所有转换并使用 Bellman Ford 吗?因为 Bellman Ford 用于在加权图中找到成本最低的路径。
谢谢。任何指导将不胜感激
【问题讨论】:
您没有指定是否有 DAG,但如果有,则有针对该特殊情况的有效算法,即线性时间运行的算法。 还要小心贝尔曼福特方法。只有可以重用边缘才是正确的,我怀疑考虑到您要解决的问题,您只想遍历边缘一次。在这种情况下,您的问题是 NP 难题:en.wikipedia.org/wiki/Longest_path_problem 【参考方案1】:您的直觉是正确的 - 您可以使用 DFS,它会为您提供最佳汇率(按重量计算的最短路径),但对于大型图表来说会非常慢。
您的第二种方法(Bellman Ford)是一个更好的主意。正如您所提到的,您必须将汇率/边权重相乘,而不是相加,但这不应该造成任何问题。
我假设您已经解决了这个问题,但是对于将来引用它的任何人-您不能使用 Dijkstra 的算法或其后代(如 A*),因为从本质上讲,该图具有负循环。您可能会找到低于1
的转换率,并可能利用它来获得总体较低的最低转换率(然后您只需将两种货币反转,以获得相反方向的最大转换率)。
数学题外话:
更清楚地看到这一点的方法 - 假设我们有一些转换率,在 3 对货币之间 - A
、B
和 C
。假设单位签出,这三个交易所的整体转换率R
将是R = A * B * C
。我们可以这样写的另一种方式是R = e ^ log(A * B * C)
,其中e
是欧拉数,log()
是自然对数(我们也可以使用10
和log10()
,或任何其他基数)。用对数规则重写,我们可以得到R = e ^ (log(A) + log(B) + log(C))
,最后是log(R) = log(A) + log(B) + log(C)
。
现在,如果我们不关心 R
的实际值,即最大/最小(或者我们愿意执行一些幂运算来得到它),我们可以满足于计算 log(R)
,或汇率的对数。这样做的好处是,权重在转换为对数的同时,相加在一起,而不是相乘。这使我们能够原封不动地使用传统的图算法实现(我们只给它们log(weight)
而不是weight
)。如果我们尝试给它通常介于0
和1
之间的东西,我们会看到log(x)
实际上变成了负数,暴露了该边缘的真实性质,以及它可能产生的潜在负循环。
总结
您可能希望使用 Bellman-Ford,只需将加法替换为乘法即可。如果您手头有一个现有的实现,但它利用加法来组合边缘权重,您可以通过传递边缘权重的log()
来轻松作弊,事情将“自动”工作。
【讨论】:
嘿狄龙,这对我来说很有意义。我有一些后续问题:当有负边缘时,贝尔曼福特不工作。不用担心,因为我们的图表都是积极的。但是,Bellman Ford 旨在获得最短路径。我们想要“最长”的路径。因此,为了符合算法的标准,在我的第二种方法中,我说我们可以否定所有边缘权重,以便贝尔曼福特在选择最短路径时实际上是在选择最长路径。但是,如果将所有边权重乘以 -1 会产生负循环怎么办? @Rayyankhan Bellman Ford 确实适用于负边缘 - 当存在负 循环 时它不起作用。此外,您的图表并非都是积极的,而不是在考虑加法时(请参阅我的数学题外话)。如果有一个负循环,你就可以赚到无限的钱,因为你只是一遍又一遍地重复交换循环来赚越来越多的钱。 我忘了在原帖中提到这一点——你当然会想要使用有向边。这可能很明显,但我还是想提一下以上是关于如何在加权图中找到最长的路径?的主要内容,如果未能解决你的问题,请参考以下文章