public static DirectedEdgedGraph <T, E> Generate(T root, Func <T, IEnumerable <KeyValuePair <T, E> > > expandFunction, IEqualityComparer <T> comparer) { DirectedEdgedGraph <T, E> result = new DirectedEdgedGraph <T, E>(comparer); result.Expand(root, expandFunction); return(result); }
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 DirectedEdgedGraph <T, E> Inverse() { DirectedEdgedGraph <T, E> result = new DirectedEdgedGraph <T, E>(Comparer); foreach (var item in Nodes) { result.Add(item); foreach (var related in RelatedTo(item)) { result.Add(related.Key, item, related.Value); } } return(result); }
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); } }
public static E GetOrCreate <T, E>(this DirectedEdgedGraph <T, E> graph, T from, T to) where T : notnull where E : new() { var dic = graph.TryRelatedTo(from); if (dic != null) { return(dic.GetOrCreate(to)); } E newEdge = new E(); graph.Add(from, to, newEdge); return(newEdge); }
public DirectedEdgedGraph <T, E> WhereEdges(Func <Edge <T, E>, bool> condition, bool keepAllNodes) { if (keepAllNodes) { DirectedEdgedGraph <T, E> result = new DirectedEdgedGraph <T, E>(Comparer); foreach (var item in Nodes) { result.Add(item, RelatedTo(item).Where(to => condition(new Edge <T, E>(item, to.Key, to.Value)))); } return(result); } else { DirectedEdgedGraph <T, E> result = new DirectedEdgedGraph <T, E>(Comparer); foreach (var e in EdgesWithValue.Where(condition)) { result.Add(e.From, e.To, e.Value); } return(result); } }
internal void FillGraphs() { var graph = new DirectedEdgedGraph <IWorkflowNodeEntity, HashSet <WorkflowConnectionEntity> >(); foreach (var e in this.Events.Values) { graph.Add(e); } foreach (var a in this.Activities.Values) { graph.Add(a); } foreach (var g in this.Gateways.Values) { graph.Add(g); } foreach (var c in this.Connections.Values) { graph.GetOrCreate(c.From, c.To).Add(c); } this.NextGraph = graph; this.PreviousGraph = graph.Inverse(); }
public static DirectedEdgedGraph <string, string> ToDirectedGraph() { DirectedEdgedGraph <string, string> result = new DirectedEdgedGraph <string, string>(); void Add(string from, string to, OperationSymbol key) { Dictionary <string, string> dic = result.TryRelatedTo(from); if (dic == null || !dic.ContainsKey(to)) { result.Add(from, to, key.ToString()); } else { result.Add(from, to, dic[to] + ", " + key.ToString()); } } foreach (var item in OperationLogic.GraphOperations <T, S>()) { switch (item.OperationType) { case OperationType.Execute: { Execute gOp = (Execute)item; foreach (var f in gOp.FromStates) { foreach (var t in gOp.ToStates) { Add(f !.ToString() !, t !.ToString() !, item.OperationSymbol); } } } break; case OperationType.Delete: { Delete dOp = (Delete)item; foreach (var f in dOp.FromStates) { Add(f !.ToString() !, "[Deleted]", item.OperationSymbol); } } break; case OperationType.Constructor: case OperationType.ConstructorFrom: case OperationType.ConstructorFromMany: { string from = item.OperationType == OperationType.Constructor ? "[New]" : item.OperationType == OperationType.ConstructorFrom ? "[From {0}]".FormatWith(item.GetType().GetGenericArguments()[2].TypeName()) : item.OperationType == OperationType.ConstructorFromMany ? "[FromMany {0}]".FormatWith(item.GetType().GetGenericArguments()[2].TypeName()) : ""; var dtoState = (IGraphToStateOperation)item; foreach (var t in dtoState.ToStates) { Add(from, t !.ToString() !, item.OperationSymbol); } } break; } } return(result); }
public DirectedEdgedGraph <Table, RelationInfo> ToDirectedGraph() { return(DirectedEdgedGraph <Table, RelationInfo> .Generate(Tables.Values, t => t.DependentTables())); }
/// <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.MinMaxBy(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); }