restructure inheritance
							parent
							
								
									92bab9db75
								
							
						
					
					
						commit
						fcd9c23ecd
					
				| 
						 | 
				
			
			@ -5,19 +5,8 @@ using Collections.Pooled;
 | 
			
		|||
 | 
			
		||||
namespace MoonTools.Core.Graph
 | 
			
		||||
{
 | 
			
		||||
    public enum SearchSymbol
 | 
			
		||||
    public class DirectedGraph<TNode, TEdgeData> : SimpleGraph<TNode, TEdgeData> where TNode : IEquatable<TNode>
 | 
			
		||||
    {
 | 
			
		||||
        Start,
 | 
			
		||||
        Finish
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class DirectedGraph<TNode, TEdgeData> : IGraph<TNode, TEdgeData> where TNode : IEquatable<TNode>
 | 
			
		||||
    {
 | 
			
		||||
        protected HashSet<TNode> nodes = new HashSet<TNode>();
 | 
			
		||||
        protected HashSet<(TNode, TNode)> edges = new HashSet<(TNode, TNode)>();
 | 
			
		||||
        protected Dictionary<(TNode, TNode), TEdgeData> edgesToEdgeData = new Dictionary<(TNode, TNode), TEdgeData>();
 | 
			
		||||
        protected Dictionary<TNode, HashSet<TNode>> neighbors = new Dictionary<TNode, HashSet<TNode>>();
 | 
			
		||||
 | 
			
		||||
        private class SimpleCycleComparer : IEqualityComparer<IEnumerable<TNode>>
 | 
			
		||||
        {
 | 
			
		||||
            public bool Equals(IEnumerable<TNode> x, IEnumerable<TNode> y)
 | 
			
		||||
| 
						 | 
				
			
			@ -31,56 +20,6 @@ namespace MoonTools.Core.Graph
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<TNode> Nodes => nodes;
 | 
			
		||||
        public IEnumerable<(TNode, TNode)> Edges => edges;
 | 
			
		||||
 | 
			
		||||
        public int Order => nodes.Count;
 | 
			
		||||
        public int Size => edges.Count;
 | 
			
		||||
 | 
			
		||||
        public void AddNode(TNode node)
 | 
			
		||||
        {
 | 
			
		||||
            if (!Exists(node))
 | 
			
		||||
            {
 | 
			
		||||
                nodes.Add(node);
 | 
			
		||||
                neighbors.Add(node, new HashSet<TNode>());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddNodes(params TNode[] nodes)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var node in nodes)
 | 
			
		||||
            {
 | 
			
		||||
                AddNode(node);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Exists(TNode node)
 | 
			
		||||
        {
 | 
			
		||||
            return nodes.Contains(node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Exists(TNode v, TNode u)
 | 
			
		||||
        {
 | 
			
		||||
            return edges.Contains((v, u));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void CheckNodes(params TNode[] givenNodes)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var node in givenNodes)
 | 
			
		||||
            {
 | 
			
		||||
                if (!Exists(node))
 | 
			
		||||
                {
 | 
			
		||||
                    throw new ArgumentException($"Vertex {node} does not exist in the graph");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int Degree(TNode node)
 | 
			
		||||
        {
 | 
			
		||||
            CheckNodes(node);
 | 
			
		||||
            return neighbors[node].Count;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void RemoveNode(TNode node)
 | 
			
		||||
        {
 | 
			
		||||
            CheckNodes(node);
 | 
			
		||||
| 
						 | 
				
			
			@ -114,7 +53,7 @@ namespace MoonTools.Core.Graph
 | 
			
		|||
 | 
			
		||||
            neighbors[v].Add(u);
 | 
			
		||||
            edges.Add((v, u));
 | 
			
		||||
            edgesToEdgeData.Add((v, u), edgeData);
 | 
			
		||||
            edgeToEdgeData.Add((v, u), edgeData);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual void AddEdges(params (TNode, TNode, TEdgeData)[] edges)
 | 
			
		||||
| 
						 | 
				
			
			@ -125,31 +64,12 @@ namespace MoonTools.Core.Graph
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void CheckEdge(TNode v, TNode u)
 | 
			
		||||
        {
 | 
			
		||||
            CheckNodes(v, u);
 | 
			
		||||
            if (!Exists(v, u)) { throw new ArgumentException($"Edge between vertex {v} and vertex {u} does not exist in the graph"); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public virtual void RemoveEdge(TNode v, TNode u)
 | 
			
		||||
        {
 | 
			
		||||
            CheckEdge(v, u);
 | 
			
		||||
            neighbors[v].Remove(u);
 | 
			
		||||
            edges.Remove((v, u));
 | 
			
		||||
            edgesToEdgeData.Remove((v, u));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public TEdgeData EdgeData(TNode v, TNode u)
 | 
			
		||||
        {
 | 
			
		||||
            CheckEdge(v, u);
 | 
			
		||||
            return edgesToEdgeData[(v, u)];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<TNode> Neighbors(TNode node)
 | 
			
		||||
        {
 | 
			
		||||
            CheckNodes(node);
 | 
			
		||||
 | 
			
		||||
            return neighbors[node];
 | 
			
		||||
            edgeToEdgeData.Remove((v, u));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<TNode> PreorderNodeDFS()
 | 
			
		||||
| 
						 | 
				
			
			@ -549,12 +469,12 @@ namespace MoonTools.Core.Graph
 | 
			
		|||
            return subGraph;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Clear()
 | 
			
		||||
        public virtual void Clear()
 | 
			
		||||
        {
 | 
			
		||||
            nodes.Clear();
 | 
			
		||||
            neighbors.Clear();
 | 
			
		||||
            edges.Clear();
 | 
			
		||||
            edgesToEdgeData.Clear();
 | 
			
		||||
            edgeToEdgeData.Clear();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,51 +6,14 @@ using MoreLinq;
 | 
			
		|||
 | 
			
		||||
namespace MoonTools.Core.Graph
 | 
			
		||||
{
 | 
			
		||||
    public class DirectedWeightedGraph<TNode, TEdgeData> : IGraph<TNode, TEdgeData> where TNode : System.IEquatable<TNode>
 | 
			
		||||
    public class DirectedWeightedGraph<TNode, TEdgeData> : DirectedGraph<TNode, TEdgeData> where TNode : System.IEquatable<TNode>
 | 
			
		||||
    {
 | 
			
		||||
        protected HashSet<TNode> nodes = new HashSet<TNode>();
 | 
			
		||||
        protected Dictionary<TNode, HashSet<TNode>> neighbors = new Dictionary<TNode, HashSet<TNode>>();
 | 
			
		||||
        protected Dictionary<(TNode, TNode), TEdgeData> edgeToEdgeData = new Dictionary<(TNode, TNode), TEdgeData>();
 | 
			
		||||
        protected Dictionary<(TNode, TNode), int> weights = new Dictionary<(TNode, TNode), int>();
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<TNode> Nodes => nodes;
 | 
			
		||||
 | 
			
		||||
        public void AddNode(TNode node)
 | 
			
		||||
        {
 | 
			
		||||
            if (Exists(node)) { return; }
 | 
			
		||||
 | 
			
		||||
            nodes.Add(node);
 | 
			
		||||
            neighbors[node] = new HashSet<TNode>();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddNodes(params TNode[] nodes)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var node in nodes)
 | 
			
		||||
            {
 | 
			
		||||
                AddNode(node);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void CheckNodes(params TNode[] givenNodes)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var node in givenNodes)
 | 
			
		||||
            {
 | 
			
		||||
                if (!Exists(node))
 | 
			
		||||
                {
 | 
			
		||||
                    throw new ArgumentException($"Vertex {node} does not exist in the graph");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddEdge(TNode v, TNode u, int weight, TEdgeData data)
 | 
			
		||||
        {
 | 
			
		||||
            CheckNodes(v, u);
 | 
			
		||||
 | 
			
		||||
            if (Exists(v, u)) { throw new ArgumentException($"Edge with vertex {v} and {u} already exists in the graph"); }
 | 
			
		||||
 | 
			
		||||
            neighbors[v].Add(u);
 | 
			
		||||
            base.AddEdge(v, u, data);
 | 
			
		||||
            weights.Add((v, u), weight);
 | 
			
		||||
            edgeToEdgeData.Add((v, u), data);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddEdges(params (TNode, TNode, int, TEdgeData)[] edges)
 | 
			
		||||
| 
						 | 
				
			
			@ -61,46 +24,18 @@ namespace MoonTools.Core.Graph
 | 
			
		|||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Clear()
 | 
			
		||||
        public override void Clear()
 | 
			
		||||
        {
 | 
			
		||||
            nodes.Clear();
 | 
			
		||||
            neighbors.Clear();
 | 
			
		||||
            edgeToEdgeData.Clear();
 | 
			
		||||
            base.Clear();
 | 
			
		||||
            weights.Clear();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Exists(TNode node) => nodes.Contains(node);
 | 
			
		||||
 | 
			
		||||
        public bool Exists(TNode v, TNode u)
 | 
			
		||||
        {
 | 
			
		||||
            CheckNodes(v, u);
 | 
			
		||||
            return neighbors[v].Contains(u);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<TNode> Neighbors(TNode node)
 | 
			
		||||
        {
 | 
			
		||||
            CheckNodes(node);
 | 
			
		||||
            return neighbors[node];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void CheckEdge(TNode v, TNode u)
 | 
			
		||||
        {
 | 
			
		||||
            CheckNodes(v, u);
 | 
			
		||||
            if (!Exists(v, u)) { throw new ArgumentException($"Edge between vertex {v} and vertex {u} does not exist in the graph"); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int Weight(TNode v, TNode u)
 | 
			
		||||
        {
 | 
			
		||||
            CheckEdge(v, u);
 | 
			
		||||
            return weights[(v, u)];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public TEdgeData EdgeData(TNode v, TNode u)
 | 
			
		||||
        {
 | 
			
		||||
            CheckEdge(v, u);
 | 
			
		||||
            return edgeToEdgeData[(v, u)];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private IEnumerable<(TNode, TNode)> ReconstructPath(PooledDictionary<TNode, TNode> cameFrom, TNode currentNode)
 | 
			
		||||
        {
 | 
			
		||||
            while (cameFrom.ContainsKey(currentNode))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ using MoreLinq;
 | 
			
		|||
 | 
			
		||||
namespace MoonTools.Core.Graph
 | 
			
		||||
{
 | 
			
		||||
    public class DirectedWeightedMultiGraph<TNode, TEdgeData> : IGraph<TNode, TEdgeData> where TNode : IEquatable<TNode>
 | 
			
		||||
    public class DirectedWeightedMultiGraph<TNode, TEdgeData> where TNode : IEquatable<TNode>
 | 
			
		||||
    {
 | 
			
		||||
        protected HashSet<TNode> nodes = new HashSet<TNode>();
 | 
			
		||||
        protected Dictionary<TNode, HashSet<TNode>> neighbors = new Dictionary<TNode, HashSet<TNode>>();
 | 
			
		||||
| 
						 | 
				
			
			@ -15,13 +15,6 @@ namespace MoonTools.Core.Graph
 | 
			
		|||
        protected Dictionary<Guid, int> weights = new Dictionary<Guid, int>();
 | 
			
		||||
        protected Dictionary<Guid, TEdgeData> edgeToEdgeData = new Dictionary<Guid, TEdgeData>();
 | 
			
		||||
 | 
			
		||||
        // store search sets to prevent GC
 | 
			
		||||
        protected HashSet<TNode> openSet = new HashSet<TNode>();
 | 
			
		||||
        protected HashSet<TNode> closedSet = new HashSet<TNode>();
 | 
			
		||||
        protected Dictionary<TNode, int> gScore = new Dictionary<TNode, int>();
 | 
			
		||||
        protected Dictionary<TNode, int> fScore = new Dictionary<TNode, int>();
 | 
			
		||||
        protected Dictionary<TNode, Guid> cameFrom = new Dictionary<TNode, Guid>();
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<TNode> Nodes => nodes;
 | 
			
		||||
 | 
			
		||||
        public void AddNode(TNode node)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,60 @@
 | 
			
		|||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.Core.Graph
 | 
			
		||||
{
 | 
			
		||||
    abstract public class Graph<TNode, TEdgeData> where TNode : System.IEquatable<TNode>
 | 
			
		||||
    {
 | 
			
		||||
        protected HashSet<TNode> nodes = new HashSet<TNode>();
 | 
			
		||||
        protected Dictionary<TNode, HashSet<TNode>> neighbors = new Dictionary<TNode, HashSet<TNode>>();
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<TNode> Nodes => nodes;
 | 
			
		||||
 | 
			
		||||
        public int Order => nodes.Count;
 | 
			
		||||
 | 
			
		||||
        public void AddNode(TNode node)
 | 
			
		||||
        {
 | 
			
		||||
            if (!Exists(node))
 | 
			
		||||
            {
 | 
			
		||||
                nodes.Add(node);
 | 
			
		||||
                neighbors.Add(node, new HashSet<TNode>());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void AddNodes(params TNode[] nodes)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var node in nodes)
 | 
			
		||||
            {
 | 
			
		||||
                AddNode(node);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public int Degree(TNode node)
 | 
			
		||||
        {
 | 
			
		||||
            CheckNodes(node);
 | 
			
		||||
            return neighbors[node].Count;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public bool Exists(TNode node)
 | 
			
		||||
        {
 | 
			
		||||
            return nodes.Contains(node);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<TNode> Neighbors(TNode node)
 | 
			
		||||
        {
 | 
			
		||||
            CheckNodes(node);
 | 
			
		||||
            return neighbors[node];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void CheckNodes(params TNode[] givenNodes)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var node in givenNodes)
 | 
			
		||||
            {
 | 
			
		||||
                if (!Exists(node))
 | 
			
		||||
                {
 | 
			
		||||
                    throw new System.ArgumentException($"Vertex {node} does not exist in the graph");
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,15 +0,0 @@
 | 
			
		|||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.Core.Graph
 | 
			
		||||
{
 | 
			
		||||
    public interface IGraph<TNode, TEdgeData> where TNode : System.IEquatable<TNode>
 | 
			
		||||
    {
 | 
			
		||||
        IEnumerable<TNode> Nodes { get; }
 | 
			
		||||
 | 
			
		||||
        void AddNode(TNode node);
 | 
			
		||||
        void AddNodes(params TNode[] nodes);
 | 
			
		||||
        bool Exists(TNode node);
 | 
			
		||||
        IEnumerable<TNode> Neighbors(TNode node);
 | 
			
		||||
        void Clear();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,33 @@
 | 
			
		|||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
 | 
			
		||||
namespace MoonTools.Core.Graph
 | 
			
		||||
{
 | 
			
		||||
    abstract public class SimpleGraph<TNode, TEdgeData> : Graph<TNode, TEdgeData> where TNode : System.IEquatable<TNode>
 | 
			
		||||
    {
 | 
			
		||||
        protected HashSet<(TNode, TNode)> edges = new HashSet<(TNode, TNode)>();
 | 
			
		||||
        protected Dictionary<(TNode, TNode), TEdgeData> edgeToEdgeData = new Dictionary<(TNode, TNode), TEdgeData>();
 | 
			
		||||
 | 
			
		||||
        public IEnumerable<(TNode, TNode)> Edges => edges;
 | 
			
		||||
 | 
			
		||||
        public int Size => edges.Count;
 | 
			
		||||
 | 
			
		||||
        public bool Exists(TNode v, TNode u)
 | 
			
		||||
        {
 | 
			
		||||
            CheckNodes(v, u);
 | 
			
		||||
            return edges.Contains((v, u));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public TEdgeData EdgeData(TNode v, TNode u)
 | 
			
		||||
        {
 | 
			
		||||
            CheckEdge(v, u);
 | 
			
		||||
            return edgeToEdgeData[(v, u)];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected void CheckEdge(TNode v, TNode u)
 | 
			
		||||
        {
 | 
			
		||||
            CheckNodes(v, u);
 | 
			
		||||
            if (!Exists(v, u)) { throw new ArgumentException($"Edge between vertex {v} and vertex {u} does not exist in the graph"); }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue