public void AddNode(Node node) { if(!_nodes.Contains(node)) { _nodes.Add(node); } }
public void Connect(Node source, Node target) { if (source.Equals(target)) return; //self reference is ignored AddNode(source); AddNode(target); var edge = new Edge(source, target); if (!_edges.Contains(edge)) { _edges.Add(edge); } }
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; }
public Edge(Node source, Node target) { //source depends on target Source = source; Target = target; }
public bool Equals(Node other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return Equals(other.Name, Name); }
public void Add(Node node) { _nodes.Add(node); }
void visit(Node node) { _graph.Remove(node); AddNode(node); }
void AddNode(Node node) { if(!_order.Contains(node)) { _order.Add(node); } }
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); } }
void Remove(Node node) { _nodes.Remove(node); _edges.RemoveWhere(e => e.Target.Equals(node)); }
IEnumerable<Node> GetTargetsForSource(Node node) { foreach (var edge in _edges) { if (edge.Source.Equals(node)) yield return edge.Target; } yield break; }