使用拓扑排序计算路径

时间:2013-07-15 01:58:49

标签: algorithm dynamic graph topological-sort

我有一个DAG,我需要计算从任何节点到另一个节点的所有路径,我已经研究了一点,我发现它可以用一些拓扑顺序完成,但到目前为止解决方案是不完整的或错误。

那么如何正确地做到这一点?。

感谢。

3 个答案:

答案 0 :(得分:2)

由于这是一个DAG,您可以在O(V + E)时间拓扑排序节点。假设源顶点是S.然后从S开始以深度第一方式遍历节点。当我们处理节点U时,让我们假设有一个边U-> V然后V当然还没有被访问(为什么?因为它是一个有向无环图)所以你可以通过节点U从S到达V [ U]方式,其中d [U]是从S到U的路径数。

因此从S到任何节点V的路径数量,d [V] = d [x1] + d [x2] + d [x3] +。 。 。 + d [xy],其中存在像x1-> V,x2-> V的边缘。 。 。 XY-> V

该算法将采用O(V + E)对图进行拓扑排序,然后计算最多O(V * E)的路径数。您可以使用邻接列表而不是邻接矩阵来进一步减少计算O(V + E)路径数的运行时间,这是迄今为止最有效的解决方案。

答案 1 :(得分:1)

您可以使用递归来计算树/ DAG中的所有路径。这是伪代码:

function numPaths(node1, node2):
    // base case, one path from node to itself
    if (node1 == node2): return 1

    totalPaths = 0
    for edge in node1.edges:
        nextNode = edge.destinationNode
        totalPaths += numPaths(nextNode, node2)

    return totalPaths

修改 这个问题的一个很好的动态方法是Floyd-Warshall algorithm

答案 2 :(得分:1)

Assume G(V,E)
Let d[i][j] = the number of all the paths from i to j
Then d[i][j]= sigma d[next][j] for all (i,next) in E

看起来太慢了?好的。记住它(有些人称之为动态编程)。喜欢这个

memset(d,-1,sizeof(d))// set all of elements of array d to -1 at the very beginning
saya(int i,int j)
{
    if (d[i][j]!=-1) return d[i][j];//d[i][j] has been calculated
    if (i==j) return d[i][j]=1;//trivival cases
    d[i][j]=0;
    for e in i.edges
        d[i][j]+=saya(e.next,j);
    return d[i][j];
}

现在saya(i,j)将返回从i到j的所有路径的数量。