给定一个边缘具有正权重,一对节点和节点之间的路径的图形,最好的算法将告诉我如何将图形的边缘权重修改到最小程度,以便指定path成为节点之间的最短路径(由A *计算)? (当然,如果我将最短路径指定为输入,则输出将是“不做任何更改”)。
注意:最小范围是指对边权重所做的总更改。例如,另一个极端(最具破坏性的变化)是将不沿指定路径的所有边的权重更改为无穷大,将沿路径的边的权重更改为零。
答案 0 :(得分:1)
您可以使用Floyd-Warshall算法计算所有路径的距离,然后修改所需的路径,使其成为最短路径。例如,想象下面的3个节点图。
让路径为a - > b - > C。 Floyd-Warshall算法将计算以下矩阵。
带绿色圆圈的数字是a - >的距离。 b(2)和b - > c(4)。红色圆圈数是a和c(3)之间路径的最短距离。由于2 + 4 = 6≠3,您知道必须将路径调整为3才能成为最小路径。
我建议这种方法的原因与仅计算最短路径的距离和相应地调整所需路径相反,这种方法允许您查看任意两个节点之间的距离,以便您可以调整边缘的权重如你所愿。
答案 1 :(得分:0)
这让我想起了神经网络训练中常见的反向传播策略。我将描绘两种策略,第一种是有缺陷的:
c(P)
。c(S)
。w(p) ∈ P
减少每个边缘权重(c(P) - c(S) - epsilon) / |P|
,其中epsilon
是一个非常小的常数,您希望路径小于c(S),{{1} }是|P|
中的边数。当然,问题在于您可能会降低路径P
(或其他路径)的成本,而不是降低S
的成本!这告诉我,这将需要一种迭代方法,从而开始向前并相对于您在每一步重新计算的最短路径成本来降低给定权重的成本。这非常昂贵,但幸运的是,最短路径算法往往有很好的动态编程解决方案!
因此修改后的算法看起来像这样(假设P
开始):
i = 0
步的费用,我们将其称为i
。c(p_0...p_i)
,以及第一个c(S)
组件的费用,我们将用i
表示。c(s_0...s_i)
减少边缘权重w(p_n)
,其中c(p_0...p_i) - c(s_0...s_i) - epsilon
是一个非常小的常数,您希望自己的路径小于c(S)。epsilon
增加1。如果i
开头为P = S
,如果epsilon
为0,则应保持原始路径不变。否则,您应该减少不超过理想更新的epsilon * |P|
。
优化此算法需要您弄清楚如何以有效的方式从c(s_0...s_i+1)
计算c(s_0...s_i)
,但这是留给读者的练习; - )