来自https://algs4.cs.princeton.edu/42digraph/
- 最短的有向环。给定有向图,设计一种算法以找到边数最少的有向环(或报告 该图是非循环的)。算法的运行时间应为 在最坏的情况下与E V成正比。
可以在这里找到解决方案:https://algs4.cs.princeton.edu/42digraph/ShortestDirectedCycle.java.html
public ShortestDirectedCycle(Digraph G) {
Digraph R = G.reverse();
length = G.V() + 1;
for (int v = 0; v < G.V(); v++) {
BreadthFirstDirectedPaths bfs = new BreadthFirstDirectedPaths(R, v);
for (int w : G.adj(v)) {
if (bfs.hasPathTo(w) && (bfs.distTo(w) + 1) < length) {
length = bfs.distTo(w) + 1;
cycle = new Stack<Integer>();
for (int x : bfs.pathTo(w))
cycle.push(x);
cycle.push(v);
}
}
}
}
该解决方案对我来说很有意义,除了第一行G.reverse()
。为什么?它与拓扑排序有关吗?
在SO上有很多关于在Digraph中查找所有循环的问题,但是我假设有一种比找到所有循环并比较它们的长度更好的方法。关于寻找最短的定向周期,存在一些问题,但是没有一个可以接受的答案。
How can I find the shortest cycle in a Directed, Weighted Graph?
Find the Shortest Cycle in Graph
Finding shortest cycles in directed or undirected graph(此为无向图)
我还发现了一个使用BFS的paper,但是显示的伪代码不能用于重构路径,只能找到最短周期的长度。
答案 0 :(得分:1)
G.reverse()
是有向图,它与G
相同,只是每个边都相反;因此,例如,如果G
的边缘从v
到w
,则G.reverse()
的边缘从w
到v
。 / p>
由于bfs
是从G.reverse()
和v
提取的,所以bfs.hasPathTo(w)
的意思是“ G
是否具有路径 from {{ 1}} 至 w
”,而v
的意思是“ bfs.distTo(w)
从G
到w
的路径长度” 。 (如果从v
而不是bfs
提取G
,它将检测到相反的路径。)
因此,它使用的循环查找算法是:对于G.reverse()
中的每个边(v
,w
),测试G
是否具有从{{1 }}返回G
。
不涉及拓扑排序。