Skip to content

Commit 4f12076

Browse files
committed
Travelling Salesman problem
1 parent e4d738a commit 4f12076

File tree

4 files changed

+120
-0
lines changed

4 files changed

+120
-0
lines changed

Advanced.Algorithms.Tests/Advanced.Algorithms.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
<Compile Include="DataStructures\Tree\Tree_Tests.cs" />
128128
<Compile Include="DataStructures\Tree\BinaryTree_Tests.cs" />
129129
<Compile Include="Geometry\PointRotation_Tests.cs" />
130+
<Compile Include="GraphAlgorithms\ShortestPath\TravellingSalesman_Tests.cs" />
130131
<Compile Include="Miscellaneous\MatrixMultiplication_Tests.cs" />
131132
<Compile Include="Geometry\ClosestPointPair_Tests.cs" />
132133
<Compile Include="Geometry\ConvexHull_Tests.cs" />
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using Advanced.Algorithms.DataStructures.Graph.AdjacencyList;
2+
using Advanced.Algorithms.GraphAlgorithms;
3+
using Microsoft.VisualStudio.TestTools.UnitTesting;
4+
5+
namespace Advanced.Algorithms.Tests.GraphAlgorithms.ShortestPath
6+
{
7+
/// <summary>
8+
/// Problem details below
9+
/// https://en.wikipedia.org/wiki/Travelling_salesman_problem
10+
/// </summary>
11+
[TestClass]
12+
public class TravellingSalesman_Tests
13+
{
14+
[TestMethod]
15+
public void TravellingSalesman_Smoke_Test()
16+
{
17+
var graph = new WeightedDiGraph<int, int>();
18+
19+
graph.AddVertex(0);
20+
graph.AddVertex(1);
21+
graph.AddVertex(2);
22+
graph.AddVertex(3);
23+
24+
graph.AddEdge(0, 1, 1);
25+
graph.AddEdge(0, 2, 15);
26+
graph.AddEdge(0, 3, 6);
27+
28+
graph.AddEdge(1, 0, 2);
29+
graph.AddEdge(1, 2, 7);
30+
graph.AddEdge(1, 3, 3);
31+
32+
graph.AddEdge(2, 0, 9);
33+
graph.AddEdge(2, 1, 6);
34+
graph.AddEdge(2, 3, 12);
35+
36+
graph.AddEdge(3, 0, 10);
37+
graph.AddEdge(3, 1, 4);
38+
graph.AddEdge(3, 2, 8);
39+
40+
Assert.AreEqual(21, TravellingSalesman.GetMinWeight(graph));
41+
}
42+
}
43+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+

2+
using Advanced.Algorithms.DataStructures.Graph.AdjacencyList;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
6+
namespace Advanced.Algorithms.GraphAlgorithms
7+
{
8+
/// <summary>
9+
/// Problem details below
10+
/// https://en.wikipedia.org/wiki/Travelling_salesman_problem
11+
/// Uses dynamic programming and have
12+
/// psuedo-polynomial time runtime complexity for this NP hard problem
13+
/// </summary>
14+
public class TravellingSalesman
15+
{
16+
public static int GetMinWeight(WeightedDiGraph<int, int> graph)
17+
{
18+
return GetMinWeight(graph.ReferenceVertex, graph.ReferenceVertex,
19+
graph.VerticesCount,
20+
new HashSet<WeightedDiGraphVertex<int, int>>(),
21+
new Dictionary<string, int>());
22+
}
23+
24+
public static int GetMinWeight(WeightedDiGraphVertex<int, int> currentVertex,
25+
WeightedDiGraphVertex<int, int> tgtVertex,
26+
int remainingVertexCount,
27+
HashSet<WeightedDiGraphVertex<int, int>> visited,
28+
Dictionary<string, int> cache)
29+
{
30+
var cacheKey = $"{currentVertex.Value}-{remainingVertexCount}";
31+
32+
if (cache.ContainsKey(cacheKey))
33+
{
34+
return cache[cacheKey];
35+
}
36+
37+
visited.Add(currentVertex);
38+
39+
var results = new List<int>();
40+
41+
foreach (var vertex in currentVertex.OutEdges)
42+
{
43+
//base case
44+
if (vertex.Key == tgtVertex
45+
&& remainingVertexCount == 1)
46+
{
47+
results.Add(vertex.Value);
48+
break;
49+
}
50+
51+
if (!visited.Contains(vertex.Key))
52+
{
53+
var result = GetMinWeight(vertex.Key, tgtVertex, remainingVertexCount - 1, visited, cache);
54+
55+
if (result != int.MaxValue)
56+
{
57+
results.Add(result + vertex.Value);
58+
}
59+
60+
}
61+
}
62+
63+
visited.Remove(currentVertex);
64+
65+
if (results.Count == 0)
66+
{
67+
return int.MaxValue;
68+
}
69+
70+
var min = results.Min();
71+
cache.Add(cacheKey, min);
72+
return min;
73+
}
74+
}
75+
}

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ Note: It is observed that among the implementations here in practice, with the e
172172
- [X] Dijikstra's algorithm ([Implementation](https://github.com/justcoding121/Advanced-Algorithms/tree/develop/Advanced.Algorithms/GraphAlgorithms/ShortestPath/Dijikstra.cs) | [Tests](https://github.com/justcoding121/Advanced-Algorithms/tree/develop/Advanced.Algorithms.Tests/GraphAlgorithms/ShortestPath/Dijikstras_Tests.cs)) using Fibornacci Heap.
173173
- [X] Floyd-Warshall algorithm ([Implementation](https://github.com/justcoding121/Advanced-Algorithms/tree/develop/Advanced.Algorithms/GraphAlgorithms/ShortestPath/Floyd-Warshall.cs) | [Tests](https://github.com/justcoding121/Advanced-Algorithms/tree/develop/Advanced.Algorithms.Tests/GraphAlgorithms/ShortestPath/FloydWarshall_Tests.cs))
174174
- [X] Johnson's algorithm ([Implementation](https://github.com/justcoding121/Advanced-Algorithms/tree/develop/Advanced.Algorithms/GraphAlgorithms/ShortestPath/Johnsons.cs) | [Tests](https://github.com/justcoding121/Advanced-Algorithms/tree/develop/Advanced.Algorithms.Tests/GraphAlgorithms/ShortestPath/Johnson_Tests.cs))
175+
- [X] Travelling Salesman Problem ([Implementation](https://github.com/justcoding121/Advanced-Algorithms/tree/develop/Advanced.Algorithms/GraphAlgorithms/ShortestPath/TravellingSalesman.cs) | [Tests](https://github.com/justcoding121/Advanced-Algorithms/tree/develop/Advanced.Algorithms.Tests/GraphAlgorithms/ShortestPath/TravellingSalesman_Tests.cs))
175176

176177
### Matching
177178

0 commit comments

Comments
 (0)