perf: BreadthFirstSearchPathManyDestinations returns an IEnumerable to support early termination

This commit is contained in:
Chris Cameron
2018-10-08 14:21:54 -04:00
parent 2a25c3d733
commit 381355beb9
2 changed files with 16 additions and 11 deletions

View File

@@ -180,9 +180,11 @@ namespace ICD.Common.Utils.Tests
{
Assert.Throws<ArgumentNullException>(() => RecursionUtils.BreadthFirstSearchManyDestinations(1, new[] { 1 }, null));
Assert.Throws<ArgumentNullException>(() => RecursionUtils.BreadthFirstSearchManyDestinations(1, null, Graph));
Assert.IsEmpty(RecursionUtils.BreadthFirstSearchManyDestinations(1, new[] { 5 }, Graph));
Assert.AreEqual(0, RecursionUtils.BreadthFirstSearchManyDestinations(1, new[] { 5 }, Graph).Count());
Dictionary<int, IEnumerable<int>> paths = RecursionUtils.BreadthFirstSearchManyDestinations(1, new[] { 21, 22, 31, 43, 62 }, WideGraph);
Dictionary<int, IEnumerable<int>> paths =
RecursionUtils.BreadthFirstSearchManyDestinations(1, new[] {21, 22, 31, 43, 62}, WideGraph)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
//Make sure all paths were found
Assert.IsTrue(paths.Keys.Contains(21));

View File

@@ -235,12 +235,16 @@ namespace ICD.Common.Utils
return null;
}
[NotNull]
public static Dictionary<T, IEnumerable<T>> BreadthFirstSearchManyDestinations<T>(T root,
public static IEnumerable<KeyValuePair<T, IEnumerable<T>>> BreadthFirstSearchManyDestinations<T>(T root,
IEnumerable<T> destinations,
Func<T, IEnumerable<T>>
getChildren)
{
if (destinations == null)
throw new ArgumentNullException("destinations");
if (getChildren == null)
throw new ArgumentNullException("getChildren");
@@ -248,7 +252,7 @@ namespace ICD.Common.Utils
}
[NotNull]
public static Dictionary<T, IEnumerable<T>> BreadthFirstSearchPathManyDestinations<T>(T root,
public static IEnumerable<KeyValuePair<T, IEnumerable<T>>> BreadthFirstSearchPathManyDestinations<T>(T root,
IEnumerable<T>
destinations,
Func<T, IEnumerable<T>>
@@ -272,12 +276,12 @@ namespace ICD.Common.Utils
foreach (T destination in
destinationsToBeProcessed.Where(destination => comparer.Equals(root, destination)).ToArray())
{
destinationsToBeProcessed.Remove(destination);
pathsToReturn.Add(destination, new[] {root});
destinationsToBeProcessed.Remove(destination);
yield return new KeyValuePair<T, IEnumerable<T>>(destination, new[] {root});
}
if (destinationsToBeProcessed.Count == 0)
return pathsToReturn;
yield break;
Queue<T> queue = new Queue<T>();
queue.Enqueue(root);
@@ -298,15 +302,14 @@ namespace ICD.Common.Utils
destinationsToBeProcessed.Where(destination => comparer.Equals(closureNode, destination)).ToArray())
{
destinationsToBeProcessed.Remove(destination);
pathsToReturn.Add(destination, GetPath(destination, root, nodeParents, comparer).Reverse());
yield return new KeyValuePair<T, IEnumerable<T>>(destination, GetPath(destination, root, nodeParents, comparer).Reverse());
}
if (destinationsToBeProcessed.Count == 0)
return pathsToReturn;
break;
}
}
return pathsToReturn;
}
/// <summary>