restructure inheritance

master
Evan Hemsley 2019-10-23 18:05:28 -07:00
parent 92bab9db75
commit fcd9c23ecd
6 changed files with 103 additions and 177 deletions

View File

@ -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();
}
}
}

View File

@ -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))

View File

@ -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)

60
Graph/Graph.cs Normal file
View File

@ -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");
}
}
}
}
}

View File

@ -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();
}
}

33
Graph/SimpleGraph.cs Normal file
View File

@ -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"); }
}
}
}