给定加权无向图,我需要找到两个节点之间的最短路径,实际上是经典的最短路径问题。但是还有一个约束:每个节点都包含一个“减少”值,可用于降低一次遍历的后续边缘的成本(不仅是相邻的,而且减少不是累积的)。因此,您可以使用之前经历过的节点中的“减少”来降低边缘成本(每个边缘的最终成本不能低于0)。
请注意,一旦我们进行了减少的节点,我们可以再次使用它来处理所有后续边缘(不仅仅是相邻边缘,并且可以无限量地使用它)。减少不会累积。
让我们考虑一下这个图:
在此图中,从节点1到5的最短路径是:
然后从节点1到节点5的总成本是13 + 0 + 0 = 13
为了解决这个问题,我尝试使用经典的Dijkstra / Bellman-Ford,但它不起作用,你可以帮我解决这个问题吗?
答案 0 :(得分:0)
似乎这可以用Bellman-Ford的变种来解决。
直到给定节点的每条路径都可以汇总为一对(C,D),其中C是该路径的成本(折扣后),D是该路径上可用的最佳折扣因子。由于折扣可以在访问该节点后无限次重复使用,因此始终使用迄今为止在该路径上看到的最大折扣是有意义的。例如,路径(1→4→3)的成本为C = 13,折扣D = 12。
关于未折现问题的复杂性是我们无法从成本中看出源和目标之间节点的“最佳”路径是什么。在您的示例中,路径(1 - > 2 - > 3)的成本低于(1 - > 4 - > 3),但后者具有更好的折扣,这就是为什么从1到5的最佳路径是(1 - > 4 - > 3 - > 5)。
我们需要记录从源到目前为止找到的节点的所有“可行”路径,而不是记录每个节点的最低成本路径(在Bellman-Ford算法中)。如果没有其他已知路径具有较低成本和较好折扣,则可以说路径是可行的。算法终止后,我们可以从源到目的地的所有可行路径中获取成本最小的路径,忽略折扣。
(编辑:我最初建议可以使用Djikstra,但我认为这不是那么简单。我不确定我们是否可以选择“最接近”的未访问节点以任何有意义的方式使我们保证找到最小的路径。其他人可能会看到如何使它工作,但...)
答案 1 :(得分:0)
我认为您可以使用Dijkstra类型的算法。 Dijkstra的算法可以被认为是计算包含从源顶点到所有其他顶点的最短路径的最小生成树。我们称之为“Dijkstra树”,它包含来自给定源顶点的所有最短路径。
Dijkstra不断向当前树添加新顶点。对于下一个顶点,他选择最接近当前树的顶点。从wikipedia:
中查看此动画
因此,当Dijkstra将新的顶点v添加到已插入的顶点u(当前树的顶点)时,必须考虑{u,v}的边权重。在您的情况下,成本不仅仅是{u,v}的边缘权重,而是权重减少了当前树中沿着最短路径的顶点减少量之和。所以你必须记住顶点中这个“Dijkstra”树的路径上顶点缩减的总和。