optimizations
							parent
							
								
									bae6acd6f3
								
							
						
					
					
						commit
						a08a39c353
					
				| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using Collections.Pooled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MoonTools.Core.Graph
 | 
					namespace MoonTools.Core.Graph
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -80,13 +81,11 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
            return neighbors[node].Count;
 | 
					            return neighbors[node].Count;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        readonly List<(TNode, TNode)> edgesToRemove = new List<(TNode, TNode)>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public void RemoveNode(TNode node)
 | 
					        public void RemoveNode(TNode node)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            CheckNodes(node);
 | 
					            CheckNodes(node);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            edgesToRemove.Clear();
 | 
					            var edgesToRemove = new PooledList<(TNode, TNode)>(ClearMode.Always);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var entry in neighbors)
 | 
					            foreach (var entry in neighbors)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -101,6 +100,8 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
                RemoveEdge(edge.Item1, edge.Item2);
 | 
					                RemoveEdge(edge.Item1, edge.Item2);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            edgesToRemove.Dispose();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            nodes.Remove(node);
 | 
					            nodes.Remove(node);
 | 
				
			||||||
            neighbors.Remove(node);
 | 
					            neighbors.Remove(node);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -149,13 +150,10 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
            return neighbors[node];
 | 
					            return neighbors[node];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        readonly Stack<TNode> dfsStack = new Stack<TNode>();
 | 
					 | 
				
			||||||
        readonly HashSet<TNode> dfsDiscovered = new HashSet<TNode>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public IEnumerable<TNode> PreorderNodeDFS()
 | 
					        public IEnumerable<TNode> PreorderNodeDFS()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            dfsStack.Clear();
 | 
					            var dfsStack = new PooledStack<TNode>(ClearMode.Always);
 | 
				
			||||||
            dfsDiscovered.Clear();
 | 
					            var dfsDiscovered = new PooledSet<TNode>(ClearMode.Always);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var node in Nodes)
 | 
					            foreach (var node in Nodes)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
