public DirectedGraph Clone() { var result = new DirectedGraph(); foreach (var node in _nodes) { var newNode = new Node(node.Name); result.AddNode(newNode); } foreach (var edge in _edges) { result.Connect(edge.Source.Name, edge.Target.Name); } return result; }
void tarjan(Node v, DirectedGraph graph) { v.SetIndex(_index); v.SetLowLink(_index); _index++; _stack.Push(v); foreach (var n in graph.GetTargetsForSource(v)) { if (n.Index == -1) { tarjan(n, graph); var lowLink = Math.Min(v.LowLink, n.LowLink); v.SetLowLink(lowLink); } else if (_stack.Contains(n)) { var lowLink = Math.Min(v.LowLink, n.Index); v.SetLowLink(lowLink); } } if(v.LowLink == v.Index) { var cycle = new Cycle(); Node n; do { n = _stack.Pop(); cycle.Add(n); } while (!v.Equals(n)); _cycles.Add(cycle); } }
public IEnumerable<Node> Order(DirectedGraph graph) { _graph = graph.Clone(); while(!_graph.IsEmpty()) { var nodes = _graph.GetEntryNodes(); foreach (var node in nodes) { visit(node); } } return _order; }
public IEnumerable<Cycle> FindCycles(DirectedGraph graph) { foreach (var node in graph._nodes) tarjan(node, graph); return _cycles; }