Skip to content

Commit

Permalink
Added dijkstra's Algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
rexiaxm7 committed Oct 8, 2018
1 parent 0f018c7 commit 67d2a5d
Show file tree
Hide file tree
Showing 8 changed files with 279 additions and 2 deletions.
9 changes: 7 additions & 2 deletions Tests/Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
Expand Down Expand Up @@ -49,6 +49,7 @@
<Reference Include="System.Core" />
</ItemGroup>
<ItemGroup>
<Compile Include="greedy\DijkstrasAlgorithmTests.cs" />
<Compile Include="sort\BubblesortTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="sort\SelectionsortTests.cs" />
Expand All @@ -65,6 +66,10 @@
<Project>{3511528E-8696-40B8-85AB-97456347A497}</Project>
<Name>csharp-algorithms</Name>
</ProjectReference>
<ProjectReference Include="..\dijkstrasAlgorithm\dijkstrasAlgorithm.csproj">
<Project>{8087DFD2-673A-499F-B130-0FAE0F31EADC}</Project>
<Name>dijkstrasAlgorithm</Name>
</ProjectReference>
<ProjectReference Include="..\selectionsort\selectionsort.csproj">
<Project>{A9022928-E9E9-45BE-BFEC-85A1A870A7EB}</Project>
<Name>selectionsort</Name>
Expand All @@ -80,4 +85,4 @@
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets'))" />
</Target>
<Import Project="..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets')" />
</Project>
</Project>
81 changes: 81 additions & 0 deletions Tests/greedy/DijkstrasAlgorithmTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Linq;
using dijkstrasalgorithm;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Tests.greedy
{
[TestClass]
public class DijkstrasAlgorithmTests
{
[TestMethod]
public void GetShortestPathTest()
{
//Arrange
var nodes = CreateNodeDictionary();
var expectedPath = new List<string> {"A", "C", "E", "F"};
const int expectedCost = 10;

//Act
var dijkstrasAlgorithm = new DijkstrasAlgorithm(nodes.Values, "A");
var shortestPath = dijkstrasAlgorithm.GetShortestPath("F");

//LogAndAssert
var actualPath = shortestPath.Select(node => node.Id).ToList();
var expectedPathString = string.Join(" -> ", expectedPath);
var actualPathString = string.Join(" -> ", actualPath);
var actualCost = shortestPath[shortestPath.Count - 1].Cost;
Console.WriteLine($"expected -- Cost: {expectedCost} Path: {expectedPathString}");
Console.WriteLine($"actual -- Cost: {actualCost} Path: {actualPathString}");
Assert.AreEqual(expectedCost, actualCost);
Assert.AreEqual(expectedPath.Count, actualPath.Count);
Assert.IsTrue(expectedPath.Zip(actualPath, (e, a) => e == a).All(e => e));
}

private IReadOnlyDictionary<string, Node> CreateNodeDictionary()
{
var node1 = new Node("A");
var node2 = new Node("B");
var node3 = new Node("C");
var node4 = new Node("D");
var node5 = new Node("E");
var node6 = new Node("F");

node1.AddEdge(new Edge(node2, 5));
node1.AddEdge(new Edge(node3, 4));
node1.AddEdge(new Edge(node4, 2));

node2.AddEdge(new Edge(node1, 5));
node2.AddEdge(new Edge(node6, 6));
node2.AddEdge(new Edge(node3, 2));

node3.AddEdge(new Edge(node2, 2));
node3.AddEdge(new Edge(node1, 4));
node3.AddEdge(new Edge(node4, 3));
node3.AddEdge(new Edge(node5, 2));

node4.AddEdge(new Edge(node1, 2));
node4.AddEdge(new Edge(node3, 3));
node4.AddEdge(new Edge(node5, 6));

node5.AddEdge(new Edge(node4, 6));
node5.AddEdge(new Edge(node3, 2));
node5.AddEdge(new Edge(node6, 4));

node6.AddEdge(new Edge(node2, 6));
node6.AddEdge(new Edge(node5, 4));

return new Dictionary<string, Node>
{
{ node1.Id, node1 },
{ node2.Id, node2 },
{ node3.Id, node3 },
{ node4.Id, node4 },
{ node5.Id, node5 },
{ node6.Id, node6 }
};
}

}
}
7 changes: 7 additions & 0 deletions csharp-algorithms.sln
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "search", "search", "{F61757
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "selectionsort", "selectionsort\selectionsort.csproj", "{A9022928-E9E9-45BE-BFEC-85A1A870A7EB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "dijkstrasAlgorithm", "dijkstrasAlgorithm\dijkstrasAlgorithm.csproj", "{8087DFD2-673A-499F-B130-0FAE0F31EADC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -39,13 +41,18 @@ Global
{A9022928-E9E9-45BE-BFEC-85A1A870A7EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A9022928-E9E9-45BE-BFEC-85A1A870A7EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A9022928-E9E9-45BE-BFEC-85A1A870A7EB}.Release|Any CPU.Build.0 = Release|Any CPU
{8087DFD2-673A-499F-B130-0FAE0F31EADC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8087DFD2-673A-499F-B130-0FAE0F31EADC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8087DFD2-673A-499F-B130-0FAE0F31EADC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8087DFD2-673A-499F-B130-0FAE0F31EADC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{C557EF5B-AEFE-407B-8D99-43B9EA625B71} = {6A9C8607-AA57-4817-B2C8-B8DD5065AC7C}
{A9022928-E9E9-45BE-BFEC-85A1A870A7EB} = {6A9C8607-AA57-4817-B2C8-B8DD5065AC7C}
{8087DFD2-673A-499F-B130-0FAE0F31EADC} = {05BBB622-53C5-4866-869B-B45978502CB5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7F2BFC66-A9D6-4C6D-A15A-984F23C11D29}
Expand Down
61 changes: 61 additions & 0 deletions dijkstrasAlgorithm/DijkstrasAlgorithm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
using System.Collections.Generic;
using System.Linq;

namespace dijkstrasalgorithm
{
public class DijkstrasAlgorithm
{
private readonly IReadOnlyDictionary<string, Node> _nodes;

public DijkstrasAlgorithm(IEnumerable<Node> nodes, string startId)
{
var nodeArray = nodes.ToArray();
_nodes = nodeArray.ToDictionary(node => node.Id, node => node);
Resolve(startId);
}

public List<Node> GetShortestPath(string endId)
{
var currentNode = _nodes[endId];
var endToStartPath = new List<Node>();

while (true)
{
endToStartPath.Add(currentNode);
if (currentNode.PreviousNode == null) break;
currentNode = currentNode.PreviousNode;
}

return Enumerable.Reverse(endToStartPath).ToList();
}

private void Resolve(string startId)
{
_nodes[startId].Cost = 0;
var destinationNodes = new Queue<Node>();
destinationNodes.Enqueue(_nodes[startId]);

do
{
var currentNode = destinationNodes.Dequeue();
if (currentNode.Visited) continue;

foreach (var edge in currentNode.Edges)
{
var node = edge.Node;
var cost = currentNode.Cost + edge.Cost;

if (node.Cost > cost)
{
node.Cost = cost;
node.PreviousNode = currentNode;
}

if (!node.Visited) destinationNodes.Enqueue(node);
}

currentNode.Visited = true;
} while (destinationNodes.Any());
}
}
}
14 changes: 14 additions & 0 deletions dijkstrasAlgorithm/Edge.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace dijkstrasalgorithm
{
public class Edge
{
public Edge(Node node, int cost)
{
Node = node;
Cost = cost;
}

public Node Node { get; }
public int Cost { get; }
}
}
23 changes: 23 additions & 0 deletions dijkstrasAlgorithm/Node.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Collections.Generic;

namespace dijkstrasalgorithm
{
public class Node
{
public Node(string id)
{
Id = id;
}

public string Id { get; }
public HashSet<Edge> Edges { get; } = new HashSet<Edge>();
public Node PreviousNode { get; set; }
public bool Visited { get; set; }
public int Cost { get; set; } = int.MaxValue;

public void AddEdge(Edge edge)
{
Edges.Add(edge);
}
}
}
36 changes: 36 additions & 0 deletions dijkstrasAlgorithm/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// アセンブリに関する一般情報は以下の属性セットをとおして制御されます。
// アセンブリに関連付けられている情報を変更するには、
// これらの属性値を変更してください。
[assembly: AssemblyTitle("dijkstrasAlgorithm")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("dijkstrasAlgorithm")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// ComVisible を false に設定すると、このアセンブリ内の型は COM コンポーネントから
// 参照できなくなります。COM からこのアセンブリ内の型にアクセスする必要がある場合は、
// その型の ComVisible 属性を true に設定してください。
[assembly: ComVisible(false)]

// このプロジェクトが COM に公開される場合、次の GUID が typelib の ID になります
[assembly: Guid("8087dfd2-673a-499f-b130-0fae0f31eadc")]

// アセンブリのバージョン情報は次の 4 つの値で構成されています:
//
// メジャー バージョン
// マイナー バージョン
// ビルド番号
// Revision
//
// すべての値を指定するか、次を使用してビルド番号とリビジョン番号を既定に設定できます
// 以下のように '*' を使用します:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
50 changes: 50 additions & 0 deletions dijkstrasAlgorithm/dijkstrasAlgorithm.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8087DFD2-673A-499F-B130-0FAE0F31EADC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>dijkstrasAlgorithm</RootNamespace>
<AssemblyName>dijkstrasAlgorithm</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="DijkstrasAlgorithm.cs" />
<Compile Include="Edge.cs" />
<Compile Include="Node.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

0 comments on commit 67d2a5d

Please sign in to comment.