diff --git a/Graph/DirectedGraph.cs b/Graph/DirectedGraph.cs index 6b750c4..58a1085 100644 --- a/Graph/DirectedGraph.cs +++ b/Graph/DirectedGraph.cs @@ -5,19 +5,8 @@ using Collections.Pooled; namespace MoonTools.Core.Graph { - public enum SearchSymbol + public class DirectedGraph : SimpleGraph where TNode : IEquatable { - Start, - Finish - } - - public class DirectedGraph : IGraph where TNode : IEquatable - { - protected HashSet nodes = new HashSet(); - protected HashSet<(TNode, TNode)> edges = new HashSet<(TNode, TNode)>(); - protected Dictionary<(TNode, TNode), TEdgeData> edgesToEdgeData = new Dictionary<(TNode, TNode), TEdgeData>(); - protected Dictionary> neighbors = new Dictionary>(); - private class SimpleCycleComparer : IEqualityComparer> { public bool Equals(IEnumerable x, IEnumerable y) @@ -31,56 +20,6 @@ namespace MoonTools.Core.Graph } } - public IEnumerable 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()); - } - } - - 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 Neighbors(TNode node) - { - CheckNodes(node); - - return neighbors[node]; + edgeToEdgeData.Remove((v, u)); } public IEnumerable 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(); } } } diff --git a/Graph/DirectedWeightedGraph.cs b/Graph/DirectedWeightedGraph.cs index ea743e2..d592f94 100644 --- a/Graph/DirectedWeightedGraph.cs +++ b/Graph/DirectedWeightedGraph.cs @@ -6,51 +6,14 @@ using MoreLinq; namespace MoonTools.Core.Graph { - public class DirectedWeightedGraph : IGraph where TNode : System.IEquatable + public class DirectedWeightedGraph : DirectedGraph where TNode : System.IEquatable { - protected HashSet nodes = new HashSet(); - protected Dictionary> neighbors = new Dictionary>(); - protected Dictionary<(TNode, TNode), TEdgeData> edgeToEdgeData = new Dictionary<(TNode, TNode), TEdgeData>(); protected Dictionary<(TNode, TNode), int> weights = new Dictionary<(TNode, TNode), int>(); - public IEnumerable Nodes => nodes; - - public void AddNode(TNode node) - { - if (Exists(node)) { return; } - - nodes.Add(node); - neighbors[node] = new HashSet(); - } - - 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 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 cameFrom, TNode currentNode) { while (cameFrom.ContainsKey(currentNode)) diff --git a/Graph/DirectedWeightedMultiGraph.cs b/Graph/DirectedWeightedMultiGraph.cs index a27f90a..051ed10 100644 --- a/Graph/DirectedWeightedMultiGraph.cs +++ b/Graph/DirectedWeightedMultiGraph.cs @@ -6,7 +6,7 @@ using MoreLinq; namespace MoonTools.Core.Graph { - public class DirectedWeightedMultiGraph : IGraph where TNode : IEquatable + public class DirectedWeightedMultiGraph where TNode : IEquatable { protected HashSet nodes = new HashSet(); protected Dictionary> neighbors = new Dictionary>(); @@ -15,13 +15,6 @@ namespace MoonTools.Core.Graph protected Dictionary weights = new Dictionary(); protected Dictionary edgeToEdgeData = new Dictionary(); - // store search sets to prevent GC - protected HashSet openSet = new HashSet(); - protected HashSet closedSet = new HashSet(); - protected Dictionary gScore = new Dictionary(); - protected Dictionary fScore = new Dictionary(); - protected Dictionary cameFrom = new Dictionary(); - public IEnumerable Nodes => nodes; public void AddNode(TNode node) diff --git a/Graph/Graph.cs b/Graph/Graph.cs new file mode 100644 index 0000000..0423230 --- /dev/null +++ b/Graph/Graph.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; + +namespace MoonTools.Core.Graph +{ + abstract public class Graph where TNode : System.IEquatable + { + protected HashSet nodes = new HashSet(); + protected Dictionary> neighbors = new Dictionary>(); + + public IEnumerable Nodes => nodes; + + public int Order => nodes.Count; + + public void AddNode(TNode node) + { + if (!Exists(node)) + { + nodes.Add(node); + neighbors.Add(node, new HashSet()); + } + } + + 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 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"); + } + } + } + + } +} \ No newline at end of file diff --git a/Graph/IGraph.cs b/Graph/IGraph.cs deleted file mode 100644 index a3939f1..0000000 --- a/Graph/IGraph.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; - -namespace MoonTools.Core.Graph -{ - public interface IGraph where TNode : System.IEquatable - { - IEnumerable Nodes { get; } - - void AddNode(TNode node); - void AddNodes(params TNode[] nodes); - bool Exists(TNode node); - IEnumerable Neighbors(TNode node); - void Clear(); - } -} \ No newline at end of file diff --git a/Graph/SimpleGraph.cs b/Graph/SimpleGraph.cs new file mode 100644 index 0000000..062d891 --- /dev/null +++ b/Graph/SimpleGraph.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; + +namespace MoonTools.Core.Graph +{ + abstract public class SimpleGraph : Graph where TNode : System.IEquatable + { + 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"); } + } + } +} \ No newline at end of file