我有以下图表,其中每个顶点都有一个相关的“概率” (graph with weighted nodes)。
我想找到从节点0到最后一个节点(最高索引,这里是5)的路径,它具有最高的乘法概率。在此图中,最佳路径为0-1-4-5,概率为0.72。
我已经考虑过使用BFS来查找起始节点和结束节点之间的所有路径,然后将每个节点的概率相乘,但我认为它对于所有图形的工作方式来说太过分了。我怎么能用python解决这个问题?
答案 0 :(得分:2)
正如朱利安所说,Dijkstra's algorithm将是一个良好的开端。您的问题与普通Dijkstra之间存在两个差异。
Dijkstra算法最小化权重之和。为了最大化概率乘积,您可以将每个权重p
映射到-log(p)
。快速校对:最大化(x1*x2*...*xn)
的产品与最大化log(x1*x2*...*xn)
相同,因为log
是monotonically increasing。 argmax(log(x1*x2*...*xn)) = argmax(log(x1)+log(x2)+...+log(xn)) = argmin(-log(x1)-log(x2)-...-log(xn)))
。请注意,如果您想要得到概率,则可以通过10^(-c)
来反转您的结果,其中c
是Dijkstra使用上述减少返回的最低成本(假设您使用基数为10的日志)。另请注意,如果任何概率为0,则log(0)
未定义,因此您应通过使权重无限来处理此问题(因此路径永远不会通过该节点)。
Dijkstra使用加权边,而你有加权节点。但它是从加权节点到加权边缘的简单缩减。使用u
定义从v
到edge_weight(u,v) = vertex_weight(v)
的边的权重。根据您的图片判断,您有一个无向图,因此您需要使用与上述相同的权重替换每个无向边和两个有向边(注意两个顶点u
和{{1之间的两条边除非v
),否则会有不同的权重。此外,如果您想要返回最短路径的值,则需要将vertex_weight(u) == vertex_weight(v)
添加到最终费用中,因为此费用会在减少时跳过。