public void UnionWith(DirectedEdgedGraph <T, E> other) { foreach (var item in other.Nodes) { Add(item, other.RelatedTo(item)); } }
public static void RemoveFullNodeSymetric(DirectedEdgedGraph <T, E> original, DirectedEdgedGraph <T, E> inverse, T node) { var from = inverse.RelatedTo(node).Keys; var to = original.RelatedTo(node).Keys; original.RemoveFullNode(node, from); inverse.RemoveFullNode(node, to); }
public IEnumerable <HashSet <T> > CompilationOrderGroups() { DirectedEdgedGraph <T, E> clone = this.Clone(); DirectedEdgedGraph <T, E> inv = this.Inverse(); while (clone.Count > 0) { var leaves = clone.Sinks(); foreach (var node in leaves) { clone.RemoveFullNode(node, inv.RelatedTo(node).Keys); } yield return(leaves); } }
/// <summary> /// A simple but effective linear-time heuristic constructs a vertex ordering, /// just as in the topological sort heuristic above, and deletes any arc going from right to left. /// /// This heuristic builds up the ordering from the outside in based on the in- and out-degrees of each vertex. /// - Any vertex of in-degree 0 is a source and can be placed first in the ordering. /// - Any vertex of out-degree 0 is a sink and can be placed last in the ordering, again without violating any constraints. /// - If not, we find the vertex with the maximum difference between in- and out-degree, /// and place it on the side of the permutation that will salvage the greatest number of constraints. /// Delete any vertex from the DAG after positioning it and repeat until the graph is empty. /// </summary> /// <returns></returns> public DirectedEdgedGraph <T, E> FeedbackEdgeSet() { DirectedEdgedGraph <T, E> result = new DirectedEdgedGraph <T, E>(Comparer); DirectedEdgedGraph <T, E> clone = this.Clone(); DirectedEdgedGraph <T, E> inv = this.Inverse(); HashSet <T> head = new HashSet <T>(); // for sources HashSet <T> tail = new HashSet <T>(); // for sinks while (clone.Count > 0) { var sinks = clone.Sinks(); if (sinks.Count() != 0) { foreach (var sink in sinks) { DirectedEdgedGraph <T, E> .RemoveFullNodeSymetric(clone, inv, sink); tail.Add(sink); } continue; } var sources = inv.Sinks(); if (sources.Count() != 0) { foreach (var source in sources) { DirectedEdgedGraph <T, E> .RemoveFullNodeSymetric(clone, inv, source); head.Add(source); } continue; } Func <T, int> fanInOut = n => clone.RelatedTo(n).Count() - inv.RelatedTo(n).Count(); MinMax <T> mm = clone.WithMinMaxPair(fanInOut); if (fanInOut(mm.Max) > -fanInOut(mm.Min)) { T node = mm.Max; foreach (var n in inv.RelatedTo(node)) { result.Add(n.Key, node, n.Value); } DirectedEdgedGraph <T, E> .RemoveFullNodeSymetric(clone, inv, node); head.Add(node); } else { T node = mm.Min; foreach (var n in clone.RelatedTo(node)) { result.Add(node, n.Key, n.Value); } DirectedEdgedGraph <T, E> .RemoveFullNodeSymetric(clone, inv, node); head.Add(node); } } return(result); }