Skip to content

Commit e0ad6d0

Browse files
committed
AStar add
1 parent 81b6259 commit e0ad6d0

File tree

3 files changed

+96
-2
lines changed

3 files changed

+96
-2
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Dijkstra.NET.Graph;
4+
5+
namespace Dijkstra.NET.ShortestPath
6+
{
7+
internal static class AStar
8+
{
9+
public static ShortestPathResult GetShortestPath(IDijkstraGraph graph, uint from, uint to, Func<uint,uint,int> heuristic, int depth)
10+
{
11+
var path = new Dictionary<uint, uint>();
12+
var distance = new Dictionary<uint, int> {[from] = 0};
13+
var d = new Dictionary<uint, int> {[from] = 0};
14+
var q = new SortedSet<uint>(new[] {from}, new NodeComparer(distance, heuristic));
15+
var current = new HashSet<uint>();
16+
17+
int Distance(uint key)
18+
{
19+
return distance.ContainsKey(key) ? distance[key] : Int32.MaxValue;
20+
}
21+
22+
do
23+
{
24+
uint u = q.Deque();
25+
26+
if (u == to)
27+
{
28+
return new ShortestPathResult(from, to, distance[u], path);
29+
}
30+
31+
current.Remove(u);
32+
33+
if (depth == d[u])
34+
{
35+
continue;
36+
}
37+
38+
graph[u]((node, cost) =>
39+
{
40+
if (Distance(node) > Distance(u) + cost)
41+
{
42+
if (current.Contains(node))
43+
{
44+
q.Remove(node);
45+
}
46+
47+
distance[node] = Distance(u) + cost;
48+
q.Add(node);
49+
current.Add(node);
50+
path[node] = u;
51+
d[node] = d[u] + 1;
52+
}
53+
});
54+
55+
} while (q.Count > 0 && depth > 0);
56+
57+
return new ShortestPathResult(from, to);
58+
}
59+
}
60+
}

src/Dijkstra.NET/ShortestPath/DijkstraExtensions.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,16 @@ public static class DijkstraExtensions
1717
public static ShortestPathResult Dijkstra(this IDijkstraGraph graph, uint from, uint to)
1818
=> Dijkstra(graph, from, to, Int32.MaxValue);
1919

20+
/// <summary>
21+
/// Get path from @from to @to
22+
/// </summary>
23+
/// <param name="graph">Source graph</param>
24+
/// <param name="from">Start node</param>
25+
/// <param name="to">End node</param>
26+
/// <returns>Value with path</returns>
27+
public static ShortestPathResult AStar(this IDijkstraGraph graph, uint from, uint to, Func<uint,uint,int> heuristic)
28+
=> AStar(graph, from, to, heuristic, Int32.MaxValue);
29+
2030
/// <summary>
2131
/// Get path from @from to @to
2232
/// </summary>
@@ -29,5 +39,18 @@ public static ShortestPathResult Dijkstra(this IDijkstraGraph graph, uint from,
2939
{
3040
return ShortestPath.Dijkstra.GetShortestPath(graph, from, to, depth);
3141
}
42+
43+
/// <summary>
44+
/// Get path from @from to @to
45+
/// </summary>
46+
/// <param name="graph">Source graph</param>
47+
/// <param name="from">Start node</param>
48+
/// <param name="to">End node</param>
49+
/// <param name="depth">Depth of path</param>
50+
/// <returns>Value with path</returns>
51+
public static ShortestPathResult AStar(this IDijkstraGraph graph, uint from, uint to, Func<uint, uint, int> heuristic, int depth)
52+
{
53+
return ShortestPath.AStar.GetShortestPath(graph, from, to, heuristic, depth);
54+
}
3255
}
3356
}

src/Dijkstra.NET/ShortestPath/NodeComparer.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,27 @@ namespace Dijkstra.NET.ShortestPath
66
internal class NodeComparer : IComparer<uint>
77
{
88
private readonly IDictionary<uint, int> _distance;
9+
private readonly Func<uint, uint, int> _heuristic;
910

1011
public NodeComparer(IDictionary<uint, int> distance)
1112
{
1213
_distance = distance;
14+
_heuristic = null;
15+
}
16+
public NodeComparer(IDictionary<uint, int> distance, Func<uint, uint, int> heuristic)
17+
{
18+
_distance = distance;
19+
_heuristic = heuristic;
1320
}
1421

1522
public int Compare(uint x, uint y)
1623
{
17-
int xDistance = _distance.ContainsKey(x) ? _distance[x] : Int32.MaxValue;
18-
int yDistance = _distance.ContainsKey(y) ? _distance[y] : Int32.MaxValue;
24+
int xDistance = _distance.ContainsKey(x) ?
25+
_heuristic is null ? _distance[x] : _distance[x] + _heuristic(x, y)
26+
: Int32.MaxValue;
27+
int yDistance = _distance.ContainsKey(y) ?
28+
_heuristic is null ? _distance[y] : _distance[y] + _heuristic(y, x)
29+
: Int32.MaxValue;
1930

2031
int comparer = xDistance.CompareTo(yDistance);
2132

0 commit comments

Comments
 (0)