Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added dijkstra's Algorithm #23

Merged
merged 1 commit into from
Oct 11, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>