Skip to content

Commit ed623b4

Browse files
committed
update FindPath
1 parent 5016191 commit ed623b4

File tree

4 files changed

+64
-57
lines changed

4 files changed

+64
-57
lines changed

Assets/Scripts/01-findPath/Algorithm/Astar.cs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Text;
5+
using UnityEngine;
6+
57
namespace LinHoweFindPath
68
{
79

@@ -13,14 +15,18 @@ public class Astar:FindPathAlgorithm
1315
//关闭列表
1416
private static List<Node> close_List = new List<Node>();
1517

16-
//g(n)初始节点到n节点的实际代价
17-
private static Func<Node, double> G = node => CostDict[node];
18+
private static Node end;
1819

19-
//h(n)是从n到目标节点最佳路径的估计代价。
20-
private static Func<Node,Node, double> H = (node,end) =>
21-
(Math.Pow(node.x - end.x, 2)/100f + Math.Pow(node.z - end.z, 2)/100f);
2220

23-
private static Node end;
21+
/// <summary>
22+
/// Astar算法
23+
/// 时间复杂度:O(n^2)
24+
/// 空间复杂度 O(n)
25+
/// </summary>
26+
/// <param name="start"></param>
27+
/// <param name="end"></param>
28+
/// <param name="nodesMap"></param>
29+
/// <returns></returns>
2430
public static Queue<Node> FindWay
2531
(
2632
Node start,Node end,
@@ -46,6 +52,7 @@ public static Queue<Node> FindWay
4652

4753
if(null == curnode)
4854
{
55+
Debug.LogError("意外的null节点");
4956
break;
5057
}
5158
else
@@ -104,7 +111,7 @@ private static bool IsInCloseList(Node node)
104111
}
105112

106113
/// <summary>
107-
/// 检测节点附近的节点
114+
/// 检测节点附近的节点,将附近的节点加入OpenList
108115
/// </summary>
109116
private static void CheckNodeNearby(Node cur)
110117
{
@@ -121,11 +128,7 @@ private static void CheckNodeNearby(Node cur)
121128
if (cost + CostDict[cur] < CostDict[node])
122129
{
123130
CostDict[node] = cost + CostDict[cur];
124-
RoadDict[node] = new Queue<Node>(NodeCount);
125-
foreach (var e in RoadDict[cur])
126-
{
127-
RoadDict[node].Enqueue(e);
128-
}
131+
RoadDict[node] = new Queue<Node>(RoadDict[cur]);
129132
RoadDict[node].Enqueue(node);
130133
}
131134

Assets/Scripts/01-findPath/Algorithm/BFS.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public class BFS : FindPathAlgorithm
1212

1313
/// <summary>
1414
/// 获得保证最小消耗的路径(需要访问所有节点)BFS
15+
/// 时间复杂度:O(n^2)
16+
/// 空间复杂度 O(n)
1517
/// </summary>
1618
/// <param name="start"></param>
1719
/// <param name="end"></param>
@@ -37,7 +39,7 @@ Dictionary<Node, int> nodesMap
3739
while (curcount < NodeCount && canGetMinNodelist.Count > 0)
3840
{
3941
//查找访问过节点中距离终点最近的点
40-
Node cur = canGetMinNodelist.First();
42+
Node cur = (Node)GetMinNodeFromArr(canGetMinNodelist, end, x=>H(x,end));
4143

4244
//查找cur所能到达的节点列表
4345
List<Node> arr = GetNearbyNode(cur, false);
@@ -63,11 +65,7 @@ Dictionary<Node, int> nodesMap
6365
{
6466
CostDict[n] = CostDict[cur] + NodesMap[n];
6567

66-
RoadDict[n] = new Queue<Node>(NodeCount);
67-
foreach (var e in RoadDict[cur])
68-
{
69-
RoadDict[n].Enqueue(e);
70-
}
68+
RoadDict[n] = new Queue<Node>(RoadDict[cur]);
7169
RoadDict[n].Enqueue(n);
7270

7371
}

Assets/Scripts/01-findPath/Algorithm/Dijkstra.cs

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ public class Dijkstra: FindPathAlgorithm
1010
{
1111

1212
/// <summary>
13-
///
13+
/// Dijkstra
14+
/// 时间复杂度:O(n^2)
15+
/// 空间复杂度 O(n)
1416
/// </summary>
1517
/// <param name="start"></param>
1618
/// <param name="end"></param>
@@ -30,48 +32,42 @@ public static Queue<Node> FindWay(
3032
int curcount = 1;
3133
CostDict[start] = 0;
3234
RoadDict[start].Enqueue(start);
33-
Node? curnode = null;
3435
Node cur = start;
35-
Func<Node, double> GetMin = node => CostDict[node];
36-
//Find
37-
while (curcount < NodeCount && cur != end)
38-
{
39-
//查找访问过节点中cost最小的节点
40-
curnode = GetMinNodeFromArr(canGetMinNodelist, end, GetMin);
41-
42-
//无法到达终点
43-
if (null == curnode)
44-
break;
45-
46-
//查找curnode下一个节点中距离终点最近的点
47-
cur = (Node)curnode;
48-
Node? minnode = GetMinNode(cur, end, GetMin);
4936

50-
if (null == minnode)
37+
bool reachEnd = false;
38+
while(curcount < NodeCount && !reachEnd)
39+
{
40+
int size = canGetMinNodelist.Count;
41+
for(int j = 0;j < size;++j)
5142
{
52-
//当前节点无法到达终点
43+
cur = canGetMinNodelist[0];
44+
List<Node> nearbynodes = GetNearbyNode(cur, false);
45+
46+
visit[cur] = true;
47+
curcount++;
5348
canGetMinNodelist.Remove(cur);
54-
continue;
55-
}
56-
else
57-
{
49+
for (int i = 0; i < nearbynodes.Count; ++i)
50+
{
51+
Node next = nearbynodes[i];
52+
if (next == end&&!reachEnd)
53+
reachEnd = true;
54+
int newcost = CostDict[cur] + NodesMap[next];
5855

56+
//cost更小的情况
57+
if (newcost < CostDict[next])
58+
{
59+
RoadDict[next].Clear();
60+
CostDict[next] = newcost;
5961

60-
Node _min = (Node)minnode;
62+
//更新路径
63+
RoadDict[next] = new Queue<Node>(RoadDict[cur]);
64+
RoadDict[next].Enqueue(next);
6165

62-
//标记为已访问
63-
visit[_min] = true;
64-
curcount++;
65-
canGetMinNodelist.Add(_min);
66+
if (!canGetMinNodelist.Contains(next))
67+
canGetMinNodelist.Add(next);
68+
}
6669

67-
//更新路径
68-
CostDict[_min] = CostDict[cur] + NodesMap[_min];
69-
RoadDict[_min].Clear();
70-
foreach (var e in RoadDict[cur])
71-
{
72-
RoadDict[_min].Enqueue(e);
7370
}
74-
RoadDict[_min].Enqueue(_min);
7571
}
7672
}
7773

Assets/Scripts/01-findPath/Algorithm/FindPathAlgorithm.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,12 @@ namespace LinHoweFindPath
77
{
88
public class FindPathAlgorithm
99
{
10+
//g(n)初始节点到n节点的实际代价
11+
protected static Func<Node, double> G = node => CostDict[node];
12+
13+
//h(n)是从n到目标节点最佳路径的估计代价。
14+
protected static Func<Node, Node, double> H = (node, end) =>
15+
(Math.Abs(node.x - end.x) + Math.Abs(node.z - end.z));
1016
/// <summary>
1117
/// 已访问且四周存在未访问节点的列表
1218
/// </summary>
@@ -70,21 +76,25 @@ protected static List<Node> GetNearbyNode(Node cur, bool thinkAboutVisit = true)
7076
for(int i = 3;i>=0;--i)
7177
{
7278
Node node = arr[i];
73-
if(!NodesMap.ContainsKey(node))
79+
80+
//不存在的节点
81+
if (!NodesMap.ContainsKey(node))
7482
{
7583
arr.RemoveAt(i);
7684
continue;
7785
}
7886

79-
if(thinkAboutVisit)
87+
if (thinkAboutVisit)
8088
{
89+
//访问过
8190
if(visit[node])
8291
{
8392
arr.RemoveAt(i);
8493
continue;
8594
}
8695
}
8796

97+
//障碍物
8898
if(NodesMap[node] >= int.MaxValue)
8999
{
90100
arr.RemoveAt(i);
@@ -101,7 +111,7 @@ protected static List<Node> GetNearbyNode(Node cur, bool thinkAboutVisit = true)
101111
/// <param name="end"></param>
102112
/// <returns></returns>
103113
protected static Node? GetMinNodeFromArr(
104-
List<Node> arr, Node end,Func<Node, double> getMinFunc)
114+
List<Node> arr, Node end, Func<Node, double> getMinFunc)
105115
{
106116
if (0 == arr.Count) return null;
107117
if (1 == arr.Count) return arr[0];
@@ -110,7 +120,7 @@ protected static List<Node> GetNearbyNode(Node cur, bool thinkAboutVisit = true)
110120
.First();
111121
return res;
112122
}
113-
//node => CostDict[node]
123+
114124
/// <summary>
115125
/// 查找start的下一个节点,保证距离end最近
116126
/// </summary>
@@ -138,7 +148,7 @@ protected static Node? GetMinNode
138148
protected static Node? GetMinNodeFromVisit(
139149
List<Node> arr, Node end, Func<Node, double> getMinFunc, bool thinkAboutVisit = true)
140150
{
141-
if(thinkAboutVisit)
151+
if (thinkAboutVisit)
142152
arr = arr
143153
.Where(node => !visit[node]).ToList();
144154

0 commit comments

Comments
 (0)