我有一个DAG,我需要计算从任何节点到另一个节点的所有路径,我已经研究了一点,我发现它可以用一些拓扑顺序完成,但到目前为止解决方案是不完整的或错误。
那么如何正确地做到这一点?。
感谢。
答案 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的所有路径的数量。