【发布时间】:2013-07-25 10:38:21
【问题描述】:
我实现了递归寻路算法。这种递归算法基于连接在一起的一组预先设置的节点来工作。每个节点都有四个包含进一步方向的指针:Top、Button、Left 和 Right。递归算法只是简单地遍历每个节点,并一个一个地寻找这四个方向中的每一个,以到达其最终目的地;举例说明,考虑以下 7 个节点:A、B、C、D、E、F、G、H。
A (Button->D, Right->B)
B (Right->C, Left->B)
C (Left->B)
D (Button->G, Right->E, Top->A)
E (Right->F, Left->D)
F (Left->E)
G (Right->H, Top->D)
H (Left->G)
这些节点在整体视图中会显示如下图。
A—B—C
|
D—E—F
|
G—H
在这个例子中,假设 walker 开始的节点是节点 A,并且想去节点 H 作为它的最终目的地。节点A按顺序查看自己的Right、Button、Left和Top;它的右边指向节点B,因此他选择去节点B;相同模式的节点 B 选择向右走,节点 C。当步行者到达节点 C 时;由于它的 Right、Top 和 Button 被阻塞,节点 C 恢复到节点 B。节点 B 也恢复到节点 A。walker 再次回到起点。然后节点A根据顺序转到它的按钮节点;这意味着它去节点 D。节点 D 去它的右边节点 E,然后是节点 F。因为节点 F 被阻塞;它返回到节点 E 和节点 D。之后,节点 D 根据 walker 顺序选择去其按钮节点 G。从那里节点 G 到节点 H。最后,步行者到达其最终目的地。
Pseudocode: Recursive Path Finding Algorithm
ArrayList findPath(GameObject currentPoint , GameObject targetPoint , ArrayList InputArrayList)
{
1-Duplicate InputArrayList as tempArrayList
2-If the currentPoint equals to target Point return inputArrayList
//*** End Condition found target
3-If the Right side of the currentPoint is empty goto step 4
3.1- Add currentPoint to tempArrayList
//*** Call Right
3.2- tempArrayList = findPath(currentpoint.Right, targetPoint, tempArrayList);
3.3- If tempArrayList is not null return tempArrayList
4-If the Button side of the currentPoint is empty goto step 5
4.1- Add currentPoint to tempArrayList
//*** Call Button
4.2- tempArrayList = findPath(currentpoint.Button, targetPoint, tempArrayList);
4.3- If tempArrayList is not null return tempArrayList
5-If the Left side of the currentPoint is empty goto step 6
5.1- Add currentPoint to tempArrayList
//*** Call Left
5.2- tempArrayList = findPath(currentpoint.Left, targetPoint, tempArrayList);
5.3- If tempArrayList is not null return tempArrayList
6-If the Top side of the currentPoint is empty goto step 7
6.1- Add currentPoint to tempArrayList
//*** Call Top
6.2- tempArrayList = findPath(currentpoint.Top, targetPoint, tempArrayList);
6.3- If tempArrayList is not null return tempArrayList
7-Return null;
//*** End Condition does not found target
}
注意:实际代码是C#,你可以从link下载。
案例研究中出现的问题: 如您理解此代码;它有一个弱点,可以说明它;考虑以下节点的整体视图,假设起始节点为节点 A,最终目的地为节点 H。
A—B—C
|
D—E—F—I
| | |
G—H—J—K
虽然最好的路径解是(A, D, G, H),但是解释的递归寻路算法找到(A, D, E, F, I, K, J, H)作为它的解;这真的看起来机器人是一个愚蠢的机器人:D!
图 1:递归寻路算法
图 2:具有学习能力的递归寻路算法
我通过添加节点的学习能力解决了这个问题。你可以从这个link 看到问题的细节。但是,我想知道是否有人可以修改递归算法以找到最短路径。
谢谢,
【问题讨论】:
-
+1 精彩演示 :)
-
所有递归需要工作的是实际存储最短路径。现在它会根据您的缠绕顺序(右、左、上、按钮(下?))返回第一个有效的目标路径。在找到
target时不返回路径,而是将currentPath + target 与类成员shortestPath进行比较,如果更短,则存储为新的shortestPath。也就是说,杰弗里的回答方式更具概括性。 -
谢谢@Kay,实际上我在我的博客上写了这个解释,然后在这里过去了:D
-
@Jerdak 感谢您特别纠正我 Button :)) 。你是对的,目前,递归算法返回第一个可能的解决方案。但是,我在这里提出问题的意思是,如何修改递归算法以找到所有可能的解决方案,无论是否有目标设备限制(iPad)。
标签: c# recursion artificial-intelligence unity3d path-finding