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