-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
279 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 } | ||
}; | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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")] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |