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