more restructuring

master
Evan Hemsley 2019-10-23 18:47:48 -07:00
parent b1a8f9d5a1
commit 01556338eb
6 changed files with 100 additions and 98 deletions

View File

@ -22,13 +22,7 @@ namespace MoonTools.Core.Graph
public virtual void AddEdge(TNode v, TNode u, TEdgeData edgeData)
{
CheckNodes(v, u);
if (v.Equals(u)) { throw new ArgumentException("Self-edges are not allowed in a simple graph. Use a multigraph instead"); }
neighbors[v].Add(u);
edges.Add((v, u));
edgeToEdgeData.Add((v, u), edgeData);
BaseAddEdge(v, u, edgeData);
}
public virtual void AddEdges(params (TNode, TNode, TEdgeData)[] edges)

View File

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
namespace MoonTools.Core.Graph
{
public class DirectedMultiGraph<TNode, TEdgeData> : MultiGraph<TNode, TEdgeData> where TNode : System.IEquatable<TNode>
{
public void AddEdge(TNode v, TNode u, TEdgeData edgeData)
{
BaseAddEdge(v, u, edgeData);
}
public void AddEdges(params (TNode, TNode, TEdgeData)[] edges)
{
foreach (var edge in edges)
{
AddEdge(edge.Item1, edge.Item2, edge.Item3);
}
}
}
}

View File

@ -12,14 +12,7 @@ namespace MoonTools.Core.Graph
public void AddEdge(TNode v, TNode u, int weight, TEdgeData edgeData)
{
CheckNodes(v, u);
if (v.Equals(u)) { throw new ArgumentException("Self-edges are not allowed in a simple graph. Use a multigraph instead"); }
neighbors[v].Add(u);
edges.Add((v, u));
edgeToEdgeData.Add((v, u), edgeData);
BaseAddEdge(v, u, edgeData);
weights.Add((v, u), weight);
}

View File

@ -6,47 +6,15 @@ using MoreLinq;
namespace MoonTools.Core.Graph
{
public class DirectedWeightedMultiGraph<TNode, TEdgeData> where TNode : IEquatable<TNode>
public class DirectedWeightedMultiGraph<TNode, TEdgeData> : MultiGraph<TNode, TEdgeData> where TNode : IEquatable<TNode>
{
protected HashSet<TNode> nodes = new HashSet<TNode>();
protected Dictionary<TNode, HashSet<TNode>> neighbors = new Dictionary<TNode, HashSet<TNode>>();
protected Dictionary<(TNode, TNode), HashSet<Guid>> edges = new Dictionary<(TNode, TNode), HashSet<Guid>>();
protected Dictionary<Guid, (TNode, TNode)> IDToEdge = new Dictionary<Guid, (TNode, TNode)>();
protected Dictionary<Guid, int> weights = new Dictionary<Guid, int>();
protected Dictionary<Guid, TEdgeData> edgeToEdgeData = new Dictionary<Guid, TEdgeData>();
public IEnumerable<TNode> Nodes => nodes;
public void AddNode(TNode node)
public Guid AddEdge(TNode v, TNode u, int weight, TEdgeData data)
{
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);
}
}
public void AddEdge(TNode v, TNode u, int weight, TEdgeData data)
{
CheckNodes(v, u);
var id = Guid.NewGuid();
neighbors[v].Add(u);
var id = BaseAddEdge(v, u, data);
weights.Add(id, weight);
if (!edges.ContainsKey((v, u)))
{
edges[(v, u)] = new HashSet<Guid>();
}
edges[(v, u)].Add(id);
edgeToEdgeData.Add(id, data);
IDToEdge.Add(id, (v, u));
return id;
}
public void AddEdges(params (TNode, TNode, int, TEdgeData)[] edges)
@ -57,45 +25,10 @@ namespace MoonTools.Core.Graph
}
}
public void Clear()
public override void Clear()
{
nodes.Clear();
neighbors.Clear();
base.Clear();
weights.Clear();
edges.Clear();
IDToEdge.Clear();
edgeToEdgeData.Clear();
}
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 IEnumerable<Guid> EdgeIDs(TNode v, TNode u)
{
CheckNodes(v, u);
return edges.ContainsKey((v, u)) ? edges[(v, u)] : Enumerable.Empty<Guid>();
}
public bool Exists(TNode node) => nodes.Contains(node);
public bool Exists(TNode v, TNode u)
{
CheckNodes(v, u);
return edges.ContainsKey((v, u));
}
public IEnumerable<TNode> Neighbors(TNode node)
{
CheckNodes(node);
return neighbors.ContainsKey(node) ? neighbors[node] : Enumerable.Empty<TNode>();
}
public IEnumerable<int> Weights(TNode v, TNode u)
@ -104,16 +37,6 @@ namespace MoonTools.Core.Graph
return edges[(v, u)].Select(id => weights[id]);
}
public TEdgeData EdgeData(Guid id)
{
if (!edgeToEdgeData.ContainsKey(id))
{
throw new ArgumentException($"Edge {id} does not exist in the graph.");
}
return edgeToEdgeData[id];
}
private IEnumerable<Guid> ReconstructPath(PooledDictionary<TNode, Guid> cameFrom, TNode currentNode)
{
while (cameFrom.ContainsKey(currentNode))

60
Graph/MultiGraph.cs Normal file
View File

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace MoonTools.Core.Graph
{
abstract public class MultiGraph<TNode, TEdgeData> : Graph<TNode, TEdgeData> where TNode : System.IEquatable<TNode>
{
protected Dictionary<(TNode, TNode), HashSet<Guid>> edges = new Dictionary<(TNode, TNode), HashSet<Guid>>();
protected Dictionary<Guid, (TNode, TNode)> IDToEdge = new Dictionary<Guid, (TNode, TNode)>();
protected Dictionary<Guid, TEdgeData> edgeToEdgeData = new Dictionary<Guid, TEdgeData>();
protected Guid BaseAddEdge(TNode v, TNode u, TEdgeData edgeData)
{
CheckNodes(v, u);
var id = Guid.NewGuid();
neighbors[v].Add(u);
if (!edges.ContainsKey((v, u)))
{
edges[(v, u)] = new HashSet<Guid>();
}
edges[(v, u)].Add(id);
edgeToEdgeData.Add(id, edgeData);
IDToEdge.Add(id, (v, u));
return id;
}
public override void Clear()
{
base.Clear();
edges.Clear();
IDToEdge.Clear();
edgeToEdgeData.Clear();
}
public IEnumerable<Guid> EdgeIDs(TNode v, TNode u)
{
CheckNodes(v, u);
return edges.ContainsKey((v, u)) ? edges[(v, u)] : Enumerable.Empty<Guid>();
}
public bool Exists(TNode v, TNode u)
{
CheckNodes(v, u);
return edges.ContainsKey((v, u));
}
public TEdgeData EdgeData(Guid id)
{
if (!edgeToEdgeData.ContainsKey(id))
{
throw new ArgumentException($"Edge {id} does not exist in the graph.");
}
return edgeToEdgeData[id];
}
}
}

View File

@ -12,6 +12,17 @@ namespace MoonTools.Core.Graph
public int Size => edges.Count;
protected void BaseAddEdge(TNode v, TNode u, TEdgeData edgeData)
{
CheckNodes(v, u);
if (v.Equals(u)) { throw new ArgumentException("Self-edges are not allowed in a simple graph. Use a multigraph instead"); }
neighbors[v].Add(u);
edges.Add((v, u));
edgeToEdgeData.Add((v, u), edgeData);
}
public bool Exists(TNode v, TNode u)
{
CheckNodes(v, u);