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);
     }
 }
Beispiel #8
0
    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();
    }
Beispiel #9
0
        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);
        }
Beispiel #10
0
 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);
    }