示例#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> > 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);
        }
示例#4
0
 public NodeWithPredecessor(TNode current, NodeWithPredecessor predecessor = null)
 {
     Predecessor = predecessor;
     Current     = current;
 }
示例#5
0
 public BfsPath(NodeWithPredecessor target)
 {
     Target = target.Current;
     Steps  = target.GetHistory().Reverse().ToArray();
     Length = Steps.Length - 1;
 }