Skip to content

Commit 0a622a0

Browse files
committed
matrix graph to generic IGraph
1 parent 30c6bfc commit 0a622a0

File tree

16 files changed

+751
-106
lines changed

16 files changed

+751
-106
lines changed

src/Advanced.Algorithms/DataStructures/Graph/AdjacencyMatrix/DiGraph.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@
66
namespace Advanced.Algorithms.DataStructures.Graph.AdjacencyMatrix
77
{
88
/// <summary>
9-
/// A directed graph implementation using dynamically growinng/shrinking adjacency matrix array.
9+
/// A directed graph implementation using dynamically growing/shrinking adjacency matrix array.
1010
/// IEnumerable enumerates all vertices.
1111
/// </summary>
1212
public class DiGraph<T> : IGraph<T>, IDiGraph<T>, IEnumerable<T>
1313
{
14+
private BitArray[] matrix;
15+
1416
private Dictionary<T, int> vertexIndices;
1517
private Dictionary<int, T> reverseVertexIndices;
1618
private Dictionary<T, DiGraphVertex<T>> vertexObjects;
1719

18-
private BitArray[] matrix;
19-
2020
private int maxSize => matrix.Length;
2121
private int usedSize;
2222
private int nextAvailableIndex;

src/Advanced.Algorithms/DataStructures/Graph/AdjacencyMatrix/Graph.cs

+139-16
Original file line numberDiff line numberDiff line change
@@ -5,37 +5,50 @@
55

66
namespace Advanced.Algorithms.DataStructures.Graph.AdjacencyMatrix
77
{
8-
98
/// <summary>
10-
/// A directed graph implementation using dynamically growinng/shrinking adjacency matrix array.
9+
/// A directed graph implementation using dynamically growing/shrinking adjacency matrix array.
1110
/// IEnumerable enumerates all vertices.
1211
/// </summary>
13-
public class Graph<T> : IEnumerable<T>
12+
public class Graph<T> : IGraph<T>, IEnumerable<T>
1413
{
15-
public int VerticesCount => usedSize;
14+
private BitArray[] matrix;
1615

1716
private Dictionary<T, int> vertexIndices;
1817
private Dictionary<int, T> reverseVertexIndices;
18+
private Dictionary<T, GraphVertex<T>> vertexObjects;
1919

20-
private BitArray[] matrix;
21-
22-
private int maxSize;
20+
private int maxSize => matrix.Length;
2321
private int usedSize;
2422
private int nextAvailableIndex;
2523

24+
public int VerticesCount => usedSize;
25+
public bool IsWeightedGraph => false;
26+
2627
public Graph()
2728
{
28-
maxSize = 1;
2929
vertexIndices = new Dictionary<T, int>();
3030
reverseVertexIndices = new Dictionary<int, T>();
31-
matrix = new BitArray[maxSize];
31+
vertexObjects = new Dictionary<T, GraphVertex<T>>();
32+
33+
matrix = new BitArray[1];
3234

3335
for (int i = 0; i < maxSize; i++)
3436
{
3537
matrix[i] = new BitArray(maxSize);
3638
}
3739
}
3840

41+
public IGraphVertex<T> ReferenceVertex => getReferenceVertex();
42+
private GraphVertex<T> getReferenceVertex()
43+
{
44+
if (this.VerticesCount == 0)
45+
{
46+
throw new Exception("Empty graph.");
47+
}
48+
49+
return vertexObjects[this.First()];
50+
}
51+
3952
/// <summary>
4053
/// Add a new vertex to this graph.
4154
/// Time complexity: O(1).
@@ -64,6 +77,7 @@ public void AddVertex(T value)
6477

6578
vertexIndices.Add(value, nextAvailableIndex);
6679
reverseVertexIndices.Add(nextAvailableIndex, value);
80+
vertexObjects.Add(value, new GraphVertex<T>(this, value));
6781

6882
nextAvailableIndex++;
6983
usedSize++;
@@ -103,6 +117,7 @@ public void RemoveVertex(T value)
103117

104118
reverseVertexIndices.Remove(index);
105119
vertexIndices.Remove(value);
120+
vertexObjects.Remove(value);
106121

107122
usedSize--;
108123

@@ -199,19 +214,37 @@ public IEnumerable<T> Edges(T vertex)
199214

200215
var index = vertexIndices[vertex];
201216

202-
var result = new List<T>();
217+
for (int i = 0; i < maxSize; i++)
218+
{
219+
if (matrix[i].Get(index))
220+
{
221+
yield return reverseVertexIndices[i];
222+
}
223+
}
224+
}
225+
226+
public int EdgesCount(T vertex)
227+
{
228+
if (!vertexIndices.ContainsKey(vertex))
229+
{
230+
throw new ArgumentException("vertex is not in this graph.");
231+
}
232+
233+
var count = 0;
234+
var index = vertexIndices[vertex];
203235

204236
for (int i = 0; i < maxSize; i++)
205237
{
206238
if (matrix[i].Get(index))
207239
{
208-
result.Add(reverseVertexIndices[i]);
240+
count++;
209241
}
210242
}
211243

212-
return result;
244+
return count;
213245
}
214246

247+
215248
private void doubleMatrixSize()
216249
{
217250
var newMatrix = new BitArray[maxSize * 2];
@@ -237,7 +270,7 @@ private void doubleMatrixSize()
237270
{
238271
for (int j = i; j < maxSize; j++)
239272
{
240-
if (matrix[i].Get(j) && matrix[j].Get(i)
273+
if (matrix[i].Get(j) && matrix[j].Get(i)
241274
&& reverseVertexIndices.ContainsKey(i)
242275
&& reverseVertexIndices.ContainsKey(j))
243276
{
@@ -253,7 +286,6 @@ private void doubleMatrixSize()
253286
matrix = newMatrix;
254287
vertexIndices = newVertexIndices;
255288
reverseVertexIndices = newReverseIndices;
256-
maxSize *= 2;
257289
}
258290

259291
private void halfMatrixSize()
@@ -281,7 +313,7 @@ private void halfMatrixSize()
281313
{
282314
for (int j = i; j < maxSize; j++)
283315
{
284-
if (matrix[i].Get(j) && matrix[j].Get(i)
316+
if (matrix[i].Get(j) && matrix[j].Get(i)
285317
&& reverseVertexIndices.ContainsKey(i)
286318
&& reverseVertexIndices.ContainsKey(j))
287319
{
@@ -297,9 +329,10 @@ private void halfMatrixSize()
297329
matrix = newMatrix;
298330
vertexIndices = newVertexIndices;
299331
reverseVertexIndices = newReverseIndices;
300-
maxSize /= 2;
301332
}
302333

334+
public IEnumerable<IGraphVertex<T>> VerticesAsEnumberable => vertexObjects.Select(x => x.Value);
335+
303336
IEnumerator IEnumerable.GetEnumerator()
304337
{
305338
return GetEnumerator();
@@ -309,5 +342,95 @@ public IEnumerator<T> GetEnumerator()
309342
{
310343
return vertexIndices.Select(x => x.Key).GetEnumerator();
311344
}
345+
346+
public bool ContainsVertex(T key)
347+
{
348+
return vertexObjects.ContainsKey(key);
349+
}
350+
351+
public IGraphVertex<T> GetVertex(T key)
352+
{
353+
return vertexObjects[key];
354+
}
355+
356+
IGraph<T> IGraph<T>.Clone()
357+
{
358+
return Clone();
359+
}
360+
361+
public Graph<T> Clone()
362+
{
363+
var graph = new Graph<T>();
364+
365+
foreach (var vertex in this)
366+
{
367+
graph.AddVertex(vertex);
368+
}
369+
370+
foreach (var vertex in this)
371+
{
372+
foreach (var edge in Edges(vertex))
373+
{
374+
graph.AddEdge(vertex, edge);
375+
}
376+
}
377+
378+
return graph;
379+
}
380+
381+
private class GraphVertex<T> : IGraphVertex<T>
382+
{
383+
Graph<T> graph;
384+
private int vertexIndex;
385+
private T vertexKey;
386+
387+
private int maxSize => graph.maxSize;
388+
private BitArray[] matrix => graph.matrix;
389+
390+
private Dictionary<T, int> vertexIndices => graph.vertexIndices;
391+
private Dictionary<int, T> reverseVertexIndices => graph.reverseVertexIndices;
392+
393+
internal GraphVertex(Graph<T> graph, T vertexKey)
394+
{
395+
if (!graph.vertexIndices.ContainsKey(vertexKey))
396+
{
397+
throw new ArgumentException("vertex is not in this graph.");
398+
}
399+
400+
this.graph = graph;
401+
this.vertexKey = vertexKey;
402+
this.vertexIndex = graph.vertexIndices[vertexKey];
403+
}
404+
405+
public T Key => vertexKey;
406+
407+
408+
IEnumerable<IEdge<T>> IGraphVertex<T>.Edges => graph.Edges(vertexKey)
409+
.Select(x => new Edge<T, int>(graph.vertexObjects[x], 1));
410+
411+
public IEdge<T> GetOutEdge(IGraphVertex<T> targetVertex)
412+
{
413+
if (!vertexIndices.ContainsKey(targetVertex.Key))
414+
{
415+
throw new ArgumentException("vertex is not in this graph.");
416+
}
417+
418+
var index = vertexIndices[targetVertex.Key];
419+
var key = targetVertex as GraphVertex<T>;
420+
return new Edge<T, int>(targetVertex, 1);
421+
}
422+
423+
public IEdge<T> GetEdge(IGraphVertex<T> targetVertex)
424+
{
425+
if (!vertexIndices.ContainsKey(targetVertex.Key))
426+
{
427+
throw new ArgumentException("vertex is not in this graph.");
428+
}
429+
430+
var index = vertexIndices[targetVertex.Key];
431+
var key = targetVertex as GraphVertex<T>;
432+
return new Edge<T, int>(targetVertex, 1);
433+
}
434+
}
312435
}
313436
}

src/Advanced.Algorithms/DataStructures/Graph/AdjacencyMatrix/WeightedDiGraph.cs

+6-13
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,21 @@
66
namespace Advanced.Algorithms.DataStructures.Graph.AdjacencyMatrix
77
{
88
/// <summary>
9-
/// A weighted graph implementation using dynamically growinng/shrinking adjacency matrix array.
9+
/// A weighted graph implementation using dynamically growing/shrinking adjacency matrix array.
1010
/// IEnumerable enumerates all vertices.
1111
/// </summary>
1212
public class WeightedDiGraph<T, TW> : IDiGraph<T>, IGraph<T>, IEnumerable<T> where TW : IComparable
1313
{
14-
public int VerticesCount { get; private set; }
15-
1614
private Dictionary<T, int> vertexIndices;
1715
private Dictionary<int, T> reverseVertexIndices;
1816
private Dictionary<T, WeightedDiGraphVertex<T, TW>> vertexObjects;
1917

2018
private TW[,] matrix;
2119
private int maxSize => matrix.GetLength(0);
20+
private int nextAvailableIndex;
2221

2322
public bool IsWeightedGraph => true;
24-
25-
private int nextAvailableIndex;
23+
public int VerticesCount => vertexObjects.Count;
2624

2725
public WeightedDiGraph()
2826
{
@@ -76,7 +74,6 @@ public void AddVertex(T value)
7674
reverseVertexIndices.Add(nextAvailableIndex, value);
7775
vertexObjects.Add(value, new WeightedDiGraphVertex<T, TW>(this, value));
7876
nextAvailableIndex++;
79-
VerticesCount++;
8077

8178
}
8279

@@ -113,7 +110,6 @@ public void RemoveVertex(T value)
113110
reverseVertexIndices.Remove(index);
114111
vertexIndices.Remove(value);
115112
vertexObjects.Remove(value);
116-
VerticesCount--;
117113

118114
}
119115

@@ -445,21 +441,18 @@ internal WeightedDiGraphVertex(WeightedDiGraph<T, TW> graph, T vertexKey)
445441

446442
public T Key => vertexKey;
447443

448-
IEnumerable<IDiEdge<T>> IDiGraphVertex<T>.OutEdges => OutEdges()
444+
IEnumerable<IDiEdge<T>> IDiGraphVertex<T>.OutEdges => graph.OutEdges(vertexKey)
449445
.Select(x => new DiEdge<T, TW>(graph.vertexObjects[x.Key], x.Value));
450446

451-
IEnumerable<IDiEdge<T>> IDiGraphVertex<T>.InEdges => InEdges()
447+
IEnumerable<IDiEdge<T>> IDiGraphVertex<T>.InEdges => graph.InEdges(vertexKey)
452448
.Select(x => new DiEdge<T, TW>(graph.vertexObjects[x.Key], x.Value));
453449

454-
IEnumerable<IEdge<T>> IGraphVertex<T>.Edges => OutEdges()
450+
IEnumerable<IEdge<T>> IGraphVertex<T>.Edges => graph.OutEdges(vertexKey)
455451
.Select(x => new Edge<T, TW>(graph.vertexObjects[x.Key], x.Value));
456452

457453
public int OutEdgeCount => graph.OutEdgeCount(vertexKey);
458454
public int InEdgeCount => graph.InEdgeCount(vertexKey);
459455

460-
public IEnumerable<KeyValuePair<T, TW>> OutEdges() => graph.OutEdges(vertexKey);
461-
public IEnumerable<KeyValuePair<T, TW>> InEdges() => graph.InEdges(vertexKey);
462-
463456
public IDiEdge<T> GetOutEdge(IDiGraphVertex<T> targetVertex)
464457
{
465458
if (!vertexIndices.ContainsKey(targetVertex.Key))

0 commit comments

Comments
 (0)