コード例 #1
0
        public IReadOnlyList <TNode> FindReachable(TNode initialNode,
                                                   ProgressReporterCallback?progressReporter = null)
        {
            var visitedNodes = new HashSet <NodeWithPredecessor>(_comparer);
            var initial      = new NodeWithPredecessor(initialNode);
            var nextNodes    = new HashSet <NodeWithPredecessor>(_comparer)
            {
                initial
            };

            while (nextNodes.Count > 0)
            {
                progressReporter?.Invoke(visitedNodes.Count, nextNodes.Count);
                visitedNodes.UnionWith(nextNodes);

                var expanded = SequentialExpandTuple(nextNodes, visitedNodes).ToList();

                nextNodes.Clear();
                foreach (var(pred, nodes) in expanded)
                {
                    var successorNodes = nodes.ToList();
                    if (successorNodes.Any())
                    {
                        nextNodes.UnionWith(successorNodes);
                    }
                }
            }

            return(visitedNodes.Select(n => n.Item).ToList());
        }
コード例 #2
0
        public IList <IPath <TNode> > FindAll2(TNode initialNode,
                                               Func <NodeWithPredecessor, bool> targetPredicate,
                                               ProgressReporterCallback?progressReporter = null,
                                               int minResults = int.MaxValue)
        {
            if (targetPredicate == null)
            {
                throw new ArgumentNullException(nameof(targetPredicate), "A meaningful targetPredicate must be provided");
            }

            var visitedNodes = new HashSet <NodeWithPredecessor>(_comparer);
            var initial      = new NodeWithPredecessor(initialNode);
            var nextNodes    = new HashSet <NodeWithPredecessor>(_comparer)
            {
                initial
            };
            var results = new List <IPath <TNode> >();

            var expander = PerformParallelSearch
                ? (Func <IEnumerable <NodeWithPredecessor>, IEnumerable <NodeWithPredecessor> >)(n =>
                                                                                                 ParallelExpand(n, visitedNodes))
                : n => SequentialExpand(n, visitedNodes);

            if (targetPredicate(initial))
            {
                results.Add(new BfsPath(initialNode));
            }


            while (nextNodes.Count > 0)
            {
                progressReporter?.Invoke(visitedNodes.Count, nextNodes.Count);

                visitedNodes.UnionWith(nextNodes);

                var expanded = expander(nextNodes);
                nextNodes = new HashSet <NodeWithPredecessor>(expanded, _comparer);

                foreach (var node in nextNodes)
                {
                    if (targetPredicate(node))
                    {
                        results.Add(new BfsPath(node));
                    }
                }

                if (results.Count >= minResults)
                {
                    break;
                }
            }

            return(results);
        }
コード例 #3
0
        public IList <IPath <TNode, TEdge> > FindAll(TNode initialNode,
                                                     Func <TNode, bool> targetPredicate,
                                                     ProgressReporterCallback progressReporter = null,
                                                     int minResults = int.MaxValue)
        {
            var visitedNodes = new HashSet <NodeWithPredecessor>(_comparer);
            var nextNodes    = new HashSet <NodeWithPredecessor>(_comparer)
            {
                new NodeWithPredecessor(initialNode)
            };

            var results = new List <IPath <TNode, TEdge> >();

            if (targetPredicate(initialNode))
            {
                results.Add(new BfsPath(initialNode));
            }

            while (nextNodes.Count > 0)
            {
                progressReporter?.Invoke(visitedNodes.Count, nextNodes.Count);

                visitedNodes.UnionWith(nextNodes);

                var expanded = nextNodes.AsParallel()
                               .SelectMany(sourceNode => _expander(sourceNode.Current)
                                           .Select(dest => new NodeWithPredecessor(dest, sourceNode))
                                           .Where(dest => !visitedNodes.Contains(dest)));

                nextNodes = new HashSet <NodeWithPredecessor>(expanded, _comparer);

                foreach (var node in nextNodes)
                {
                    if (targetPredicate(node.Current))
                    {
                        results.Add(new BfsPath(node));
                    }
                }

                if (results.Count >= minResults)
                {
                    break;
                }
            }

            return(results);
        }
コード例 #4
0
        public IList <IPath <TNode> > FindLeafs(TNode initialNode,
                                                ProgressReporterCallback?progressReporter = null,
                                                int minResults = int.MaxValue)
        {
            var visitedNodes = new HashSet <NodeWithPredecessor>(_comparer);
            var initial      = new NodeWithPredecessor(initialNode);
            var nextNodes    = new HashSet <NodeWithPredecessor>(_comparer)
            {
                initial
            };
            var results = new List <IPath <TNode> >();

            while (nextNodes.Count > 0)
            {
                progressReporter?.Invoke(visitedNodes.Count, nextNodes.Count);
                visitedNodes.UnionWith(nextNodes);

                var expanded = SequentialExpandTuple(nextNodes, visitedNodes).ToList();

                nextNodes.Clear();
                foreach (var(pred, nodes) in expanded)
                {
                    var successorNodes = nodes.ToList();
                    if (successorNodes.Any())
                    {
                        nextNodes.UnionWith(successorNodes);
                    }
                    else
                    {
                        results.Add(new BfsPath(pred));
                    }
                }

                if (results.Count >= minResults)
                {
                    break;
                }
            }

            return(results);
        }