コード例 #1
0
        /// <summary>
        ///     Determines whether the <see cref="GraphSet{T}" /> is cyclic.
        /// </summary>
        /// <typeparam name="T">type of element</typeparam>
        /// <param name="set">The set.</param>
        /// <returns>
        ///     <c>true</c> if the specified set is cyclic; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsCyclic <T>(this GraphSet <T> set)
        {
            var heads = set.GetNodes().Where(x => x.Parents.Count == 0).ToList();

            if (heads.Count == 0)
            {
                return(true);
            }
            var markedHeads = heads.Select(x => new MarkedNode <T>(x, new HashSet <GraphNode <T> >().ToIHashSet()));
            var stack       = new Stack <MarkedNode <T> >(markedHeads);

            while (stack.Any())
            {
                var node = stack.Pop();
                if (node.MarkingSet.Contains(node.Node))
                {
                    return(true);
                }
                node.MarkingSet.Add(node.Node);
                foreach (var child in node.Node.Children)
                {
                    stack.Push(new MarkedNode <T>(child, node.MarkingSet.Clone()));
                }
            }
            return(false);
        }
コード例 #2
0
        /// <summary>
        ///     Transform a <see cref="GraphSet{T}" /> to <see cref="GraphSet{TX}" />.
        /// </summary>
        /// <typeparam name="T">the type of element</typeparam>
        /// <typeparam name="TX">The type of element of the new <see cref="GraphSet{T}" />.</typeparam>
        /// <param name="enumerable">The enumerable.</param>
        /// <param name="func">The function.</param>
        /// <returns>new <see cref="GraphSet{T}" /></returns>
        public static GraphSet <TX> ToGraphSet <T, TX>(this IEnumerable <GraphNode <T> > enumerable, Func <T, TX> func)
        {
            var nodes      = enumerable.ToArray();
            var dictionary = new Dictionary <GraphNode <T>, GraphNode <TX> >();
            var graphSet   = new GraphSet <TX>();

            foreach (var item in nodes)
            {
                var node = graphSet.Add(func(item.Value));
                dictionary[item] = node;
            }
            foreach (var item in nodes)
            {
                var currentNode = dictionary[item];
                foreach (var child in item.Children)
                {
                    var childNode = dictionary[child];
                    currentNode.AddChild(childNode);
                }
                foreach (var parent in item.Parents)
                {
                    var parentNode = dictionary[parent];
                    currentNode.AddParent(parentNode);
                }
            }
            return(graphSet);
        }
コード例 #3
0
 internal GraphNode(GraphSet <T> set, T value)
 {
     _set      = set;
     _parents  = new HashSet <GraphNode <T> >();
     _children = new HashSet <GraphNode <T> >();
     Value     = value;
     set.Add(this);
 }
コード例 #4
0
        /// <summary>
        ///     ContinueWith specified <see cref="Action{T}" /> on each <see cref="Task" /> on the GraphSet
        /// </summary>
        /// <typeparam name="T">Type of the elements</typeparam>
        /// <param name="set">The set.</param>
        /// <param name="action">The action.</param>
        /// <returns><see cref="GraphSet{TaskPair}" /> with continuation tasks.</returns>
        /// <exception cref="System.InvalidOperationException">Cannot process task on a cyclic graph</exception>
        public static GraphSet <TaskPair <T> > ContinueWith <T>(this GraphSet <TaskPair <T> > set, Action <T> action)
        {
            if (set.IsCyclic())
            {
                throw new InvalidOperationException("Cannot process task on a cyclic graph");
            }
            var tasks   = new Dictionary <GraphNode <TaskPair <T> >, Task>();
            var taskSet = set.ToGraphSet(x => new TaskPair <T>(x.Value)
            {
                Task = x.Task
            });

            foreach (var node in taskSet.GetNodes())
            {
                tasks[node]     = node.Value.Task;
                node.Value.Task = null;
            }
            var nodes = taskSet.GetNodes().Where(n => n.Parents.Count == 0).ToArray();

            foreach (var node in nodes)
            {
                node.Value.Task = tasks[node].ContinueWith(t => action(node.Value.Value));
            }
            var queue = new Queue <GraphNode <TaskPair <T> > >(nodes);

            while (queue.Any())
            {
                var node = queue.Dequeue();
                if (node.Value.Task == null)
                {
                    var allParentsHaveTask = node.Parents.All(x => x.Value.Task != null);
                    if (allParentsHaveTask)
                    {
                        var list = node.Parents.Select(x => x.Value.Task).ToList();
                        list.Add(tasks[node]);
                        node.Value.Task = Task.Factory.ContinueWhenAll(
                            list.ToArray(),
                            x => action(node.Value.Value));
                    }
                    queue.Enqueue(node);
                }
                else
                {
                    foreach (var child in node.Children)
                    {
                        if (child.Value.Task == null)
                        {
                            queue.Enqueue(child);
                        }
                    }
                }
            }
            return(taskSet);
        }
