【发布时间】:2011-07-10 18:37:24
【问题描述】:
这是 tarjan 循环检测的有效 C# 实现。
算法在这里找到: http://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
public class TarjanCycleDetect
{
private static List<List<Vertex>> StronglyConnectedComponents;
private static Stack<Vertex> S;
private static int index;
private static DepGraph dg;
public static List<List<Vertex>> DetectCycle(DepGraph g)
{
StronglyConnectedComponents = new List<List<Vertex>>();
index = 0;
S = new Stack<Vertex>();
dg = g;
foreach (Vertex v in g.vertices)
{
if (v.index < 0)
{
strongconnect(v);
}
}
return StronglyConnectedComponents;
}
private static void strongconnect(Vertex v)
{
v.index = index;
v.lowlink = index;
index++;
S.Push(v);
foreach (Vertex w in v.dependencies)
{
if (w.index < 0)
{
strongconnect(w);
v.lowlink = Math.Min(v.lowlink, w.lowlink);
}
else if (S.Contains(w))
{
v.lowlink = Math.Min(v.lowlink, w.index);
}
}
if (v.lowlink == v.index)
{
List<Vertex> scc = new List<Vertex>();
Vertex w;
do
{
w = S.Pop();
scc.Add(w);
} while (v != w);
StronglyConnectedComponents.Add(scc);
}
}
注意 DepGraph 只是一个顶点列表。并且 Vertex 有一个代表边缘的其他 Vertex 列表。 index 和 lowlink 也被初始化为 -1
编辑:这是有效的......我只是误解了结果。
【问题讨论】:
-
为什么是`v.lowlink = Math.Min(v.lowlink, w.index)`而不是
v.lowlink = Math.Min(v.lowlink, w.lowlink)? -
@LinMa 无论从技术上来说都是正确的。
-
此算法不适用于字符串值。我必须在项目及其依赖项中找到循环依赖项。需要进行任何更改才能使其正常工作?
标签: c# algorithm cycle directed-graph tarjans-algorithm