diff --git a/Algorithms.Dijktra.Tests/Algorithms.Dijktra.Tests.csproj b/Algorithms.Dijktra.Tests/Algorithms.Dijktra.Tests.csproj
new file mode 100644
index 00000000..e59c2c5f
--- /dev/null
+++ b/Algorithms.Dijktra.Tests/Algorithms.Dijktra.Tests.csproj
@@ -0,0 +1,30 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Algorithms.Dijktra.Tests/DijkstraUTests.cs b/Algorithms.Dijktra.Tests/DijkstraUTests.cs
new file mode 100644
index 00000000..6a82ff1d
--- /dev/null
+++ b/Algorithms.Dijktra.Tests/DijkstraUTests.cs
@@ -0,0 +1,201 @@
+using Algorithms.Graph.Dijkstra;
+using DataStructures.Graph;
+using FluentAssertions;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Algorithms.Dijktra.Tests
+{
+ [TestFixture]
+ public class DijkstraUTests
+ {
+ [Test]
+ public void DijkstraTest1_GraphIsNull()
+ {
+ var graph = new DirectedWeightedGraph(5);
+ var a = graph.AddVertex('A');
+
+ Func[]> action = () => DijkstraAlgorithm.GenerateShortestPath(null!, a);
+
+ action.Should().Throw()
+ .WithMessage($"Value cannot be null. (Parameter '{nameof(graph)}')");
+ }
+
+ [Test]
+ public void DijkstraTest2_VertexDoesntBelongToGraph()
+ {
+ var graph = new DirectedWeightedGraph(5);
+ var startVertex = graph.AddVertex('A');
+
+ Func[]> action = () => DijkstraAlgorithm.GenerateShortestPath(
+ new DirectedWeightedGraph(5), startVertex);
+
+ action.Should().Throw()
+ .WithMessage($"Value cannot be null. (Parameter '{nameof(graph)}')");
+ }
+
+ [Test]
+ public void DijkstraTest3_BasicGraph()
+ {
+ var graph = new DirectedWeightedGraph(4);
+ var a = graph.AddVertex('A');
+ var b = graph.AddVertex('B');
+ var c = graph.AddVertex('C');
+ var d = graph.AddVertex('D');
+
+ graph.AddEdge(a, b, 4);
+ graph.AddEdge(a, c, 7);
+ graph.AddEdge(b, c, 2);
+ graph.AddEdge(b, d, 3);
+ graph.AddEdge(c, d, 5);
+
+
+ var shortestPathList = DijkstraAlgorithm.GenerateShortestPath(graph, a);
+ shortestPathList.Length.Should().Be(4);
+
+ shortestPathList[0].PreviousVertex.Should().Be(a);
+ shortestPathList[0].Vertex.Should().Be(a);
+ shortestPathList[0].Distance.Should().Be(0);
+ shortestPathList[0].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {a} is Distance: {0}");
+
+ shortestPathList[1].PreviousVertex.Should().Be(a);
+ shortestPathList[1].Vertex.Should().Be(b);
+ shortestPathList[1].Distance.Should().Be(4);
+ shortestPathList[1].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {b} is Distance: {4}");
+
+ shortestPathList[2].PreviousVertex.Should().Be(b);
+ shortestPathList[2].Vertex.Should().Be(c);
+ shortestPathList[2].Distance.Should().Be(6);
+ shortestPathList[2].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {c} is Distance: {6}");
+
+ shortestPathList[3].PreviousVertex.Should().Be(b);
+ shortestPathList[3].Vertex.Should().Be(d);
+ shortestPathList[3].Distance.Should().Be(7);
+ shortestPathList[3].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {d} is Distance: {7}");
+ }
+
+ [Test]
+ public void DijkstraTest4_SparseGraph()
+ {
+ var graph = new DirectedWeightedGraph(6);
+ var a = graph.AddVertex('A');
+ var b = graph.AddVertex('B');
+ var c = graph.AddVertex('C');
+ var d = graph.AddVertex('D');
+ var e = graph.AddVertex('E');
+ var f = graph.AddVertex('F');
+
+ graph.AddEdge(a, f, 4);
+
+
+ var shortestPathList = DijkstraAlgorithm.GenerateShortestPath(graph, a);
+ shortestPathList.Length.Should().Be(6);
+
+ shortestPathList[0].PreviousVertex.Should().Be(a);
+ shortestPathList[0].Vertex.Should().Be(a);
+ shortestPathList[0].Distance.Should().Be(0);
+ shortestPathList[0].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {a} is Distance: {0}");
+
+ shortestPathList[1].PreviousVertex.Should().Be(null);
+ shortestPathList[1].Vertex.Should().Be(b);
+ shortestPathList[1].Distance.Should().Be(double.MaxValue);
+ shortestPathList[1].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {b} is Distance: {double.MaxValue}");
+
+ shortestPathList[2].PreviousVertex.Should().Be(null);
+ shortestPathList[2].Vertex.Should().Be(c);
+ shortestPathList[2].Distance.Should().Be(double.MaxValue);
+ shortestPathList[2].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {c} is Distance: {double.MaxValue}");
+
+ shortestPathList[3].PreviousVertex.Should().Be(null);
+ shortestPathList[3].Vertex.Should().Be(d);
+ shortestPathList[3].Distance.Should().Be(double.MaxValue);
+ shortestPathList[3].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {d} is Distance: {double.MaxValue}");
+
+ shortestPathList[4].PreviousVertex.Should().Be(null);
+ shortestPathList[4].Vertex.Should().Be(e);
+ shortestPathList[4].Distance.Should().Be(double.MaxValue);
+ shortestPathList[4].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {e} is Distance: {double.MaxValue}");
+
+ shortestPathList[5].PreviousVertex.Should().Be(a);
+ shortestPathList[5].Vertex.Should().Be(f);
+ shortestPathList[5].Distance.Should().Be(4);
+ shortestPathList[5].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {f} is Distance: {4}");
+ }
+
+ [Test]
+ public void DijkstraTest5_DenseGraph()
+ {
+ var graph = new DirectedWeightedGraph(6);
+ var a = graph.AddVertex('A');
+ var b = graph.AddVertex('B');
+ var c = graph.AddVertex('C');
+ var d = graph.AddVertex('D');
+ var e = graph.AddVertex('E');
+ var f = graph.AddVertex('F');
+
+ graph.AddEdge(a, b, 1);
+ graph.AddEdge(a, d, 2);
+ graph.AddEdge(b, c, 1);
+ graph.AddEdge(b, d, 2);
+ graph.AddEdge(b, e, 3);
+ graph.AddEdge(c, e, 2);
+ graph.AddEdge(c, f, 1);
+ graph.AddEdge(d, e, 1);
+ graph.AddEdge(e, f, 1);
+
+ var shortestPathList = DijkstraAlgorithm.GenerateShortestPath(graph, a);
+ shortestPathList.Length.Should().Be(6);
+
+ shortestPathList[0].PreviousVertex.Should().Be(a);
+ shortestPathList[0].Vertex.Should().Be(a);
+ shortestPathList[0].Distance.Should().Be(0);
+ shortestPathList[0].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {a} is Distance: {0}");
+
+ shortestPathList[1].PreviousVertex.Should().Be(a);
+ shortestPathList[1].Vertex.Should().Be(b);
+ shortestPathList[1].Distance.Should().Be(1);
+ shortestPathList[1].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {b} is Distance: {1}");
+
+ shortestPathList[2].PreviousVertex.Should().Be(b);
+ shortestPathList[2].Vertex.Should().Be(c);
+ shortestPathList[2].Distance.Should().Be(2);
+ shortestPathList[2].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {c} is Distance: {2}");
+
+ shortestPathList[3].PreviousVertex.Should().Be(a);
+ shortestPathList[3].Vertex.Should().Be(d);
+ shortestPathList[3].Distance.Should().Be(2);
+ shortestPathList[3].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {d} is Distance: {2}");
+
+ shortestPathList[4].PreviousVertex.Should().Be(d);
+ shortestPathList[4].Vertex.Should().Be(e);
+ shortestPathList[4].Distance.Should().Be(3);
+ shortestPathList[4].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {e} is Distance: {3}");
+
+ shortestPathList[5].PreviousVertex.Should().Be(c);
+ shortestPathList[5].Vertex.Should().Be(f);
+ shortestPathList[5].Distance.Should().Be(3);
+ shortestPathList[5].PrintDistance().Should()
+ .Be($"Start from Vertex: {a} to Vertex {f} is Distance: {3}");
+
+ }
+ }
+
+}
diff --git a/Algorithms/Graph/Dijkstra/DijkstraAlgorithm.cs b/Algorithms/Graph/Dijkstra/DijkstraAlgorithm.cs
index 8aee1f0f..4bcf7753 100644
--- a/Algorithms/Graph/Dijkstra/DijkstraAlgorithm.cs
+++ b/Algorithms/Graph/Dijkstra/DijkstraAlgorithm.cs
@@ -73,11 +73,11 @@ private static DistanceModel[] InitializeDistanceArray(
{
var distArray = new DistanceModel[graph.Count];
- distArray[startVertex.Index] = new DistanceModel(startVertex, startVertex, 0);
+ distArray[startVertex.Index] = new DistanceModel(startVertex, startVertex, startVertex, 0);
foreach (var vertex in graph.Vertices.Where(x => x != null && !x.Equals(startVertex)))
{
- distArray[vertex!.Index] = new DistanceModel(vertex, null, double.MaxValue);
+ distArray[vertex!.Index] = new DistanceModel(vertex, null, startVertex, double.MaxValue);
}
return distArray;
diff --git a/Algorithms/Graph/Dijkstra/DistanceModel.cs b/Algorithms/Graph/Dijkstra/DistanceModel.cs
index 133fa6d1..e99de447 100644
--- a/Algorithms/Graph/Dijkstra/DistanceModel.cs
+++ b/Algorithms/Graph/Dijkstra/DistanceModel.cs
@@ -13,6 +13,8 @@ public class DistanceModel
public Vertex? PreviousVertex { get; set; }
+ public Vertex? StartVertex { get; set; }
+
public double Distance { get; set; }
public DistanceModel(Vertex? vertex, Vertex? previousVertex, double distance)
@@ -22,6 +24,17 @@ public DistanceModel(Vertex? vertex, Vertex? previousVertex, double distan
Distance = distance;
}
+ public DistanceModel(Vertex? vertex, Vertex? previousVertex, Vertex? startVertex, double distance)
+ {
+ Vertex = vertex;
+ PreviousVertex = previousVertex;
+ Distance = distance;
+ StartVertex = startVertex;
+ }
+
public override string ToString() =>
- $"Vertex: {Vertex} - Distance: {Distance} - Previous: {PreviousVertex}";
+ $"From Previous Vertex: {PreviousVertex} to Vertex {Vertex} is Distance: {Distance}";
+
+ public string PrintDistance() =>
+ $"Start from Vertex: {StartVertex} to Vertex {Vertex} is Distance: {Distance}";
}
diff --git a/C-Sharp.sln b/C-Sharp.sln
index 857df3e5..4927092e 100644
--- a/C-Sharp.sln
+++ b/C-Sharp.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.28803.352
+# Visual Studio Version 17
+VisualStudioVersion = 17.13.35818.85 d17.13
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Docs", "Docs", "{DAB16DEC-AF31-4B59-8DD5-5C76C1A23052}"
ProjectSection(SolutionItems) = preProject
@@ -21,16 +21,16 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Configs", "Configs", "{F3AC
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Algorithms", "Algorithms\Algorithms.csproj", "{EC967159-73D8-4E44-8455-E2D16DB4CBBB}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Algorithms.Tests", "Algorithms.Tests\Algorithms.Tests.csproj", "{56817595-1552-409B-93B8-F8082F8490A5}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataStructures", "DataStructures\DataStructures.csproj", "{E9C27C73-1F95-4C6E-9DB4-F8585426A850}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataStructures.Tests", "DataStructures.Tests\DataStructures.Tests.csproj", "{39174100-3A6E-45B2-9AA9-7C69764C0750}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Utilities", "Utilities\Utilities.csproj", "{3A41157D-296D-4BFC-A34E-91B5ED7F0905}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Utilities.Tests", "Utilities.Tests\Utilities.Tests.csproj", "{ED47E2E2-045C-41DD-B555-A64944D6C2F5}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "UnitTest", "UnitTest", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Algorithms.Dijktra.Tests", "Algorithms.Dijktra.Tests\Algorithms.Dijktra.Tests.csproj", "{D64DF824-C9E7-4696-BA83-1B87B7C4B5E1}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -41,18 +41,10 @@ Global
{EC967159-73D8-4E44-8455-E2D16DB4CBBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EC967159-73D8-4E44-8455-E2D16DB4CBBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EC967159-73D8-4E44-8455-E2D16DB4CBBB}.Release|Any CPU.Build.0 = Release|Any CPU
- {56817595-1552-409B-93B8-F8082F8490A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {56817595-1552-409B-93B8-F8082F8490A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {56817595-1552-409B-93B8-F8082F8490A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {56817595-1552-409B-93B8-F8082F8490A5}.Release|Any CPU.Build.0 = Release|Any CPU
{E9C27C73-1F95-4C6E-9DB4-F8585426A850}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E9C27C73-1F95-4C6E-9DB4-F8585426A850}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E9C27C73-1F95-4C6E-9DB4-F8585426A850}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E9C27C73-1F95-4C6E-9DB4-F8585426A850}.Release|Any CPU.Build.0 = Release|Any CPU
- {39174100-3A6E-45B2-9AA9-7C69764C0750}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {39174100-3A6E-45B2-9AA9-7C69764C0750}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {39174100-3A6E-45B2-9AA9-7C69764C0750}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {39174100-3A6E-45B2-9AA9-7C69764C0750}.Release|Any CPU.Build.0 = Release|Any CPU
{3A41157D-296D-4BFC-A34E-91B5ED7F0905}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3A41157D-296D-4BFC-A34E-91B5ED7F0905}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3A41157D-296D-4BFC-A34E-91B5ED7F0905}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -61,10 +53,17 @@ Global
{ED47E2E2-045C-41DD-B555-A64944D6C2F5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ED47E2E2-045C-41DD-B555-A64944D6C2F5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ED47E2E2-045C-41DD-B555-A64944D6C2F5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D64DF824-C9E7-4696-BA83-1B87B7C4B5E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D64DF824-C9E7-4696-BA83-1B87B7C4B5E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D64DF824-C9E7-4696-BA83-1B87B7C4B5E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D64DF824-C9E7-4696-BA83-1B87B7C4B5E1}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {D64DF824-C9E7-4696-BA83-1B87B7C4B5E1} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
+ EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9D733AD8-7C69-4F40-ADBB-2DD8EA9F18FB}
EndGlobalSection