是否有可能使用Graphs.jl模块中的Dijkstra algorithm从源顶点到目标顶点获取整个路径?
当更新到顶点的距离时,会调用 update_vertex!(visitor,u,v,d)方法。仅当找到属于最短路径的新顶点时才更新距离?我不太确定。
感谢。
修改
根据文档,有可能使用Floyd-Warshall algorithm使用属性 dists 和 nexts 重建最短路径,但我不确定如何。我想在 GenericGraph 上运行它。
有什么想法吗?
答案 0 :(得分:1)
算法的结果包含一个名为parents
的字段,如@DanGetz指出的那样。每个节点在到达它之前具有访问的最后一个节点(即,在最短路径中的父)。使用每个节点的父节点,您可以使用简单的递归函数回溯每个节点的最短路径:
spath(x, r, s) = x == s ? x : [spath(r.parents[x], r, s) x]
其中r
是Dijkstra算法的结果,s
是传递给它的源。
可以通过列表理解获得每个节点的最短路径。找到example in the documentation的结果:
julia> [spath(x, r, 1) for x in g.vertices]
5-element Array{Any,1}:
1
1x3 Array{Int64,2}:
1 3 2
1x2 Array{Int64,2}:
1 3
1x4 Array{Int64,2}:
1 3 2 4
1x3 Array{Int64,2}:
1 3 5
可能有更好的算法(即一些动态编程方法来记住大图的路径),但作为一个例子,递归方法完成了这项工作。
一个快速递归代码,适用于每个最短路径有多个父母的词典:
function spath(current, parents, source, current_path)
if current == source || isempty(parents[current])
return Any[[current; current_path]]
end
results = []
for node in parents[current]
results = [spath(node, parents, source, [current; current_path]); results]
end
results
end
注意当前路径作为参数(它的副本)传递到叶节点(源),因此,当它到达它时返回整个最短路径。同样,它可能不是最有效的实施(我不是一个朱莉娅大师),但它完成了这项工作。
对于你的例子:
julia> parents = {2=>[1,3],3=>[1],1=>[]}
julia> [(i, spath(i, parents, 1, [])) for i in keys(parents)]
3-element Array{Tuple{Any,Array{Any,1}},1}:
(2,Any[Any[1,3,2],Any[1,2]])
(3,Any[Any[1,3]])
(1,Any[Any[1]])