| 
						 | 
					@ -177,75 +175,49 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            dfsStack.Dispose();
 | 
				
			||||||
 | 
					            dfsDiscovered.Dispose();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // public IEnumerable<TNode> PostorderNodeDFS()
 | 
					        private IEnumerable<TNode> PostorderNodeDFSHelper(PooledSet<TNode> discovered, TNode v)
 | 
				
			||||||
        // {
 | 
					 | 
				
			||||||
        //     dfsStack.Clear();
 | 
					 | 
				
			||||||
        //     dfsDiscovered.Clear();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //     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;
 | 
					 | 
				
			||||||
        //                 }
 | 
					 | 
				
			||||||
        //             }
 | 
					 | 
				
			||||||
        //         }
 | 
					 | 
				
			||||||
        //     }
 | 
					 | 
				
			||||||
        // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        List<TNode> postorderOutput = new List<TNode>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        public IEnumerable<TNode> PostorderNodeDFS()
 | 
					 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            dfsDiscovered.Clear();
 | 
					            discovered.Add(v);
 | 
				
			||||||
            postorderOutput.Clear();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            void dfsHelper(TNode v) // refactor this to remove closure
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                dfsDiscovered.Add(v);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var neighbor in Neighbors(v))
 | 
					            foreach (var neighbor in Neighbors(v))
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                    if (!dfsDiscovered.Contains(neighbor))
 | 
					                if (!discovered.Contains(neighbor))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                        dfsHelper(neighbor);
 | 
					                    foreach (var node in PostorderNodeDFSHelper(discovered, neighbor))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        yield return node;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                postorderOutput.Add(v);
 | 
					            yield return v;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEnumerable<TNode> PostorderNodeDFS()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var dfsDiscovered = new PooledSet<TNode>(ClearMode.Always);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var node in Nodes)
 | 
					            foreach (var node in Nodes)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                if (!dfsDiscovered.Contains(node))
 | 
					                if (!dfsDiscovered.Contains(node))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    dfsHelper(node);
 | 
					                    foreach (var thing in PostorderNodeDFSHelper(dfsDiscovered, node))
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        yield return thing;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            return postorderOutput;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        readonly Queue<TNode> bfsQueue = new Queue<TNode>();
 | 
					 | 
				
			||||||
        readonly HashSet<TNode> bfsDiscovered = new HashSet<TNode>();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public IEnumerable<TNode> NodeBFS()
 | 
					        public IEnumerable<TNode> NodeBFS()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            bfsQueue.Clear();
 | 
					            var bfsQueue = new PooledQueue<TNode>(ClearMode.Always);
 | 
				
			||||||
            bfsDiscovered.Clear();
 | 
					            var bfsDiscovered = new PooledSet<TNode>(ClearMode.Always);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            foreach (var node in Nodes)
 | 
					            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<PooledSet<TNode>> lexicographicSets = new List<PooledSet<TNode>>();
 | 
				
			||||||
 | 
					        HashSet<PooledSet<TNode>> replacedSets = new HashSet<PooledSet<TNode>>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public IEnumerable<TNode> LexicographicBFS()
 | 
					        public IEnumerable<TNode> LexicographicBFS()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var sets = new List<List<TNode>>();
 | 
					            lexicographicSets.Add(Nodes.ToPooledSet());
 | 
				
			||||||
            sets.Add(Nodes.ToList());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            while (sets.Count > 0)
 | 
					            while (lexicographicSets.Count > 0)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var firstSet = sets[0];
 | 
					                var firstSet = lexicographicSets[0];
 | 
				
			||||||
                var node = firstSet[0];
 | 
					                var node = firstSet.First();
 | 
				
			||||||
                firstSet.RemoveAt(0);
 | 
					                firstSet.Remove(node);
 | 
				
			||||||
                if (firstSet.Count == 0) { sets.RemoveAt(0); }
 | 
					                if (firstSet.Count == 0) { lexicographicSets.RemoveAt(0); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                yield return node;
 | 
					                yield return node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var replaced = new List<List<TNode>>();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                foreach (var neighbor in Neighbors(node))
 | 
					                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 s = lexicographicSets.Find(set => set.Contains(neighbor));
 | 
				
			||||||
                        var sIndex = sets.IndexOf(s);
 | 
					                        var sIndex = lexicographicSets.IndexOf(s);
 | 
				
			||||||
                        List<TNode> t;
 | 
					                        PooledSet<TNode> t;
 | 
				
			||||||
                        if (replaced.Contains(s))
 | 
					                        if (replacedSets.Contains(s) && sIndex > 0)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            t = sets[sIndex - 1];
 | 
					                            t = lexicographicSets[sIndex - 1];
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        else
 | 
					                        else
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            t = new List<TNode>();
 | 
					                            t = new PooledSet<TNode>(ClearMode.Always);
 | 
				
			||||||
                            sets.Insert(sIndex, t);
 | 
					                            lexicographicSets.Insert(sIndex, t);
 | 
				
			||||||
                            replaced.Add(s);
 | 
					                            replacedSets.Add(s);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        s.Remove(neighbor);
 | 
					                        s.Remove(neighbor);
 | 
				
			||||||
                        t.Add(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()
 | 
					        public bool Cyclic()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,5 +4,6 @@
 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
    <PackageReference Include="morelinq" Version="3.2.0"/>
 | 
					    <PackageReference Include="morelinq" Version="3.2.0"/>
 | 
				
			||||||
 | 
					    <PackageReference Include="Collections.Pooled" Version="1.0.82"/>
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
</Project>
 | 
					</Project>
 | 
				
			||||||
| 
						 | 
					@ -1,5 +1,6 @@
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using Collections.Pooled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace MoonTools.Core.Graph
 | 
					namespace MoonTools.Core.Graph
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -21,7 +22,7 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
                    .All(pair =>
 | 
					                    .All(pair =>
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        var (node, index) = 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)));
 | 
					                        return Clique(Neighbors(node).Intersect(successors).Union(Enumerable.Repeat(node, 1)));
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
| 
						 | 
					@ -31,9 +32,9 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            get
 | 
					            get
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var colors = new Dictionary<TNode, Color>();
 | 
					                var colors = new PooledDictionary<TNode, Color>();
 | 
				
			||||||
                var d = new Dictionary<TNode, int>();
 | 
					                var d = new PooledDictionary<TNode, int>();
 | 
				
			||||||
                var partition = new Dictionary<TNode, int>();
 | 
					                var partition = new PooledDictionary<TNode, int>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                foreach (var node in Nodes)
 | 
					                foreach (var node in Nodes)
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
| 
						 | 
					@ -47,7 +48,7 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
                partition[start] = 1;
 | 
					                partition[start] = 1;
 | 
				
			||||||
                d[start] = 0;
 | 
					                d[start] = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var stack = new Stack<TNode>();
 | 
					                var stack = new PooledStack<TNode>();
 | 
				
			||||||
                stack.Push(start);
 | 
					                stack.Push(start);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                while (stack.Count > 0)
 | 
					                while (stack.Count > 0)
 | 
				
			||||||
| 
						 | 
					@ -68,6 +69,11 @@ namespace MoonTools.Core.Graph
 | 
				
			||||||
                    colors[node] = Color.Black;
 | 
					                    colors[node] = Color.Black;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                stack.Dispose();
 | 
				
			||||||
 | 
					                colors.Dispose();
 | 
				
			||||||
 | 
					                d.Dispose();
 | 
				
			||||||
 | 
					                partition.Dispose();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue