Julia:从Graphs.jl中的Dijkstra函数获取整个路径

时间:2016-03-31 19:20:48

标签: algorithm julia dijkstra

是否有可能使用Graphs.jl模块中的Dijkstra algorithm从源顶点到目标顶点获取整个路径?

当更新到顶点的距离时,会调用 update_vertex!(visitor,u,v,d)方法。仅当找到属于最短路径的新顶点时才更新距离?我不太确定。

感谢。

修改

根据文档,有可能使用Floyd-Warshall algorithm使用属性 dists nexts 重建最短路径,但我不确定如何。我想在 GenericGraph 上运行它。

有什么想法吗?

1 个答案:

答案 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]])