回答
您可以使用递归来计算树/ 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。
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的所有路径的数量。
由于这是一个DAG,您可以在O(V + E)时间内对拓扑进行拓扑排序。假设源顶点为S.然后从S开始以深度第一方式遍历节点。当我们处理节点U时,假设有一个边U-> V,那么V当然还没有被访问(为什么?因为它是一个有向无环图)所以你可以通过节点U在S到V达到d [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)的路径数的运行时间,这是迄今为止最有效的解决方案。
IT必须在相反的方向迭代拓扑排序列表? –
@ bones.felipe:不,从根到叶。 。 。 – Fallen
但是,例如,如果我有这个拓扑列表:0-2-1-3其中除了0-> 1和2-> 3之外,它计数5否? –
- 1. 拓扑排序
- 2. 拓扑使用排序DFS
- 3. 拓扑排序伪
- 4. 拓扑排序Neo4j
- 5. 拓扑排序(卡恩算法)麻烦
- 6. 拓扑排序寻找到的路径数量
- 7. 唯一拓扑排序意味着存在哈密顿路径
- 8. 为什么拓扑排序找到最短路径O(V + E)
- 9. 使用合金4.2的拓扑排序
- 10. 拓扑排序和循环
- 11. 拓扑排序变体
- 12. 稳定拓扑排序
- 13. 拓扑图排序java
- 14. 拓扑排序asm x86
- 15. 在算法中正确使用拓扑排序
- 16. 如何高效地计算树形拓扑中的路径长度?
- 17. 拓扑排序的C++实现
- 18. 排序(拓扑)maven依赖关系
- 19. 图表:拓扑排序,需要说明
- 20. 有向无环图的拓扑排序
- 21. Dummies的迭代/动态拓扑排序
- 22. 通过圆弧进行拓扑排序
- 23. 在Spark GraphX中实现拓扑排序
- 24. 拓扑层分离算法
- 25. 如何使用ArcMap或其他软件计算拓扑距离?
- 26. MPI虚拟拓扑设计
- 27. Chicken计划中的拓扑排序错误?
- 28. 拓扑为了使用BFS
- 29. 使用拓扑排序的打印(未检测)循环
- 30. 排序和拓扑排序有什么区别?
那么这是我做的第一件事,但它似乎太慢了。这就是我研究和发现这种拓扑排序的原因。 –
为什么拓扑排序可以帮助您计算路径?它旨在将非DAG转换为DAG,而不是简化计数。 – isaach1000
因为这个天真的递归在一些DAG上做了很多冗余的工作。如果你记忆,记忆表最终按照拓扑顺序构建。 –