From 43254f9e54810a0ee7fabd6a382298522a1b7b34 Mon Sep 17 00:00:00 2001 From: Leroy Korterink Date: Sat, 27 Oct 2018 23:49:22 +0200 Subject: [PATCH] Clean up graph code --- Graph/Edge.cs | 4 +-- Graph/Graph.cs | 66 +++++++++++++++++++++++++++++++--------- Graph/IGraph.cs | 2 +- GraphTests/GraphTests.cs | 43 +++++++++++++++----------- 4 files changed, 80 insertions(+), 35 deletions(-) diff --git a/Graph/Edge.cs b/Graph/Edge.cs index df373c9..144e783 100644 --- a/Graph/Edge.cs +++ b/Graph/Edge.cs @@ -2,10 +2,10 @@ namespace Graph { public class Edge { - public IVertex Destination; + public Vertex Destination; public double Cost; - public Edge(IVertex destination, double cost) + public Edge(Vertex destination, double cost) { Destination = destination; Cost = cost; diff --git a/Graph/Graph.cs b/Graph/Graph.cs index f9ebee3..e8cbe69 100644 --- a/Graph/Graph.cs +++ b/Graph/Graph.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Net.Http.Headers; using PriorityQueue; namespace Graph @@ -18,7 +17,7 @@ public class Graph : IGraph /// /// /// - public IVertex GetVertex(string vertexName) + public Vertex GetVertex(string vertexName) { if (VertexMap.TryGetValue(vertexName, out var vertex)) return vertex; @@ -28,9 +27,15 @@ public IVertex GetVertex(string vertexName) return vertex; } + /// + /// Adds a new edge to the current graph + /// + /// + /// + /// public void AddEdge(string sourceVertexName, string destinationVertexName, double cost) { - var sourceVertex = (Vertex) GetVertex(sourceVertexName); + var sourceVertex = GetVertex(sourceVertexName); var destinationVertex = GetVertex(destinationVertexName); sourceVertex.AdjacentVertices.Add(new Edge(destinationVertex, cost)); @@ -77,12 +82,6 @@ public string PathToString(string destinationName) return $"(Cost is: {vertex.Distance}) {PathToString(vertex)}"; } - - public override string ToString() - { - throw new NotImplementedException(); - } - #region Shortest-path algorithms /// @@ -106,13 +105,13 @@ public void Unweighted(string startVertexName) while (queue.Count != 0) { var currentVertex = queue.Dequeue(); - + // Set visited to true so we can check if the graph is connected or not currentVertex.Visited = true; currentVertex.AdjacentVertices.ForEach(edge => { - var adjacentVertex = (Vertex) edge.Destination; + var adjacentVertex = edge.Destination; if (adjacentVertex.Distance != Infinity) return; @@ -124,6 +123,12 @@ public void Unweighted(string startVertexName) } } + /// + /// Single-source weighted shortest-path algorithm + /// + /// + /// + /// public void Dijkstra(string startVertexName) { ClearAll(); @@ -151,7 +156,7 @@ public void Dijkstra(string startVertexName) vertex.AdjacentVertices.ForEach(edge => { - var adjacentVertex = (Vertex) edge.Destination; + var adjacentVertex = edge.Destination; var edgeCost = edge.Cost; if (edgeCost < 0) @@ -171,10 +176,14 @@ public void Dijkstra(string startVertexName) #endregion + /// + /// Checks whether all vertices in this graph are connected + /// + /// public bool IsConnected() { - Unweighted(VertexMap.First().Value.Name); - + Unweighted(VertexMap.First().Value.Name); + foreach (var vertex in VertexMap.Values) // Return false when any vertex has not been visited if (!vertex.Visited) @@ -182,6 +191,35 @@ public bool IsConnected() return true; } + + /// + /// Prints vertex with its adjacent vertices + /// + /// V0 --> V1(2) V3(1) + /// V1 --> V3(3) V4(10) + /// V2 --> V0(4) V5(5) + /// V3 --> V2(2) V5(8) V6(4) V4(2) + /// V4 --> V6(6) + /// V5 --> + /// V6 --> V5(1) + /// + /// + public override string ToString() + { + var output = ""; + + foreach (var vertex in VertexMap.Values) + { + var adjacentVertexes = vertex.AdjacentVertices.Aggregate( + "", + (accumulator, edge) => { return accumulator += $"{edge.Destination.Name}({edge.Cost})"; } + ); + + output += vertex.Name + " --> " + adjacentVertexes; + } + + return output; + } } #region Custom error classes diff --git a/Graph/IGraph.cs b/Graph/IGraph.cs index e1d05f7..f911d3e 100644 --- a/Graph/IGraph.cs +++ b/Graph/IGraph.cs @@ -2,7 +2,7 @@ namespace Graph { public interface IGraph { - IVertex GetVertex(string vertexName); + Vertex GetVertex(string vertexName); void AddEdge(string sourceVertexName, string destinationVertexName, double cost); diff --git a/GraphTests/GraphTests.cs b/GraphTests/GraphTests.cs index d10135a..a6e7352 100644 --- a/GraphTests/GraphTests.cs +++ b/GraphTests/GraphTests.cs @@ -54,7 +54,7 @@ public void Should_GetVertex() var myGraph = new Graph.Graph(); myGraph.AddEdge("V0", "V1", 5); - var myVertex = (Vertex) myGraph.GetVertex("V0"); + var myVertex = myGraph.GetVertex("V0"); Assert.Equal("V0", myVertex.Name); } @@ -65,7 +65,7 @@ public void Should_AddEdge() var myGraph = new Graph.Graph(); myGraph.AddEdge("V0", "V1", 5); - var myVertex = (Vertex) myGraph.GetVertex("V0"); + var myVertex = myGraph.GetVertex("V0"); Assert.Equal(5, myVertex.AdjacentVertices[0].Cost); } @@ -88,13 +88,13 @@ public void Should_Unweighted() myGraph.Unweighted("V0"); - Assert.Equal(0, ((Vertex) myGraph.GetVertex("V0")).Distance); - Assert.Equal(1, ((Vertex) myGraph.GetVertex("V1")).Distance); - Assert.Equal(2, ((Vertex) myGraph.GetVertex("V2")).Distance); - Assert.Equal(1, ((Vertex) myGraph.GetVertex("V3")).Distance); - Assert.Equal(2, ((Vertex) myGraph.GetVertex("V4")).Distance); - Assert.Equal(2, ((Vertex) myGraph.GetVertex("V5")).Distance); - Assert.Equal(2, ((Vertex) myGraph.GetVertex("V6")).Distance); + Assert.Equal(0, (myGraph.GetVertex("V0")).Distance); + Assert.Equal(1, (myGraph.GetVertex("V1")).Distance); + Assert.Equal(2, (myGraph.GetVertex("V2")).Distance); + Assert.Equal(1, (myGraph.GetVertex("V3")).Distance); + Assert.Equal(2, (myGraph.GetVertex("V4")).Distance); + Assert.Equal(2, (myGraph.GetVertex("V5")).Distance); + Assert.Equal(2, (myGraph.GetVertex("V6")).Distance); } [Fact] @@ -104,13 +104,13 @@ public void Should_Dijkstra() myGraph.Dijkstra("V0"); - Assert.Equal(0, ((Vertex) myGraph.GetVertex("V0")).Distance); - Assert.Equal(2, ((Vertex) myGraph.GetVertex("V1")).Distance); - Assert.Equal(3, ((Vertex) myGraph.GetVertex("V2")).Distance); - Assert.Equal(1, ((Vertex) myGraph.GetVertex("V3")).Distance); - Assert.Equal(3, ((Vertex) myGraph.GetVertex("V4")).Distance); - Assert.Equal(6, ((Vertex) myGraph.GetVertex("V5")).Distance); - Assert.Equal(5, ((Vertex) myGraph.GetVertex("V6")).Distance); + Assert.Equal(0, (myGraph.GetVertex("V0")).Distance); + Assert.Equal(2, (myGraph.GetVertex("V1")).Distance); + Assert.Equal(3, (myGraph.GetVertex("V2")).Distance); + Assert.Equal(1, (myGraph.GetVertex("V3")).Distance); + Assert.Equal(3, (myGraph.GetVertex("V4")).Distance); + Assert.Equal(6, (myGraph.GetVertex("V5")).Distance); + Assert.Equal(5, (myGraph.GetVertex("V6")).Distance); } [Fact] @@ -120,12 +120,12 @@ public void Should_ReturnTrue_When_IsConnected() Assert.True(myGraph.IsConnected()); } - + [Fact] public void Should_ReturnFalse_When_IsNotConnected() { var myGraph = new Graph.Graph(); - + myGraph.AddEdge("V0", "V1", 2); myGraph.AddEdge("V2", "V3", 3); @@ -137,7 +137,14 @@ public void Should_ToString() { var myGraph = CreateGraph(); + myGraph.Dijkstra("V0"); + _output.WriteLine(myGraph.ToString()); + + Assert.Equal( + "V0 --> V1(2) V3(1)\nV1 --> V3(3) V4(10)\nV2 --> V0(4) V5(5)\nV3 --> V2(2) V5(8) V6(4) V4(2)\nV4 --> V6(6)\nV5 -->\nV6 --> V5(1)\n", + myGraph.ToString() + ); } } } \ No newline at end of file