diff --git a/Graph/DirectedGraph.cs b/Graph/DirectedGraph.cs index 19e241b..fa267ff 100644 --- a/Graph/DirectedGraph.cs +++ b/Graph/DirectedGraph.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Collections.Pooled; namespace MoonTools.Core.Graph { @@ -80,13 +81,11 @@ namespace MoonTools.Core.Graph return neighbors[node].Count; } - readonly List<(TNode, TNode)> edgesToRemove = new List<(TNode, TNode)>(); - public void RemoveNode(TNode node) { CheckNodes(node); - edgesToRemove.Clear(); + var edgesToRemove = new PooledList<(TNode, TNode)>(ClearMode.Always); foreach (var entry in neighbors) { @@ -101,6 +100,8 @@ namespace MoonTools.Core.Graph RemoveEdge(edge.Item1, edge.Item2); } + edgesToRemove.Dispose(); + nodes.Remove(node); neighbors.Remove(node); } @@ -149,13 +150,10 @@ namespace MoonTools.Core.Graph return neighbors[node]; } - readonly Stack dfsStack = new Stack(); - readonly HashSet dfsDiscovered = new HashSet(); - public IEnumerable PreorderNodeDFS() { - dfsStack.Clear(); - dfsDiscovered.Clear(); + var dfsStack = new PooledStack(ClearMode.Always); + var dfsDiscovered = new PooledSet(ClearMode.Always); foreach (var node in Nodes) { @@ -177,75 +175,49 @@ namespace MoonTools.Core.Graph } } } + + dfsStack.Dispose(); + dfsDiscovered.Dispose(); } - // public IEnumerable PostorderNodeDFS() - // { - // dfsStack.Clear(); - // dfsDiscovered.Clear(); + private IEnumerable PostorderNodeDFSHelper(PooledSet discovered, TNode v) + { + discovered.Add(v); - // foreach (var node in Nodes) - // { - // if (!dfsDiscovered.Contains(node)) - // { - // dfsStack.Push(node); - // while (dfsStack.Count > 0) - // { - // var current = dfsStack.Pop(); - // if (!dfsDiscovered.Contains(current)) - // { - // dfsDiscovered.Add(current); - // foreach (var neighbor in Neighbors(current)) - // { - // dfsStack.Push(neighbor); - // } - // yield return current; - // } - // } - // } - // } - // } + foreach (var neighbor in Neighbors(v)) + { + if (!discovered.Contains(neighbor)) + { + foreach (var node in PostorderNodeDFSHelper(discovered, neighbor)) + { + yield return node; + } + } + } - List postorderOutput = new List(); + yield return v; + } public IEnumerable PostorderNodeDFS() { - dfsDiscovered.Clear(); - postorderOutput.Clear(); - - void dfsHelper(TNode v) // refactor this to remove closure - { - dfsDiscovered.Add(v); - - foreach (var neighbor in Neighbors(v)) - { - if (!dfsDiscovered.Contains(neighbor)) - { - dfsHelper(neighbor); - } - } - - postorderOutput.Add(v); - } + var dfsDiscovered = new PooledSet(ClearMode.Always); foreach (var node in Nodes) { if (!dfsDiscovered.Contains(node)) { - dfsHelper(node); + foreach (var thing in PostorderNodeDFSHelper(dfsDiscovered, node)) + { + yield return thing; + } } } - - return postorderOutput; } - readonly Queue bfsQueue = new Queue(); - readonly HashSet bfsDiscovered = new HashSet(); - public IEnumerable NodeBFS() { - bfsQueue.Clear(); - bfsDiscovered.Clear(); + var bfsQueue = new PooledQueue(ClearMode.Always); + var bfsDiscovered = new PooledSet(ClearMode.Always); foreach (var node in Nodes) { @@ -267,49 +239,54 @@ namespace MoonTools.Core.Graph } } } + + bfsQueue.Dispose(); + bfsDiscovered.Dispose(); } - // hoo boy this is bad for the GC + List> lexicographicSets = new List>(); + HashSet> replacedSets = new HashSet>(); + public IEnumerable LexicographicBFS() { - var sets = new List>(); - sets.Add(Nodes.ToList()); + lexicographicSets.Add(Nodes.ToPooledSet()); - while (sets.Count > 0) + while (lexicographicSets.Count > 0) { - var firstSet = sets[0]; - var node = firstSet[0]; - firstSet.RemoveAt(0); - if (firstSet.Count == 0) { sets.RemoveAt(0); } + var firstSet = lexicographicSets[0]; + var node = firstSet.First(); + firstSet.Remove(node); + if (firstSet.Count == 0) { lexicographicSets.RemoveAt(0); } yield return node; - var replaced = new List>(); - foreach (var neighbor in Neighbors(node)) { - if (sets.Any(set => set.Contains(neighbor))) + if (lexicographicSets.Any(set => set.Contains(neighbor))) { - var s = sets.Find(set => set.Contains(neighbor)); - var sIndex = sets.IndexOf(s); - List t; - if (replaced.Contains(s)) + var s = lexicographicSets.Find(set => set.Contains(neighbor)); + var sIndex = lexicographicSets.IndexOf(s); + PooledSet t; + if (replacedSets.Contains(s) && sIndex > 0) { - t = sets[sIndex - 1]; + t = lexicographicSets[sIndex - 1]; } else { - t = new List(); - sets.Insert(sIndex, t); - replaced.Add(s); + t = new PooledSet(ClearMode.Always); + lexicographicSets.Insert(sIndex, t); + replacedSets.Add(s); } s.Remove(neighbor); t.Add(neighbor); - if (s.Count == 0) { sets.Remove(s); } + if (s.Count == 0) { lexicographicSets.Remove(s); replacedSets.Remove(s); } } } } + + lexicographicSets.Clear(); + replacedSets.Clear(); } public bool Cyclic() diff --git a/Graph/MoonTools.Core.Graph.csproj b/Graph/MoonTools.Core.Graph.csproj index e69a172..c61d549 100644 --- a/Graph/MoonTools.Core.Graph.csproj +++ b/Graph/MoonTools.Core.Graph.csproj @@ -4,5 +4,6 @@ + \ No newline at end of file diff --git a/Graph/UndirectedGraph.cs b/Graph/UndirectedGraph.cs index ddc5be4..6ef0cf9 100644 --- a/Graph/UndirectedGraph.cs +++ b/Graph/UndirectedGraph.cs @@ -1,5 +1,6 @@ using System.Linq; using System.Collections.Generic; +using Collections.Pooled; namespace MoonTools.Core.Graph { @@ -21,7 +22,7 @@ namespace MoonTools.Core.Graph .All(pair => { var (node, index) = pair; - var successors = lexicographicOrder.Skip(index - 1).Take(nodes.Count - index - 1); + var successors = lexicographicOrder.Skip(index).Take(nodes.Count - index); return Clique(Neighbors(node).Intersect(successors).Union(Enumerable.Repeat(node, 1))); }); } @@ -31,9 +32,9 @@ namespace MoonTools.Core.Graph { get { - var colors = new Dictionary(); - var d = new Dictionary(); - var partition = new Dictionary(); + var colors = new PooledDictionary(); + var d = new PooledDictionary(); + var partition = new PooledDictionary(); foreach (var node in Nodes) { @@ -47,7 +48,7 @@ namespace MoonTools.Core.Graph partition[start] = 1; d[start] = 0; - var stack = new Stack(); + var stack = new PooledStack(); stack.Push(start); while (stack.Count > 0) @@ -68,6 +69,11 @@ namespace MoonTools.Core.Graph colors[node] = Color.Black; } + stack.Dispose(); + colors.Dispose(); + d.Dispose(); + partition.Dispose(); + return true; } }