コード例 #5
0
        /// <summary>
        ///     Gets the when all task on a GraphSet of TaskPair
        /// </summary>
        /// <typeparam name="T">type of elements</typeparam>
        /// <param name="set">The set.</param>
        /// <returns>task</returns>
        public static Task GetWhenAllTask <T>(this GraphSet <TaskPair <T> > set)
        {
            var list = new List <Task>();

            foreach (var x in set.GetNodes())
            {
                list.Add(x.Value.Task);
            }
            var array = list.ToArray();

            return(Task.Factory.ContinueWhenAll(array, tasks => { }));
        }
コード例 #6
0
        /// <summary>
        ///     ContinueWith specified <see cref="Action{T}" /> on the leaves of the GraphSet.
        /// </summary>
        /// <typeparam name="T">Type of the elements</typeparam>
        /// <param name="set">The set.</param>
        /// <param name="action">The action.</param>
        /// <returns><see cref="GraphSet{TaskPair}" /> with continuation tasks.</returns>
        /// <exception cref="System.InvalidOperationException">Cannot process task on a cyclic graph</exception>
        public static GraphSet <TaskPair <T> > ContinueOnLeavesWith <T>(this GraphSet <TaskPair <T> > set, Action <T> action)
        {
            if (set.IsCyclic())
            {
                throw new InvalidOperationException("Cannot process task on a cyclic graph");
            }
            var taskSet = set.ToGraphSet(x => new TaskPair <T>(x.Value)
            {
                Task = x.Task
            });
            var graphNodes = taskSet.GetNodes().Where(x => x.Children.Count == 0);

            foreach (var node in graphNodes)
            {
                node.Value.Task = node.Value.Task.ContinueWith(x => action(node.Value.Value));
            }
            return(taskSet);
        }
コード例 #7
0
        /// <summary>
        ///     Transforms a <see cref="GraphSet{T}" /> to a GraphSet of Task executing the <see cref="Action{T}" /> on
        ///     each of the nodes while respecting the graph order.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="set">The set.</param>
        /// <param name="action">The action.</param>
        /// <returns>
        ///     <see cref="GraphSet{TaskPair}" />
        /// </returns>
        /// <exception cref="System.InvalidOperationException">Cannot process task on a cyclic graph</exception>
        public static GraphSet <TaskPair <T> > ToTaskGraph <T>(this GraphSet <T> set, Action <T> action)
        {
            if (set.IsCyclic())
            {
                throw new InvalidOperationException("Cannot process task on a cyclic graph");
            }
            var taskSet = set.ToGraphSet(x => new TaskPair <T>(x));
            var nodes   = taskSet.GetNodes().Where(n => n.Parents.Count == 0).ToArray();

            foreach (var node in nodes)
            {
                node.Value.Task = Task.Factory.StartNew(() => { action(node.Value.Value); });
            }
            var queue = new Queue <GraphNode <TaskPair <T> > >(nodes);

            while (queue.Any())
            {
                var node = queue.Dequeue();
                if (node.Value.Task == null)
                {
                    var allParentsHaveTask = node.Parents.All(x => x.Value.Task != null);
                    if (allParentsHaveTask)
                    {
                        node.Value.Task = Task.Factory.ContinueWhenAll(
                            node.Parents.Select(x => x.Value.Task).ToArray(),
                            x => { action(node.Value.Value); });
                    }
                    queue.Enqueue(node);
                }
                else
                {
                    foreach (var child in node.Children)
                    {
                        if (child.Value.Task == null)
                        {
                            queue.Enqueue(child);
                        }
                    }
                }
            }
            return(taskSet);
        }
コード例 #8
0
ファイル: GraphSet.cs プロジェクト: leoxialtd/Leoxia.Core
 /// <summary>
 ///     Initializes a new instance of the <see cref="GraphSet{T}" /> class.
 /// </summary>
 /// <param name="set">The set.</param>
 public GraphSet(GraphSet <T> set) : this(set._nodes, x => true)
 {
 }
コード例 #9
0
 /// <summary>
 ///     Get a <see cref="GraphSet{T}" /> with only elements
 ///     satisfying the <see cref="Predicate{T}" />
 /// </summary>
 /// <typeparam name="T">the type of elements</typeparam>
 /// <param name="set">The set.</param>
 /// <param name="predicate">The predicate.</param>
 /// <returns>new filtered <see cref="GraphSet{T}" /></returns>
 public static GraphSet <T> Filter <T>(this GraphSet <T> set, Predicate <T> predicate)
 {
     return(new GraphSet <T>(set.GetNodes().Where(x => predicate(x.Value)), predicate));
 }
コード例 #10
0
        /// <summary>
        ///     Get the task corresponding to application of <see cref="Action{T}" /> on all nodes of
        ///     the <see cref="GraphSet{T}" />
        /// </summary>
        /// <typeparam name="T">type of the elements</typeparam>
        /// <param name="set">The set.</param>
        /// <param name="action">The action.</param>
        /// <returns>task</returns>
        public static Task ToTask <T>(this GraphSet <T> set, Action <T> action)
        {
            var taskSet = set.ToTaskGraph(action);

            return(GetWhenAllTask(taskSet));
        }