Skip to content

Commit 9d4e478

Browse files
committed
Update FindWay Algorithm
1 parent 54d9257 commit 9d4e478

File tree

5 files changed

+126
-189
lines changed

5 files changed

+126
-189
lines changed

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

Lines changed: 14 additions & 139 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,24 @@ public class Astar:FindPathAlgorithm
1313
//关闭列表
1414
private static List<Node> close_List = new List<Node>();
1515

16+
//g(n)初始节点到n节点的实际代价
17+
private static Func<Node, double> G = node => CostDict[node];
18+
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);
22+
23+
private static Node end;
1624
public static Queue<Node> FindWay
1725
(
1826
Node start,Node end,
1927
Dictionary<Node, int> nodesMap)
2028
{
29+
Astar.end = end;
2130
Init(nodesMap);
2231

32+
//f(n) = g(n) + h(n),其中f(n)是节点n从初始点到目标点的估价函数
33+
Func<Node, double> F = node => G(node) + H(node, end);
2334

2435
//First Node
2536
CostDict[start] = 0;
@@ -28,11 +39,10 @@ public static Queue<Node> FindWay
2839
open_List.Add(start);
2940

3041
Node? curnode = null;
31-
Func<Node, int> GetMin = node => CostDict[node];
3242
while (!(IsInOpenList(end))) //当终点存在开启列表中就意味着寻路结束了
3343
{
3444
//查找开启列表中cost最小的节点
35-
curnode = GetMinNodeFromArr(open_List, end, GetMin);
45+
curnode = GetMinNodeFromArr(open_List, end, F);
3646

3747
if(null == curnode)
3848
{
@@ -129,143 +139,8 @@ private static void CheckNodeNearby(Node cur)
129139
}
130140
}
131141

132-
/// <summary>
133-
/// 不使用closelist ,算法思想和FindWay没有本质不同
134-
/// </summary>
135-
/// <param name="start"></param>
136-
/// <param name="end"></param>
137-
/// <param name="nodesMap"></param>
138-
/// <param name="NodeCount"></param>
139-
/// <returns></returns>
140-
public static Queue<Node> FindWay2(
141-
Node start,
142-
Node end,
143-
Dictionary<Node, int> nodesMap)
144-
{
145-
//Init
146-
FindPathAlgorithm.Init(nodesMap);
147-
148-
//First Node
149-
canGetMinNodelist.Add(start);
150-
int curcount = 1;
151-
CostDict[start] = 0;
152-
RoadDict[start].Enqueue(start);
153-
Node? curnode = null;
154-
Node cur = start;
155-
Func<Node, int> GetMin = node => CostDict[node];
156-
//Find
157-
while (curcount < NodeCount && cur != end)
158-
{
159-
//查找访问过节点中cost最小的节点
160-
curnode = GetMinNodeFromArr(canGetMinNodelist, end, GetMin);
161-
162-
//无法到达终点
163-
if (null == curnode)
164-
break;
165-
166-
//查找curnode下一个节点中距离终点最近的点
167-
cur = (Node)curnode;
168-
Node? minnode = GetMinNode(cur, end, GetMin);
169-
170-
if (null == minnode)
171-
{
172-
//当前节点无法到达终点
173-
canGetMinNodelist.Remove(cur);
174-
continue;
175-
}
176-
else
177-
{
178-
179-
180-
Node _min = (Node)minnode;
181-
182-
//标记为已访问
183-
visit[_min] = true;
184-
curcount++;
185-
canGetMinNodelist.Add(_min);
186-
187-
//更新路径
188-
CostDict[_min] = CostDict[cur] + NodesMap[_min];
189-
RoadDict[_min].Clear();
190-
foreach (var e in RoadDict[cur])
191-
{
192-
RoadDict[_min].Enqueue(e);
193-
}
194-
RoadDict[_min].Enqueue(_min);
195-
}
196-
}
197-
198-
return RoadDict[end];
199-
}
142+
200143

201-
/// <summary>
202-
/// 以距离为导向的寻路
203-
/// </summary>
204-
/// <param name="start"></param>
205-
/// <param name="end"></param>
206-
/// <param name="nodesMap"></param>
207-
/// <returns></returns>
208-
public static Queue<Node> FindWayGreedy(
209-
Node start,
210-
Node end,
211-
Dictionary<Node, int> nodesMap
212-
)
213-
{
214-
//Init
215-
216-
FindPathAlgorithm.Init(nodesMap);
217-
218-
//First Node
219-
CostDict[start] = 0;
220-
RoadDict[start].Enqueue(start);
221-
222-
Func<Node, int> GetMin = node => (int)(Math.Pow(node.x - end.x, 2) + Math.Pow(node.z - end.z, 2));
223-
224-
canGetMinNodelist.Add(start);
225-
Node? curnode = null;
226-
Node cur = start;
227-
//Find
228-
while (cur != end)
229-
{
230-
//查找访问过节点中距离终点最近的节点
231-
curnode = GetMinNodeFromArr(canGetMinNodelist, end, GetMin);
232-
233-
//无法到达终点
234-
if (null == curnode)
235-
break;
236-
237-
//查找curnode下一个节点中距离终点最近的点
238-
cur = (Node)curnode;
239-
Node? minnode = GetMinNode(cur, end, GetMin);
240-
241-
if (null == minnode)
242-
{
243-
//当前节点无法到达终点
244-
canGetMinNodelist.Remove(cur);
245-
continue;
246-
}
247-
else
248-
{
249-
250-
251-
Node _min = (Node)minnode;
252-
253-
//标记为已访问
254-
visit[_min] = true;
255-
canGetMinNodelist.Add(_min);
256-
257-
//更新路径
258-
CostDict[_min] = CostDict[cur] + NodesMap[_min];
259-
RoadDict[_min].Clear();
260-
foreach (var e in RoadDict[cur])
261-
{
262-
RoadDict[_min].Enqueue(e);
263-
}
264-
RoadDict[_min].Enqueue(_min);
265-
}
266-
}
267-
268-
return RoadDict[end];
269-
}
144+
270145
}
271146
}

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

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,77 @@ public class BFS : FindPathAlgorithm
99
{
1010
private static Dictionary<Node, int> reachCostLeave =
1111
new Dictionary<Node, int>();
12+
13+
/// <summary>
14+
/// 获得保证最小消耗的路径(需要访问所有节点)BFS
15+
/// </summary>
16+
/// <param name="start"></param>
17+
/// <param name="end"></param>
18+
/// <param name="nodesMap"></param>
19+
/// <returns></returns>
20+
public static Queue<Node> FindWay(
21+
Node start,
22+
Node end,
23+
Dictionary<Node, int> nodesMap
24+
)
25+
{
26+
27+
//Init
28+
FindPathAlgorithm.Init(nodesMap);
29+
30+
//First Node
31+
canGetMinNodelist.Add(start);
32+
int curcount = 1;
33+
CostDict[start] = 0;
34+
RoadDict[start].Enqueue(start);
35+
36+
//Find
37+
while (curcount < NodeCount && canGetMinNodelist.Count > 0)
38+
{
39+
//查找访问过节点中距离终点最近的点
40+
Node cur = canGetMinNodelist.First();
41+
42+
//查找cur所能到达的节点列表
43+
List<Node> arr = GetNearbyNode(cur, false);
44+
45+
//遍历列表里的所有的节点
46+
for (int i = 0; i < arr.Count; i++)
47+
{
48+
49+
Node n = arr[i];
50+
51+
//设置为已访问
52+
if (!visit[n])
53+
{
54+
55+
canGetMinNodelist.Add(n);
56+
visit[n] = true;
57+
curcount++;
58+
}
59+
60+
61+
//如果新的路径更短,更新路径
62+
if (CostDict[n] > CostDict[cur] + NodesMap[n])
63+
{
64+
CostDict[n] = CostDict[cur] + NodesMap[n];
65+
66+
RoadDict[n] = new Queue<Node>(NodeCount);
67+
foreach (var e in RoadDict[cur])
68+
{
69+
RoadDict[n].Enqueue(e);
70+
}
71+
RoadDict[n].Enqueue(n);
72+
73+
}
74+
75+
}
76+
canGetMinNodelist.Remove(cur);
77+
78+
79+
}
80+
81+
return RoadDict[end];
82+
}
1283
/// <summary>
1384
/// 战棋游戏人物可到达位置计算
1485
/// </summary>

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

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,20 @@ namespace LinHoweFindPath
88
{
99
public class Dijkstra: FindPathAlgorithm
1010
{
11-
1211

1312
/// <summary>
14-
/// 获得保证最小消耗的路径(需要访问所有节点)BFS
13+
///
1514
/// </summary>
1615
/// <param name="start"></param>
1716
/// <param name="end"></param>
1817
/// <param name="nodesMap"></param>
18+
/// <param name="NodeCount"></param>
1919
/// <returns></returns>
2020
public static Queue<Node> FindWay(
2121
Node start,
2222
Node end,
23-
Dictionary<Node, int> nodesMap
24-
)
23+
Dictionary<Node, int> nodesMap)
2524
{
26-
2725
//Init
2826
Init(nodesMap);
2927

@@ -32,54 +30,54 @@ Dictionary<Node, int> nodesMap
3230
int curcount = 1;
3331
CostDict[start] = 0;
3432
RoadDict[start].Enqueue(start);
35-
33+
Node? curnode = null;
34+
Node cur = start;
35+
Func<Node, double> GetMin = node => CostDict[node];
3636
//Find
37-
while (curcount < NodeCount && canGetMinNodelist.Count > 0)
37+
while (curcount < NodeCount && cur != end)
3838
{
39-
//查找访问过节点中距离终点最近的点
40-
Node cur = canGetMinNodelist.First();
39+
//查找访问过节点中cost最小的节点
40+
curnode = GetMinNodeFromArr(canGetMinNodelist, end, GetMin);
41+
42+
//无法到达终点
43+
if (null == curnode)
44+
break;
4145

42-
//查找cur所能到达的节点列表
43-
List<Node> arr = GetNearbyNode(cur, false);
46+
//查找curnode下一个节点中距离终点最近的点
47+
cur = (Node)curnode;
48+
Node? minnode = GetMinNode(cur, end, GetMin);
4449

45-
//遍历列表里的所有的节点
46-
for (int i = 0; i < arr.Count; i++)
50+
if (null == minnode)
51+
{
52+
//当前节点无法到达终点
53+
canGetMinNodelist.Remove(cur);
54+
continue;
55+
}
56+
else
4757
{
4858

49-
Node n = arr[i];
5059

51-
//设置为已访问
52-
if (!visit[n])
53-
{
60+
Node _min = (Node)minnode;
5461

55-
canGetMinNodelist.Add(n);
56-
visit[n] = true;
57-
curcount++;
58-
}
62+
//标记为已访问
63+
visit[_min] = true;
64+
curcount++;
65+
canGetMinNodelist.Add(_min);
5966

60-
61-
//如果新的路径更短,更新路径
62-
if (CostDict[n] > CostDict[cur] + NodesMap[n])
67+
//更新路径
68+
CostDict[_min] = CostDict[cur] + NodesMap[_min];
69+
RoadDict[_min].Clear();
70+
foreach (var e in RoadDict[cur])
6371
{
64-
CostDict[n] = CostDict[cur] + NodesMap[n];
65-
66-
RoadDict[n] = new Queue<Node>(NodeCount);
67-
foreach (var e in RoadDict[cur])
68-
{
69-
RoadDict[n].Enqueue(e);
70-
}
71-
RoadDict[n].Enqueue(n);
72-
72+
RoadDict[_min].Enqueue(e);
7373
}
74-
74+
RoadDict[_min].Enqueue(_min);
7575
}
76-
canGetMinNodelist.Remove(cur);
77-
78-
7976
}
8077

8178
return RoadDict[end];
8279
}
80+
8381

8482
}
8583
}

0 commit comments

Comments
 (0)